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