diff --git a/frontend/views/plugins/SalasPlugin.tsx b/frontend/views/plugins/SalasPlugin.tsx index 86177f0..25a9e4b 100644 --- a/frontend/views/plugins/SalasPlugin.tsx +++ b/frontend/views/plugins/SalasPlugin.tsx @@ -337,6 +337,17 @@ const ReservaModal: React.FC<{ sala: Sala; onClose: () => void; onReserved: () = const ocupadasDoDia = diaSel ? ocupadas.filter(o => new Date(o.inicio).toDateString() === diaSel.toDateString()) : []; const rangeFim = diaSel ? (() => { const d = new Date(diaSel); d.setDate(d.getDate() + (f.modelo === 'mensal' ? 29 : 6)); return d; })() : null; + // ── Wizard (4 passos, formato slide) ── + const [step, setStep] = useState(0); + const [formaPagamento, setFormaPagamento] = useState('pix'); + const STEPS = ['Dados', 'Calendário', 'Resumo', 'Pagamento']; + const FORMAS: Record = { pix: 'PIX', dinheiro: 'Dinheiro', transferencia: 'Transferência', cartao: 'Cartão' }; + const modeloLabel = MODELOS.find(m => m.id === f.modelo)?.label || ''; + const total = (() => { + const m = MODELOS.find(x => x.id === f.modelo); const v = m ? Number(sala[m.valor]) : NaN; + return Number.isFinite(v) ? (f.modelo === 'hora' ? v * Math.max(1, qtd) : v) : 0; + })(); + // Modelo padrão = 1º disponível. useEffect(() => { if (modelosDisp.length && !modelosDisp.some(m => m.id === f.modelo)) setF(p => ({ ...p, modelo: modelosDisp[0].id })); /* eslint-disable-next-line */ }, []); // Recalcula início/fim conforme dia + modelo + horário. @@ -369,7 +380,8 @@ const ReservaModal: React.FC<{ sala: Sala; onClose: () => void; onReserved: () = const res = await apiFetch(`/api/salas/${sala.id}/reservas`, { method: 'POST', body: JSON.stringify({ - inicio: new Date(f.inicio).toISOString(), fim: new Date(f.fim).toISOString(), modelo: f.modelo, observacoes: f.observacoes || null, + inicio: new Date(f.inicio).toISOString(), fim: new Date(f.fim).toISOString(), modelo: f.modelo, + observacoes: [f.observacoes, `Forma de pagamento: ${FORMAS[formaPagamento] || formaPagamento}`].filter(Boolean).join(' · ') || null, clinicaId: comoUnidade && ws?.id ? ws.id : null, profissionalUsuarioId: comoUnidade && profissionalId ? profissionalId : null, }), @@ -385,152 +397,231 @@ const ReservaModal: React.FC<{ sala: Sala; onClose: () => void; onReserved: () = return (
-
-
-
-

RESERVAR {sala.nome}

-

{[sala.cidade, sala.estado].filter(Boolean).join(' · ')}

+
+ {/* Header + stepper */} +
+
+
+

Reservar {sala.nome}

+

{[sala.cidade, sala.estado].filter(Boolean).join(' · ')}

+
+ +
+
+ {STEPS.map((s, i) => ( + + ))}
-
-
- {ws?.id && ( -
- -
- {[{ v: false, l: 'PESSOAL' }, { v: true, l: ws.nome?.toUpperCase() || 'UNIDADE' }].map(o => ( - - ))} + + {/* Slides */} +
+
+ + {/* PASSO 1 — Dados */} +
+ {ws?.id && ( +
+ +
+ {[{ v: false, l: 'PESSOAL' }, { v: true, l: ws.nome?.toUpperCase() || 'UNIDADE' }].map(o => ( + + ))} +
+
+ )} + {comoUnidade && ( +
+ + +

O anti-conflito verifica a agenda do profissional selecionado

+
+ )} +
+ +