/* App shell — sidebar nav, top bar, mobile bottom nav */ const NAV = [ { id: "today", label: "Hoy", icon: "home" }, { id: "metrics", label: "Métricas", icon: "metrics" }, { id: "activities", label: "Actividades", icon: "activity" }, { id: "agents", label: "Coach", icon: "coach" }, { id: "plans", label: "Planes", icon: "plan" }, { id: "knowledge", label: "Biblioteca", icon: "book" }, { id: "settings", label: "Configuración", icon: "settings" }, ]; const Sidebar = ({ route, setRoute, density, onboardingActive, user, inDemo }) => { const name = inDemo ? "Demo" : (user?.name || (user?.email ? user.email.split("@")[0] : "usuario")); const initial = (name?.[0] || "·").toUpperCase(); const sub = inDemo ? "modo demo" : (user?.email || "self-hosted"); // Suscripción al singleton de uploads para mostrar un badge "N" sobre el ítem // "Biblioteca" cuando hay archivos procesando o pendientes (incluso si el // user está en otra ruta). Re-render por subscribe/notify. const [, setTick] = React.useState(0); React.useEffect(() => { if (typeof window === "undefined" || typeof window.__af_uploadQueue__?.subscribe !== "function") return undefined; return window.__af_uploadQueue__.subscribe(() => setTick((t) => t + 1)); }, []); const uploadActive = (typeof window !== "undefined" && window.__af_uploadQueue__) ? window.__af_uploadQueue__.activeCount() : 0; return ( ); }; const MobileNav = ({ route, setRoute }) => { const [open, setOpen] = React.useState(false); const goto = (id) => { setRoute(id); setOpen(false); }; const current = NAV.find(n => n.id === route); return ( <> {/* Top mobile bar with hamburger + current screen */}