From bb6e3b0d2563f1324266ef223c6a5364aab0b53a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gustavo?= <166467972+JoaoGustavo-dev@users.noreply.github.com> Date: Mon, 27 Oct 2025 23:11:33 -0300 Subject: [PATCH] fix-reports --- susconecta/app/paciente/page.tsx | 124 ++++++++++++++---- .../app/resultados/ResultadosClient.tsx | 34 ++++- 2 files changed, 130 insertions(+), 28 deletions(-) diff --git a/susconecta/app/paciente/page.tsx b/susconecta/app/paciente/page.tsx index bee91e7..df43035 100644 --- a/susconecta/app/paciente/page.tsx +++ b/susconecta/app/paciente/page.tsx @@ -269,13 +269,22 @@ export default function PacientePage() { // Consultas fictícias const [currentDate, setCurrentDate] = useState(new Date()) + + // helper: produce a local YYYY-MM-DD key (uses local timezone, not toISOString UTC) + const localDateKey = (d: Date) => { + const y = d.getFullYear() + const m = String(d.getMonth() + 1).padStart(2, '0') + const day = String(d.getDate()).padStart(2, '0') + return `${y}-${m}-${day}` + } + const consultasFicticias = [ { id: 1, medico: "Dr. Carlos Andrade", especialidade: "Cardiologia", local: "Clínica Coração Feliz", - data: new Date().toISOString().split('T')[0], + data: localDateKey(new Date()), hora: "09:00", status: "Confirmada" }, @@ -284,7 +293,7 @@ export default function PacientePage() { medico: "Dra. Fernanda Lima", especialidade: "Dermatologia", local: "Clínica Pele Viva", - data: new Date().toISOString().split('T')[0], + data: localDateKey(new Date()), hora: "14:30", status: "Pendente" }, @@ -293,7 +302,7 @@ export default function PacientePage() { medico: "Dr. João Silva", especialidade: "Ortopedia", local: "Hospital Ortopédico", - data: (() => { let d = new Date(); d.setDate(d.getDate()+1); return d.toISOString().split('T')[0] })(), + data: (() => { let d = new Date(); d.setDate(d.getDate()+1); return localDateKey(d) })(), hora: "11:00", status: "Cancelada" }, @@ -312,7 +321,7 @@ export default function PacientePage() { setCurrentDate(new Date()); } - const todayStr = currentDate.toISOString().split('T')[0]; + const todayStr = localDateKey(currentDate) const consultasDoDia = consultasFicticias.filter(c => c.data === todayStr); function Consultas() { @@ -415,7 +424,7 @@ export default function PacientePage() { medico: doc?.full_name || a.doctor_id || '---', especialidade: doc?.specialty || '', local: a.location || a.place || '', - data: sched ? sched.toISOString().split('T')[0] : '', + data: sched ? localDateKey(sched) : '', hora: sched ? sched.toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' }) : '', status: a.status ? String(a.status) : 'Pendente', } @@ -442,6 +451,8 @@ export default function PacientePage() { qs.set('tipo', tipoConsulta) // 'teleconsulta' | 'presencial' if (especialidade) qs.set('especialidade', especialidade) if (localizacao) qs.set('local', localizacao) + // indicate navigation origin so destination can alter UX (e.g., show modal instead of redirect) + qs.set('origin', 'paciente') return `/resultados?${qs.toString()}` } @@ -532,7 +543,7 @@ export default function PacientePage() { setMostrarAgendadas(open)}> - + Consultas agendadas Gerencie suas consultas confirmadas, pendentes ou canceladas. @@ -544,7 +555,7 @@ export default function PacientePage() { type="button" variant="outline" size="icon" - onClick={() => navigateDate('prev')} + onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('prev') }} aria-label="Dia anterior" className={`group shadow-sm ${hoverPrimaryIconClass}`} > @@ -555,7 +566,7 @@ export default function PacientePage() { type="button" variant="outline" size="icon" - onClick={() => navigateDate('next')} + onClick={(e: any) => { e.stopPropagation(); e.preventDefault(); navigateDate('next') }} aria-label="Próximo dia" className={`group shadow-sm ${hoverPrimaryIconClass}`} > @@ -579,7 +590,7 @@ export default function PacientePage() { -
+
{loadingAppointments && mostrarAgendadas ? (
Carregando consultas...
) : appointmentsError ? ( @@ -663,7 +674,7 @@ export default function PacientePage() {
- @@ -680,6 +691,7 @@ export default function PacientePage() { const [reports, setReports] = useState(null) const [loadingReports, setLoadingReports] = useState(false) const [reportsError, setReportsError] = useState(null) + const [reportDoctorName, setReportDoctorName] = useState(null) useEffect(() => { let mounted = true @@ -701,6 +713,30 @@ export default function PacientePage() { return () => { mounted = false } }, [patientId]) + // When a report is selected, try to fetch doctor name if we have an id + useEffect(() => { + let mounted = true + if (!selectedReport) { + setReportDoctorName(null) + return + } + const maybeDoctorId = selectedReport.doctor_id || selectedReport.created_by || null + if (!maybeDoctorId) { + setReportDoctorName(null) + return + } + (async () => { + try { + const docs = await buscarMedicosPorIds([String(maybeDoctorId)]).catch(() => []) + if (!mounted) return + if (docs && docs.length) setReportDoctorName(docs[0].full_name || docs[0].name || null) + } catch (e) { + // ignore + } + })() + return () => { mounted = false } + }, [selectedReport]) + return (

Laudos

@@ -730,22 +766,58 @@ export default function PacientePage() { !open && setSelectedReport(null)}> - - Laudo Médico - - {selectedReport && ( - <> -
{selectedReport.title || selectedReport.name || 'Laudo'}
-
Data: {new Date(selectedReport.report_date || selectedReport.created_at || Date.now()).toLocaleDateString('pt-BR')}
-
{selectedReport.content || selectedReport.body || JSON.stringify(selectedReport, null, 2)}
- - )} -
-
- - - -
+ + Laudo Médico + + {selectedReport && ( + <> +
+
{selectedReport.title || selectedReport.name || 'Laudo'}
+
Data: {new Date(selectedReport.report_date || selectedReport.created_at || Date.now()).toLocaleDateString('pt-BR')}
+ {reportDoctorName &&
Profissional: {reportDoctorName}
} +
+ + {/* Prefer HTML content when available */} + {selectedReport.content_html ? ( +
+ ) : ( +
+ {selectedReport.exam && ( +
+
Exame
+
{selectedReport.exam}
+
+ )} + {selectedReport.diagnosis && ( +
+
Diagnóstico
+
{selectedReport.diagnosis}
+
+ )} + {selectedReport.conclusion && ( +
+
Conclusão
+
{selectedReport.conclusion}
+
+ )} + {/* fallback to generic content/body */} + {!(selectedReport.content_html || selectedReport.diagnosis || selectedReport.conclusion || selectedReport.content || selectedReport.body) && ( +
{JSON.stringify(selectedReport, null, 2)}
+ )} +
+ )} + {/* Optional: doctor signature or footer */} + {selectedReport.doctor_signature && ( +
Assinatura: assinatura
+ )} + + )} + + + + + +
) diff --git a/susconecta/app/resultados/ResultadosClient.tsx b/susconecta/app/resultados/ResultadosClient.tsx index 72f4064..e9ef340 100644 --- a/susconecta/app/resultados/ResultadosClient.tsx +++ b/susconecta/app/resultados/ResultadosClient.tsx @@ -100,6 +100,9 @@ export default function ResultadosClient() { setToast({ type, msg }) setTimeout(() => setToast(null), 3000) } + // booking success modal (used when origin=paciente) + const [bookingSuccessOpen, setBookingSuccessOpen] = useState(false) + const [bookedWhenLabel, setBookedWhenLabel] = useState(null) // 1) Obter patientId a partir do usuário autenticado (email -> patients) useEffect(() => { @@ -273,8 +276,20 @@ export default function ResultadosClient() { }) setConfirmOpen(false) setPendingAppointment(null) - // Navigate to agenda after a short delay so user sees the toast - setTimeout(() => router.push('/agenda'), 500) + // If the user came from the paciente area, keep them here and show a success modal + const origin = params?.get('origin') + if (origin === 'paciente') { + try { + const when = new Date(iso).toLocaleString('pt-BR', { dateStyle: 'long', timeStyle: 'short' }) + setBookedWhenLabel(when) + } catch { + setBookedWhenLabel(iso) + } + setBookingSuccessOpen(true) + } else { + // Navigate to agenda after a short delay so user sees the toast + setTimeout(() => router.push('/agenda'), 500) + } } catch (e: any) { showToast('error', e?.message || 'Falha ao agendar') } finally { @@ -534,6 +549,21 @@ export default function ResultadosClient() {
+ {/* Booking success modal shown when origin=paciente */} + setBookingSuccessOpen(open)}> + + + Consulta agendada + +
+

Sua consulta foi agendada com sucesso{bookedWhenLabel ? ` para ${bookedWhenLabel}` : ''}.

+
+
+ +
+
+
+ {/* Hero de filtros (mantido) */}