fase 2.3: portal publico de reservas en linea (5 endpoints anonimos con rate limit y token HMAC, wizard movil, gestion/cancelacion por enlace, distintivo en agenda, editor y enlace publico en Configuracion); apagado por defecto

This commit is contained in:
2026-10-11 08:28:33 +00:00
parent 358b85afcd
commit add9b28188
14 changed files with 1859 additions and 4 deletions

View File

@@ -13,13 +13,15 @@ import ImpactoModal from '../components/ImpactoModal';
import SucursalesPanel from '../components/SucursalesPanel';
import CategoriasPanel from '../components/CategoriasPanel';
import TerminologiaPanel from '../components/TerminologiaPanel';
import ReservasOnlinePanel from '../components/ReservasOnlinePanel';
import { Card, Button, Input, PageHeader, toast } from '../components/ui';
import { odooApi, type Doctor, type ClinicSettings, type ImpuestosSettings, BRAND_DEFAULT, CLINIC_SETTINGS_DEFAULT, IMPUESTOS_DEFAULT } from '../services/odoo';
import { odooApi, type Doctor, type ClinicSettings, type ImpuestosSettings, BRAND_DEFAULT, CLINIC_SETTINGS_DEFAULT, IMPUESTOS_DEFAULT, RESERVAS_ONLINE_DEFAULT } from '../services/odoo';
import { useAuth } from '../lib/auth';
import { publicarClinicSettings } from '../lib/clinic-settings';
const TABS = [
{ key: 'clinica', label: 'Clínica' },
{ key: 'reservas', label: 'Reservas en línea' },
{ key: 'sucursales', label: 'Sucursales' },
{ key: 'categorias', label: 'Categorías' },
{ key: 'terminologia', label: 'Terminología' },
@@ -32,7 +34,7 @@ const TABS = [
] as const;
// Secciones que ve gerencia (admin del sistema ve todas).
const TABS_GERENCIA = ['sucursales', 'categorias', 'terminologia', 'usuarios', 'roles', 'tickets'];
const TABS_GERENCIA = ['reservas', 'sucursales', 'categorias', 'terminologia', 'usuarios', 'roles', 'tickets'];
const SUBCATALOGOS = [
{ key: 'diagnosticos', label: 'Diagnósticos' },
@@ -106,6 +108,7 @@ const Configuracion: FC = () => {
...CLINIC_SETTINGS_DEFAULT,
...next,
impuestos: { ...IMPUESTOS_DEFAULT, ...(next.impuestos || {}) },
reservas_online: { ...RESERVAS_ONLINE_DEFAULT, ...(next.reservas_online || {}) },
});
})
.catch(() => {
@@ -372,6 +375,12 @@ const Configuracion: FC = () => {
<TerminologiaPanel />
</Card.Body>
</Card>
) : tab === 'reservas' ? (
<Card>
<Card.Body>
<ReservasOnlinePanel settings={settings} onSaved={setSettings} />
</Card.Body>
</Card>
) : (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 sm:gap-6">
<Card>