1import { FC, useEffect } from "react";
2import {
3 DialogTitle,
4 DialogContent,
5 Dialog,
6 DialogHeader,
7 Form,
8 Button,
9} from '@marzneshin/components';
10import { useForm } from 'react-hook-form';
11import { zodResolver } from '@hookform/resolvers/zod';
12import { useTranslation } from 'react-i18next';
13import {
14 HostSchema,
15 HostType,
16 getDefaultValues,
17 useHostsCreationMutation,
18 useHostsUpdateMutation
19} from "@marzneshin/features/hosts";
20import { RemarkField } from "./fields/remark";
21import {
22 AddressField,
23 PortField,
24 HostField,
25 PathField,
26 SecurityFields,
27} from "./fields";
28
29interface MutationDialogProps {
30 entity: HostType | null
31 open: boolean
32 inboundId: number
33 onOpenChange: (state: boolean) => void
34}
35
36const transformFormValue = (values: HostType) => {
37 const alpn = values.alpn === "none" ? "" : values.alpn
38 const fingerprint = values.fingerprint === "none" ? "" : values.fingerprint
39 return { ...values, alpn, fingerprint }
40}
41
42export const HostsMutationDialog: FC<MutationDialogProps> = ({
43 inboundId,
44 entity,
45 open,
46 onOpenChange,
47}) => {
48 const form = useForm({
49 defaultValues: entity ? entity : getDefaultValues(),
50 resolver: zodResolver(HostSchema)
51 });
52 const updateMutation = useHostsUpdateMutation();
53 const createMutation = useHostsCreationMutation();
54 const { t } = useTranslation();
55
56 const submit = (values: HostType) => {
57 const host = transformFormValue(values)
58 if (entity && entity.id !== undefined) {
59 updateMutation.mutate({ hostId: entity.id, host });
60 } else {
61 createMutation.mutate({ inboundId, host });
62 }
63 onOpenChange(false);
64 };
65
66 useEffect(() => {
67 if (entity) form.reset(entity);
68 else form.reset(getDefaultValues());
69 }, [entity, form]);
70
71 return (
72 <Dialog open={open} onOpenChange={onOpenChange} defaultOpen={true}>
73 <DialogContent>
74 <DialogHeader>
75 <DialogTitle className="text-primary">
76 {entity
77 ? t('page.hosts.dialogs.edition.title')
78 : t('page.hosts.dialogs.creation.title')}
79 </DialogTitle>
80 </DialogHeader>
81 <Form {...form}>
82 <form onSubmit={form.handleSubmit(submit)}>
83 <RemarkField />
84 <div className="flex flex-row gap-1 items-center">
85 <AddressField />
86 <PortField />
87 </div>
88 <PathField />
89 <HostField />
90 <SecurityFields />
91 <Button
92 className="mt-3 w-full font-semibold"
93 type="submit"
94 disabled={form.formState.isSubmitting}
95 >
96 {t('submit')}
97 </Button>
98 </form>
99 </Form>
100 </DialogContent>
101 </Dialog>
102 );
103};