UX Dashboard: fila Hoy en la clinica, KPIs clickeables, deltas; Cumpleanos wa.me E.164; Mis ventas con grafica diaria

This commit is contained in:
2026-09-17 07:25:16 +00:00
parent 8ba3d2582b
commit afc208a7b7
6 changed files with 382 additions and 35 deletions

View File

@@ -5,6 +5,7 @@ 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';
@@ -24,6 +25,9 @@ const fmtDate = (s: string | null) => {
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<Period>('month');
const [items, setItems] = useState<Birthday[]>([]);
@@ -156,17 +160,24 @@ const Cumpleanos: FC = () => {
{fmtMoney(b.amount_due)}
</td>
<td className="px-4 py-3 text-right">
{b.phone && (
{waLink(b.whatsapp || b.phone, waBirthdayText(b.name)) ? (
<a
href={`https://wa.me/${b.phone.replace(/\D/g, '')}?text=${encodeURIComponent(
`¡Feliz cumpleaños ${b.name.split(' ')[0]}! 🎉 Te esperamos en SKEEN Derma Experts.`
)}`}
href={waLink(b.whatsapp || b.phone, waBirthdayText(b.name)) || '#'}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-theme-heading hover:text-theme-heading text-xs font-medium"
className="inline-flex items-center gap-1 text-theme-heading hover:text-theme-accent text-xs font-medium"
title={`Abrir WhatsApp: ${b.whatsapp || b.phone}`}
>
<MessageCircle size={14} /> WhatsApp
</a>
) : (
<span
className="inline-flex items-center gap-1 text-xs font-medium text-theme-muted opacity-50 cursor-not-allowed"
title="Paciente sin teléfono registrado"
aria-disabled="true"
>
<MessageCircle size={14} /> WhatsApp
</span>
)}
</td>
</tr>