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 { waLink } from '../lib/whatsapp'; import { exportToExcel } from '../lib/exporter'; 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 waBirthdayText = (name: string) => `¡Feliz cumpleaños ${(name || '').split(' ')[0]}! Le saluda el equipo de SKEEN Derma Experts.`; 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 = async () => { try { await exportToExcel({ filename: `cumpleaneros-skeen-${period}-${new Date().toISOString().split('T')[0]}`, sheetName: 'Cumpleañeros', title: 'Cumpleañeros SKEEN', subtitle: `Periodo: ${period} · ${items.length} pacientes`, columns: [ { header: 'Nombre', key: 'name' }, { header: 'Teléfono', key: 'phone' }, { header: 'Fecha nacimiento', key: 'birth_date', format: 'date' }, { header: 'Cumple el', key: 'occurs_on', format: 'date' }, { header: 'Cumple años', key: 'turning_age', format: 'number' }, { header: 'Última visita', key: 'last_visit', format: 'date' }, { header: 'Total gastado', key: 'total_spent', format: 'currency' }, { header: 'Adeudo', key: 'amount_due', format: 'currency' }, { header: 'VIP', key: 'vip' }, ], rows: items.map((b) => ({ name: b.name, phone: b.phone, birth_date: b.birth_date, occurs_on: b.occurs_on, turning_age: b.turning_age, last_visit: b.last_visit, total_spent: b.total_spent, amount_due: b.amount_due, vip: b.is_vip ? 'Sí' : 'No', })), }); toast.success(`Excel descargado (${items.length} cumpleañeros)`); } catch (err) { toast.error('Error al exportar'); console.error(err); } }; 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-theme-muted'}`}> {fmtMoney(b.amount_due)} {waLink(b.whatsapp || b.phone, waBirthdayText(b.name)) ? ( WhatsApp ) : ( WhatsApp )}
)}
); }; export default Cumpleanos;