import type { FC } from 'react'; import { useEffect, useState, useCallback } from 'react'; import { Clock } from 'lucide-react'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from 'recharts'; import { Card, Input, Badge, EmptyState, Skeleton, toast } from '../ui'; import { ExportButton } from '../ui/ExportButton'; import { exportToExcel } from '../../lib/exporter'; import { odooApi, type HoraAgendaRow } from '../../services/odoo'; import type { BadgeVariant } from '../ui/Badge'; import { useReportRange } from '../../lib/reportRange'; const citaStateLabels: Record = { pending: 'Pendiente', confirmed: 'Confirmada', arrived: 'Llegó', in_progress: 'En curso', done: 'Completada', cancelled: 'Cancelada', no_show: 'No show', }; const citaStateBadge = (state: string): BadgeVariant => { switch (state) { case 'done': return 'success'; case 'cancelled': case 'no_show': return 'danger'; case 'pending': return 'warning'; default: return 'info'; } }; const HorasAgendaReport: FC = () => { // Rango global de Reportes; los campos Inicio/Fin fijan uno propio const { start, end, setStart, setEnd } = useReportRange('horas-agenda'); const [horas, setHoras] = useState([]); const [loading, setLoading] = useState(true); const load = useCallback(async () => { try { setLoading(true); const res = await odooApi.getHorasAgenda(start, end); if (res.status === 'success') setHoras(res.horas); } catch (err) { toast.error('Error al cargar horas de agenda'); console.error(err); } finally { setLoading(false); } }, [start, end]); useEffect(() => { load(); }, [load]); const [exporting, setExporting] = useState(false); const exportar = async () => { try { setExporting(true); const rows: Record[] = []; horas.forEach((h) => { Object.entries(h.by_state).forEach(([state, count]) => rows.push({ hora: h.hora, estado: citaStateLabels[state] || state, citas: count })); }); await exportToExcel({ filename: `horas-agenda-${start}_${end}`, sheetName: 'Horas agenda', title: 'Horas agenda', subtitle: `Del ${start} al ${end} · ${total} citas`, columns: [ { header: 'Hora', key: 'hora' }, { header: 'Estado', key: 'estado' }, { header: 'Citas', key: 'citas', format: 'number' }, ], rows, totals: { hora: '', estado: 'Total citas', citas: total }, }); toast.success('Excel descargado'); } catch (err) { toast.error('Error al exportar'); console.error(err); } finally { setExporting(false); } }; const chartData = horas.map((h) => ({ name: h.hora, citas: h.total })); const total = horas.reduce((acc, h) => acc + h.total, 0); return (
setStart(e.target.value)} className="sm:max-w-[160px]" /> setEnd(e.target.value)} className="sm:max-w-[160px]" />

{total} citas en el periodo

Citas por hora del día

{loading ? ( ) : total === 0 ? ( } /> ) : ( )}
{!loading && total > 0 && (
{horas.filter((h) => h.total > 0).map((h) => ( ))}
Hora Citas Estados
{h.hora} {h.total}
{Object.entries(h.by_state).map(([state, count]) => ( {citaStateLabels[state] || state}: {count} ))}
)}
); }; export default HorasAgendaReport;