import { useState } from 'react' import { useQuery, useMutation } from '@tanstack/react-query' import { DocumentChartBarIcon, ArrowDownTrayIcon, CalendarIcon, ClockIcon, CheckCircleIcon, ExclamationCircleIcon, } from '@heroicons/react/24/outline' import clsx from 'clsx' import { format } from 'date-fns' import { es } from 'date-fns/locale' import { reportesApi, vehiculosApi } from '@/api' import Card, { CardHeader } from '@/components/ui/Card' import Button from '@/components/ui/Button' import Input from '@/components/ui/Input' import Select from '@/components/ui/Select' import Table from '@/components/ui/Table' import Badge from '@/components/ui/Badge' import { useToast } from '@/components/ui/Toast' import { Reporte } from '@/types' const tiposReporte = [ { id: 'actividad', nombre: 'Reporte de Actividad', descripcion: 'Resumen de actividad de vehiculos incluyendo viajes, distancia y tiempo de operacion', icono: DocumentChartBarIcon, }, { id: 'combustible', nombre: 'Reporte de Combustible', descripcion: 'Analisis de consumo de combustible, costos y rendimiento por vehiculo', icono: DocumentChartBarIcon, }, { id: 'alertas', nombre: 'Reporte de Alertas', descripcion: 'Historial de alertas generadas, tiempos de respuesta y resolucion', icono: DocumentChartBarIcon, }, { id: 'velocidad', nombre: 'Reporte de Velocidad', descripcion: 'Analisis de velocidades, excesos y patrones de conduccion', icono: DocumentChartBarIcon, }, { id: 'geocercas', nombre: 'Reporte de Geocercas', descripcion: 'Entradas, salidas y tiempo de permanencia en geocercas', icono: DocumentChartBarIcon, }, { id: 'mantenimiento', nombre: 'Reporte de Mantenimiento', descripcion: 'Historial de servicios, costos y programacion de mantenimiento', icono: DocumentChartBarIcon, }, ] export default function Reportes() { const toast = useToast() const [selectedTipo, setSelectedTipo] = useState(null) const [params, setParams] = useState({ vehiculoId: '', desde: format(new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), 'yyyy-MM-dd'), hasta: format(new Date(), 'yyyy-MM-dd'), formato: 'pdf' as 'pdf' | 'excel' | 'csv', }) const { data: vehiculos } = useQuery({ queryKey: ['vehiculos'], queryFn: () => vehiculosApi.list(), }) const { data: historial, isLoading: loadingHistorial } = useQuery({ queryKey: ['reportes-historial'], queryFn: () => reportesApi.listHistorial({ pageSize: 20 }), }) const generarMutation = useMutation({ mutationFn: () => reportesApi.generar({ tipo: selectedTipo!, vehiculoId: params.vehiculoId || undefined, desde: params.desde, hasta: params.hasta, formato: params.formato, }), onSuccess: (data) => { toast.success('Reporte generado exitosamente') // Download file if (data.url) { window.open(data.url, '_blank') } }, onError: () => { toast.error('Error al generar reporte') }, }) const handleGenerarReporte = () => { if (!selectedTipo) { toast.error('Selecciona un tipo de reporte') return } generarMutation.mutate() } const historialReportes = historial?.items || [] const columns = [ { key: 'tipo', header: 'Tipo', render: (r: Reporte) => (
{r.tipo.replace('_', ' ')}
), }, { key: 'periodo', header: 'Periodo', render: (r: Reporte) => ( {format(new Date(r.desde), 'd MMM', { locale: es })} -{' '} {format(new Date(r.hasta), 'd MMM yyyy', { locale: es })} ), }, { key: 'vehiculo', header: 'Vehiculo', render: (r: Reporte) => ( {r.vehiculo?.nombre || 'Todos los vehiculos'} ), }, { key: 'generado', header: 'Generado', render: (r: Reporte) => (

{format(new Date(r.createdAt), 'd MMM yyyy', { locale: es })}

{format(new Date(r.createdAt), 'HH:mm')}

), }, { key: 'estado', header: 'Estado', render: (r: Reporte) => { switch (r.estado) { case 'completado': return Completado case 'procesando': return Procesando case 'error': return Error default: return {r.estado} } }, }, { key: 'formato', header: 'Formato', render: (r: Reporte) => ( {r.formato} ), }, { key: 'acciones', header: '', sortable: false, render: (r: Reporte) => (
{r.estado === 'completado' && r.url && ( )}
), }, ] return (
{/* Header */}

Generador de Reportes

Crea reportes personalizados de tu flota

{/* Report types */}

Tipos de reporte

{tiposReporte.map((tipo) => ( setSelectedTipo(tipo.id)} >

{tipo.nombre}

{tipo.descripcion}

))}
{/* Report configuration */}
setParams({ ...params, desde: e.target.value })} className={clsx( 'flex-1 px-3 py-2 bg-slate-800/50 border border-slate-700/50 rounded-lg', 'text-white focus:outline-none focus:ring-2 focus:ring-accent-500' )} /> - setParams({ ...params, hasta: e.target.value })} className={clsx( 'flex-1 px-3 py-2 bg-slate-800/50 border border-slate-700/50 rounded-lg', 'text-white focus:outline-none focus:ring-2 focus:ring-accent-500' )} />