"use client"; import { invoke } from "@tauri-apps/api/core"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { LoadingButton } from "@/components/loading-button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import type { ProxySettings, StoredProxy } from "@/types"; import { RippleButton } from "./ui/ripple"; interface RegularFormData { name: string; proxy_type: string; host: string; port: number; username: string; password: string; } interface DynamicFormData { name: string; url: string; format: string; } type ProxyMode = "regular" | "dynamic"; interface ProxyFormDialogProps { isOpen: boolean; onClose: () => void; editingProxy?: StoredProxy | null; } export function ProxyFormDialog({ isOpen, onClose, editingProxy, }: ProxyFormDialogProps) { const { t } = useTranslation(); const [isSubmitting, setIsSubmitting] = useState(false); const [isTesting, setIsTesting] = useState(false); const [mode, setMode] = useState("regular"); const [regularForm, setRegularForm] = useState({ name: "", proxy_type: "http", host: "", port: 8080, username: "", password: "", }); const [dynamicForm, setDynamicForm] = useState({ name: "", url: "", format: "json", }); const resetForm = useCallback(() => { setRegularForm({ name: "", proxy_type: "http", host: "", port: 8080, username: "", password: "", }); setDynamicForm({ name: "", url: "", format: "json", }); setMode("regular"); }, []); useEffect(() => { if (isOpen) { if (editingProxy) { if (editingProxy.dynamic_proxy_url) { setMode("dynamic"); setDynamicForm({ name: editingProxy.name, url: editingProxy.dynamic_proxy_url, format: editingProxy.dynamic_proxy_format || "json", }); } else { setMode("regular"); setRegularForm({ name: editingProxy.name, proxy_type: editingProxy.proxy_settings.proxy_type, host: editingProxy.proxy_settings.host, port: editingProxy.proxy_settings.port, username: editingProxy.proxy_settings.username ?? "", password: editingProxy.proxy_settings.password ?? "", }); } } else { resetForm(); } } }, [isOpen, editingProxy, resetForm]); const handleTestDynamic = useCallback(async () => { if (!dynamicForm.url.trim()) { toast.error(t("proxies.dynamic.urlRequired")); return; } setIsTesting(true); try { const settings = await invoke("fetch_dynamic_proxy", { url: dynamicForm.url.trim(), format: dynamicForm.format, }); toast.success( t("proxies.dynamic.testSuccess", { host: settings.host, port: settings.port, }), ); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); toast.error(t("proxies.dynamic.testFailed", { error: errorMessage })); } finally { setIsTesting(false); } }, [dynamicForm, t]); const handleSubmit = useCallback(async () => { if (mode === "regular") { if (!regularForm.name.trim()) { toast.error(t("proxies.form.nameRequired", "Proxy name is required")); return; } if (!regularForm.host.trim() || !regularForm.port) { toast.error( t("proxies.form.hostPortRequired", "Host and port are required"), ); return; } } else { if (!dynamicForm.name.trim()) { toast.error(t("proxies.form.nameRequired", "Proxy name is required")); return; } if (!dynamicForm.url.trim()) { toast.error(t("proxies.dynamic.urlRequired")); return; } } setIsSubmitting(true); try { if (editingProxy) { if (mode === "dynamic") { await invoke("update_stored_proxy", { proxyId: editingProxy.id, name: dynamicForm.name.trim(), dynamicProxyUrl: dynamicForm.url.trim(), dynamicProxyFormat: dynamicForm.format, }); } else { await invoke("update_stored_proxy", { proxyId: editingProxy.id, name: regularForm.name.trim(), proxySettings: { proxy_type: regularForm.proxy_type, host: regularForm.host.trim(), port: regularForm.port, username: regularForm.username.trim() || undefined, password: regularForm.password.trim() || undefined, }, }); } toast.success(t("toasts.success.proxyUpdated")); } else { if (mode === "dynamic") { await invoke("create_stored_proxy", { name: dynamicForm.name.trim(), dynamicProxyUrl: dynamicForm.url.trim(), dynamicProxyFormat: dynamicForm.format, }); } else { await invoke("create_stored_proxy", { name: regularForm.name.trim(), proxySettings: { proxy_type: regularForm.proxy_type, host: regularForm.host.trim(), port: regularForm.port, username: regularForm.username.trim() || undefined, password: regularForm.password.trim() || undefined, }, }); } toast.success(t("toasts.success.proxyCreated")); } onClose(); } catch (error) { console.error("Failed to save proxy:", error); const errorMessage = error instanceof Error ? error.message : String(error); toast.error(`Failed to save proxy: ${errorMessage}`); } finally { setIsSubmitting(false); } }, [mode, regularForm, dynamicForm, editingProxy, onClose, t]); const handleClose = useCallback(() => { if (!isSubmitting) { onClose(); } }, [isSubmitting, onClose]); const isRegularValid = regularForm.name.trim() && regularForm.host.trim() && regularForm.port > 0 && regularForm.port <= 65535; const isDynamicValid = dynamicForm.name.trim() && dynamicForm.url.trim(); const isFormValid = mode === "regular" ? isRegularValid : isDynamicValid; const isEditingDynamic = editingProxy?.dynamic_proxy_url != null; return ( {editingProxy ? t("proxies.edit") : t("proxies.add")}
{!editingProxy && ( { setMode(v as ProxyMode); }} > {t("proxies.tabs.regular")} {t("proxies.tabs.dynamic")} )} {editingProxy && isEditingDynamic && (

{t("proxies.dynamic.description")}

)} {mode === "regular" ? ( <>
{ setRegularForm({ ...regularForm, name: e.target.value }); }} placeholder="e.g. Office Proxy, Home VPN, etc." disabled={isSubmitting} />
{ setRegularForm({ ...regularForm, host: e.target.value }); }} placeholder={t("proxies.form.hostPlaceholder")} disabled={isSubmitting} />
{ setRegularForm({ ...regularForm, port: parseInt(e.target.value, 10) || 0, }); }} placeholder={t("proxies.form.portPlaceholder")} min="1" max="65535" disabled={isSubmitting} />
{ setRegularForm({ ...regularForm, username: e.target.value, }); }} placeholder={t("proxies.form.usernamePlaceholder")} disabled={isSubmitting} />
{ setRegularForm({ ...regularForm, password: e.target.value, }); }} placeholder={t("proxies.form.passwordPlaceholder")} disabled={isSubmitting} />
) : ( <>
{ setDynamicForm({ ...dynamicForm, name: e.target.value }); }} placeholder="e.g. My Tunnel" disabled={isSubmitting} />
{ setDynamicForm({ ...dynamicForm, url: e.target.value }); }} placeholder={t("proxies.dynamic.urlPlaceholder")} disabled={isSubmitting} />

{dynamicForm.format === "json" ? t("proxies.dynamic.formatJsonHint") : t("proxies.dynamic.formatTextHint")}

{isTesting ? t("proxies.dynamic.testing") : t("proxies.dynamic.testUrl")} )}
{t("common.cancel", "Cancel")} {editingProxy ? t("proxies.edit") : t("proxies.add")}
); }