import { useCallback, useEffect, useState } from "react"; import { Link, Outlet, useLocation, useOutletContext } from "react-router-dom"; import { getUserConfig, updateUserConfig, type UserConfig, type UserConfigUpdate } from "../api/settings"; import { Icon } from "../components/icon"; type SettingsStatus = "loading" | "ready" | "error"; const TABS = [ { label: "General", path: "general" }, { label: "SSH Keys", path: "ssh-keys" }, { label: "Tool Types", path: "tool-types" }, { label: "Tool Configs", path: "tool-configs" }, ] as const; const THEME_OPTIONS = [ { value: "system", label: "System" }, { value: "light", label: "Light" }, { value: "dark", label: "Dark" }, ]; type SettingsOutletContext = { config: UserConfig; handleChange: (key: keyof UserConfigUpdate, value: string | null) => void; handleSave: () => Promise; saveStatus: "idle" | "saving" | "saved" | "error"; }; export const SettingsPage = () => { const location = useLocation(); const [status, setStatus] = useState("loading"); const [config, setConfig] = useState({ theme: "system", default_editor: null, git_user_name: null, git_user_email: null, last_session_id: null, }); const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle"); const loadConfig = useCallback(async () => { try { const data = await getUserConfig(); setConfig(data); setStatus("ready"); } catch { setStatus("error"); } }, []); useEffect(() => { void loadConfig(); }, [loadConfig]); const handleChange = (key: keyof UserConfigUpdate, value: string | null) => { setConfig((prev) => ({ ...prev, [key]: value })); setSaveStatus("idle"); }; const handleSave = async () => { setSaveStatus("saving"); try { const update: UserConfigUpdate = { theme: config.theme, default_editor: config.default_editor, git_user_name: config.git_user_name, git_user_email: config.git_user_email, }; const updated = await updateUserConfig(update); setConfig(updated); setSaveStatus("saved"); if (updated.theme === "system") { document.documentElement.removeAttribute("data-theme"); } else { document.documentElement.setAttribute("data-theme", updated.theme); } window.setTimeout(() => setSaveStatus("idle"), 2000); } catch { setSaveStatus("error"); } }; if (status === "loading") { return

Loading settings...

; } if (status === "error") { return (

Failed to load settings

); } const parts = location.pathname.split("/").filter(Boolean); const activePath = location.pathname.endsWith("/settings") ? "general" : (parts[parts.length - 1] ?? "general"); return (

Configuration

Settings

General preferences, SSH keys, tool types, and tool configs live here.

); }; export const GeneralSettingsTab = () => { const { config, handleChange, handleSave, saveStatus } = useOutletContext(); return (

General

{saveStatus === "saved" && Settings saved!} {saveStatus === "error" && Failed to save}
); };