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