gitscope
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/users/dialogs/mutation/index.tsx · v0.3.0-alpha8
Source
1 857e289 Mrdn 2y ago import { FC, useCallback, useEffect, useState } from "react";
2 857e289 Mrdn 2y ago import {
3 857e289 Mrdn 2y ago DialogTitle,
4 857e289 Mrdn 2y ago DialogContent,
5 857e289 Mrdn 2y ago Dialog,
6 857e289 Mrdn 2y ago DialogHeader,
7 857e289 Mrdn 2y ago Form,
8 857e289 Mrdn 2y ago Button,
9 857e289 Mrdn 2y ago Tabs,
10 857e289 Mrdn 2y ago TabsTrigger,
11 7707f15 Mrdn 2y ago TabsContent,
12 7707f15 Mrdn 2y ago FormLabel
13 857e289 Mrdn 2y ago } from '@marzneshin/components';
14 857e289 Mrdn 2y ago import { useTranslation } from 'react-i18next';
15 857e289 Mrdn 2y ago import {
16 857e289 Mrdn 2y ago UserMutationType,
17 857e289 Mrdn 2y ago useUsersCreationMutation,
18 857e289 Mrdn 2y ago useUsersUpdateMutation
19 857e289 Mrdn 2y ago } from "@marzneshin/features/users";
20 857e289 Mrdn 2y ago import { UserSchema } from "./schema";
21 857e289 Mrdn 2y ago import {
22 857e289 Mrdn 2y ago UsernameField,
23 857e289 Mrdn 2y ago DataLimitField,
24 857e289 Mrdn 2y ago ExpireDateField,
25 857e289 Mrdn 2y ago DataLimitResetStrategyField,
26 857e289 Mrdn 2y ago NoteField,
27 857e289 Mrdn 2y ago ServicesField,
28 857e289 Mrdn 2y ago } from "./fields";
29 857e289 Mrdn 2y ago import { useMutationDialog } from "@marzneshin/hooks";
30 857e289 Mrdn 2y ago import { TabsList } from "@radix-ui/react-tabs";
31 857e289 Mrdn 2y ago import { OnHoldExpireDurationField } from "./fields/onhold-expire-duration";
32 857e289 Mrdn 2y ago import { OnHoldTimeoutField } from "./fields/onhold-timeout";
33 857e289 Mrdn 2y ago
34 857e289 Mrdn 2y ago interface UsersMutationDialogProps {
35 857e289 Mrdn 2y ago entity: UserMutationType | null;
36 857e289 Mrdn 2y ago open: boolean;
37 857e289 Mrdn 2y ago onOpenChange: (state: boolean) => void;
38 857e289 Mrdn 2y ago }
39 857e289 Mrdn 2y ago
40 857e289 Mrdn 2y ago export const UsersMutationDialog: FC<UsersMutationDialogProps> = ({
41 857e289 Mrdn 2y ago entity,
42 857e289 Mrdn 2y ago open,
43 857e289 Mrdn 2y ago onOpenChange,
44 857e289 Mrdn 2y ago }) => {
45 857e289 Mrdn 2y ago const { t } = useTranslation();
46 857e289 Mrdn 2y ago const getDefaultValues = useCallback((): UserMutationType => ({
47 857e289 Mrdn 2y ago services: [],
48 79c373b Mrdn 2y ago data_limit: 1,
49 857e289 Mrdn 2y ago expire: null,
50 857e289 Mrdn 2y ago username: '',
51 857e289 Mrdn 2y ago data_limit_reset_strategy: 'no_reset',
52 857e289 Mrdn 2y ago status: 'active',
53 857e289 Mrdn 2y ago note: '',
54 857e289 Mrdn 2y ago on_hold_expire_duration: 0,
55 766b9d1 Mrdn 2y ago on_hold_timeout: undefined,
56 857e289 Mrdn 2y ago }), []);
57 857e289 Mrdn 2y ago
58 857e289 Mrdn 2y ago
59 857e289 Mrdn 2y ago const { form, handleSubmit } = useMutationDialog({
60 857e289 Mrdn 2y ago entity,
61 857e289 Mrdn 2y ago onOpenChange,
62 857e289 Mrdn 2y ago createMutation: useUsersCreationMutation(),
63 857e289 Mrdn 2y ago updateMutation: useUsersUpdateMutation(),
64 857e289 Mrdn 2y ago schema: UserSchema,
65 857e289 Mrdn 2y ago getDefaultValue: getDefaultValues,
66 857e289 Mrdn 2y ago })
67 857e289 Mrdn 2y ago
68 79c373b Mrdn 2y ago const [
69 79c373b Mrdn 2y ago selectedDataLimitTab,
70 79c373b Mrdn 2y ago setSelectedDataLimitTab
71 79c373b Mrdn 2y ago ] = useState<'limited' | 'unlimited' | string>('limited');
72 79c373b Mrdn 2y ago useEffect(() => {
73 79c373b Mrdn 2y ago if (selectedDataLimitTab === 'limited') {
74 79c373b Mrdn 2y ago form.setValue("data_limit", 1)
75 79c373b Mrdn 2y ago form.setValue("data_limit_reset_strategy", "no_reset");
76 79c373b Mrdn 2y ago } else {
77 79c373b Mrdn 2y ago form.setValue("data_limit", 0)
78 79c373b Mrdn 2y ago form.setValue("data_limit_reset_strategy", "no_reset");
79 79c373b Mrdn 2y ago }
80 79c373b Mrdn 2y ago }, [selectedDataLimitTab, form]);
81 79c373b Mrdn 2y ago
82 39380ee Mrdn 2y ago const getUserExpirationMethod = useCallback((entity: UserMutationType) => {
83 39380ee Mrdn 2y ago if (entity.status === "on_hold")
84 39380ee Mrdn 2y ago return 'onhold'
85 39380ee Mrdn 2y ago else if (entity.expire !== undefined)
86 39380ee Mrdn 2y ago return 'determined'
87 39380ee Mrdn 2y ago else
88 39380ee Mrdn 2y ago return 'unlimited'
89 39380ee Mrdn 2y ago }, [])
90 2e70304 Mrdn 2y ago
91 39380ee Mrdn 2y ago const defaultExpirationMethodTab = entity?.username ? getUserExpirationMethod(entity) : 'determined'
92 79c373b Mrdn 2y ago const [
93 79c373b Mrdn 2y ago selectedExpirationMethodTab,
94 79c373b Mrdn 2y ago setSelectedExpirationMethodTab
95 39380ee Mrdn 2y ago ] = useState<'determined' | 'onhold' | 'unlimited' | string>(defaultExpirationMethodTab);
96 39380ee Mrdn 2y ago
97 857e289 Mrdn 2y ago useEffect(() => {
98 97ed755 Mrdn 2y ago form.setValue("status", "active")
99 79c373b Mrdn 2y ago if (selectedExpirationMethodTab === 'onhold') {
100 857e289 Mrdn 2y ago form.setValue("status", "on_hold")
101 857e289 Mrdn 2y ago form.setValue("expire", null);
102 857e289 Mrdn 2y ago form.clearErrors("expire");
103 79c373b Mrdn 2y ago } else if (selectedExpirationMethodTab === "unlimited") {
104 2e70304 Mrdn 2y ago form.setValue("expire", undefined);
105 2e70304 Mrdn 2y ago form.setValue("on_hold_expire_duration", undefined);
106 766b9d1 Mrdn 2y ago form.setValue("on_hold_timeout", undefined);
107 7707f15 Mrdn 2y ago form.clearErrors("expire");
108 7707f15 Mrdn 2y ago form.clearErrors("on_hold_expire_duration");
109 7707f15 Mrdn 2y ago form.clearErrors("on_hold_timeout");
110 857e289 Mrdn 2y ago } else {
111 857e289 Mrdn 2y ago form.setValue("on_hold_expire_duration", 0);
112 857e289 Mrdn 2y ago form.setValue("on_hold_timeout", null);
113 857e289 Mrdn 2y ago form.clearErrors("on_hold_expire_duration");
114 857e289 Mrdn 2y ago form.clearErrors("on_hold_timeout");
115 857e289 Mrdn 2y ago }
116 79c373b Mrdn 2y ago }, [selectedExpirationMethodTab, form]);
117 857e289 Mrdn 2y ago
118 857e289 Mrdn 2y ago return (
119 857e289 Mrdn 2y ago <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
120 7707f15 Mrdn 2y ago <DialogContent className="sm:max-w-full md:max-w-[600px]">
121 857e289 Mrdn 2y ago <DialogHeader>
122 857e289 Mrdn 2y ago <DialogTitle className="text-primary">
123 857e289 Mrdn 2y ago {entity
124 857e289 Mrdn 2y ago ? t('page.users.dialogs.edition.title')
125 857e289 Mrdn 2y ago : t('page.users.dialogs.creation.title')}
126 857e289 Mrdn 2y ago </DialogTitle>
127 857e289 Mrdn 2y ago </DialogHeader>
128 857e289 Mrdn 2y ago <Form {...form}>
129 857e289 Mrdn 2y ago <form onSubmit={handleSubmit}>
130 857e289 Mrdn 2y ago <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid">
131 857e289 Mrdn 2y ago <div>
132 857e289 Mrdn 2y ago <UsernameField />
133 79c373b Mrdn 2y ago <FormLabel>
134 79c373b Mrdn 2y ago {t('page.users.data_limit_method')}
135 79c373b Mrdn 2y ago </FormLabel>
136 857e289 Mrdn 2y ago <div className="flex gap-2 items-center w-full sm:flex-row md:flex-col">
137 79c373b Mrdn 2y ago <Tabs defaultValue="limited" onValueChange={setSelectedDataLimitTab} className="mt-2 w-full">
138 79c373b Mrdn 2y ago <TabsList className="flex flex-row items-center p-1 w-full rounded-md bg-accent">
139 79c373b Mrdn 2y ago <TabsTrigger
140 79c373b Mrdn 2y ago className="w-full"
141 79c373b Mrdn 2y ago value="limited">
142 79c373b Mrdn 2y ago {t('page.users.limited')}
143 79c373b Mrdn 2y ago </TabsTrigger>
144 79c373b Mrdn 2y ago <TabsTrigger
145 79c373b Mrdn 2y ago className="w-full"
146 79c373b Mrdn 2y ago value="unlimited">
147 79c373b Mrdn 2y ago {t('page.users.unlimited')}
148 79c373b Mrdn 2y ago </TabsTrigger>
149 79c373b Mrdn 2y ago </TabsList>
150 79c373b Mrdn 2y ago <TabsContent value="limited">
151 79c373b Mrdn 2y ago <DataLimitField />
152 79c373b Mrdn 2y ago {form.watch().data_limit !== 0 && <DataLimitResetStrategyField />}
153 79c373b Mrdn 2y ago </TabsContent>
154 79c373b Mrdn 2y ago </Tabs>
155 857e289 Mrdn 2y ago </div>
156 7707f15 Mrdn 2y ago <FormLabel>
157 7707f15 Mrdn 2y ago {t('page.users.expire_method')}
158 7707f15 Mrdn 2y ago </FormLabel>
159 39380ee Mrdn 2y ago <Tabs defaultValue={defaultExpirationMethodTab} onValueChange={setSelectedExpirationMethodTab} className="mt-2 w-full">
160 857e289 Mrdn 2y ago <TabsList className="flex flex-row items-center p-1 w-full rounded-md bg-accent">
161 857e289 Mrdn 2y ago <TabsTrigger
162 857e289 Mrdn 2y ago className="w-full"
163 857e289 Mrdn 2y ago value="determined">
164 857e289 Mrdn 2y ago {t('page.users.determined_expire')}
165 857e289 Mrdn 2y ago </TabsTrigger>
166 857e289 Mrdn 2y ago <TabsTrigger
167 857e289 Mrdn 2y ago className="w-full"
168 857e289 Mrdn 2y ago value="onhold">
169 857e289 Mrdn 2y ago {t('page.users.onhold_expire')}
170 857e289 Mrdn 2y ago </TabsTrigger>
171 7707f15 Mrdn 2y ago <TabsTrigger
172 7707f15 Mrdn 2y ago className="w-full"
173 7707f15 Mrdn 2y ago value="unlimited">
174 7707f15 Mrdn 2y ago {t('page.users.unlimited')}
175 7707f15 Mrdn 2y ago </TabsTrigger>
176 857e289 Mrdn 2y ago </TabsList>
177 857e289 Mrdn 2y ago <TabsContent value="determined">
178 857e289 Mrdn 2y ago <ExpireDateField />
179 857e289 Mrdn 2y ago </TabsContent>
180 857e289 Mrdn 2y ago <TabsContent value="onhold">
181 857e289 Mrdn 2y ago <OnHoldExpireDurationField />
182 857e289 Mrdn 2y ago <OnHoldTimeoutField />
183 857e289 Mrdn 2y ago </TabsContent>
184 857e289 Mrdn 2y ago </Tabs>
185 857e289 Mrdn 2y ago <NoteField />
186 857e289 Mrdn 2y ago </div>
187 857e289 Mrdn 2y ago <div>
188 97ed755 Mrdn 2y ago <ServicesField />
189 857e289 Mrdn 2y ago </div>
190 857e289 Mrdn 2y ago </div>
191 857e289 Mrdn 2y ago <Button
192 857e289 Mrdn 2y ago className="mt-3 w-full font-semibold"
193 857e289 Mrdn 2y ago type="submit"
194 857e289 Mrdn 2y ago disabled={form.formState.isSubmitting}
195 857e289 Mrdn 2y ago >
196 857e289 Mrdn 2y ago {t('submit')}
197 857e289 Mrdn 2y ago </Button>
198 857e289 Mrdn 2y ago </form>
199 857e289 Mrdn 2y ago </Form>
200 857e289 Mrdn 2y ago </DialogContent>
201 857e289 Mrdn 2y ago </Dialog>
202 857e289 Mrdn 2y ago );
203 857e289 Mrdn 2y ago };