import React, { useState, useRef, useEffect } from "react"; /* ===== Estilos embutidos ===== */ const styles = ` .laudo-wrap { display:flex; gap:24px; padding:18px; font-family: Inter, Roboto, Arial, sans-serif; } .left-col { width: 100%; max-width: 1160px; background:#f7fbff; border-radius:8px; padding:18px; box-shadow: 0 1px 0 rgba(0,0,0,0.03);} .title-row { display:flex; justify-content:space-between; align-items:center; margin-bottom:12px; } .page-title { font-size:20px; color:#2b4a78; font-weight:700; } .laudo-table { width:100%; border-collapse:collapse; background:#fff; border-radius:8px; overflow:visible; } .laudo-row { display:flex; padding:14px 12px; align-items:center; border-bottom:1px solid #eef3f8; position:relative; overflow:visible; } .col { flex:1; padding:0 8px; font-size:14px; color:#2e3a4b; } .col.small { flex:0 0 90px; text-align:right; } .row-actions { position:relative; flex: 0 0 88px; display:flex; justify-content:flex-end; } .action-btn { background:transparent; border:1px solid #d7e6fb; border-radius:8px; height:40px; width:40px; display:flex; align-items:center; justify-content:center; cursor:pointer; } .dropdown { position:absolute; right:0; top:48px; background:white; border-radius:8px; box-shadow: 0 10px 30px rgba(20,30,50,0.12); min-width:220px; padding:8px 0; z-index:9999; } .dropdown .item { padding:12px 18px; cursor:pointer; font-size:15px; color:#244056; } .dropdown .item:hover { background:#f6fbff; } .viewer-modal, .preview-modal, .confirm-modal { position:fixed; inset:0; display:flex; align-items:center; justify-content:center; z-index:12000; } .modal-backdrop { position:absolute; inset:0; background: rgba(9,20,40,0.45); } .modal-card { position:relative; width:92%; max-width:1100px; background:white; border-radius:10px; padding:18px; box-shadow: 0 10px 60px rgba(10,20,40,0.25); max-height:88vh; overflow:auto; } .viewer-header { display:flex; justify-content:space-between; align-items:flex-start; gap:10px; margin-bottom:12px; } .patient-info { font-size:13px; color:#3a556b; } .toolbar { display:flex; gap:8px; align-items:center; flex-wrap:wrap; margin-bottom:12px; } .tool-btn { padding:8px 10px; border-radius:6px; border:1px solid #e6eef8; cursor:pointer; background:#fff; font-size:13px; } .editor-area { border:1px solid #e6eef8; border-radius:8px; padding:14px; min-height:360px; background: #fff; color:#1f2d3d; font-size:15px; line-height:1.5; } .footer-controls { display:flex; justify-content:space-between; align-items:center; margin-top:12px; } .toggle { display:flex; align-items:center; gap:8px; } .btn { padding:8px 12px; border-radius:8px; border:none; cursor:pointer; font-weight:600; } .btn.secondary { background:#eef6ff; color:#2f63a6; border:1px solid #d6e9ff; } .btn.primary { background:#2f63a6; color:white; } .small-muted { color:#7f95a8; font-size:13px; } .empty { padding:40px; text-align:center; color:#7d97b4; } `; /* ===== Mock data (simula APIDOG) ===== */ function mockFetchLaudos() { return [ { id: "LAU-300551296", pedido: 300551296, data: "29/07/2025", paciente: { nome: "Sarah Mariana Oliveira", cpf: "616.869.070-**", nascimento: "1990-03-25", convenio: "Unimed" }, solicitante: "Sandro Rangel Santos", exame: "US - Abdome Total", conteudo: "RELATÓRIO MÉDICO\n\nAchados: Imagens compatíveis com ...\nConclusão: Órgãos sem alterações significativas.", status: "rascunho" }, { id: "LAU-300659170", pedido: 300659170, data: "29/07/2025", paciente: { nome: "Laissa Helena Marquetti", cpf: "950.684.57-**", nascimento: "1986-09-12", convenio: "Bradesco" }, solicitante: "Sandro Rangel Santos", exame: "US - Mamária Bilateral", conteudo: "RELATÓRIO MÉDICO\n\nAchados: text...", status: "rascunho" }, { id: "LAU-300658301", pedido: 300658301, data: "28/07/2025", paciente: { nome: "Vera Lúcia Oliveira Santos", cpf: "928.005.**", nascimento: "1979-02-02", convenio: "Particular" }, solicitante: "Dr. Fulano", exame: "US - Transvaginal", conteudo: "RELATÓRIO MÉDICO\n\nAchados: ...", status: "rascunho" } ]; } function mockDeleteLaudo(id) { return new Promise((res) => setTimeout(() => res({ ok: true }), 500)); } /* ===== Componente ===== */ export default function LaudoManager() { const [laudos, setLaudos] = useState([]); const [openDropdownId, setOpenDropdownId] = useState(null); const [viewerLaudo, setViewerLaudo] = useState(null); const [showPreview, setShowPreview] = useState(false); const [showConfirmDelete, setShowConfirmDelete] = useState(false); const [toDelete, setToDelete] = useState(null); const [loadingDelete, setLoadingDelete] = useState(false); useEffect(() => { const el = document.createElement("style"); el.innerHTML = styles; document.head.appendChild(el); const data = mockFetchLaudos(); setLaudos(data); return () => document.head.removeChild(el); }, []); // Fecha dropdown ao clicar fora useEffect(() => { function onDocClick(e) { // se clicar em um botão de ação (ícone), não fecha if (e.target.closest && e.target.closest('.action-btn')) return; // se clicar dentro de um dropdown, não fecha if (e.target.closest && e.target.closest('.dropdown')) return; // caso contrário, fecha qualquer dropdown aberto setOpenDropdownId(null); } document.addEventListener('click', onDocClick); return () => document.removeEventListener('click', onDocClick); }, []); function toggleDropdown(id, e) { e.stopPropagation(); // evita que o document click feche imediatamente setOpenDropdownId(prev => (prev === id ? null : id)); } function handleOpenViewer(laudo) { setViewerLaudo(laudo); setOpenDropdownId(null); } function handleRequestDelete(laudo) { setToDelete(laudo); setOpenDropdownId(null); setShowConfirmDelete(true); } async function confirmDelete(typed) { if (!toDelete) return; if (typed.trim().toUpperCase() !== "EXCLUIR") { alert("Confirmação inválida. Digite EXCLUIR para confirmar."); return; } setLoadingDelete(true); try { const resp = await mockDeleteLaudo(toDelete.id); if (resp.ok || resp === true) { setLaudos(curr => curr.filter(l => l.id !== toDelete.id)); setShowConfirmDelete(false); setToDelete(null); alert("Laudo excluído com sucesso."); } else { alert("Erro ao excluir. Tente novamente."); } } catch (err) { alert("Erro de rede ao excluir."); } finally { setLoadingDelete(false); } } function handlePrint(laudo) { setViewerLaudo(laudo); setShowPreview(true); setOpenDropdownId(null); } return (
{line}
))}