import { useEffect, useMemo, useState } from 'react' import { FeatureBadge, FeatureCallout } from '../components/FeatureState.jsx' import { featurePanelClass } from '../components/featureStateStyles.js' import { reportRepository } from '../repositories/reportRepository.js' import { patientRepository } from '../repositories/patientRepository.js' const statusConfig = { rascunho: { label: 'Rascunho', pill: 'bg-amber-500/20 text-amber-400', stat: 'text-amber-400', }, finalizado: { label: 'Finalizado', pill: 'bg-emerald-500/20 text-emerald-400', stat: 'text-emerald-400', }, enviado: { label: 'Enviado', pill: 'bg-blue-500/20 text-blue-400', stat: 'text-blue-400', }, } const adminUsers = reportRepository.getAdminUsers() const currentUser = reportRepository.getCurrentUser() const doctors = reportRepository.getDoctors() const reportTypes = reportRepository.getReportTypes() const templates = reportRepository.getTemplates() const emptyEditor = { id: null, type: reportTypes[0], patient: '', doctor: doctors[0], content: '', showDate: true, signDigital: true, } const inputClass = 'h-10 w-full rounded-lg border border-[#404040] bg-[#1a1a1a] px-3 text-sm text-[#e5e5e5] outline-none transition placeholder:text-[#a3a3a3] focus:border-[#3b82f6] focus:ring-1 focus:ring-[#3b82f6]' const labelClass = 'mb-1.5 block text-xs font-medium text-[#e5e5e5]' const cardClass = 'rounded-2xl border border-[#404040] bg-[#262626] shadow-sm' export function ReportsPage() { const [reports, setReports] = useState([]) const [patients, setPatients] = useState([]) useEffect(() => { reportRepository.getInitialReports().then(setReports).catch(console.error) patientRepository.getAll().then(setPatients).catch(console.error) }, []) const [search, setSearch] = useState('') const [filterStatus, setFilterStatus] = useState('') const [openMenuId, setOpenMenuId] = useState(null) const [editorOpen, setEditorOpen] = useState(false) const [templatesOpen, setTemplatesOpen] = useState(false) const [historyReport, setHistoryReport] = useState(null) const [confirmRelease, setConfirmRelease] = useState(null) const [deliveryReport, setDeliveryReport] = useState(null) const [confirmDelete, setConfirmDelete] = useState(null) const [deleteConfirmText, setDeleteConfirmText] = useState('') const [preview, setPreview] = useState(false) const [editor, setEditor] = useState(emptyEditor) const filteredReports = useMemo(() => { return reports.filter((report) => { const matchesSearch = [report.patient, report.type] .join(' ') .toLowerCase() .includes(search.toLowerCase()) const matchesStatus = !filterStatus || report.status === filterStatus return matchesSearch && matchesStatus }) }, [filterStatus, reports, search]) const stats = [ { label: 'Rascunhos', status: 'rascunho' }, { label: 'Finalizados', status: 'finalizado' }, { label: 'Enviados', status: 'enviado' }, ].map((stat) => ({ ...stat, value: reports.filter((report) => report.status === stat.status).length, })) function openNew(template = null) { setEditor({ ...emptyEditor, type: template?.type || emptyEditor.type, content: template?.content || '', }) setPreview(false) setTemplatesOpen(false) setEditorOpen(true) } function openEdit(report) { setEditor({ id: report.id, type: report.type, patient: report.patient, doctor: report.doctor, content: report.content, showDate: report.showDate, signDigital: report.signDigital, }) setOpenMenuId(null) setPreview(false) setEditorOpen(true) } async function saveReport(status) { if (!editor.patient.trim() || !editor.content.trim()) return try { const selectedPatient = patients.find(p => p.name === editor.patient || p.full_name === editor.patient) const patientId = selectedPatient?.id || null if (editor.id) { const updated = await reportRepository.update(editor.id, { type: editor.type, content: editor.content, patientId: patientId, status, }) setReports(curr => curr.map(r => r.id == updated.id ? { ...updated, status } : r)) } else { const created = await reportRepository.create({ type: editor.type, content: editor.content, patientId: patientId, status, }) setReports(curr => [{ ...created, status }, ...curr]) } setEditorOpen(false) } catch(e) { alert(e.message || 'Erro ao persistir na Base de Dados') } } function releaseReport(reportId) { setReports((currentReports) => currentReports.map((report) => report.id === reportId ? { ...report, status: 'finalizado', versions: [ ...report.versions, { version: report.versions.length + 1, action: 'Liberado', user: currentUser, summary: 'Laudo liberado' }, ], } : report, ), ) setConfirmRelease(null) } function sendReport(reportId) { setReports((currentReports) => currentReports.map((report) => report.id === reportId ? { ...report, status: 'enviado', versions: [ ...report.versions, { version: report.versions.length + 1, action: 'Enviado', user: currentUser, summary: 'Laudo enviado ao paciente' }, ], } : report, ), ) setOpenMenuId(null) } function deleteReport(reportId) { setReports((currentReports) => currentReports.filter((report) => report.id !== reportId)) setConfirmDelete(null) setDeleteConfirmText('') } return (

Gestão de Laudos

{stats.map((stat) => (

{stat.label}

{stat.value}

))}
setSearch(event.target.value)} placeholder="Buscar por paciente ou tipo..." value={search} />
{filteredReports.length ? ( filteredReports.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} report={report} setOpenMenuId={setOpenMenuId} /> )) ) : ( )}
Tipo Paciente Médico Data Status Versões Ações
Nenhum laudo encontrado.
{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} /> ) : null}
) } function ReportRow({ onDelete, onDelivery, onEdit, onHistory, onPrint, onRelease, onSend, open, report, setOpenMenuId, }) { return (
{report.type}
{report.patient} {report.doctor} {report.date} {statusConfig[report.status].label} {open ? ( <>
{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} />