From 7736869fc47128ee3c4a8b44d43360a848225e20 Mon Sep 17 00:00:00 2001 From: ZhenYi <434836402@qq.com> Date: Mon, 20 Apr 2026 19:33:04 +0800 Subject: [PATCH] feat(frontend): integrate ThemeSwitcher, restore custom palette on page load --- src/components/layout/sidebar-system.tsx | 173 +++++++++++++---------- src/main.tsx | 14 ++ 2 files changed, 109 insertions(+), 78 deletions(-) diff --git a/src/components/layout/sidebar-system.tsx b/src/components/layout/sidebar-system.tsx index 28d5e9c..a677480 100644 --- a/src/components/layout/sidebar-system.tsx +++ b/src/components/layout/sidebar-system.tsx @@ -10,32 +10,47 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; -import {BookOpen, Box, ChevronDown, Compass, Home, LayoutGrid, Monitor, Moon, Plus, Sun, Users} from 'lucide-react'; +import { + BookOpen, + Box, + ChevronDown, + Compass, + Home, + LayoutGrid, + Monitor, + Moon, + Plus, + Sliders, + Sun, + Users +} from 'lucide-react'; import {useNavigate} from 'react-router-dom'; import {Avatar, AvatarFallback, AvatarImage} from '@/components/ui/avatar'; +import {useState} from 'react'; +import {ThemeSwitcher} from '@/components/room/ThemeSwitcher'; const btnClass = 'flex w-full h-9 justify-start items-center rounded-md font-medium hover:bg-muted cursor-pointer bg-transparent border-0 text-left text-sm'; -export function SidebarSystem({collapsed}: {collapsed: boolean}) { +export function SidebarSystem({collapsed}: { collapsed: boolean }) { const {theme, setTheme} = useTheme(); const navigate = useNavigate(); const workspaceCtx = tryUseWorkspace(); const workspaces = workspaceCtx?.workspaces; const currentWorkspace = workspaceCtx?.currentWorkspace; + const [themeSheetOpen, setThemeSheetOpen] = useState(false); return (
- {/* Workspace switcher — only shown when inside WorkspaceProvider */} {workspaceCtx && ( - - - } - > + + + } + > {currentWorkspace ? ( @@ -48,70 +63,74 @@ export function SidebarSystem({collapsed}: {collapsed: boolean}) { )} - {!collapsed && ( - + {!collapsed && ( + {currentWorkspace?.name || 'Workspaces'} - )} - {!collapsed && } - - - - Workspaces - {workspaces?.workspaces.map((ws) => ( - navigate(`/w/${ws.slug}`)} - className="gap-2" - > - - - - {ws.name.charAt(0).toUpperCase()} - - - {ws.name} - @{ws.slug} + )} + {!collapsed && } + + + + Workspaces + {workspaces?.workspaces.map((ws) => ( + navigate(`/w/${ws.slug}`)} + className="gap-2" + > + + + + {ws.name.charAt(0).toUpperCase()} + + + {ws.name} + @{ws.slug} + + ))} + + navigate('/w/me')} className="gap-2"> + + All Workspaces - ))} - - navigate('/w/me')} className="gap-2"> - - All Workspaces - - navigate('/init/workspace')} className="gap-2"> - - Create Workspace - - - - + navigate('/init/workspace')} className="gap-2"> + + Create Workspace + + + + )} - - - - @@ -125,13 +144,13 @@ export function SidebarSystem({collapsed}: {collapsed: boolean}) { /> } > - + {theme === 'dark' ? ( - + ) : theme === 'light' ? ( - + ) : ( - + )} {!collapsed && Theme} @@ -139,36 +158,34 @@ export function SidebarSystem({collapsed}: {collapsed: boolean}) { {!collapsed && ( - Theme Settings + Theme + setThemeSheetOpen(true)}> + + Design System + + setTheme('light')}> - + Light setTheme('dark')}> - + Dark setTheme('system')}> - + System )} {collapsed && ( - <> - setTheme('light')}> - - - setTheme('dark')}> - - - setTheme('system')}> - - - + setThemeSheetOpen(true)}> + + )} +
); -} +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 7a482cb..b098bdc 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,20 @@ import {UserProvider} from '@/contexts'; import {ThemeProvider} from '@/contexts/theme-context'; import './index.css'; import App from './App.tsx'; +import {applyPaletteToDOM, loadActivePresetId} from '@/components/room/design-system'; + +// Restore custom palette on page load (before first render) +const activePreset = loadActivePresetId(); +if (activePreset === 'custom') { + const customPalette = localStorage.getItem('theme-custom-palette'); + if (customPalette) { + try { + applyPaletteToDOM(JSON.parse(customPalette)); + } catch { + // ignore malformed stored palette + } + } +} const queryClient = new QueryClient();