ux(agenda): modal do evento sem rolagem; descricao em caixa rolavel

- compacta header/espacamentos/botoes (cabe sem scroll do modal)
- procedimento vira chip no header; caixa Descricao (observacoes/texto longo) com max-h + scroll proprio

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
VPS 4 Builder
2026-06-09 19:09:11 +02:00
parent 61bf22860c
commit 3003ffa2f4
+29 -19
View File
@@ -132,26 +132,36 @@ const DetailPage: React.FC<Props> = (p) => {
catch (e: any) { toast.error(e?.message || 'ERRO NA OPERAÇÃO.'); }
};
const nome = ag.pacienteNome || ag.pacientenome || '';
// Descrição = observações OU o texto longo (ex.: títulos dos eventos importados do Google).
const descricao = ag.observacoes || (nome.length > 40 ? nome : '');
return (
<div className="space-y-5">
<div className="flex items-start gap-3">
<div className="p-3 bg-blue-50 rounded-2xl shrink-0"><User size={22} className="text-blue-600" /></div>
<div className="space-y-3">
<div className="flex items-start gap-2.5">
<div className="p-2.5 bg-blue-50 rounded-xl shrink-0"><User size={20} className="text-blue-600" /></div>
<div className="min-w-0 flex-1">
<h3 className="text-lg font-black text-gray-900 leading-tight uppercase tracking-tight truncate">{ag.pacienteNome || ag.pacientenome}</h3>
<div className="flex items-center gap-2 flex-wrap mt-1.5">
<h3 className="text-base font-black text-gray-900 leading-tight uppercase tracking-tight truncate">{nome}</h3>
<div className="flex items-center gap-2 flex-wrap mt-1">
<span className={`text-[10px] font-black uppercase px-2 py-0.5 rounded-full ${STATUS_COLOR[status] || 'bg-gray-100 text-gray-600'}`}>{STATUS_LABEL[status] || status || '—'}</span>
{pacienteId ? <FaltasBadge pacienteId={pacienteId} /> : null}
{ag.procedimento ? (
<span className="inline-flex items-center gap-1 text-[10px] font-bold text-gray-600 uppercase bg-gray-50 px-2 py-0.5 rounded-full">
<Stethoscope size={11} className="text-blue-400" /> {ag.procedimento}
</span>
) : null}
</div>
</div>
</div>
{ag.procedimento && (
<div className="flex items-center gap-2 text-[11px] font-bold text-gray-600 uppercase bg-gray-50 px-3 py-2 rounded-xl w-fit">
<Stethoscope size={13} className="text-blue-400" /> {ag.procedimento}
{descricao ? (
<div>
<label className="text-[9px] font-black text-gray-400 uppercase tracking-widest">Descrição</label>
<div className="mt-1 text-[11px] text-gray-600 bg-gray-50 rounded-xl p-2.5 max-h-20 overflow-y-auto custom-scrollbar whitespace-pre-wrap break-words">{descricao}</div>
</div>
)}
) : null}
<div className="grid grid-cols-2 gap-4 py-3 border-y border-gray-100">
<div className="grid grid-cols-2 gap-4 py-2 border-y border-gray-100">
<div className="space-y-1.5">
<label className="text-[9px] font-black text-gray-400 uppercase tracking-widest">Data e hora</label>
<p className="flex items-center gap-1.5 text-xs font-bold text-gray-700"><CalendarRange size={14} className="text-blue-500" />{ag.start ? new Date(ag.start).toLocaleDateString('pt-BR', { weekday: 'short', day: 'numeric', month: 'short' }) : '—'}</p>
@@ -177,48 +187,48 @@ const DetailPage: React.FC<Props> = (p) => {
{/* Ações de status */}
<div className="grid grid-cols-2 gap-2">
<button onClick={() => run(() => HybridBackend.atualizarAgendamento(ag.id, { status: 'confirmado' as any }), 'CONFIRMADO!')}
className="flex items-center justify-center gap-1.5 py-3 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-emerald-200 hover:text-emerald-600 transition-all">
className="flex items-center justify-center gap-1.5 py-2.5 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-emerald-200 hover:text-emerald-600 transition-all">
<CheckCircle2 size={15} /> Confirmar
</button>
<button onClick={() => run(() => HybridBackend.marcarFalta(ag.id), 'FALTA REGISTRADA.')}
className="flex items-center justify-center gap-1.5 py-3 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-red-200 hover:text-red-600 transition-all">
className="flex items-center justify-center gap-1.5 py-2.5 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-red-200 hover:text-red-600 transition-all">
<AlertCircle size={15} /> Marcar falta
</button>
<button onClick={() => run(() => HybridBackend.remarcarAgendamento(ag.id), 'ENVIADO PARA "A REAGENDAR".')}
title="Sem data definida — vai para a lista 'A reagendar'"
className="flex items-center justify-center gap-1.5 py-3 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-amber-200 hover:text-amber-600 transition-all">
className="flex items-center justify-center gap-1.5 py-2.5 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-amber-200 hover:text-amber-600 transition-all">
<CalendarClock size={15} /> Reagendar depois
</button>
{inativo ? (
<button onClick={() => run(() => HybridBackend.restaurarAgendamento(ag.id), 'AGENDAMENTO RESTAURADO.')}
className="flex items-center justify-center gap-1.5 py-3 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-blue-200 hover:text-blue-600 transition-all">
className="flex items-center justify-center gap-1.5 py-2.5 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-blue-200 hover:text-blue-600 transition-all">
<RotateCcw size={15} /> Restaurar
</button>
) : (
<button onClick={() => { if (confirm('CANCELAR ESTE AGENDAMENTO?')) run(() => HybridBackend.excluirAgendamento(ag.id), 'AGENDAMENTO CANCELADO.'); }}
className="flex items-center justify-center gap-1.5 py-3 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-red-200 hover:text-red-600 transition-all">
className="flex items-center justify-center gap-1.5 py-2.5 rounded-xl text-[11px] font-black uppercase border-2 bg-white border-gray-100 text-gray-500 hover:border-red-200 hover:text-red-600 transition-all">
<Ban size={15} /> Cancelar
</button>
)}
</div>
{/* Navegação / ações principais */}
<div className="space-y-2 pt-1">
<div className="space-y-2">
<button onClick={() => push({ title: 'HISTÓRICO', render: () => <HistoryPage appointmentId={ag.id} /> })}
className="w-full flex items-center justify-between px-4 py-3 rounded-xl bg-gray-50 hover:bg-gray-100 transition-colors text-xs font-black uppercase text-gray-600">
className="w-full flex items-center justify-between px-4 py-2.5 rounded-xl bg-gray-50 hover:bg-gray-100 transition-colors text-xs font-black uppercase text-gray-600">
<span className="flex items-center gap-2"><History size={15} /> Histórico</span>
<span className="text-gray-300"></span>
</button>
<div className="flex gap-2">
{p.podeAtender && (
<button onClick={() => { p.onAtender?.(); }}
className="flex-1 py-3 bg-emerald-600 text-white rounded-xl text-[11px] font-black uppercase hover:bg-emerald-700 transition-all flex items-center justify-center gap-1.5">
className="flex-1 py-2.5 bg-emerald-600 text-white rounded-xl text-[11px] font-black uppercase hover:bg-emerald-700 transition-all flex items-center justify-center gap-1.5">
<ClipboardCheck size={15} /> Atender
</button>
)}
<button onClick={() => { p.onEditar(); }}
title="Mover para um novo horário agora"
className="flex-1 py-3 bg-blue-600 text-white rounded-xl text-[11px] font-black uppercase hover:bg-blue-700 transition-all flex items-center justify-center gap-1.5">
className="flex-1 py-2.5 bg-blue-600 text-white rounded-xl text-[11px] font-black uppercase hover:bg-blue-700 transition-all flex items-center justify-center gap-1.5">
<Pencil size={15} /> Mudar horário
</button>
</div>