From afac4b9870bd6743f624ea650d6b7cee9bf5cde6 Mon Sep 17 00:00:00 2001 From: ashim-hq Date: Tue, 21 Apr 2026 23:25:34 +0800 Subject: [PATCH] fix: wire up Default Tool View save in General settings The with value/onChange - Add Save Settings button mirroring SystemSection's pattern - Redirect home page to /fullscreen when defaultToolView is "fullscreen" Closes #75 --- .../components/settings/settings-dialog.tsx | 80 ++++++++++++++++--- apps/web/src/pages/home-page.tsx | 8 +- apps/web/src/stores/settings-store.ts | 4 +- 3 files changed, 78 insertions(+), 14 deletions(-) diff --git a/apps/web/src/components/settings/settings-dialog.tsx b/apps/web/src/components/settings/settings-dialog.tsx index a1950fad..4d098616 100644 --- a/apps/web/src/components/settings/settings-dialog.tsx +++ b/apps/web/src/components/settings/settings-dialog.tsx @@ -27,6 +27,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { useAuth } from "@/hooks/use-auth"; import { apiDelete, apiGet, apiPost, apiPut, clearToken, formatHeaders } from "@/lib/api"; import { cn, copyToClipboard } from "@/lib/utils"; +import { useSettingsStore } from "@/stores/settings-store"; import { GemLogo } from "../common/gem-logo"; import { AiFeaturesSection } from "./ai-features-section"; @@ -179,19 +180,29 @@ interface TeamEntry { function GeneralSection() { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); + const [defaultToolView, setDefaultToolView] = useState("sidebar"); + const [saving, setSaving] = useState(false); + const [saveMsg, setSaveMsg] = useState(null); useEffect(() => { - apiGet<{ user: SessionUser }>("/auth/session") - .then((data) => setUser(data.user)) - .catch(() => { - // Fallback to localStorage if session endpoint fails - setUser({ - id: 0, - username: localStorage.getItem("ashim-username") || "", - role: "unknown", - }); - }) - .finally(() => setLoading(false)); + Promise.all([ + apiGet<{ user: SessionUser }>("/auth/session") + .then((data) => setUser(data.user)) + .catch(() => { + setUser({ + id: 0, + username: localStorage.getItem("ashim-username") || "", + role: "unknown", + }); + }), + apiGet<{ settings: Record }>("/v1/settings") + .then((data) => { + if (data.settings.defaultToolView) { + setDefaultToolView(data.settings.defaultToolView); + } + }) + .catch(() => {}), + ]).finally(() => setLoading(false)); }, []); const handleLogout = () => { @@ -200,6 +211,23 @@ function GeneralSection() { window.location.href = "/login"; }; + const handleSave = useCallback(async () => { + setSaving(true); + setSaveMsg(null); + try { + await apiPut("/v1/settings", { defaultToolView }); + setSaveMsg("Settings saved."); + useSettingsStore.setState({ + defaultToolView: defaultToolView as "sidebar" | "fullscreen", + }); + } catch { + setSaveMsg("Failed to save settings."); + } finally { + setSaving(false); + setTimeout(() => setSaveMsg(null), 3000); + } + }, [defaultToolView]); + const username = user?.username || "admin"; const role = user?.role || "unknown"; @@ -237,7 +265,11 @@ function GeneralSection() { {/* Default view */} - setDefaultToolView(e.target.value)} + className="px-3 py-1.5 rounded-lg border border-border bg-background text-sm text-foreground" + > @@ -247,6 +279,30 @@ function GeneralSection() { {APP_VERSION} + +
+ + {saveMsg && ( + + {saveMsg} + + )} +
); } diff --git a/apps/web/src/pages/home-page.tsx b/apps/web/src/pages/home-page.tsx index 4e479bb1..313b5cec 100644 --- a/apps/web/src/pages/home-page.tsx +++ b/apps/web/src/pages/home-page.tsx @@ -24,7 +24,7 @@ export function HomePage() { currentEntry, } = useFileStore(); const navigate = useNavigate(); - const { fetch: fetchSettings } = useSettingsStore(); + const { fetch: fetchSettings, defaultToolView, loaded: settingsLoaded } = useSettingsStore(); const { fetch: fetchFeatures, isToolInstalled } = useFeaturesStore(); useEffect(() => { @@ -32,6 +32,12 @@ export function HomePage() { fetchFeatures(); }, [fetchSettings, fetchFeatures]); + useEffect(() => { + if (settingsLoaded && defaultToolView === "fullscreen" && files.length === 0) { + navigate("/fullscreen", { replace: true }); + } + }, [settingsLoaded, defaultToolView, files.length, navigate]); + const handleFiles = useCallback( (newFiles: File[]) => { reset(); diff --git a/apps/web/src/stores/settings-store.ts b/apps/web/src/stores/settings-store.ts index 34a34d86..0fbbc5af 100644 --- a/apps/web/src/stores/settings-store.ts +++ b/apps/web/src/stores/settings-store.ts @@ -4,6 +4,7 @@ import { apiGet } from "@/lib/api"; interface SettingsState { disabledTools: string[]; experimentalEnabled: boolean; + defaultToolView: "sidebar" | "fullscreen"; loaded: boolean; fetch: () => Promise; } @@ -11,6 +12,7 @@ interface SettingsState { export const useSettingsStore = create((set, get) => ({ disabledTools: [], experimentalEnabled: false, + defaultToolView: "sidebar", loaded: false, fetch: async () => { @@ -23,10 +25,10 @@ export const useSettingsStore = create((set, get) => ({ set({ disabledTools: data.settings.disabledTools ? JSON.parse(data.settings.disabledTools) : [], experimentalEnabled: data.settings.enableExperimentalTools === "true", + defaultToolView: data.settings.defaultToolView === "fullscreen" ? "fullscreen" : "sidebar", loaded: true, }); } catch { - // Settings fetch failed - default to no disabled tools set({ loaded: true }); } },