import React, { useState, useMemo } from 'react'; import { Card, Button, Badge, Input, Select, Modal } from '../../ui'; import { Table } from '../../ui'; import type { AnalyticsReport, ReportsTableProps, ExportFormat, ReportType, CustomAction } from './types'; const REPORT_TYPE_LABELS: Record = { sales: 'Ventas', production: 'Producción', inventory: 'Inventario', financial: 'Financiero', customer: 'Clientes', performance: 'Rendimiento', }; const STATUS_COLORS = { active: 'bg-green-100 text-green-800 border-green-200', inactive: 'bg-yellow-100 text-yellow-800 border-yellow-200', archived: 'bg-gray-100 text-gray-800 border-gray-200', }; const STATUS_LABELS = { active: 'Activo', inactive: 'Inactivo', archived: 'Archivado', }; export const ReportsTable: React.FC = ({ reports = [], loading = false, error, selectedReports = [], onSelectionChange, onReportClick, onEditReport, onDeleteReport, onScheduleReport, onShareReport, onExportReport, filters = [], onFiltersChange, sortable = true, pagination, bulkActions = false, customActions = [], tableConfig, }) => { const [searchTerm, setSearchTerm] = useState(''); const [typeFilter, setTypeFilter] = useState('all'); const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive' | 'archived'>('all'); const [sortField, setSortField] = useState('updated_at'); const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc'); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [reportToDelete, setReportToDelete] = useState(null); const [isScheduleModalOpen, setIsScheduleModalOpen] = useState(false); const [reportToSchedule, setReportToSchedule] = useState(null); const [isShareModalOpen, setIsShareModalOpen] = useState(false); const [reportToShare, setReportToShare] = useState(null); const filteredAndSortedReports = useMemo(() => { let filtered = reports.filter(report => { const matchesSearch = !searchTerm || report.name.toLowerCase().includes(searchTerm.toLowerCase()) || report.description?.toLowerCase().includes(searchTerm.toLowerCase()) || report.category.toLowerCase().includes(searchTerm.toLowerCase()); const matchesType = typeFilter === 'all' || report.type === typeFilter; const matchesStatus = statusFilter === 'all' || report.status === statusFilter; return matchesSearch && matchesType && matchesStatus; }); if (sortable && sortField) { filtered.sort((a, b) => { const aVal = a[sortField]; const bVal = b[sortField]; if (aVal === null || aVal === undefined) return 1; if (bVal === null || bVal === undefined) return -1; let comparison = 0; if (typeof aVal === 'string' && typeof bVal === 'string') { comparison = aVal.localeCompare(bVal); } else if (typeof aVal === 'number' && typeof bVal === 'number') { comparison = aVal - bVal; } else { comparison = String(aVal).localeCompare(String(bVal)); } return sortDirection === 'asc' ? comparison : -comparison; }); } return filtered; }, [reports, searchTerm, typeFilter, statusFilter, sortField, sortDirection, sortable]); const handleSort = (field: keyof AnalyticsReport) => { if (sortField === field) { setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); } else { setSortField(field); setSortDirection('asc'); } }; const handleSelectAll = (checked: boolean) => { if (onSelectionChange) { onSelectionChange(checked ? filteredAndSortedReports.map(r => r.id) : []); } }; const handleSelectReport = (reportId: string, checked: boolean) => { if (onSelectionChange) { if (checked) { onSelectionChange([...selectedReports, reportId]); } else { onSelectionChange(selectedReports.filter(id => id !== reportId)); } } }; const handleDeleteConfirm = () => { if (reportToDelete && onDeleteReport) { onDeleteReport(reportToDelete); } setIsDeleteModalOpen(false); setReportToDelete(null); }; const handleBulkDelete = () => { if (selectedReports.length > 0 && onDeleteReport) { selectedReports.forEach(id => onDeleteReport(id)); if (onSelectionChange) { onSelectionChange([]); } } }; const renderActionButton = (report: AnalyticsReport, action: string) => { switch (action) { case 'view': return ( ); case 'edit': return ( ); case 'schedule': return ( ); case 'share': return ( ); case 'export': return (
); case 'delete': return ( ); default: return null; } }; const tableColumns = [ { key: 'select', title: ( 0} onChange={(e) => handleSelectAll(e.target.checked)} className="rounded" /> ), render: (report: AnalyticsReport) => ( handleSelectReport(report.id, e.target.checked)} className="rounded" /> ), width: 50, visible: bulkActions, }, { key: 'name', title: 'Nombre', sortable: true, render: (report: AnalyticsReport) => (
{report.description && (

{report.description}

)}
), minWidth: 200, }, { key: 'type', title: 'Tipo', sortable: true, render: (report: AnalyticsReport) => ( {REPORT_TYPE_LABELS[report.type]} ), width: 120, }, { key: 'category', title: 'Categoría', sortable: true, width: 120, }, { key: 'status', title: 'Estado', sortable: true, render: (report: AnalyticsReport) => ( {STATUS_LABELS[report.status]} ), width: 100, }, { key: 'last_run', title: 'Última ejecución', sortable: true, render: (report: AnalyticsReport) => ( report.last_run ? new Date(report.last_run).toLocaleDateString('es-ES') : '-' ), width: 140, }, { key: 'next_run', title: 'Próxima ejecución', sortable: true, render: (report: AnalyticsReport) => ( report.next_run ? new Date(report.next_run).toLocaleDateString('es-ES') : '-' ), width: 140, }, { key: 'updated_at', title: 'Actualizado', sortable: true, render: (report: AnalyticsReport) => ( new Date(report.updated_at).toLocaleDateString('es-ES') ), width: 120, }, { key: 'actions', title: 'Acciones', render: (report: AnalyticsReport) => (
{renderActionButton(report, 'view')} {renderActionButton(report, 'edit')} {renderActionButton(report, 'schedule')} {renderActionButton(report, 'export')} {renderActionButton(report, 'delete')}
), width: 200, }, ].filter(col => col.visible !== false); if (error) { return (

Error al cargar los reportes

{error}

); } return ( <> {/* Filters and Actions */}
{/* Search */} {(tableConfig?.showSearch !== false) && (
setSearchTerm(e.target.value)} className="w-full" />
)} {/* Filters */}
{/* Bulk Actions */} {bulkActions && selectedReports.length > 0 && (
)}
{/* Table */}
{/* Pagination */} {pagination && (

Mostrando {Math.min(pagination.pageSize * (pagination.current - 1) + 1, pagination.total)} - {Math.min(pagination.pageSize * pagination.current, pagination.total)} de {pagination.total} reportes

Página {pagination.current} de {Math.ceil(pagination.total / pagination.pageSize)}
)} {/* Delete Confirmation Modal */} { setIsDeleteModalOpen(false); setReportToDelete(null); }} title="Confirmar eliminación" >

¿Estás seguro de que deseas eliminar este reporte? Esta acción no se puede deshacer.

{/* Schedule Modal */} { setIsScheduleModalOpen(false); setReportToSchedule(null); }} title="Programar reporte" >

Configurar programación para: {reportToSchedule?.name}

{/* Share Modal */} { setIsShareModalOpen(false); setReportToShare(null); }} title="Compartir reporte" >

Compartir: {reportToShare?.name}

); }; export default ReportsTable;