https://dev.kronoz.win/r/marzneshin.git
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<{ label: string; value: string | number | JSX.Element }> = ({ label, value }) => (
29 <TableRow>
30 <TableCell>{label}</TableCell>
31 <TableCell>{value}</TableCell>
32 </TableRow>
33);
34
35const DateTableRow: FC<{ label: string; date: Date | string }> = ({ label, date }) => {
36 let formattedDate = '';
37 if (date && isValid(date)) {
38 formattedDate = format(date, "PPP");
39 }
40 return (
41 <TableRowWithCell label={label} value={formattedDate} />
42 );
43};
44
45const CircularProgressBarRow: FC<{ label: string; value: number; limit: number }> = ({ label, value, limit }) => (
46 <TableRow>
47 <TableCell>{label}</TableCell>
48 <TableCell><CircularProgress size="sm" value={value / limit * 100} /></TableCell>
49 </TableRow>
50);
51
52export const UserInfoTable: FC<UserInfoTableProps> = ({ entity }) => {
53 const { t } = useTranslation();
54 const { mutate: resetUsage } = useUserUsageResetCmd()
55 const expireDate = entity.expire ? (isDate(entity.expire) ? entity.expire : new Date(entity.expire)) : null;
56
57 return (
58 <Card>
59 <CardHeader className="flex flex-row justify-between items-center w-full">
60 <CardTitle>{t('user_info')}</CardTitle>
61 <div className="flex flex-row justify-center items-center gap-3">
62 <Button onClick={() => resetUsage(entity)}>
63 {t('page.users.reset_usage')}
64 </Button>
65 <UserStatusEnableButton user={entity} />
66 </div>
67 </CardHeader>
68 <CardContent>
69 <Table>
70 <TableBody>
71 <TableRowWithCell label={t('username')} value={entity.username} />
72 <TableRowWithCell label={t('status')} value={<UsersStatusBadge status={UsersStatus[entity.status]} />} />
73 {(expireDate && entity.on_hold_expire_duration === 0) ? (
74 <DateTableRow label={t('page.users.expire_date')} date={expireDate} />
75 ) : (
76 <>
77 <TableRowWithCell label={t('page.users.on_hold_expire_duration')} value={entity.on_hold_expire_duration} />
78 {entity.on_hold_timeout &&
79 <DateTableRow label={t('page.users.expire_date')} date={entity.on_hold_timeout} />
80 }
81 </>
82 )}
83 {entity.data_limit &&
84 <CircularProgressBarRow label={t('page.users.used_traffic')} value={entity.used_traffic} limit={entity.data_limit} />
85 }
86 <DateTableRow label={t('page.users.online_at')} date={entity.online_at} />
87 <TableRowWithCell label={t('note')} value={entity.note} />
88 </TableBody>
89 </Table>
90 </CardContent>
91 </Card>
92 );
93};