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.
This commit is contained in:
seriouselly
2026-06-12 12:26:11 +07:00
parent d5ff1a5cc0
commit a77a6c84ff
2 changed files with 23 additions and 8 deletions
+16 -7
View File
@@ -14,29 +14,38 @@ import {
} from "lucide-react"; } from "lucide-react";
import { MobileNav } from "./mobile-nav"; import { MobileNav } from "./mobile-nav";
import { useAuthStore } from "@/store/auth-store"; import { useAuthStore } from "@/store/auth-store";
import { useUiStore } from "@/store/ui-store";
const NAV_ITEMS = [ const NAV_ITEMS = [
{ path: "/dashboard", label: "Dashboard", icon: LayoutDashboard }, { path: "/dashboard", label: "Dashboard", icon: LayoutDashboard },
{ path: "/scan", label: "Pindai Daun", icon: Scan }, { path: "/scan", label: "Pindai Daun", icon: Scan },
{ path: "/diagnoses", label: "Diagnosa", icon: Activity }, { path: "/diagnoses", label: "Diagnosa", icon: Activity },
{ path: "/catalog", label: "Pustaka", icon: BookOpen, altPath: "/library" }, { 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 }, { path: "/telemetry", label: "Telemetry", icon: ChartBar, expertOnly: true },
]; ];
export function Sidebar() { export function Sidebar() {
const location = useLocation(); const location = useLocation();
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = 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 user = useAuthStore((state) => state.user);
const isExpert = user?.role === "expert"; const isExpert = user?.role === "expert";
const filteredNavItems = NAV_ITEMS.filter((item) => { if (!item.expertOnly || isExpert) { const filteredNavItems = NAV_ITEMS.filter((item) => {
return true; if (!item.expertOnly || isExpert) {
} return true;
return false; }
}); return false;
});
const isActive = (path: string, altPath?: string) => { const isActive = (path: string, altPath?: string) => {
if (path === "/dashboard" || path === "/scan") { if (path === "/dashboard" || path === "/scan") {
+7 -1
View File
@@ -1,12 +1,18 @@
import { create } from 'zustand'; import { create } from "zustand";
type UiState = { type UiState = {
dashboardCompact: boolean; dashboardCompact: boolean;
toggleDashboardCompact: () => void; toggleDashboardCompact: () => void;
isSidebarOpen: boolean;
setIsSidebarOpen: (isOpen: boolean) => void;
}; };
export const useUiStore = create<UiState>((set) => ({ export const useUiStore = create<UiState>((set) => ({
dashboardCompact: false, dashboardCompact: false,
toggleDashboardCompact: () => toggleDashboardCompact: () =>
set((state) => ({ dashboardCompact: !state.dashboardCompact })), set((state) => ({ dashboardCompact: !state.dashboardCompact })),
isSidebarOpen: false,
setIsSidebarOpen: (isOpen: boolean) => set({ isSidebarOpen: isOpen }),
})); }));