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 tipoBobinaService from '../../services/Impresion/tipoBobinaService'; // Servicio específico import type { TipoBobinaDto } from '../../models/dtos/Impresion/TipoBobinaDto'; import type { CreateTipoBobinaDto } from '../../models/dtos/Impresion/CreateTipoBobinaDto'; import type { UpdateTipoBobinaDto } from '../../models/dtos/Impresion/UpdateTipoBobinaDto'; import TipoBobinaFormModal from '../../components/Modals/Impresion/TipoBobinaFormModal'; // Modal específico import { usePermissions } from '../../hooks/usePermissions'; import axios from 'axios'; const GestionarTiposBobinaPage: React.FC = () => { const [tiposBobina, setTiposBobina] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [filtroDenominacion, setFiltroDenominacion] = useState(''); const [modalOpen, setModalOpen] = useState(false); const [editingTipoBobina, setEditingTipoBobina] = useState(null); const [apiErrorMessage, setApiErrorMessage] = useState(null); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(5); const [anchorEl, setAnchorEl] = useState(null); const [selectedTipoBobinaRow, setSelectedTipoBobinaRow] = useState(null); const { tienePermiso, isSuperAdmin } = usePermissions(); // Permisos específicos para Tipos de Bobina (IB006 a IB009) const puedeVer = isSuperAdmin || tienePermiso("IB006"); const puedeCrear = isSuperAdmin || tienePermiso("IB007"); const puedeModificar = isSuperAdmin || tienePermiso("IB008"); const puedeEliminar = isSuperAdmin || tienePermiso("IB009"); const cargarTiposBobina = useCallback(async () => { if (!puedeVer) { setError("No tiene permiso para ver esta sección."); setLoading(false); return; } setLoading(true); setError(null); setApiErrorMessage(null); try { const data = await tipoBobinaService.getAllTiposBobina(filtroDenominacion); setTiposBobina(data); } catch (err) { console.error(err); setError('Error al cargar los tipos de bobina.'); } finally { setLoading(false); } }, [filtroDenominacion, puedeVer]); useEffect(() => { cargarTiposBobina(); }, [cargarTiposBobina]); const handleOpenModal = (tipoBobina?: TipoBobinaDto) => { setEditingTipoBobina(tipoBobina || null); setApiErrorMessage(null); setModalOpen(true); }; const handleCloseModal = () => { setModalOpen(false); setEditingTipoBobina(null); }; const handleSubmitModal = async (data: CreateTipoBobinaDto | (UpdateTipoBobinaDto & { idTipoBobina: number })) => { setApiErrorMessage(null); try { if (editingTipoBobina && 'idTipoBobina' in data) { await tipoBobinaService.updateTipoBobina(editingTipoBobina.idTipoBobina, data); } else { await tipoBobinaService.createTipoBobina(data as CreateTipoBobinaDto); } cargarTiposBobina(); } catch (err: any) { console.error("Error en submit modal (padre - TiposBobina):", err); const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Ocurrió un error inesperado al guardar el tipo de bobina.'; setApiErrorMessage(message); throw err; } }; const handleDelete = async (id: number) => { if (window.confirm(`¿Está seguro de que desea eliminar este tipo de bobina (ID: ${id})?`)) { setApiErrorMessage(null); try { await tipoBobinaService.deleteTipoBobina(id); cargarTiposBobina(); } catch (err: any) { console.error("Error al eliminar tipo de bobina:", err); const message = axios.isAxiosError(err) && err.response?.data?.message ? err.response.data.message : 'Ocurrió un error inesperado al eliminar el tipo de bobina.'; setApiErrorMessage(message); } } handleMenuClose(); }; const handleMenuOpen = (event: React.MouseEvent, tipoBobina: TipoBobinaDto) => { setAnchorEl(event.currentTarget); setSelectedTipoBobinaRow(tipoBobina); }; const handleMenuClose = () => { setAnchorEl(null); setSelectedTipoBobinaRow(null); }; const handleChangePage = (_event: unknown, newPage: number) => { setPage(newPage); }; const handleChangeRowsPerPage = (event: React.ChangeEvent) => { setRowsPerPage(parseInt(event.target.value, 10)); setPage(0); }; const displayData = tiposBobina.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage); if (!loading && !puedeVer) { return ( Gestionar Tipos de Bobina {error || "No tiene permiso para acceder a esta sección."} ); } return ( Gestionar Tipos de Bobina setFiltroDenominacion(e.target.value)} /> {/* */} {puedeCrear && ( )} {loading && } {error && !loading && {error}} {apiErrorMessage && {apiErrorMessage}} {!loading && !error && ( Denominación {(puedeModificar || puedeEliminar) && Acciones} {displayData.length === 0 && !loading ? ( No se encontraron tipos de bobina. ) : ( displayData.map((tipo) => ( {tipo.denominacion} {(puedeModificar || puedeEliminar) && ( handleMenuOpen(e, tipo)} disabled={!puedeModificar && !puedeEliminar} > )} )) )}
)} {puedeModificar && ( { handleOpenModal(selectedTipoBobinaRow!); handleMenuClose(); }}> Modificar )} {puedeEliminar && ( handleDelete(selectedTipoBobinaRow!.idTipoBobina)}> Eliminar )} {(!puedeModificar && !puedeEliminar) && Sin acciones} setApiErrorMessage(null)} />
); }; export default GestionarTiposBobinaPage;