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