1import { type FC, useEffect, useCallback } 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 type { UserMutationType } from "@marzneshin/features/users";
15import {
16 DATA_LIMIT_METRIC,
17 useUsersCreationMutation,
18 useUsersUpdateMutation,
19 UserSchema,
20} from "@marzneshin/features/users";
21import { UsernameField, NoteField, ServicesField } from "./fields";
22import { useMutationDialog } from "@marzneshin/hooks";
23import { DataLimitFields, ExpirationMethodFields } from "./sections";
24
25interface UsersMutationDialogProps {
26 entity: UserMutationType | null;
27 open: boolean;
28 onOpenChange: (state: boolean) => void;
29 onClose: () => void;
30}
31
32export const UsersMutationDialog: FC<UsersMutationDialogProps> = ({
33 entity,
34 open,
35 onOpenChange,
36 onClose,
37}) => {
38 const { t } = useTranslation();
39 const getDefaultValues = useCallback(
40 (): UserMutationType => ({
41 service_ids: [],
42 expire_strategy: "fixed_date",
43 username: "",
44 data_limit_reset_strategy: "no_reset",
45 note: "",
46 }),
47 [],
48 );
49
50 const { form, handleSubmit } = useMutationDialog({
51 entity,
52 onOpenChange,
53 createMutation: useUsersCreationMutation(),
54 updateMutation: useUsersUpdateMutation(),
55 schema: UserSchema,
56 getDefaultValue: getDefaultValues,
57 loadFormtter: (d) => ({
58 ...d,
59 data_limit: (d.data_limit ? d.data_limit : 0) / DATA_LIMIT_METRIC,
60 }),
61 });
62
63 useEffect(() => {
64 if (!open) onClose();
65 }, [open, onClose]);
66
67 return (
68 <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
69 <DialogContent className="min-w-full h-full md:h-auto md:min-w-[42rem]">
70 <ScrollArea className="flex flex-col justify-between h-full ">
71 <DialogHeader className="mb-3">
72 <DialogTitle className="text-primary">
73 {entity
74 ? t("page.users.dialogs.edition.title")
75 : t("page.users.dialogs.creation.title")}
76 </DialogTitle>
77 </DialogHeader>
78 <Form {...form}>
79 <form onSubmit={handleSubmit} >
80 <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid h-full">
81 <div className="space-y-3">
82 <UsernameField disabled={!!entity?.username} />
83 <Separator />
84 <DataLimitFields />
85 <Separator />
86 <ExpirationMethodFields entity={entity} />
87 <Separator />
88 <NoteField />
89 </div>
90 <VStack>
91 <ServicesField />
92 </VStack>
93 </div>
94 <Button
95 className="mt-3 w-full font-semibold"
96 type="submit"
97 disabled={form.formState.isSubmitting}
98 >
99 {t("submit")}
100 </Button>
101 </form>
102 </Form>
103 </ScrollArea>
104 </DialogContent>
105 </Dialog>
106 );
107};