Staff: campo tipo Doctor/Cosmetologa, filtro por tipo en agenda y selector editable en modulo Medicos

This commit is contained in:
2026-08-31 05:19:13 +00:00
parent 339ba235b1
commit fea4918494
6 changed files with 80 additions and 6 deletions

View File

@@ -2,7 +2,7 @@ import type { FC } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { Mail, Phone, Stethoscope, Briefcase, Save, Percent, Eye, CalendarDays, FileText, ShoppingCart, Users, ClipboardList, CreditCard, DollarSign } from 'lucide-react';
import Layout from '../components/Layout';
import { Card, Badge, EmptyState, PageHeader, Skeleton, MobileCard, Input, Button, Modal, toast } from '../components/ui';
import { Card, Badge, EmptyState, PageHeader, Skeleton, MobileCard, Input, Button, Modal, Select, toast } from '../components/ui';
import { odooApi, type Doctor, type DoctorHistory } from '../services/odoo';
const medicalTerms = ['doctor', 'dra', 'médico', 'medico', 'especialista', 'dermatólogo', 'dermatologo', 'skin', 'clínico', 'clinico'];
@@ -152,6 +152,22 @@ const Medicos: FC = () => {
}
};
// Tipo de staff (Doctor / Cosmetóloga): guardado in-place al cambiar el selector
const [savingTypeId, setSavingTypeId] = useState<number | null>(null);
const saveStaffType = async (d: Doctor, staff_type: 'doctor' | 'cosmetologa') => {
if ((d.staff_type ?? 'doctor') === staff_type) return;
setSavingTypeId(d.id);
try {
await odooApi.updateDoctor(d.id, { staff_type });
setEmployees((prev) => prev.map((e) => (e.id === d.id ? { ...e, staff_type } : e)));
toast.success(`${d.name}: tipo actualizado a ${staff_type === 'cosmetologa' ? 'Cosmetóloga' : 'Doctor'}`);
} catch {
toast.error('No se pudo guardar el tipo');
} finally {
setSavingTypeId(null);
}
};
return (
<Layout title="Médicos" subtitle="Equipo médico">
<PageHeader title="Médicos" subtitle="Especialistas de la clínica" />
@@ -172,6 +188,7 @@ const Medicos: FC = () => {
<tr>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Nombre</th>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Puesto</th>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">Tipo</th>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase hidden md:table-cell">Teléfono</th>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase hidden lg:table-cell">Email</th>
<th className="text-left p-3 text-xs font-medium text-theme-muted uppercase">% Comisión</th>
@@ -188,6 +205,18 @@ const Medicos: FC = () => {
{d.job_title || 'Sin puesto'}
</Badge>
</td>
<td className="p-3" onClick={(e) => e.stopPropagation()}>
<Select
options={[
{ value: 'doctor', label: 'Doctor' },
{ value: 'cosmetologa', label: 'Cosmetóloga' },
]}
value={d.staff_type ?? 'doctor'}
onChange={(e) => saveStaffType(d, e.target.value as 'doctor' | 'cosmetologa')}
disabled={savingTypeId === d.id}
className="max-w-[150px]"
/>
</td>
<td className="p-3 text-sm text-theme-muted hidden md:table-cell">
<a href={`tel:${d.work_phone}`} className="hover:text-theme-heading">
<Phone size={14} className="inline mr-1 text-theme-muted" />