2025-04-22 16:04:37 +08:00

225 lines
5.8 KiB
TypeScript

import { Form, FormInstance } from "antd";
import { Input } from "@/components/ui/input";
import { FormDialog } from "@/components/FormDialog";
import { countryCodeMap } from "@/data";
import { DIALOGTYPE } from "../../index";
import "./index.scss";
import { DefaultLink } from "./pathChoose";
import { Button } from "@/components/ui/button";
import { Switch } from "@/components/ui/switch";
export interface DialogConfig {
title: string;
desc: string;
successText: string;
}
const IpPortInput = ({
value,
onChange,
}: {
value?: { port: string; ip: string };
onChange?: (data: { port: string; ip: string }) => void;
}) => {
const [ipAndPort, setIpAndPort] = useState<{
port: string;
ip: string;
}>(value ? value : { port: "", ip: "" });
const handleChagne = ({ key, val }: { key: "port" | "ip"; val: string }) => {
const newValue = value ? { ...value } : { port: "", ip: "" };
newValue[key] = val;
onChange?.(newValue);
};
useEffect(() => {
if (value) {
setIpAndPort(value);
}
}, [value]);
return (
<div className="flex items-center gap-1.5">
<Input
className="data-[state=checked]:bg-[#1E3A8A] flex-shrink-0 !w-[600px]"
placeholder="请输入IP"
value={ipAndPort?.ip}
onChange={(e) => {
handleChagne?.({ key: "ip", val: e.target.value });
}}
/>
<Input
className="data-[state=checked]:bg-[#1E3A8A] "
placeholder="请输入端口"
type="number"
min={0}
max={65535}
value={ipAndPort?.port}
onChange={(e) => {
handleChagne?.({ key: "port", val: e.target.value });
}}
/>
</div>
);
};
const SwitchComponent = ({
value,
onChange,
}: {
value?: boolean;
onChange?: (data: boolean) => void;
}) => {
const [checked, setChecked] = useState(value);
return (
<div className="flex items-center">
<Switch
className="data-[state=checked]:bg-[#1E3A8A]"
checked={checked}
onCheckedChange={(e) => {
setChecked(e);
onChange?.(e);
}}
/>
<div className="ml-2 text-zinc-900 text-sm font-medium leading-tight">
</div>
</div>
);
};
const NodeForm = ({ form }: { form: FormInstance }) => {
return (
<Form
className="-mt-1"
form={form}
name="dynamic_form_nest_item"
autoComplete="off"
layout="vertical"
>
{/* <Form.Item name="uid" className="hidden">
<div className="hidden">uid</div>
</Form.Item> */}
<Form.Item name="name" label="节点名称" rules={[{ required: true, message: '请输入节点名称' }]}>
<Input
className="link_name_input placeholder:text-base placeholder:text-zinc-400 text-[16px]"
placeholder="节点名称"
/>
</Form.Item>
<Form.Item name="private_key" label="私钥" rules={[{ required: true, message: '请输入私钥' }]}>
<Input
className="link_name_input placeholder:text-base placeholder:text-zinc-400 text-[16px]"
placeholder="私钥"
/>
</Form.Item>
<Form.Item name="public_key" label="公钥" rules={[{ required: true, message: '请输入公钥' }]}>
<Input
className="link_name_input placeholder:text-base placeholder:text-zinc-400 text-[16px]"
placeholder="公钥"
/>
</Form.Item>
<Form.Item name="ipAndPort" label="IP+端口" rules={[{ required: true, message: '请输入IP+端口' }]}>
<IpPortInput />
</Form.Item>
<Form.Item name="exit">
<SwitchComponent />
</Form.Item>
</Form>
);
};
const NetworkForm = ({ form }: { form: FormInstance }) => {
return (
<Form
className="-mt-1"
form={form}
name="dynamic_form_nest_item"
autoComplete="off"
layout="vertical"
>
<Form.Item
name="inbound"
label="入口节点"
rules={[{ required: true, message: "请选择入口节点" }]}
>
<DefaultLink
des="入口节点"
type="entry"
countries={Object.keys(countryCodeMap)
// .splice(0, 50)
.map((key) => key)}
/>
</Form.Item>
<Form.Item
name="outbound"
label="出口节点"
rules={[{ required: true, message: "请选择出口节点" }]}
>
<DefaultLink
des="出口节点"
type="exit"
countries={Object.keys(countryCodeMap)
// .splice(0, 50)
.map((key) => key)}
/>
</Form.Item>
</Form>
);
};
export const FormAlertDialog = ({
open,
setOpen,
successHandle,
dialogLoading,
form,
type,
canSubmit,
handleSelectFile,
}: {
open: boolean;
setOpen: (open: boolean) => void;
successHandle: () => void;
dialogLoading: boolean;
canSubmit: boolean;
form: FormInstance;
type: DialogConfig;
handleSelectFile: () => void;
}) => {
const showDialog = (open: boolean) => {
setOpen(open);
};
return (
<FormDialog
open={open}
openChange={showDialog}
title={type.title}
describe={type.desc}
successText={type.successText}
successHandle={successHandle}
submitLoading={dialogLoading}
form={form}
contentClass="w-[850px] flex flex-col max-h-[calc(100vh-100px)] overflow-y-hidden "
successStyle={
canSubmit
? "bg-[#1E3A8A] hover:bg-[#1D4ED8] active:bg-[#1E40AF]"
: "bg-[#1E3A8A] hover:bg-[#1E3A8A] opacity-50"
}
>
<Button
className="absolute top-3 right-12 bg-transparent text-zinc-900 border border-zinc-200"
onClick={() => handleSelectFile()}
>
</Button>
{open && type.title === DIALOGTYPE.ADDNode.title ? (
<NodeForm form={form} />
) : (
<NetworkForm form={form} />
)}
</FormDialog>
);
};