import { useEffect, useState } from "react"; import { PageHeader } from "../components/layout/PageHeader"; import { Button, Card, Input, Select } from "../components/ui"; import { useData, useRepos } from "../data/DataContext"; import type { AiSettings, PlacementSettings } from "../domain/types"; import { useI18n } from "../i18n/I18nContext"; import { CURRENCIES, LOCALES, type AppCurrency, type AppLocale } from "../lib/i18n/types"; import type { ThemePreference } from "../lib/theme"; import { useTheme } from "../theme/ThemeContext"; export function SettingsPage() { const repos = useRepos(); const { refresh } = useData(); const { t, locale, currency, setPrefs } = useI18n(); const { preference, setPreference } = useTheme(); const [ai, setAi] = useState(null); const [placement, setPlacement] = useState(null); const [apiKey, setApiKey] = useState(""); const [researchKey, setResearchKey] = useState(""); const [braveKey, setBraveKey] = useState(""); const [exaKey, setExaKey] = useState(""); const [copyModels, setCopyModels] = useState([]); const [researchModels, setResearchModels] = useState([]); const [message, setMessage] = useState(""); const [busy, setBusy] = useState(""); const [draftLocale, setDraftLocale] = useState(locale); const [draftCurrency, setDraftCurrency] = useState(currency); useEffect(() => { setDraftLocale(locale); setDraftCurrency(currency); }, [locale, currency]); useEffect(() => { void (async () => { setAi(await repos.settings.getAi()); setPlacement(await repos.settings.getPlacement()); })(); }, [repos.settings]); async function loadModels(kind: "copy" | "research") { if (!ai) return; setBusy(kind); try { const provider = kind === "copy" ? ai.provider : ai.research_provider; const models = await repos.settings.listModels(provider); if (kind === "copy") setCopyModels(models); else setResearchModels(models); setMessage(t("settings.modelsLoaded", { provider })); } finally { setBusy(""); } } async function saveAi() { if (!ai) return; setBusy("ai"); try { const next = await repos.settings.saveAi({ ...ai, api_key: apiKey || undefined, research_api_key: researchKey || undefined, }); setAi(next); setApiKey(""); setResearchKey(""); setMessage(t("settings.aiSaved")); refresh(); } finally { setBusy(""); } } async function savePlacement() { if (!placement) return; setBusy("placement"); try { const next = await repos.settings.savePlacement({ ...placement, brave_api_key: braveKey || undefined, exa_api_key: exaKey || undefined, }); setPlacement(next); setBraveKey(""); setExaKey(""); setMessage(t("settings.searchSaved")); refresh(); } finally { setBusy(""); } } function saveLocaleCurrency() { setPrefs({ locale: draftLocale, currency: draftCurrency }); setMessage(t("settings.localeSaved")); } function pickTheme(next: ThemePreference) { setPreference(next); setMessage(t("settings.themeSaved")); } return ( <> {message ? (

{message}

) : null}

{t("settings.theme")}

{( [ ["light", t("settings.themeLight")], ["dark", t("settings.themeDark")], ["system", t("settings.themeSystem")], ] as const ).map(([id, label]) => ( ))}
{ai ? (
setApiKey(e.target.value)} placeholder={ai.api_key_configured ? t("settings.configured") : ""} /> setResearchKey(e.target.value)} placeholder={ai.research_api_key_configured ? t("settings.configured") : ""} />
) : (

{t("common.loading")}

)}
{placement ? (
setBraveKey(e.target.value)} placeholder={ placement.brave_api_key_configured ? t("settings.configured") : t("settings.notConfigured") } /> setExaKey(e.target.value)} placeholder={ placement.exa_api_key_configured ? t("settings.configured") : t("settings.notConfigured") } />
) : (

{t("common.loading")}

)}
); }