Permisos: marketing (export completo, agenda/citas, cumpleanos, visitas, WACRM), gerencia gestiona usuarios y roles, recepcion edita expedientes, cosmetologas ven agenda, fix del sidebar que no dejaba seleccionar Leads

This commit is contained in:
2026-09-18 03:23:44 +00:00
parent c38783eb31
commit cebf8d663d
13 changed files with 354 additions and 47 deletions

View File

@@ -133,6 +133,7 @@ const Pacientes: FC = () => {
const [entryDetail, setEntryDetail] = useState<
{ kind: 'cita'; item: Appointment } | { kind: 'venta'; item: Sale } | { kind: 'visita'; item: Visita } | null
>(null);
const [exporting, setExporting] = useState(false);
const [onlyIncomplete, setOnlyIncomplete] = useState(false);
const [onlyVip, setOnlyVip] = useState(false);
const [onlyRecent, setOnlyRecent] = useState(false);
@@ -415,13 +416,30 @@ const Pacientes: FC = () => {
].sort((a, b) => b.date.localeCompare(a.date))
: [];
// Exportación COMPLETA: pide al servidor todos los pacientes del filtro
// (no sólo la página visible). Hoy son ~7.2k filas.
const exportPatients = async () => {
try {
setExporting(true);
const res = await odooApi.exportPatients({
search: search || undefined,
incomplete: onlyIncomplete ? 1 : undefined,
vip: onlyVip ? 1 : undefined,
recent: onlyRecent ? 1 : (onlyStale ? 0 : undefined),
doctor_id: doctorFilter ? parseInt(doctorFilter, 10) : undefined,
});
if (res.status !== 'success') {
toast.error('Error al exportar');
return;
}
const todos = res.patients;
await exportToExcel({
filename: `pacientes-skeen-${new Date().toISOString().split('T')[0]}`,
sheetName: 'Pacientes',
title: 'Pacientes SKEEN',
subtitle: `${patients.length} pacientes de la vista actual`,
subtitle: res.truncado
? `${res.total} de ${res.total_disponible} pacientes (límite ${res.limite})`
: `${res.total} pacientes (exportación completa)`,
columns: [
{ header: 'Expediente', key: 'patient_id' },
{ header: 'Nombre', key: 'name' },
@@ -436,24 +454,26 @@ const Pacientes: FC = () => {
{ header: 'Fuente', key: 'source' },
{ header: 'VIP', key: 'vip' },
],
rows: patients.map((p) => ({
rows: todos.map((p) => ({
patient_id: p.patient_id, name: p.name, phone: p.phone, email: p.email,
birth_date: p.birth_date, gender: p.gender || '', last_visit: p.last_visit,
total_visits: p.total_visits, wallet_points: p.wallet_points,
total_spent: p.total_spent, source: p.source, vip: p.is_vip ? 'Sí' : 'No',
})),
});
toast.success(`Excel descargado (${patients.length} pacientes de la vista actual)`);
toast.success(`Excel descargado (${res.total} pacientes)`);
} catch (err) {
toast.error('Error al exportar');
console.error(err);
} finally {
setExporting(false);
}
};
return (
<Layout title="Pacientes" subtitle="Directorio de pacientes">
<PageHeader title="Pacientes" subtitle="Busca, crea y gestiona pacientes">
<Button variant="outline" onClick={exportPatients} disabled={patients.length === 0}>
<Button variant="outline" onClick={exportPatients} loading={exporting} disabled={patients.length === 0}>
<Download size={16} className="mr-2" />
Exportar CSV
</Button>