diff --git a/web/src/components/AuthFooter.tsx b/web/src/components/AuthFooter.tsx index 6553af5bc..0ad7b4ff4 100644 --- a/web/src/components/AuthFooter.tsx +++ b/web/src/components/AuthFooter.tsx @@ -1,6 +1,8 @@ import { observer } from "mobx-react-lite"; +import { useState } from "react"; import { cn } from "@/lib/utils"; import { workspaceStore } from "@/store"; +import { loadTheme } from "@/utils/theme"; import LocaleSelect from "./LocaleSelect"; import ThemeSelect from "./ThemeSelect"; @@ -9,10 +11,22 @@ interface Props { } const AuthFooter = observer(({ className }: Props) => { + // Local state for login page theme since we can't persist to server + const [localTheme, setLocalTheme] = useState(workspaceStore.state.theme || "default"); + + const handleThemeChange = (theme: string) => { + // Update local state + setLocalTheme(theme); + // Update workspace store for immediate UI feedback + workspaceStore.state.setPartial({ theme }); + // Apply theme to DOM + loadTheme(theme); + }; + return (
workspaceStore.state.setPartial({ locale })} /> - workspaceStore.state.setPartial({ theme })} /> +
); }); diff --git a/web/src/components/Settings/PreferencesSection.tsx b/web/src/components/Settings/PreferencesSection.tsx index 978343e74..df237e023 100644 --- a/web/src/components/Settings/PreferencesSection.tsx +++ b/web/src/components/Settings/PreferencesSection.tsx @@ -47,7 +47,10 @@ const PreferencesSection = observer(() => {
- {t("setting.preference-section.theme")} +
+ {t("setting.preference-section.theme")} + Your personal theme preference (overrides default) +
diff --git a/web/src/components/Settings/WorkspaceSection.tsx b/web/src/components/Settings/WorkspaceSection.tsx index 6d0830812..d44052a91 100644 --- a/web/src/components/Settings/WorkspaceSection.tsx +++ b/web/src/components/Settings/WorkspaceSection.tsx @@ -81,7 +81,10 @@ const WorkspaceSection = observer(() => {

{t("setting.system-section.title")}

- Theme +
+ Default Theme + Sets the default theme for all users +
updatePartialSetting({ theme: value })} diff --git a/web/src/components/ThemeSelect.tsx b/web/src/components/ThemeSelect.tsx index 3e0a1a4e2..24d69eb7c 100644 --- a/web/src/components/ThemeSelect.tsx +++ b/web/src/components/ThemeSelect.tsx @@ -1,12 +1,14 @@ +import { observer } from "mobx-react-lite"; import { Moon, Palette, Sun, Wallpaper } from "lucide-react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"; -import { workspaceStore } from "@/store"; +import { workspaceStore, userStore } from "@/store"; import { THEME_OPTIONS } from "@/utils/theme"; interface ThemeSelectProps { value?: string; onValueChange?: (theme: string) => void; className?: string; + showEffectiveTheme?: boolean; } const THEME_ICONS: Record = { @@ -16,8 +18,13 @@ const THEME_ICONS: Record = { whitewall: , }; -const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {}) => { +const ThemeSelect = observer(({ value, onValueChange, className, showEffectiveTheme = false }: ThemeSelectProps = {}) => { const currentTheme = value || workspaceStore.state.theme || "default"; + + // Calculate effective theme (user preference overrides workspace default) + const effectiveTheme = userStore.state.userGeneralSetting?.theme || workspaceStore.state.theme || "default"; + + const displayTheme = showEffectiveTheme ? effectiveTheme : currentTheme; const handleThemeChange = (newTheme: Theme) => { if (onValueChange) { @@ -32,6 +39,9 @@ const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {})
+ {showEffectiveTheme && effectiveTheme !== currentTheme && ( + (effective: {effectiveTheme}) + )}
@@ -40,12 +50,15 @@ const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {})
{THEME_ICONS[option.value]} {option.label} + {showEffectiveTheme && option.value === effectiveTheme && ( + + )}
))}
); -}; +}); export default ThemeSelect;