"use client" import { createContext, useCallback, useContext, useEffect, useMemo, useState, type ReactNode, } from "react" import { loadPersistedPanelState, savePersistedPanelState, } from "@/lib/panel-state-storage" const DEFAULT_WIDTH = 320 const MIN_WIDTH = 200 const MAX_WIDTH = 600 const DEFAULT_IS_OPEN = true interface SidebarContextValue { isOpen: boolean width: number minWidth: number maxWidth: number toggle: () => void setWidth: (w: number) => void } const SidebarContext = createContext(null) export function useSidebarContext() { const ctx = useContext(SidebarContext) if (!ctx) { throw new Error("useSidebarContext must be used within SidebarProvider") } return ctx } function clampWidth(width: number) { return Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, width)) } interface SidebarProviderProps { children: ReactNode folderId: number } export function SidebarProvider({ children, folderId }: SidebarProviderProps) { const storageKey = useMemo( () => `folder:${folderId}:left-sidebar`, [folderId] ) const [isOpen, setIsOpen] = useState(DEFAULT_IS_OPEN) const [width, setWidthState] = useState(DEFAULT_WIDTH) const [restored, setRestored] = useState(false) const toggle = useCallback(() => setIsOpen((prev) => !prev), []) const setWidth = useCallback((w: number) => { setWidthState(clampWidth(w)) }, []) useEffect(() => { const stored = loadPersistedPanelState(storageKey) // On mobile (< 768px), always start closed regardless of persisted state. const isMobileViewport = window.innerWidth < 768 const defaultOpen = isMobileViewport ? false : DEFAULT_IS_OPEN // Hydrate from localStorage after mount to keep SSR/CSR markup consistent. // eslint-disable-next-line react-hooks/set-state-in-effect setIsOpen(isMobileViewport ? false : (stored?.isOpen ?? defaultOpen)) setWidthState(clampWidth(stored?.width ?? DEFAULT_WIDTH)) setRestored(true) }, [storageKey]) useEffect(() => { if (!restored) return savePersistedPanelState(storageKey, { isOpen, width }) }, [isOpen, restored, storageKey, width]) const value = useMemo( () => ({ isOpen, width, minWidth: MIN_WIDTH, maxWidth: MAX_WIDTH, toggle, setWidth, }), [isOpen, width, toggle, setWidth] ) return ( {children} ) }