// src/layouts/MainLayout.tsx import React, { type ReactNode, useState, useEffect, useMemo } // << AÑADIR useMemo from 'react'; import { Box, AppBar, Toolbar, Typography, Tabs, Tab, Paper, IconButton, Menu, MenuItem, ListItemIcon, ListItemText, Divider, Button } from '@mui/material'; import AccountCircle from '@mui/icons-material/AccountCircle'; import LockResetIcon from '@mui/icons-material/LockReset'; import LogoutIcon from '@mui/icons-material/Logout'; import { useAuth } from '../contexts/AuthContext'; import ChangePasswordModal from '../components/Modals/Usuarios/ChangePasswordModal'; import { useNavigate, useLocation } from 'react-router-dom'; import { usePermissions } from '../hooks/usePermissions'; // <<--- AÑADIR ESTA LÍNEA interface MainLayoutProps { children: ReactNode; } // Definición original de módulos const allAppModules = [ { label: 'Inicio', path: '/', requiredPermission: null }, // Inicio siempre visible { label: 'Distribución', path: '/distribucion', requiredPermission: 'SS001' }, { label: 'Contables', path: '/contables', requiredPermission: 'SS002' }, { label: 'Impresión', path: '/impresion', requiredPermission: 'SS003' }, { label: 'Reportes', path: '/reportes', requiredPermission: 'SS004' }, { label: 'Radios', path: '/radios', requiredPermission: 'SS005' }, { label: 'Usuarios', path: '/usuarios', requiredPermission: 'SS006' }, ]; const MainLayout: React.FC = ({ children }) => { const { user, // user ya está disponible aquí logout, isAuthenticated, isPasswordChangeForced, showForcedPasswordChangeModal, setShowForcedPasswordChangeModal, passwordChangeCompleted } = useAuth(); const { tienePermiso, isSuperAdmin } = usePermissions(); // <<--- OBTENER HOOK DE PERMISOS const navigate = useNavigate(); const location = useLocation(); const [selectedTab, setSelectedTab] = useState(false); const [anchorElUserMenu, setAnchorElUserMenu] = useState(null); // --- INICIO DE CAMBIO: Filtrar módulos basados en permisos --- const accessibleModules = useMemo(() => { if (!isAuthenticated) return []; // Si no está autenticado, ningún módulo excepto quizás login (que no está aquí) return allAppModules.filter(module => { if (module.requiredPermission === null) return true; // Inicio siempre accesible return isSuperAdmin || tienePermiso(module.requiredPermission); }); }, [isAuthenticated, isSuperAdmin, tienePermiso]); // --- FIN DE CAMBIO --- useEffect(() => { // --- INICIO DE CAMBIO: Usar accessibleModules para encontrar el tab --- const currentModulePath = accessibleModules.findIndex(module => location.pathname === module.path || (module.path !== '/' && location.pathname.startsWith(module.path + '/')) ); if (currentModulePath !== -1) { setSelectedTab(currentModulePath); } else if (location.pathname === '/') { // Asegurar que Inicio se seleccione si es accesible const inicioIndex = accessibleModules.findIndex(m => m.path === '/'); if (inicioIndex !== -1) setSelectedTab(inicioIndex); else setSelectedTab(false); } else { setSelectedTab(false); } // --- FIN DE CAMBIO --- }, [location.pathname, accessibleModules]); // << CAMBIO: dependencia a accessibleModules const handleOpenUserMenu = (event: React.MouseEvent) => { setAnchorElUserMenu(event.currentTarget); }; const handleCloseUserMenu = () => { setAnchorElUserMenu(null); }; const handleChangePasswordClick = () => { setShowForcedPasswordChangeModal(true); handleCloseUserMenu(); }; const handleLogoutClick = () => { logout(); handleCloseUserMenu(); }; const handleModalClose = (passwordChangedSuccessfully: boolean) => { if (passwordChangedSuccessfully) { passwordChangeCompleted(); } else { if (isPasswordChangeForced) { logout(); // Si es forzado y cancela/falla, desloguear } else { setShowForcedPasswordChangeModal(false); // Si no es forzado, solo cerrar modal } } }; const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => { // --- INICIO DE CAMBIO: Navegar usando accessibleModules --- if (accessibleModules[newValue]) { setSelectedTab(newValue); navigate(accessibleModules[newValue].path); } // --- FIN DE CAMBIO --- }; const isReportesModule = location.pathname.startsWith('/reportes'); if (showForcedPasswordChangeModal && isPasswordChangeForced) { // ... (sin cambios) return ( ); } // Si no hay módulos accesibles después del login (y no es el cambio de clave forzado) // Esto podría pasar si un usuario no tiene permiso para NINGUNA sección, ni siquiera Inicio. // Deberías redirigir a login o mostrar un mensaje de "Sin acceso". if (isAuthenticated && !isPasswordChangeForced && accessibleModules.length === 0) { return ( No tiene acceso a ninguna sección del sistema. ); } return ( navigate('/')}> Sistema de Gestión - El Día {/* ... (Menú de usuario sin cambios) ... */} {user && ( Hola, {user.nombreCompleto} )} {isAuthenticated && ( <> {user && ( {user.nombreCompleto} {user.username} )} {user && } {!isPasswordChangeForced && ( Cambiar Contraseña )} Cerrar Sesión )} {/* --- INICIO DE CAMBIO: Renderizar Tabs solo si hay módulos accesibles y está autenticado --- */} {isAuthenticated && accessibleModules.length > 0 && ( {/* Mapear sobre accessibleModules en lugar de allAppModules */} {accessibleModules.map((module) => ( ))} )} {/* --- FIN DE CAMBIO --- */} {children} `1px solid ${theme.palette.divider}` }}> Usuario: {user?.username} | Acceso: {user?.esSuperAdmin ? 'Super Administrador' : (user?.perfil || `ID ${user?.idPerfil}`)} handleModalClose(false)} isFirstLogin={false} /> ); }; export default MainLayout;