gitscope
← marzneshin / v0.3.0 / dashboard/src/features/users/dialogs/settings/user-info/table.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/users/dialogs/settings/user-info/table.tsx · TypeScript
Blame Raw
  1import {
  2    Button,
  3    Card,
  4    CardContent,
  5    CardHeader,
  6    CardTitle,
  7    Table,
  8    TableBody,
  9    TableCell,
 10    TableRow,
 11} from "@marzneshin/components";
 12import { FC } from "react";
 13import {
 14    useUserUsageResetCmd,
 15    UserType,
 16    UsersStatus,
 17    UsersStatusBadge,
 18} from "@marzneshin/features/users";
 19import { CircularProgress } from "@nextui-org/progress";
 20import { useTranslation } from "react-i18next";
 21import { format, isDate, isValid } from "date-fns";
 22import { UserStatusEnableButton } from "./user-status-enable-button";
 23
 24interface UserInfoTableProps {
 25    entity: UserType;
 26}
 27
 28const TableRowWithCell: FC<{
 29    label: string;
 30    value: string | number | JSX.Element;
 31}> = ({ label, value }) => (
 32    <TableRow>
 33        <TableCell>{label}</TableCell>
 34        <TableCell>{value}</TableCell>
 35    </TableRow>
 36);
 37
 38const DateTableRow: FC<{ label: string; date: Date | string }> = ({
 39    label,
 40    date,
 41}) => {
 42    let formattedDate = "";
 43    if (date && isValid(date)) {
 44        formattedDate = format(date, "PPP");
 45    }
 46    return <TableRowWithCell label={label} value={formattedDate} />;
 47};
 48
 49const CircularProgressBarRow: FC<{
 50    label: string;
 51    value: number;
 52    limit: number;
 53}> = ({ label, value, limit }) => (
 54    <TableRow>
 55        <TableCell>{label}</TableCell>
 56        <TableCell>
 57            <CircularProgress size="sm" value={(value / limit) * 100} />
 58        </TableCell>
 59    </TableRow>
 60);
 61
 62export const UserInfoTable: FC<UserInfoTableProps> = ({ entity }) => {
 63    const { t } = useTranslation();
 64    const { mutate: resetUsage } = useUserUsageResetCmd();
 65    const expireDate = entity.expire
 66        ? isDate(entity.expire)
 67            ? entity.expire
 68            : new Date(entity.expire)
 69        : null;
 70
 71    return (
 72        <Card>
 73            <CardHeader className="flex flex-row justify-between items-center w-full">
 74                <CardTitle>{t("user_info")}</CardTitle>
 75            </CardHeader>
 76            <CardContent>
 77                <Table>
 78                    <TableBody>
 79                        <TableRowWithCell label={t("username")} value={entity.username} />
 80                        <TableRowWithCell
 81                            label={t("status")}
 82                            value={<UsersStatusBadge status={UsersStatus[entity.status]} />}
 83                        />
 84                        {expireDate && entity.on_hold_expire_duration === 0 ? (
 85                            <DateTableRow
 86                                label={t("page.users.expire_date")}
 87                                date={expireDate}
 88                            />
 89                        ) : (
 90                            <>
 91                                <TableRowWithCell
 92                                    label={t("page.users.on_hold_expire_duration")}
 93                                    value={entity.on_hold_expire_duration}
 94                                />
 95                                {entity.on_hold_timeout && (
 96                                    <DateTableRow
 97                                        label={t("page.users.expire_date")}
 98                                        date={entity.on_hold_timeout}
 99                                    />
100                                )}
101                            </>
102                        )}
103                        {entity.data_limit && (
104                            <CircularProgressBarRow
105                                label={t("page.users.used_traffic")}
106                                value={entity.used_traffic}
107                                limit={entity.data_limit}
108                            />
109                        )}
110                        <DateTableRow
111                            label={t("page.users.online_at")}
112                            date={entity.online_at}
113                        />
114                        <TableRowWithCell label={t("note")} value={entity.note} />
115                    </TableBody>
116                </Table>
117                <div className="flex flex-row justify-center items-center gap-2">
118                    <Button className="w-full" onClick={() => resetUsage(entity)}>
119                        {t("page.users.reset_usage")}
120                    </Button>
121                    <UserStatusEnableButton user={entity} />
122                </div>
123            </CardContent>
124        </Card>
125    );
126};