import { useState, useEffect, useRef } from "react"; import type { ValidationSettings as VS } from "@/api/types"; import { api } from "@/api/client"; import { useUiStore } from "@/stores/uiStore"; import { useT } from "@/lib/i18n"; import { IconSettings } from "@/components/shared/Icons"; function Toggle({ checked, onChange, }: { checked: boolean; onChange: (v: boolean) => void; }) { return ( ); } function SettingRow({ label, desc, checked, onChange, }: { label: string; desc?: string; checked: boolean; onChange: (v: boolean) => void; }) { return (

{label}

{desc &&

{desc}

}
); } function ThreadStepper({ value, onChange, }: { value: number; onChange: (v: number) => void; }) { const t = useT(); const [editing, setEditing] = useState(false); const [input, setInput] = useState(""); const inputRef = useRef(null); const clamp = (n: number) => Math.max(1, n); const commit = () => { onChange(clamp(parseInt(input) || value)); setEditing(false); }; const btnCls = "h-6 px-1.5 rounded bg-dark-700 border border-dark-600 text-gray-300 hover:bg-dark-600 text-xs flex items-center justify-center select-none leading-none"; return (
{t("tools.maxThreads")}
{editing ? ( setInput(e.target.value)} onBlur={commit} onKeyDown={(e) => { if (e.key === "Enter") commit(); if (e.key === "Escape") setEditing(false); }} className="w-10 text-center text-sm font-mono bg-dark-900 border border-accent rounded outline-none text-gray-100 py-0.5" /> ) : ( { setInput(String(value)); setEditing(true); }} title="Двойной клик для ручного ввода" > {value} )}
); } export function ValidationSettings() { const t = useT(); const [settings, setSettings] = useState({ fetch_profile: true, check_ban: true, max_threads: 5, auto_revalidate_browser: true, auto_proxy_on_import: false, auto_validate_on_import: false, auto_proxy_on_import_mafile: true, auto_proxy_on_import_logpass: true, auto_proxy_on_import_token: true, auto_validate_on_import_mafile: true, auto_validate_on_import_logpass: true, auto_validate_on_import_token: true, }); const [importTab, setImportTab] = useState<"mafile" | "logpass" | "token">( "mafile", ); const hidePasswords = useUiStore((s) => s.hidePasswords); const setHidePasswords = useUiStore((s) => s.setHidePasswords); const loadImportSettings = useUiStore((s) => s.loadImportSettings); const addToast = useUiStore((s) => s.addToast); useEffect(() => { api .getValidationSettings() .then(setSettings) .catch(() => {}); }, []); const save = async () => { try { await api.updateValidationSettings(settings); await loadImportSettings(); // sync stale uiStore values addToast("success", t("toast.settingsSaved")); } catch (e: unknown) { addToast( "error", t("misc.error", { error: e instanceof Error ? e.message : String(e) }), ); } }; return (
Settings

{t("tools.validationSettings")}

setSettings({ ...settings, fetch_profile: v })} /> setSettings({ ...settings, check_ban: v })} /> setSettings({ ...settings, auto_revalidate_browser: v }) } />
setSettings((s) => ({ ...s, max_threads: v }))} />

{t("tools.importSettings")}

{/* Tab switcher */}
{(["mafile", "logpass", "token"] as const).map((tab) => ( ))}
{/* Per-tab toggles */} {(["mafile", "logpass", "token"] as const).map((tab) => importTab === tab ? (
setSettings({ ...settings, [`auto_proxy_on_import_${tab}`]: v, }) } /> setSettings({ ...settings, [`auto_validate_on_import_${tab}`]: v, }) } />
) : null, )}

{t("settings.display")}

); }