From 77079e173cbd18d86419dfd814719b8d243132b4 Mon Sep 17 00:00:00 2001 From: EdilbertoC Date: Tue, 28 Apr 2026 14:00:14 -0300 Subject: [PATCH] refactor(principal): remove legenda global do AppShell --- src/App.jsx | 2 +- src/components/AppShell.jsx | 8 +- src/mappers/reportMapper.js | 102 +- src/pages/AgendaPage.jsx | 7 +- src/pages/PatientsPage.jsx | 44 +- src/pages/ReportsPage.jsx | 1346 +++++++++++++------------- src/repositories/reportRepository.js | 176 +--- 7 files changed, 770 insertions(+), 915 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 2a9c4ed..348b3d1 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -145,7 +145,7 @@ function resolveRoute(pathname, navigate) { if (pathname === '/laudos') { return { element: , - title: 'Laudos', + title: 'Relatorios medicos', withShell: true, } } diff --git a/src/components/AppShell.jsx b/src/components/AppShell.jsx index 8726804..f44c0c7 100644 --- a/src/components/AppShell.jsx +++ b/src/components/AppShell.jsx @@ -2,14 +2,13 @@ import { useEffect, useMemo, useState } from 'react' import { profileRepository } from '../repositories/profileRepository.js' import { BrandLogo } from './Brand.jsx' -import { FeatureLegend } from './FeatureState.jsx' const navItems = [ { href: '/inicio', label: 'Painel', icon: 'pulse', activePaths: ['/inicio', '/home', '/dashboard'] }, { href: '/agenda', label: 'Agenda', icon: 'calendar' }, { href: '/pacientes', label: 'Pacientes', icon: 'users', exact: true }, { href: '/prontuario', label: 'Prontuario', icon: 'file' }, - { href: '/laudos', label: 'Laudos', icon: 'clipboard' }, + { href: '/laudos', label: 'Relatorios medicos', icon: 'clipboard' }, { href: '/camunicacao', label: 'Comunicacao', @@ -26,7 +25,7 @@ const titles = { '/dashboard': 'Painel', '/agenda': 'Agenda', '/consultas': 'Consultas', - '/laudos': 'Laudos', + '/laudos': 'Relatorios medicos', '/pacientes': 'Pacientes', '/prontuario': 'Prontuario', '/camunicacao': 'Comunicacao', @@ -198,9 +197,6 @@ export function AppShell({ children, currentPath, navigate, routeTitle }) {
-
- -
{pageTitle}
diff --git a/src/mappers/reportMapper.js b/src/mappers/reportMapper.js index 1f9f01f..c23fb99 100644 --- a/src/mappers/reportMapper.js +++ b/src/mappers/reportMapper.js @@ -2,72 +2,60 @@ export const reportMapper = { toUi(apiData) { if (!apiData) return null - const patient = apiData.patient || apiData.paciente || apiData.patients || {} - const doctor = apiData.doctor || apiData.medico || apiData.professional || apiData.doctors || {} - const createdAt = apiData.created_at || apiData.createdAt || apiData.data_criacao || apiData.date - const status = normalizeStatus(apiData.status || apiData.situacao) - return { - id: String(apiData.id || apiData.report_id || apiData.laudo_id), - patientId: apiData.patientId || apiData.patient_id || apiData.paciente_id || patient.id || '', - patient: apiData.patientName || apiData.patient_name || patient.full_name || patient.nome || patient.name || 'Paciente', - date: createdAt ? new Date(createdAt).toLocaleDateString('pt-BR') : 'Sem data', - doctor: apiData.doctorName || apiData.doctor_name || apiData.medico_nome || doctor.name || doctor.nome || 'Medico(a)', - author: apiData.author || apiData.autor || doctor.name || doctor.nome || 'Medico(a)', - type: apiData.type || apiData.report_type || apiData.tipo || apiData.tipo_laudo || 'Laudo medico', - status, - content: apiData.content || apiData.conteudo || apiData.text || '', - cid: apiData.cid || '', - tags: apiData.tags || [], - verified: apiData.verified ?? apiData.verificado ?? status !== 'rascunho', - showDate: apiData.showDate ?? apiData.exibir_data ?? true, - signDigital: apiData.signDigital ?? apiData.assinatura_digital ?? true, - versions: normalizeVersions(apiData.versions || apiData.versoes), + id: String(apiData.id || ''), + orderNumber: apiData.order_number || '', + patientId: apiData.patient_id || '', + status: normalizeStatus(apiData.status), + exam: apiData.exam || '', + requestedBy: apiData.requested_by || '', + cidCode: apiData.cid_code || '', + diagnosis: apiData.diagnosis || '', + conclusion: apiData.conclusion || '', + contentHtml: apiData.content_html || '', + contentJson: apiData.content_json ?? null, + hideDate: Boolean(apiData.hide_date), + hideSignature: Boolean(apiData.hide_signature), + dueAt: apiData.due_at || '', + createdBy: apiData.created_by || '', + updatedBy: apiData.updated_by || '', + createdAt: apiData.created_at || '', + updatedAt: apiData.updated_at || '', } }, - toApi(uiData, dialect = 'api') { - if (dialect === 'supabase') { - return { - patient_id: uiData.patientId, - report_type: uiData.type, - content: uiData.content, - status: uiData.status, - cid: uiData.cid || null, - } - } - - return { + toApi(uiData) { + return cleanPayload({ patient_id: uiData.patientId, - paciente_id: uiData.patientId, - report_type: uiData.type, - tipo: uiData.type, - content: uiData.content, - conteudo: uiData.content, - status: uiData.status, - cid: uiData.cid || null, - } + status: normalizeApiStatus(uiData.status), + exam: emptyToUndefined(uiData.exam), + requested_by: emptyToUndefined(uiData.requestedBy), + cid_code: emptyToUndefined(uiData.cidCode), + diagnosis: emptyToUndefined(uiData.diagnosis), + conclusion: emptyToUndefined(uiData.conclusion), + content_html: emptyToUndefined(uiData.contentHtml), + content_json: uiData.contentJson === undefined ? undefined : uiData.contentJson, + hide_date: Boolean(uiData.hideDate), + hide_signature: Boolean(uiData.hideSignature), + due_at: emptyToUndefined(uiData.dueAt), + }) }, } function normalizeStatus(status) { - if (!status) return 'rascunho' - - const normalized = String(status).toLowerCase() - if (['finalizado', 'liberado', 'assinado'].includes(normalized)) return 'finalizado' - if (['enviado', 'entregue'].includes(normalized)) return 'enviado' - return 'rascunho' + return status === 'draft' ? 'draft' : 'draft' } -function normalizeVersions(versions) { - if (Array.isArray(versions) && versions.length) return versions - - return [ - { - version: 1, - action: 'Criado', - user: 'Sistema', - summary: 'Registro importado da API', - }, - ] +function normalizeApiStatus(status) { + return status === 'draft' ? 'draft' : 'draft' +} + +function emptyToUndefined(value) { + return value === '' || value === null ? undefined : value +} + +function cleanPayload(payload) { + return Object.fromEntries( + Object.entries(payload).filter(([, value]) => value !== undefined), + ) } diff --git a/src/pages/AgendaPage.jsx b/src/pages/AgendaPage.jsx index 95e28c8..635740e 100644 --- a/src/pages/AgendaPage.jsx +++ b/src/pages/AgendaPage.jsx @@ -11,8 +11,6 @@ import { } from 'date-fns' import { ptBR } from 'date-fns/locale' -import { FeatureBadge } from '../components/FeatureState.jsx' -import { featurePanelClass } from '../components/featureStateStyles.js' import { AgendaDailyView } from '../components/calendar/AgendaDailyView.jsx' import { AgendaWeeklyView } from '../components/calendar/AgendaWeeklyView.jsx' import { AgendaMonthlyView } from '../components/calendar/AgendaMonthlyView.jsx' @@ -131,7 +129,7 @@ export function AgendaPage({ navigate }) { {error ? ( -
+

Nao foi possivel liberar a agenda

{error}

@@ -142,14 +140,13 @@ export function AgendaPage({ navigate }) {
) : (
-
+

{format(baseDate, "EEEE, dd 'de' MMMM", { locale: ptBR })}

-

Visualização: {activeView.toLowerCase()} | {visibleAppointments.length} registros visíveis diff --git a/src/pages/PatientsPage.jsx b/src/pages/PatientsPage.jsx index 33a383e..b28ab17 100644 --- a/src/pages/PatientsPage.jsx +++ b/src/pages/PatientsPage.jsx @@ -301,43 +301,43 @@ async function deletePatient(patientId) { ) : null}

- +
- - - - - - - + + + + + + + {paginatedPatients.length ? ( paginatedPatients.map((patient) => ( - - - - - - - + + + + + - + - - - - + + + - - ) } -function ReportEditorModal({ editor, onClose, onSave, preview, setEditor, setPreview }) { - const isValid = editor.patient.trim() && editor.content.trim() +function ReportEditorModal({ editor, onChange, onClose, onSave, patientOptions, professionalOptions, saving }) { + const isValid = Boolean(editor.patientId) + + function updateField(field, value) { + onChange((current) => ({ ...current, [field]: value })) + } return (
@@ -436,102 +479,132 @@ function ReportEditorModal({ editor, onClose, onSave, preview, setEditor, setPre onClick={(event) => event.stopPropagation()} >
-

{editor.id ? 'Editar Laudo' : 'Novo Laudo'}

-
- - -
+

+ {editor.id ? 'Editar relatorio medico' : 'Novo relatorio medico'} +

+
- {preview ? ( -
-
-

{editor.type}

- {editor.showDate ?

{new Date().toLocaleDateString('pt-BR')}

: null} -
-

Paciente: {editor.patient || '-'}

-

Médico(a): {editor.doctor}

-

- {editor.content || 'Nenhum conteúdo inserido.'} -

- {editor.signDigital ? ( -
-

{editor.doctor}

-

Assinatura Digital - MediConnect

-
- ) : null} -
- ) : ( -
-
- - - - - setEditorValue(setEditor, 'patient', event.target.value)} - placeholder="Digite o nome do paciente..." - value={editor.patient} - /> - -
- - updateField('patientId', event.target.value)} value={editor.patientId}> + + {patientOptions.map((patient) => ( + ))} - -
NomeTelefoneCidadeEstadoUltimo atendimentoProximo atendimentoAcoesNomeTelefoneCidadeEstadoUltimo atendimentoProximo atendimentoAcoes
+ {patient.phone}{patient.city}{patient.state}{patient.lastVisit || 'Ainda nao houve atendimento'}{patient.nextVisit || 'Nenhum atendimento agendado'} + {patient.phone}{patient.city}{patient.state}{patient.lastVisit || 'Ainda nao houve atendimento'}{patient.nextVisit || 'Nenhum atendimento agendado'} - +

Relatorios medicos

+

Consulta, criacao e edicao de relatorios medicos.

+
{stats.map((stat) => ( -
-

{stat.label}

-

{stat.value}

+
+
+

{stat.label}

+

{stat.value}

+
))}
-
-
-
- - setSearch(event.target.value)} - placeholder="Buscar por paciente ou tipo..." - value={search} - /> -
- +
+
+ + + + + + + + + + + + + + +
-
- + {error ? ( +
+ {error} +
+ ) : null} + +
+
- - - - - - - + + + + + + + - {filteredReports.length ? ( - filteredReports.map((report) => ( + {loading ? ( + + + + ) : paginatedReports.length ? ( + paginatedReports.map((report) => ( { - setConfirmDelete({ report }) - setDeleteConfirmText('') - setOpenMenuId(null) - }} - onDelivery={() => { - setDeliveryReport(report) - setOpenMenuId(null) - }} onEdit={() => openEdit(report)} - onHistory={() => { - setHistoryReport(report) - setOpenMenuId(null) - }} - onPrint={() => { - window.print() - setOpenMenuId(null) - }} - onRelease={() => { - setConfirmRelease(report) - setOpenMenuId(null) - }} - onSend={() => sendReport(report.id)} - open={openMenuId === report.id} + onView={() => setViewerReport(report)} report={report} - setOpenMenuId={setOpenMenuId} /> )) ) : ( )}
TipoPacienteMédicoDataStatusVersõesAçõesNumeroExamePacienteSolicitanteCriado emStatusAcoes
+ Carregando relatorios medicos... +
- Nenhum laudo encontrado. + Nenhum relatorio encontrado com os filtros atuais.
+ +
+

+ Mostrando {enrichedReports.length ? startIndex + 1 : 0}-{Math.min(startIndex + ITEMS_PER_PAGE, enrichedReports.length)} de{' '} + {enrichedReports.length} relatorios +

+
+ setPage(currentPage - 1)}> + + + {Array.from({ length: totalPages }, (_, index) => index + 1).map((pageNumber) => ( + + ))} + setPage(currentPage + 1)}> + + +
+
- {templatesOpen ? setTemplatesOpen(false)} onUseTemplate={openNew} /> : null} - {historyReport ? setHistoryReport(null)} report={historyReport} /> : null} - {deliveryReport ? setDeliveryReport(null)} report={deliveryReport} /> : null} - {confirmRelease ? ( - setConfirmRelease(null)} - onConfirm={() => releaseReport(confirmRelease.id)} - report={confirmRelease} - /> - ) : null} - {confirmDelete ? ( - setConfirmDelete(null)} - onConfirm={() => deleteReport(confirmDelete.report.id)} - report={confirmDelete.report} - setConfirmText={setDeleteConfirmText} - /> - ) : null} {editorOpen ? ( setEditorOpen(false)} - onSave={saveReport} - preview={preview} - setEditor={setEditor} - setPreview={setPreview} + onSave={handleSave} + patientOptions={patientOptions} + professionalOptions={professionalOptions} + saving={saving} /> ) : null} + + {viewerReport ? ( + setViewerReport(null)} report={viewerReport} /> + ) : null}
) } -function ReportRow({ - onDelete, - onDelivery, - onEdit, - onHistory, - onPrint, - onRelease, - onSend, - open, - report, - setOpenMenuId, -}) { +function ReportRow({ onEdit, onView, report }) { return (
+ {report.orderNumber || '-'}
- - {report.type} + + {report.exam || 'Sem exame'}
{report.patient}{report.doctor}{report.date} + {report.patientName}{report.requestedBy || '-'}{formatDate(report.createdAt)} {statusConfig[report.status].label} - - - - {open ? ( - <> - +
+ + +