/** * Composable unificado para manejar el estado de la sidebar * * Centraliza todo el estado relacionado con la sidebar para evitar * inconsistencias entre múltiples refs y watchers en cascada. * * Características: * - Estado persistente en cookies * - Sincronización automática entre open/collapsed * - Manejo de responsive (mobile vs desktop) * - DashboardSidebar de Nuxt UI maneja el cierre en navegación */ import { ref, computed } from 'vue' // Storage key para las cookies const STORAGE_KEY = 'analytics-dashboard-sidebar' // Tipos interface SidebarState { open: boolean collapsed: boolean size: number } // Estado global singleton const sidebarState = ref(null) export function useSidebarState() { // Detectar si estamos en mobile (debe hacerse antes de leer el estado) const isMobile = computed(() => { if (import.meta.server) return false return window.innerWidth < 1024 // lg breakpoint }) // Inicializar estado solo una vez (singleton) if (!sidebarState.value) { // Leer de cookie si existe const savedState = useCookie(STORAGE_KEY, { default: () => ({ // En desktop, open=false porque no hay overlay (la sidebar siempre está visible) // En mobile, open=false significa que el overlay está cerrado (comportamiento correcto) open: false, collapsed: false, size: 28 // defaultSize }) }) sidebarState.value = savedState.value } // Referencias reactivas al estado const open = computed({ get: () => sidebarState.value?.open ?? false, set: (value: boolean) => { if (sidebarState.value) { sidebarState.value.open = value // Persistir en cookie const cookie = useCookie(STORAGE_KEY) cookie.value = sidebarState.value } } }) const collapsed = computed({ get: () => sidebarState.value?.collapsed ?? false, set: (value: boolean) => { if (sidebarState.value) { sidebarState.value.collapsed = value // Persistir en cookie const cookie = useCookie(STORAGE_KEY) cookie.value = sidebarState.value } } }) const size = computed({ get: () => sidebarState.value?.size ?? 28, set: (value: number) => { if (sidebarState.value) { sidebarState.value.size = value // Persistir en cookie const cookie = useCookie(STORAGE_KEY) cookie.value = sidebarState.value } } }) // Funciones de control function toggle() { open.value = !open.value } function toggleCollapse() { collapsed.value = !collapsed.value } function setOpen(value: boolean) { open.value = value } function setCollapsed(value: boolean) { collapsed.value = value } return { // Estado open, collapsed, size, isMobile, // Acciones toggle, toggleCollapse, setOpen, setCollapsed } }