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 zonaService from '../../services/Distribucion/zonaService'; // Servicio de Zonas import type { ZonaDto } from '../../models/dtos/Zonas/ZonaDto'; // DTO de Zonas import type { CreateZonaDto } from '../../models/dtos/Zonas/CreateZonaDto'; // DTOs Create import type { UpdateZonaDto } from '../../models/dtos/Zonas/UpdateZonaDto'; // DTOs Update import ZonaFormModal from '../../components/Modals/Distribucion/ZonaFormModal'; // Modal de Zonas import { usePermissions } from '../../hooks/usePermissions'; // Hook de permisos import axios from 'axios'; // Para manejo de errores const GestionarZonasPage: React.FC = () => { const [zonas, setZonas] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filtroNombre, setFiltroNombre] = useState(''); // const [filtroDescripcion, setFiltroDescripcion] = useState(''); // Si añades filtro por descripción const [modalOpen, setModalOpen] = useState(false); const [editingZona, setEditingZona] = useState(null); // Usar ZonaDto aquí también const [apiErrorMessage, setApiErrorMessage] = useState(null); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(5); const [anchorEl, setAnchorEl] = useState(null); const [selectedZonaRow, setSelectedZonaRow] = useState(null); const { tienePermiso, isSuperAdmin } = usePermissions(); // Ajustar códigos de permiso para Zonas const puedeCrear = isSuperAdmin || tienePermiso("ZD002"); const puedeModificar = isSuperAdmin || tienePermiso("ZD003"); const puedeEliminar = isSuperAdmin || tienePermiso("ZD004"); const cargarZonas = useCallback(async () => { setLoading(true); setError(null); try { // Usar servicio de zonas y filtros const data = await zonaService.getAllZonas(filtroNombre/*, filtroDescripcion*/); setZonas(data); } catch (err) { console.error(err); setError('Error al cargar las zonas.'); } finally { setLoading(false); } }, [filtroNombre/*, filtroDescripcion*/]); // Añadir dependencias de filtro useEffect(() => { cargarZonas(); }, [cargarZonas]); const handleOpenModal = (zona?: ZonaDto) => { setEditingZona(zona || null); setApiErrorMessage(null); setModalOpen(true); }; const handleCloseModal = () => { setModalOpen(false); setEditingZona(null); }; const handleSubmitModal = async (data: CreateZonaDto | UpdateZonaDto) => { setApiErrorMessage(null); try { if (editingZona) { // Es Update await zonaService.updateZona(editingZona.idZona, data as UpdateZonaDto); } else { // Es Create await zonaService.createZona(data as CreateZonaDto); } cargarZonas(); // Recargar lista } catch (err: any) { console.error("Error en submit modal (padre):", err); if (axios.isAxiosError(err) && err.response) { setApiErrorMessage(err.response.data?.message || 'Error al guardar la zona.'); } else { setApiErrorMessage('Ocurrió un error inesperado al guardar la zona.'); } throw err; } }; const handleDelete = async (id: number) => { if (window.confirm('¿Está seguro de que desea eliminar esta zona? (Se marcará como inactiva)')) { setApiErrorMessage(null); try { await zonaService.deleteZona(id); // Llama al soft delete cargarZonas(); // Recarga la lista (la zona eliminada ya no debería aparecer si el filtro es solo activas) } catch (err: any) { console.error("Error al eliminar zona:", err); if (axios.isAxiosError(err) && err.response) { setApiErrorMessage(err.response.data?.message || 'Error al eliminar.'); } else { setApiErrorMessage('Ocurrió un error inesperado al eliminar.'); } } } handleMenuClose(); }; const handleMenuOpen = (event: React.MouseEvent, zona: ZonaDto) => { setAnchorEl(event.currentTarget); setSelectedZonaRow(zona); }; const handleMenuClose = () => { setAnchorEl(null); setSelectedZonaRow(null); }; const handleChangePage = (_event: unknown, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = (event: React.ChangeEvent) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; // Adaptar para paginación const displayData = zonas.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage); return ( Gestionar Zonas setFiltroNombre(e.target.value)} /> {/* */} {puedeCrear && ( )} {loading && } {error && !loading && {error}} {apiErrorMessage && {apiErrorMessage}} {!loading && !error && ( Nombre Descripción Acciones {displayData.length === 0 && !loading ? ( No se encontraron zonas. ) : ( displayData.map((zona) => ( {zona.nombre} {zona.descripcion || '-'} handleMenuOpen(e, zona)} disabled={!puedeModificar && !puedeEliminar} > )) )}
)} {puedeModificar && ( { handleOpenModal(selectedZonaRow!); handleMenuClose(); }}> Modificar )} {puedeEliminar && ( handleDelete(selectedZonaRow!.idZona)}> Eliminar )} {(!puedeModificar && !puedeEliminar) && Sin acciones} setApiErrorMessage(null)} />
); }; export default GestionarZonasPage;