// ROCA GOLF — Sidebar + Topbar (golf dark theme only) // ── Permisos ────────────────────────────────────────────────────────────────── // v9.0: ya no hay un mapa fijo aquí — el backend calcula qué módulos puede ver // cada usuario (rol + excepciones individuales, configurables en Configuración // → Permisos, ver api/permisos.php) y lo manda en user.modulos al hacer login // o restaurar sesión (api/auth.php, api/session.php). Este archivo solo LEE esa // lista; la fuente de verdad real está en api/config.php (userCan/modulosDeUsuario). // Fallback a [] (nada) si por algo faltara — fail-closed, no fail-open. function canAccess(user, viewId) { const modulos = user && Array.isArray(user.modulos) ? user.modulos : []; return modulos.includes(viewId); } const ROL_LABELS = { administrador: 'Administrador', contralor: 'Contralor', auxiliarcontable: 'Auxiliar Contable', directorproyectos: 'Director de Proyectos', tesorero: 'Tesorero', supervisor: 'Supervisor', proyectos: 'Proyectos', }; const IcoUsuarios = (s = 15) => ( ); function Sidebar({ active = "dashboard", onNav, alertCount = 4, user, onLogout }) { const rol = user?.rol || ''; const allItems = [ { group: "Operación", links: [ { id: "dashboard", label: "Dashboard", icon: Icon.dashboard }, { id: "reports", label: "Reportes", icon: Icon.reports }, { id: "oc", label: "Órdenes de compra", icon: Icon.oc }, { id: "alerts", label: "Presupuestos", icon: Icon.budget, badge: alertCount }, { id: "reporte_ia", label: "Reporte IA", icon: Icon.reporteia } ]}, { group: "Catálogos", links: [ { id: "catalog", label: "Insumos", icon: Icon.catalog }, { id: "admin_proy", label: "Admin. de Proyecto", icon: Icon.budget }, { id: "import_presupuesto", label: "Importar Presupuesto (IA)", icon: Icon.excel }, { id: "import_oc", label: "Importar OCs", icon: Icon.excel }, { id: "vendors", label: "Proveedores", icon: Icon.vendors }, { id: "history", label: "Historial", icon: Icon.history } ]}, { group: "Sistema", links: [ { id: "usuarios", label: "Usuarios", icon: IcoUsuarios }, { id: "reestructuracion", label: "Reestructuración", icon: Icon.edit }, { id: "settings", label: "Configuración", icon: Icon.settings } ]} ]; // Filtrar ítems según los módulos efectivos del usuario; omitir grupos vacíos const items = allItems .map(g => ({ ...g, links: g.links.filter(l => canAccess(user, l.id)) })) .filter(g => g.links.length > 0); const rolLabel = ROL_LABELS[rol] || rol; return ( ); } function Topbar({ crumbs = "Compras / Dashboard", title = "Panel general", periodLabel = "Q2 2026 · Abril", actions, onSearch }) { return (
{crumbs}

{title}

{Icon.search()} onSearch && onSearch(e.target.value)}/>
{actions || }
); } Object.assign(window, { Sidebar, Topbar, canAccess });