import { HTTPProxyConfig, TCPProxyConfig, TypedProxyConfig, UDPProxyConfig, STCPProxyConfig } from '@/types/proxy' import * as z from 'zod' import React from 'react' import { ZodPortSchema, ZodStringSchema } from '@/lib/consts' import { useEffect, useState } from 'react' import { zodResolver } from '@hookform/resolvers/zod' import { Control, FieldValues, useForm } from 'react-hook-form' import { Button } from '@/components/ui/button' import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form' import { Input } from '@/components/ui/input' import { $clientProxyConfigs } from '@/store/proxy' import { useStore } from '@nanostores/react' import { YesIcon } from './ui/icon' import { Label } from './ui/label' import { useQuery } from '@tanstack/react-query' import { getServer } from '@/api/server' import { ServerConfig } from '@/types/server' import { ArrowRightIcon } from 'lucide-react' export const TCPConfigSchema = z.object({ remotePort: ZodPortSchema, localIP: ZodStringSchema.default('127.0.0.1'), localPort: ZodPortSchema, }) export const UDPConfigSchema = z.object({ remotePort: ZodPortSchema.optional(), localIP: ZodStringSchema.default('127.0.0.1'), localPort: ZodPortSchema, }) export const HTTPConfigSchema = z.object({ localPort: ZodPortSchema, localIP: ZodStringSchema.default('127.0.0.1'), subDomain: ZodStringSchema, }) export const STCPConfigSchema = z.object({ localIP: ZodStringSchema.default('127.0.0.1'), localPort: ZodPortSchema, secretKey: ZodStringSchema, }) export interface ProxyFormProps { clientID: string serverID: string proxyName: string defaultProxyConfig?: TypedProxyConfig } const IPField = ({ control, name, label, defaultValue, }: { control: Control name: string label: string defaultValue?: string }) => { return ( ( {label} )} defaultValue={defaultValue} /> ) } const PortField = ({ control, name, label, defaultValue, }: { control: Control name: string label: string defaultValue?: number }) => { return ( ( {label} )} defaultValue={defaultValue} /> ) } const SecretKeyField = ({ control, name, label, defaultValue, }: { control: Control name: string label: string defaultValue?: string }) => { return ( ( {label} )} defaultValue={defaultValue} /> ) } export const TCPProxyForm: React.FC = ({ serverID, clientID, defaultProxyConfig, proxyName }) => { const defaultConfig = defaultProxyConfig as TCPProxyConfig const [_, setTCPConfig] = useState() const form = useForm>({ resolver: zodResolver(TCPConfigSchema), }) useEffect(() => { setTCPConfig(undefined) form.reset({}) }, [form]) const clientProxyConfigs = useStore($clientProxyConfigs) const onSubmit = async (values: z.infer) => { handleSave() setTCPConfig({ type: 'tcp', ...values, name: proxyName }) const newProxiyConfigs = clientProxyConfigs.map((proxyCfg) => { if (proxyCfg.name === proxyName) { return { ...values, type: 'tcp', name: proxyName } as TCPProxyConfig } return proxyCfg }) $clientProxyConfigs.set(newProxiyConfigs) } const [isSaveDisabled, setSaveDisabled] = useState(false) const handleSave = () => { setSaveDisabled(true) setTimeout(() => { setSaveDisabled(false) }, 3000) } const { data: server } = useQuery({ queryKey: ['getServer', serverID], queryFn: () => { return getServer({ serverId: serverID }) }, }) return (
{server?.server?.ip && defaultConfig.remotePort && defaultConfig.localIP && defaultConfig.localPort && (
{' '} {' '}
)} ) } export const STCPProxyForm: React.FC = ({ serverID, clientID, defaultProxyConfig, proxyName }) => { const defaultConfig = defaultProxyConfig as STCPProxyConfig const [_, setSTCPConfig] = useState() const form = useForm>({ resolver: zodResolver(STCPConfigSchema), }) useEffect(() => { setSTCPConfig(undefined) form.reset({}) }, [form]) const clientProxyConfigs = useStore($clientProxyConfigs) const onSubmit = async (values: z.infer) => { handleSave() setSTCPConfig({ type: 'stcp', ...values, name: proxyName }) const newProxiyConfigs = clientProxyConfigs.map((proxyCfg) => { if (proxyCfg.name === proxyName) { return { ...values, type: 'stcp', name: proxyName } as STCPProxyConfig } return proxyCfg }) $clientProxyConfigs.set(newProxiyConfigs) } const [isSaveDisabled, setSaveDisabled] = useState(false) const handleSave = () => { setSaveDisabled(true) setTimeout(() => { setSaveDisabled(false) }, 3000) } const { data: server } = useQuery({ queryKey: ['getServer', serverID], queryFn: () => { return getServer({ serverId: serverID }) }, }) return (
) } export const UDPProxyForm: React.FC = ({ serverID, clientID, defaultProxyConfig, proxyName }) => { const [_, setUDPConfig] = useState() const form = useForm>({ resolver: zodResolver(UDPConfigSchema), }) useEffect(() => { setUDPConfig(undefined) form.reset({}) }, []) const clientProxyConfigs = useStore($clientProxyConfigs) const onSubmit = async (values: z.infer) => { handleSave() setUDPConfig({ type: 'udp', ...values, name: proxyName }) const newProxiyConfigs = clientProxyConfigs.map((proxyCfg) => { if (proxyCfg.name === proxyName) { return { ...values, type: 'udp', name: proxyName } as UDPProxyConfig } return proxyCfg }) $clientProxyConfigs.set(newProxiyConfigs) } const [isSaveDisabled, setSaveDisabled] = useState(false) const handleSave = () => { setSaveDisabled(true) setTimeout(() => { setSaveDisabled(false) }, 3000) } const { data: server } = useQuery({ queryKey: ['getServer', serverID], queryFn: () => { return getServer({ serverId: serverID }) }, }) return (

{`${server?.server?.ip}:${(defaultProxyConfig as UDPProxyConfig).remotePort} -> ${ defaultProxyConfig?.localIP }:${defaultProxyConfig?.localPort}`}

( 本地端口 )} defaultValue={defaultProxyConfig === undefined ? 1234 : defaultProxyConfig.localPort} /> ( 转发地址 )} defaultValue={defaultProxyConfig === undefined ? '127.0.0.1' : defaultProxyConfig.localIP} /> ( 远端端口 )} defaultValue={defaultProxyConfig === undefined ? 4321 : (defaultProxyConfig as UDPProxyConfig).remotePort} /> ) } export const HTTPProxyForm: React.FC = ({ serverID, clientID, defaultProxyConfig, proxyName }) => { const [_, setHTTPConfig] = useState() const [serverConfig, setServerConfig] = useState() const form = useForm>({ resolver: zodResolver(HTTPConfigSchema), }) useEffect(() => { setHTTPConfig(undefined) form.reset({}) }, []) const clientProxyConfigs = useStore($clientProxyConfigs) const onSubmit = async (values: z.infer) => { handleSave() setHTTPConfig({ ...values, type: 'http', name: proxyName }) const newProxiyConfigs = clientProxyConfigs.map((proxyCfg) => { if (proxyCfg.name === proxyName) { return { ...values, type: 'http', name: proxyName } as HTTPProxyConfig } return proxyCfg }) $clientProxyConfigs.set(newProxiyConfigs) } const [isSaveDisabled, setSaveDisabled] = useState(false) const handleSave = () => { setSaveDisabled(true) setTimeout(() => { setSaveDisabled(false) }, 3000) } const { data: server } = useQuery({ queryKey: ['getServer', serverID], queryFn: () => { return getServer({ serverId: serverID }) }, }) useEffect(() => { if (server && server.server?.config) { setServerConfig(JSON.parse(server.server?.config) as ServerConfig) } }, [server]) return (

{`http://${(defaultProxyConfig as HTTPProxyConfig).subdomain}.${serverConfig?.subDomainHost}:${ serverConfig?.vhostHTTPPort } -> ${defaultProxyConfig?.localIP}:${defaultProxyConfig?.localPort}`}

( 本地端口 )} defaultValue={defaultProxyConfig === undefined ? 1234 : defaultProxyConfig.localPort} /> ( 转发地址 )} defaultValue={defaultProxyConfig === undefined ? '127.0.0.1' : defaultProxyConfig.localIP} /> ( 远端子域名 )} defaultValue={defaultProxyConfig === undefined ? '' : (defaultProxyConfig as HTTPProxyConfig).subdomain} /> ) }