import React, { useState, useEffect } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import { useUser } from '../context/UserContext'; import { fetchWithAuth } from '../fetchWithAuth'; export default function Sidebar({ isMobileOpen, onMobileClose }) { const isDebugMode = import.meta.env.VITE_DEBUG_MODE === 'true'; // Permisos RBAC — cargados desde /rbac/my-permissions/ al hacer login const [userPermissions, setUserPermissions] = useState(() => { try { return JSON.parse(localStorage.getItem('user_permissions') || '[]'); } catch { return []; } }); const hasPermission = (codename) => userPermissions.includes(codename); // Estados para responsividad const [isCollapsed, setIsCollapsed] = useState(false); const [internalMobileOpen, setInternalMobileOpen] = useState(false); // Usar estado interno si no se pasan props const mobileOpen = isMobileOpen !== undefined ? isMobileOpen : internalMobileOpen; const handleMobileClose = onMobileClose || (() => setInternalMobileOpen(false)); const handleMobileOpen = () => setInternalMobileOpen(true); const location = useLocation(); const navigate = useNavigate(); const { user: currentUser, loading } = useUser(); const handleLogout = () => { localStorage.removeItem('access'); localStorage.removeItem('refresh'); localStorage.removeItem('user_id'); localStorage.removeItem('user_is_importador'); localStorage.removeItem('user_groups'); localStorage.removeItem('user_permissions'); localStorage.removeItem('username'); localStorage.removeItem('user_email'); localStorage.removeItem('user_first_name'); localStorage.removeItem('user_last_name'); window.dispatchEvent(new CustomEvent('authStateChanged')); navigate('/login'); }; // Cerrar menú móvil cuando se navega o cuando la pantalla es grande useEffect(() => { const handleResize = () => { if (window.innerWidth >= 1024) { // lg breakpoint handleMobileClose(); } }; window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); // Cerrar menú móvil cuando cambia la ubicación useEffect(() => { handleMobileClose(); }, [location.pathname]); // Si no hay permisos en localStorage (sesión previa al RBAC), los carga del servidor useEffect(() => { if (userPermissions.length === 0 && localStorage.getItem('access')) { const apiUrl = import.meta.env.VITE_EFC_API_URL || ''; fetchWithAuth(`${apiUrl}/rbac/my-permissions/`) .then(res => res.ok ? res.json() : null) .then(data => { if (data && Array.isArray(data.permissions)) { localStorage.setItem('user_permissions', JSON.stringify(data.permissions)); setUserPermissions(data.permissions); } }) .catch(() => {}); } }, []); // El usuario y loading ahora vienen del contexto global // Definir todas las secciones const allMenuSections = [ { title: 'Organización', items: [ { name: 'Home', path: '/admin', icon: ( ) }, ...( hasPermission('organizacion.view') ? [ { name: 'Mi Organización', path: '/organization', icon: ( ) } ] : [] ) ] }, { title: 'Servicios', items: [ { name: 'Procesos', path: '/procesos', icon: ( ) }, ...( hasPermission('auditoria.view') ? [{ name: 'Auditor', path: '/auditor', icon: ( ) }] : [] ) ] }, { title: 'Documentación', items: [ // Mostrar Reportes siempre { name: 'Reportes', path: '/reports', icon: ( ) }, { name: 'Expedientes', path: '/expedientes', icon: ( ) }, { name: 'Documentos', path: '/documents', icon: ( ) }, { name: 'Datastage', path: '/datastage', icon: ( ), onClick: () => navigate('/datastage') } ] }, // Nueva sección Tableros - Solo mostrar si DEBUG_MODE es true y tiene cards.view ...( (isDebugMode && hasPermission('cards.view')) ? [ { title: 'Tableros', items: [ { name: 'Resumen de cumplimiento', path: '/tablero/cumplimiento', icon: ( ) } ] } ] : [] ), { title: 'Acceso a Usuarios', items: [ ...( hasPermission('importadores.view') ? [{ name: 'Importadores', path: '/importers', icon: ( ) }] : [] ), ...( hasPermission('usuarios.view') ? [{ name: 'Usuarios', path: '/users', icon: ( ) }] : [] ), ...( hasPermission('usuarios.manage_roles') ? [{ name: 'Perfiles', path: '/profiles', icon: ( ) }] : [] ), ...( hasPermission('vucem.view') ? [{ name: 'Ventanilla Única', path: '/vucem', icon: ( ) }] : [] ), ] } ]; // Ocultar secciones que no tienen ningún item visible const menuSections = allMenuSections.filter( section => section && section.items && section.items.length > 0 ); return ( <> {/* Botón flotante para abrir menú en móvil - solo cuando se usa standalone */} {!mobileOpen && isMobileOpen === undefined && ( )} {/* Overlay para móviles */} {mobileOpen && (
)} {/* Sidebar */}{currentUser.first_name} {currentUser.last_name}
{currentUser.username}
> ) : ( <>Usuario
Sin datos
> )} {/* Debug temporal */} {process.env.NODE_ENV === 'development' && (