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/common/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/modules/users";
22import { ServicesField } from "@marzneshin/modules/services";
23import { NoteField } from "./fields";
24import { type MutationDialogProps, useMutationDialog } from "@marzneshin/common/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 data_limit: undefined,
38 note: "",
39 expire_date: "",
40 expire_strategy: "fixed_date",
41 }),
42 [],
43 );
44
45 const { open, onOpenChange, form, handleSubmit } = useMutationDialog({
46 entity,
47 onClose,
48 createMutation: useUsersCreationMutation(),
49 updateMutation: useUsersUpdateMutation(),
50 schema: UserSchema,
51 defaultValue,
52 loadFormtter: (d) => ({
53 ...d,
54 data_limit: (d.data_limit ? d.data_limit : 0) / DATA_LIMIT_METRIC,
55 }),
56 });
57
58 return (
59 <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
60 <DialogContent className="min-w-full h-full md:h-auto md:min-w-[42rem]">
61 <ScrollArea className="flex flex-col justify-between h-full ">
62 <DialogHeader className="mb-3">
63 <DialogTitle className="text-primary">
64 {entity
65 ? t("page.users.dialogs.edition.title")
66 : t("page.users.dialogs.creation.title")}
67 </DialogTitle>
68 </DialogHeader>
69 <Form {...form}>
70 <form onSubmit={handleSubmit}>
71 <div className="flex-col grid-cols-2 gap-2 sm:flex md:grid h-full">
72 <div className="space-y-3">
73 <UsernameField disabled={!!entity?.username} />
74 <Separator />
75 <DataLimitFields />
76 <Separator />
77 <ExpirationMethodFields entity={entity} />
78 <Separator />
79 <NoteField />
80 </div>
81 <VStack>
82 <ServicesField />
83 </VStack>
84 </div>
85 <Button
86 className="mt-3 w-full font-semibold"
87 type="submit"
88 disabled={form.formState.isSubmitting}
89 >
90 {t("submit")}
91 </Button>
92 </form>
93 </Form>
94 </ScrollArea>
95 </DialogContent>
96 </Dialog>
97 );
98};