import React, { useState, useEffect } from 'react'; import { Plus, Edit, Trash2, Loader, CheckCircle, XCircle } from 'lucide-react'; import { apiClient, validateChileanRut, formatChileanRut } from '../../services/api'; import logger from '../../utils/logger'; import { useTranslation } from 'react-i18next'; interface Ley21121Record { _id: string; rut: string; razonSocial: string; rolCausa: string; fechaDesde: string; fechaHasta: string; duracion: string; motivo: string; createdAt: string; updatedAt: string; } const Ley21121Page: React.FC = () => { const { t } = useTranslation(); const token = localStorage.getItem('token'); const [records, setRecords] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [openDialog, setOpenDialog] = useState(false); const [dialogMode, setDialogMode] = useState<'create' | 'edit'>('create'); const [currentRecord, setCurrentRecord] = useState>({}); const [isValidRut, setIsValidRut] = useState(null); const [formattedRut, setFormattedRut] = useState(''); const [snackbar, setSnackbar] = useState<{ open: boolean; message: string; severity: 'success' | 'error' }>({ open: false, message: '', severity: 'success' }); const [selected, setSelected] = useState([]); const [deleting, setDeleting] = useState(false); // Fetch all records const fetchRecords = async () => { setLoading(true); try { const response = await apiClient.get('/ley21121'); setRecords(response.data.data); setError(null); } catch (err) { logger.error('Error fetching records:', err); setError(t('ley21121.messages.loadError')); } finally { setLoading(false); } }; useEffect(() => { fetchRecords(); }, [token]); // Handle form input changes const handleInputChange = (e: React.ChangeEvent) => { const { name, value } = e.target; // If the field is RUT, validate and format it if (name === 'rut') { // Format RUT as user types if (value) { const formatted = formatChileanRut(value); setFormattedRut(formatted); // Validate RUT const isValid = validateChileanRut(value); setIsValidRut(isValid); // Store the sanitized RUT (without dots, uppercase) const sanitizedRut = formatted.replace(/\./g, ''); setCurrentRecord({ ...currentRecord, [name]: sanitizedRut }); } else { setFormattedRut(''); setIsValidRut(null); setCurrentRecord({ ...currentRecord, [name]: '' }); } } else { setCurrentRecord({ ...currentRecord, [name]: value }); } }; // Handle date changes const handleDateChange = (date: Date | null, field: 'fechaDesde' | 'fechaHasta') => { if (date) { setCurrentRecord({ ...currentRecord, [field]: date.toISOString() }); } }; // Open dialog for creating a new record const handleOpenCreateDialog = () => { setDialogMode('create'); setCurrentRecord({}); setOpenDialog(true); }; // Open dialog for editing an existing record const handleOpenEditDialog = (record: Ley21121Record) => { setDialogMode('edit'); setCurrentRecord({ ...record }); setOpenDialog(true); }; // Close dialog const handleCloseDialog = () => { setOpenDialog(false); }; // Save record (create or update) const handleSaveRecord = async () => { // Validate RUT before saving if (currentRecord.rut && !validateChileanRut(currentRecord.rut)) { setSnackbar({ open: true, message: t('ley21121.form.rut.invalid'), severity: 'error' }); return; } try { if (dialogMode === 'create') { await apiClient.post('/ley21121', currentRecord); setSnackbar({ open: true, message: t('ley21121.messages.createSuccess'), severity: 'success' }); } else { await apiClient.put(`/ley21121/${currentRecord._id}`, currentRecord); setSnackbar({ open: true, message: t('ley21121.messages.updateSuccess'), severity: 'success' }); } handleCloseDialog(); fetchRecords(); } catch (err) { logger.error('Error saving record:', err); setSnackbar({ open: true, message: t('ley21121.messages.saveError'), severity: 'error' }); } }; // Delete record const handleDeleteRecord = async (id: string) => { if (window.confirm(t('ley21121.messages.deleteConfirm'))) { try { await apiClient.delete(`/ley21121/${id}`); setSnackbar({ open: true, message: t('ley21121.messages.deleteSuccess'), severity: 'success' }); fetchRecords(); } catch (err) { logger.error('Error deleting record:', err); setSnackbar({ open: true, message: t('ley21121.messages.deleteError'), severity: 'error' }); } } }; // Handle select all checkbox const handleSelectAll = (e: React.ChangeEvent) => { if (e.target.checked) { setSelected(records.map((r) => r._id)); } else { setSelected([]); } }; // Handle select one checkbox const handleSelectOne = (id: string) => { if (selected.includes(id)) { setSelected(selected.filter((s) => s !== id)); } else { setSelected([...selected, id]); } }; // Handle delete selected records const handleDeleteSelected = async () => { if (selected.length === 0) return; if (!window.confirm(t('ley21121.messages.deleteConfirm'))) return; setDeleting(true); let deletedCount = 0; let errorCount = 0; for (const id of selected) { try { await apiClient.delete(`/ley21121/${id}`); deletedCount++; } catch (err) { errorCount++; logger.error('Error deleting record:', err); } } setDeleting(false); setSelected([]); if (errorCount > 0) { setSnackbar({ open: true, message: `Se eliminaron ${deletedCount} registros. ${errorCount} errores.`, severity: 'error' }); } else { setSnackbar({ open: true, message: `Se eliminaron ${deletedCount} registros exitosamente.`, severity: 'success' }); } await fetchRecords(); }; // Close snackbar const handleCloseSnackbar = () => { setSnackbar({ ...snackbar, open: false }); }; // Format date for display const formatDate = (dateString: string) => { try { const date = new Date(dateString); if (isNaN(date.getTime())) { return t('ley21121.messages.invalidDate'); } // Format as dd/MM/yyyy const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear(); return `${day}/${month}/${year}`; } catch (error) { return t('ley21121.messages.invalidDate'); } }; if (loading) { return (
); } else if (error) { return (
{error}
); } return (

{t('ley21121.title')}

{records.length === 0 ? ( ) : ( records.map((record) => ( )) )}
0} onChange={handleSelectAll} /> {t('ley21121.table.headers.rut')} {t('ley21121.table.headers.company')} {t('ley21121.table.headers.caseRole')} {t('ley21121.table.headers.dates')} {t('ley21121.table.headers.duration')} {t('ley21121.table.headers.reason')} {t('ley21121.table.headers.actions')}
{t('ley21121.table.empty')}
handleSelectOne(record._id)} /> {record.rut} {record.razonSocial} {record.rolCausa} {t('ley21121.from')} {formatDate(record.fechaDesde)}
{t('ley21121.to')} {formatDate(record.fechaHasta)}
{record.duracion} {record.motivo}
{/* Dialog for creating/editing records */} {openDialog && (

{dialogMode === 'create' ? t('ley21121.dialog.createTitle') : t('ley21121.dialog.editTitle')}

{isValidRut === true && } {isValidRut === false && }
{isValidRut === false && (

{t('ley21121.form.rut.invalid')}

)}
{ const date = e.target.value ? new Date(e.target.value) : null; handleDateChange(date, 'fechaDesde'); }} required />
{ const date = e.target.value ? new Date(e.target.value) : null; handleDateChange(date, 'fechaHasta'); }} required />
)} {/* Notification */} {snackbar.open && (
{snackbar.message}
)}
); }; export default Ley21121Page;