import React, { useState, useEffect, useCallback } from 'react'; import { Box, Typography, TextField, Button, Paper, IconButton, Menu, MenuItem, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TablePagination, CircularProgress, Alert } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import MoreVertIcon from '@mui/icons-material/MoreVert'; import empresaService from '../../services/Distribucion/empresaService'; // Importar el servicio de Empresas import type { EmpresaDto } from '../../models/dtos/Distribucion/EmpresaDto'; import type { CreateEmpresaDto } from '../../models/dtos/Distribucion/CreateEmpresaDto'; import type { UpdateEmpresaDto } from '../../models/dtos/Distribucion/UpdateEmpresaDto'; import EmpresaFormModal from '../../components/Modals/Distribucion/EmpresaFormModal'; // Importar el modal de Empresas import { usePermissions } from '../../hooks/usePermissions'; // Importar hook de permisos import axios from 'axios'; // Para manejo de errores de API const GestionarEmpresasPage: React.FC = () => { const [empresas, setEmpresas] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); // Para errores al cargar datos const [filtroNombre, setFiltroNombre] = useState(''); // const [filtroDetalle, setFiltroDetalle] = useState(''); // Descomentar si añades filtro por detalle const [modalOpen, setModalOpen] = useState(false); const [editingEmpresa, setEditingEmpresa] = useState(null); const [apiErrorMessage, setApiErrorMessage] = useState(null); // Para errores del modal (Create/Update/Delete) const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(5); // Para el menú contextual de acciones por fila const [anchorEl, setAnchorEl] = useState(null); const [selectedEmpresaRow, setSelectedEmpresaRow] = useState(null); const { tienePermiso, isSuperAdmin } = usePermissions(); // Usar el hook // Determinar permisos específicos para Empresas (basado en los códigos DE001 a DE004) const puedeVer = isSuperAdmin || tienePermiso("DE001"); // Necesario para mostrar la página const puedeCrear = isSuperAdmin || tienePermiso("DE002"); const puedeModificar = isSuperAdmin || tienePermiso("DE003"); const puedeEliminar = isSuperAdmin || tienePermiso("DE004"); const cargarEmpresas = useCallback(async () => { if (!puedeVer) { // Si no tiene permiso de ver, no cargar nada setError("No tiene permiso para ver esta sección."); setLoading(false); return; } setLoading(true); setError(null); setApiErrorMessage(null); // Limpiar errores API al recargar try { const data = await empresaService.getAllEmpresas(filtroNombre/*, filtroDetalle*/); setEmpresas(data); } catch (err) { console.error(err); setError('Error al cargar las empresas.'); } finally { setLoading(false); } }, [filtroNombre, puedeVer /*, filtroDetalle*/]); // Añadir puedeVer como dependencia useEffect(() => { cargarEmpresas(); }, [cargarEmpresas]); // Ejecutar al montar y cuando cambien las dependencias de cargarEmpresas const handleOpenModal = (empresa?: EmpresaDto) => { setEditingEmpresa(empresa || null); setApiErrorMessage(null); // Limpiar error API antes de abrir modal setModalOpen(true); }; const handleCloseModal = () => { setModalOpen(false); setEditingEmpresa(null); // No limpiamos apiErrorMessage aquí, se limpia al intentar un nuevo submit o al recargar }; const handleSubmitModal = async (data: CreateEmpresaDto | (UpdateEmpresaDto & { idEmpresa: number })) => { setApiErrorMessage(null); // Limpiar error previo // No necesitamos setLoading aquí, el modal lo maneja try { if (editingEmpresa && 'idEmpresa' in data) { // Es Update (verificamos si initialData existe Y data tiene id) await empresaService.updateEmpresa(editingEmpresa.idEmpresa, data); } else { // Es Create await empresaService.createEmpresa(data as CreateEmpresaDto); } cargarEmpresas(); // Recargar lista en éxito // handleCloseModal(); // El modal se cierra solo desde su propio onSubmit exitoso } catch (err: any) { console.error("Error en submit modal (padre):", err); const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Ocurrió un error inesperado al guardar la empresa.'; setApiErrorMessage(message); throw err; // Re-lanzar para que el modal sepa que hubo error y no se cierre } // No poner finally setLoading(false) aquí, el modal lo controla }; const handleDelete = async (id: number) => { // Opcional: mostrar un mensaje de confirmación más detallado if (window.confirm(`¿Está seguro de que desea eliminar esta empresa (ID: ${id})? Esta acción también eliminará los saldos asociados.`)) { setApiErrorMessage(null); // Limpiar errores previos try { await empresaService.deleteEmpresa(id); cargarEmpresas(); // Recargar la lista para reflejar la eliminación } catch (err: any) { console.error("Error al eliminar empresa:", err); const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Ocurrió un error inesperado al eliminar la empresa.'; setApiErrorMessage(message); // Mostrar error de API } } handleMenuClose(); // Cerrar el menú de acciones }; // --- Handlers para el menú y paginación (sin cambios respecto a Zonas/TiposPago) --- const handleMenuOpen = (event: React.MouseEvent, empresa: EmpresaDto) => { setAnchorEl(event.currentTarget); setSelectedEmpresaRow(empresa); }; const handleMenuClose = () => { setAnchorEl(null); setSelectedEmpresaRow(null); }; const handleChangePage = (_event: unknown, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = (event: React.ChangeEvent) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; // Datos a mostrar en la tabla actual según paginación const displayData = empresas.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage); // Si no tiene permiso para ver, mostrar mensaje y salir if (!loading && !puedeVer) { return ( Gestionar Empresas {error || "No tiene permiso para acceder a esta sección."} ); } return ( Gestionar Empresas setFiltroNombre(e.target.value)} /> {/* Mostrar botón de agregar solo si tiene permiso */} {puedeCrear && ( )} {/* Indicador de carga */} {loading && } {/* Mensaje de error al cargar datos */} {error && !loading && {error}} {/* Mensaje de error de la API (modal/delete) */} {apiErrorMessage && {apiErrorMessage}} {/* Tabla de datos (solo si no está cargando y no hubo error de carga inicial) */} {!loading && !error && ( Nombre Detalle {/* Mostrar columna de acciones solo si tiene permiso de modificar o eliminar */} {(puedeModificar || puedeEliminar) && Acciones} {displayData.length === 0 && !loading ? ( No se encontraron empresas. ) : ( displayData.map((emp) => ( {emp.nombre} {emp.detalle || '-'} {/* Mostrar botón de acciones solo si tiene permiso */} {(puedeModificar || puedeEliminar) && ( handleMenuOpen(e, emp)} // Deshabilitar si no tiene ningún permiso específico (redundante por la condición de la celda, pero seguro) disabled={!puedeModificar && !puedeEliminar} > )} )) )}
{/* Paginación */}
)} {/* Menú contextual para acciones de fila */} {/* Mostrar opción Modificar solo si tiene permiso */} {puedeModificar && ( { handleOpenModal(selectedEmpresaRow!); handleMenuClose(); }}> Modificar )} {/* Mostrar opción Eliminar solo si tiene permiso */} {puedeEliminar && ( handleDelete(selectedEmpresaRow!.idEmpresa)}> Eliminar )} {/* Mensaje si no hay acciones disponibles (por si acaso) */} {(!puedeModificar && !puedeEliminar) && Sin acciones} {/* Modal para Crear/Editar */} setApiErrorMessage(null)} // Pasar función para limpiar el error />
); }; export default GestionarEmpresasPage;