gitscope
← marzneshin / v0.5.2 / dashboard/src/features/users/components/dialogs/mutation/index.tsx
https://dev.kronoz.win/r/marzneshin.git
dashboard/src/features/users/components/dialogs/mutation/index.tsx · TypeScript
Blame Raw
 1import { type FC, useMemo } from "react";
 2import {
 3    Separator,
 4    DialogTitle,
 5    DialogContent,
 6    Dialog,
 7    DialogHeader,
 8    Form,
 9    Button,
10    ScrollArea,
11    VStack,
12} from "@marzneshin/components";
13import { useTranslation } from "react-i18next";
14import {
15    DATA_LIMIT_METRIC,
16    useUsersCreationMutation,
17    useUsersUpdateMutation,
18    UserSchema,
19    UsernameField,
20    type UserMutationType,
21} from "@marzneshin/features/users";
22import { ServicesField } from "@marzneshin/features/services";
23import { NoteField } from "./fields";
24import { type MutationDialogProps, useMutationDialog } from "@marzneshin/hooks";
25import { DataLimitFields, ExpirationMethodFields } from "./sections";
26
27export const UsersMutationDialog: FC<MutationDialogProps<UserMutationType>> = ({
28    entity,
29    onClose,
30}) => {
31    const { t } = useTranslation();
32    const defaultValue = useMemo(
33        () => ({
34            service_ids: [],
35            username: "",
36            data_limit_reset_strategy: "no_reset",
37            note: "",
38            expire_date: "",
39            expire_strategy: "fixed_date",
40        }),
41        [],
42    );
43
44    const { open, onOpenChange, form, handleSubmit } = useMutationDialog({
45        entity,
46        onClose,
47        createMutation: useUsersCreationMutation(),
48        updateMutation: useUsersUpdateMutation(),
49        schema: UserSchema,
50        defaultValue,
51        loadFormtter: (d) => ({
52            ...d,
53            data_limit: (d.data_limit ? d.data_limit : 0) / DATA_LIMIT_METRIC,
54        }),
55    });
56
57    return (
58        <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
59            <DialogContent className="min-w-full h-full md:h-auto md:min-w-[42rem]">
60                <ScrollArea className="flex flex-col justify-between h-full ">
61                    <DialogHeader className="mb-3">
62                        <DialogTitle className="text-primary">
63                            {entity
64                                ? t("page.users.dialogs.edition.title")
65                                : t("page.users.dialogs.creation.title")}
66                        </DialogTitle>
67                    </DialogHeader>
68                    <Form {...form}>
69                        <form onSubmit={handleSubmit}>
70                            <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid h-full">
71                                <div className="space-y-3">
72                                    <UsernameField disabled={!!entity?.username} />
73                                    <Separator />
74                                    <DataLimitFields />
75                                    <Separator />
76                                    <ExpirationMethodFields entity={entity} />
77                                    <Separator />
78                                    <NoteField />
79                                </div>
80                                <VStack>
81                                    <ServicesField />
82                                </VStack>
83                            </div>
84                            <Button
85                                className="mt-3 w-full font-semibold"
86                                type="submit"
87                                disabled={form.formState.isSubmitting}
88                            >
89                                {t("submit")}
90                            </Button>
91                        </form>
92                    </Form>
93                </ScrollArea>
94            </DialogContent>
95        </Dialog>
96    );
97};