From a77a6c84ff1bafaf9ed72b434c8b1d51a5736e02 Mon Sep 17 00:00:00 2001 From: seriouselly Date: Fri, 12 Jun 2026 12:26:11 +0700 Subject: [PATCH] fix(sidebar): persist sidebar state across page navigation - Move `isSidebarOpen` state from local component (`useState`) to global Zustand store (`ui-store.ts`). - Fix an issue where the sidebar would incorrectly reset to its default closed state when navigating between routes (e.g., to the Telemetry page) due to component remounting. - Ensure consistent sidebar toggle behavior across the entire dashboard application. --- apps/web/src/components/layout/sidebar.tsx | 23 +++++++++++++++------- apps/web/src/store/ui-store.ts | 8 +++++++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/apps/web/src/components/layout/sidebar.tsx b/apps/web/src/components/layout/sidebar.tsx index 8fa5825..725916a 100644 --- a/apps/web/src/components/layout/sidebar.tsx +++ b/apps/web/src/components/layout/sidebar.tsx @@ -14,29 +14,38 @@ import { } from "lucide-react"; import { MobileNav } from "./mobile-nav"; import { useAuthStore } from "@/store/auth-store"; +import { useUiStore } from "@/store/ui-store"; const NAV_ITEMS = [ { path: "/dashboard", label: "Dashboard", icon: LayoutDashboard }, { path: "/scan", label: "Pindai Daun", icon: Scan }, { path: "/diagnoses", label: "Diagnosa", icon: Activity }, { path: "/catalog", label: "Pustaka", icon: BookOpen, altPath: "/library" }, - { path: "/expert/reviews", label: "Tinjauan Pakar", icon: UserCheck, expertOnly: true }, + { + path: "/expert/reviews", + label: "Tinjauan Pakar", + icon: UserCheck, + expertOnly: true, + }, { path: "/telemetry", label: "Telemetry", icon: ChartBar, expertOnly: true }, ]; export function Sidebar() { const location = useLocation(); - const [isSidebarOpen, setIsSidebarOpen] = useState(false); const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const isSidebarOpen = useUiStore((state) => state.isSidebarOpen); + const setIsSidebarOpen = useUiStore((state) => state.setIsSidebarOpen); + const user = useAuthStore((state) => state.user); const isExpert = user?.role === "expert"; - const filteredNavItems = NAV_ITEMS.filter((item) => { if (!item.expertOnly || isExpert) { - return true; - } - return false; -}); + const filteredNavItems = NAV_ITEMS.filter((item) => { + if (!item.expertOnly || isExpert) { + return true; + } + return false; + }); const isActive = (path: string, altPath?: string) => { if (path === "/dashboard" || path === "/scan") { diff --git a/apps/web/src/store/ui-store.ts b/apps/web/src/store/ui-store.ts index 8f0fcfa..d37c811 100644 --- a/apps/web/src/store/ui-store.ts +++ b/apps/web/src/store/ui-store.ts @@ -1,12 +1,18 @@ -import { create } from 'zustand'; +import { create } from "zustand"; type UiState = { dashboardCompact: boolean; toggleDashboardCompact: () => void; + + isSidebarOpen: boolean; + setIsSidebarOpen: (isOpen: boolean) => void; }; export const useUiStore = create((set) => ({ dashboardCompact: false, toggleDashboardCompact: () => set((state) => ({ dashboardCompact: !state.dashboardCompact })), + + isSidebarOpen: false, + setIsSidebarOpen: (isOpen: boolean) => set({ isSidebarOpen: isOpen }), }));