import { useState, useEffect } from 'react'; /** * useState but persisted to sessionStorage * Useful for preserving UI state (expanded/collapsed sections, etc.) * * @param key - Storage key (should be unique) * @param defaultValue - Default value if nothing in storage * @returns [value, setValue] tuple like useState * * @example * const [isExpanded, setIsExpanded] = usePersistedState('sidebar-expanded', false); */ export function usePersistedState( key: string, defaultValue: T ): [T, (value: T | ((prev: T) => T)) => void] { const [value, setValue] = useState(() => { // Only access sessionStorage on client if (typeof window === 'undefined') { return defaultValue; } try { const stored = sessionStorage.getItem(key); return stored !== null ? JSON.parse(stored) : defaultValue; } catch (error) { console.error(`Error reading from sessionStorage (key: ${key}):`, error); return defaultValue; } }); // Persist to storage when value changes useEffect(() => { if (typeof window === 'undefined') return; try { sessionStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.error(`Error writing to sessionStorage (key: ${key}):`, error); } }, [key, value]); return [value, setValue]; } /** * Like usePersistedState but for localStorage (persists between sessions) */ export function useLocalStorageState( key: string, defaultValue: T ): [T, (value: T | ((prev: T) => T)) => void] { const [value, setValue] = useState(() => { if (typeof window === 'undefined') { return defaultValue; } try { const stored = localStorage.getItem(key); return stored !== null ? JSON.parse(stored) : defaultValue; } catch (error) { console.error(`Error reading from localStorage (key: ${key}):`, error); return defaultValue; } }); useEffect(() => { if (typeof window === 'undefined') return; try { localStorage.setItem(key, JSON.stringify(value)); } catch (error) { console.error(`Error writing to localStorage (key: ${key}):`, error); } }, [key, value]); return [value, setValue]; }