1import { type FC, useMemo } from "react";
2import {
3 DialogTitle,
4 DialogContent,
5 Dialog,
6 DialogHeader,
7 Form,
8 FormItem,
9 FormControl,
10 FormMessage,
11 FormLabel,
12 Input,
13 FormField,
14 Button,
15 Select,
16 SelectContent,
17 SelectItem,
18 SelectTrigger,
19 SelectValue,
20 FormDescription,
21 HStack,
22} from "@marzneshin/common/components";
23import { useTranslation } from "react-i18next";
24import {
25 NodeSchema,
26 useNodesCreationMutation,
27 useNodesUpdateMutation,
28} from "../..";
29import type { NodeType } from "../..";
30import { useMutationDialog, MutationDialogProps } from "@marzneshin/common/hooks";
31
32export const MutationDialog: FC<MutationDialogProps<NodeType>> = ({
33 entity,
34 onClose,
35}) => {
36 const updateMutation = useNodesUpdateMutation();
37 const createMutation = useNodesCreationMutation();
38 const { t } = useTranslation();
39
40 const defaultValue = useMemo(() => ({
41 id: 0,
42 name: "",
43 address: "",
44 status: "none",
45 port: 62050,
46 usage_coefficient: 1,
47 connection_backend: "grpclib",
48 }), []);
49
50 const { onOpenChange, open, form, handleSubmit } = useMutationDialog({
51 entity,
52 onClose,
53 schema: NodeSchema,
54 createMutation,
55 updateMutation,
56 defaultValue,
57 });
58
59 return (
60 <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
61 <DialogContent>
62 <DialogHeader>
63 <DialogTitle className="text-primary">
64 {entity
65 ? t("page.nodes.dialogs.edition.title")
66 : t("page.nodes.dialogs.creation.title")}
67 </DialogTitle>
68 </DialogHeader>
69 <Form {...form}>
70 <form onSubmit={handleSubmit}>
71 <FormField
72 control={form.control}
73 name="name"
74 render={({ field }) => (
75 <FormItem className="w-full">
76 <FormLabel>{t("name")}</FormLabel>
77 <FormControl>
78 <Input {...field} />
79 </FormControl>
80 <FormMessage />
81 </FormItem>
82 )}
83 />
84 <div className="flex flex-row gap-2 items-center">
85 <FormField
86 control={form.control}
87 name="address"
88 render={({ field }) => (
89 <FormItem className="w-2/3">
90 <FormLabel>{t("address")}</FormLabel>
91 <FormControl>
92 <Input {...field} />
93 </FormControl>
94 <FormMessage />
95 </FormItem>
96 )}
97 />
98 <FormField
99 control={form.control}
100 name="port"
101 render={({ field }) => (
102 <FormItem className="w-1/3">
103 <FormLabel>{t("port")}</FormLabel>
104 <FormControl>
105 <Input type="number" {...field} />
106 </FormControl>
107 <FormMessage />
108 </FormItem>
109 )}
110 />
111 </div>
112 <HStack>
113 <FormField
114 control={form.control}
115 name="connection_backend"
116 render={({ field }) => (
117 <FormItem className="w-full">
118 <FormLabel>{t("page.nodes.connection_backend")}</FormLabel>
119 <Select
120 onValueChange={field.onChange}
121 defaultValue={field.value}
122 >
123 <FormControl>
124 <SelectTrigger>
125 <SelectValue placeholder="Nodes Connection" />
126 </SelectTrigger>
127 </FormControl>
128 <SelectContent>
129 <SelectItem value="grpclib">grpclib</SelectItem>
130 <SelectItem value="grpcio">grpcio</SelectItem>
131 </SelectContent>
132 </Select>
133 <FormDescription>
134 {t("page.nodes.connection_backend_desc")}
135 </FormDescription>
136 <FormMessage />
137 </FormItem>
138 )}
139 />
140 <FormField
141 control={form.control}
142 name="usage_coefficient"
143 render={({ field }) => (
144 <FormItem className="w-1/2">
145 <FormLabel>{t("page.nodes.usage_coefficient")}</FormLabel>
146 <FormControl>
147 <Input {...field} />
148 </FormControl>
149 <FormMessage />
150 </FormItem>
151 )}
152 />
153 </HStack>
154 <Button
155 className="mt-3 w-full font-semibold"
156 type="submit"
157 disabled={form.formState.isSubmitting}
158 >
159 {t("submit")}
160 </Button>
161 </form>
162 </Form>
163 </DialogContent>
164 </Dialog>
165 );
166};