1import { FC, useCallback, useEffect, useState } from "react";
2import {
3 DialogTitle,
4 DialogContent,
5 Dialog,
6 DialogHeader,
7 Form,
8 Button,
9 Tabs,
10 TabsTrigger,
11 TabsContent
12} from '@marzneshin/components';
13import { useTranslation } from 'react-i18next';
14import {
15 UserMutationType,
16 useUsersCreationMutation,
17 useUsersUpdateMutation
18} from "@marzneshin/features/users";
19import { UserSchema } from "./schema";
20import {
21 UsernameField,
22 DataLimitField,
23 ExpireDateField,
24 DataLimitResetStrategyField,
25 NoteField,
26 ServicesField,
27} from "./fields";
28import { useMutationDialog } from "@marzneshin/hooks";
29import { TabsList } from "@radix-ui/react-tabs";
30import { OnHoldExpireDurationField } from "./fields/onhold-expire-duration";
31import { OnHoldTimeoutField } from "./fields/onhold-timeout";
32
33interface UsersMutationDialogProps {
34 entity: UserMutationType | null;
35 open: boolean;
36 onOpenChange: (state: boolean) => void;
37}
38
39export const UsersMutationDialog: FC<UsersMutationDialogProps> = ({
40 entity,
41 open,
42 onOpenChange,
43}) => {
44 const { t } = useTranslation();
45 const getDefaultValues = useCallback((): UserMutationType => ({
46 services: [],
47 data_limit: 0,
48 expire: null,
49 username: '',
50 data_limit_reset_strategy: 'no_reset',
51 status: 'active',
52 note: '',
53 on_hold_expire_duration: 0,
54 on_hold_timeout: null,
55 }), []);
56
57 const [services, setServices] = useState<number[]>(entity ? entity.services : [])
58
59 const { form, handleSubmit } = useMutationDialog({
60 entity,
61 onOpenChange,
62 createMutation: useUsersCreationMutation(),
63 updateMutation: useUsersUpdateMutation(),
64 schema: UserSchema,
65 getDefaultValue: getDefaultValues,
66 })
67
68 useEffect(() => {
69 form.setValue("services", services.map(Number).filter(item => typeof item === 'number'))
70 }, [services, form])
71
72
73 const [selectedTab, setSelectedTab] = useState<'determined' | 'onhold' | string>('determined');
74
75 useEffect(() => {
76 if (selectedTab === 'onhold') {
77 form.setValue("status", "on_hold")
78 form.setValue("expire", null);
79 form.clearErrors("expire");
80 } else {
81 form.setValue("status", "active")
82 form.setValue("on_hold_expire_duration", 0);
83 form.setValue("on_hold_timeout", null);
84 form.clearErrors("on_hold_expire_duration");
85 form.clearErrors("on_hold_timeout");
86 }
87 }, [selectedTab, form]);
88
89 return (
90 <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
91 <DialogContent>
92 <DialogHeader>
93 <DialogTitle className="text-primary">
94 {entity
95 ? t('page.users.dialogs.edition.title')
96 : t('page.users.dialogs.creation.title')}
97 </DialogTitle>
98 </DialogHeader>
99 <Form {...form}>
100 <form onSubmit={handleSubmit}>
101 <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid">
102 <div>
103 <UsernameField />
104 <div className="flex gap-2 items-center w-full sm:flex-row md:flex-col">
105 <DataLimitField />
106 {form.watch().data_limit !== 0 && <DataLimitResetStrategyField />}
107 </div>
108 <Tabs defaultValue="determined" onValueChange={setSelectedTab} className="mt-2 w-full">
109 <TabsList className="flex flex-row items-center p-1 w-full rounded-md bg-accent">
110 <TabsTrigger
111 className="w-full"
112 value="determined">
113 {t('page.users.determined_expire')}
114 </TabsTrigger>
115 <TabsTrigger
116 className="w-full"
117 value="onhold">
118 {t('page.users.onhold_expire')}
119 </TabsTrigger>
120 </TabsList>
121 <TabsContent value="determined">
122 <ExpireDateField />
123 </TabsContent>
124 <TabsContent value="onhold">
125 <OnHoldExpireDurationField />
126 <OnHoldTimeoutField />
127 </TabsContent>
128 </Tabs>
129 <NoteField />
130 </div>
131 <div>
132 <ServicesField services={services} setServices={setServices} />
133 </div>
134 </div>
135 <Button
136 className="mt-3 w-full font-semibold"
137 type="submit"
138 disabled={form.formState.isSubmitting}
139 >
140 {t('submit')}
141 </Button>
142 </form>
143 </Form>
144 </DialogContent>
145 </Dialog>
146 );
147};