import type { FC } from 'react'; import { useEffect, useState } from 'react'; import { Cake, MessageCircle, Star, Download } from 'lucide-react'; import Layout from '../components/Layout'; import { Card, PageHeader, Button, toast } from '../components/ui'; import { odooApi } from '../services/odoo'; import type { Birthday } from '../services/odoo'; import { downloadCsv } from '../lib/utils'; type Period = 'today' | 'week' | 'month'; const PERIODS: { value: Period; label: string }[] = [ { value: 'today', label: 'Hoy' }, { value: 'week', label: 'Próximos 7 días' }, { value: 'month', label: 'Este mes' }, ]; const fmtMoney = (n: number) => (n || 0).toLocaleString('es-MX', { style: 'currency', currency: 'MXN', maximumFractionDigits: 0 }); const fmtDate = (s: string | null) => { if (!s) return '—'; const d = new Date(`${s}T12:00:00`); return d.toLocaleDateString('es-MX', { day: '2-digit', month: 'short' }); }; const Cumpleanos: FC = () => { const [period, setPeriod] = useState('month'); const [items, setItems] = useState([]); const [range, setRange] = useState<{ start: string; end: string } | null>(null); const [loading, setLoading] = useState(true); useEffect(() => { let active = true; setLoading(true); odooApi .getBirthdays(period) .then((res) => { if (!active) return; setItems(res.birthdays || []); setRange({ start: res.start, end: res.end }); }) .catch(() => { if (!active) return; setItems([]); }) .finally(() => active && setLoading(false)); return () => { active = false; }; }, [period]); const exportBirthdays = () => { const rows: (string | number | boolean | null | undefined)[][] = [ ['Nombre', 'Teléfono', 'Fecha nacimiento', 'Cumple el', 'Cumple años', 'Última visita', 'Total gastado', 'Adeudo', 'VIP'], ]; items.forEach((b) => rows.push([ b.name, b.phone, b.birth_date, b.occurs_on, b.turning_age, b.last_visit, b.total_spent, b.amount_due, b.is_vip ? 'Sí' : 'No', ]) ); downloadCsv(`cumpleaneros-skeen-${period}-${new Date().toISOString().split('T')[0]}.csv`, rows); toast.success(`CSV descargado (${items.length} cumpleañeros)`); }; return (
{PERIODS.map((p) => ( ))} {range && ( {range.start} → {range.end} · {items.length} pacientes )}
{loading ? (

Cargando...

) : items.length === 0 ? (

No hay cumpleañeros en este periodo.

) : (
{items.map((b) => ( ))}
Fecha Paciente Cumple Última visita Total gastado Adeudo
{fmtDate(b.occurs_on)}
{b.is_vip && } {b.name}
{b.phone}
{b.turning_age} años {fmtDate(b.last_visit)} {fmtMoney(b.total_spent)} 0 ? 'text-rose-600' : 'text-[#A87B5D]'}`}> {fmtMoney(b.amount_due)} {b.phone && ( WhatsApp )}
)}
); }; export default Cumpleanos;