"use client"; import { useState, useCallback, useSyncExternalStore } from "react"; import { type Icon, Gear, Code, UserCircle, Plug, ChartBar } from "@/components/ui/icon"; import { cn } from "@/lib/utils"; import { Button } from "@/components/ui/button"; import { GeneralSection } from "./GeneralSection"; import { ProviderManager } from "./ProviderManager"; import { CliSettingsSection } from "./CliSettingsSection"; import { UsageStatsSection } from "./UsageStatsSection"; import { AssistantWorkspaceSection } from "./AssistantWorkspaceSection"; import { useTranslation } from "@/hooks/useTranslation"; import type { TranslationKey } from "@/i18n"; type Section = "general" | "providers" | "cli" | "usage" | "assistant"; interface SidebarItem { id: Section; label: string; icon: Icon; } const sidebarItems: SidebarItem[] = [ { id: "general", label: "General", icon: Gear }, { id: "providers", label: "Providers", icon: Plug }, { id: "cli", label: "Claude CLI", icon: Code }, { id: "usage", label: "Usage", icon: ChartBar }, { id: "assistant", label: "Assistant", icon: UserCircle }, ]; function getSectionFromHash(): Section { if (typeof window === "undefined") return "general"; const hash = window.location.hash.replace("#", ""); if (sidebarItems.some((item) => item.id === hash)) { return hash as Section; } return "general"; } function subscribeToHash(callback: () => void) { window.addEventListener("hashchange", callback); return () => window.removeEventListener("hashchange", callback); } export function SettingsLayout() { // useSyncExternalStore subscribes to hash changes without triggering // the react-hooks/set-state-in-effect lint rule. const hashSection = useSyncExternalStore(subscribeToHash, getSectionFromHash, () => "general" as Section); // Local state allows immediate UI update on click before the hash updates. const [overrideSection, setOverrideSection] = useState
(null); const activeSection = overrideSection ?? hashSection; const { t } = useTranslation(); const settingsLabelKeys: Record = { 'General': 'settings.general', 'Providers': 'settings.providers', 'Claude CLI': 'settings.claudeCli', 'Usage': 'settings.usage', 'Assistant': 'settings.assistant', }; const handleSectionChange = useCallback((section: Section) => { setOverrideSection(section); window.history.replaceState(null, "", `/settings#${section}`); // Clear override so subsequent hash changes take effect queueMicrotask(() => setOverrideSection(null)); }, []); return (

{t('settings.title')}

{t('settings.description')}

{/* Sidebar */} {/* Content */}
{activeSection === "general" && } {activeSection === "providers" && } {activeSection === "cli" && } {activeSection === "usage" && } {activeSection === "assistant" && }
); }