// src/pages/LaudoManager.jsx import API_KEY from '../components/utils/apiKeys'; import { Link } from 'react-router-dom'; import React, { useState, useEffect } from 'react'; import { useAuth } from '../components/utils/AuthProvider'; import { GetPatientByID } from '../components/utils/Functions-Endpoints/Patient'; import { GetDoctorByID } from '../components/utils/Functions-Endpoints/Doctor'; import { useNavigate } from 'react-router-dom'; import html2pdf from 'html2pdf.js'; import TiptapViewer from '../PagesMedico/TiptapViewer' import '../PagesMedico/styleMedico/DoctorRelatorioManager.css'; const LaudoManager = () => { const navigate = useNavigate(); const { getAuthorizationHeader } = useAuth(); const authHeader = getAuthorizationHeader(); const [relatoriosOriginais, setRelatoriosOriginais] = useState([]); const [relatoriosFiltrados, setRelatoriosFiltrados] = useState([]); const [relatoriosFinais, setRelatoriosFinais] = useState([]); const [pacientesComRelatorios, setPacientesComRelatorios] = useState([]); const [medicosComRelatorios, setMedicosComRelatorios] = useState([]); const [showModal, setShowModal] = useState(false); const [relatorioModal, setRelatorioModal] = useState(null); const [termoPesquisa, setTermoPesquisa] = useState(''); const [filtroExame, setFiltroExame] = useState(''); const [modalIndex, setModalIndex] = useState(0); const [showProtocolModal, setShowProtocolModal] = useState(false); const [protocolForIndex, setProtocolForIndex] = useState(null); const [paginaAtual, setPaginaAtual] = useState(1); const [itensPorPagina, setItensPorPagina] = useState(10); const [noPermissionText, setNoPermissionText] = useState(null); const isSecretary = true; const totalPaginas = Math.max(1, Math.ceil(relatoriosFinais.length / itensPorPagina)); const indiceInicial = (paginaAtual - 1) * itensPorPagina; const indiceFinal = indiceInicial + itensPorPagina; const relatoriosPaginados = relatoriosFinais.slice(indiceInicial, indiceFinal); useEffect(() => { let mounted = true; const fetchReports = async () => { try { const myHeaders = new Headers(); myHeaders.append('apikey', API_KEY); if (authHeader) myHeaders.append('Authorization', authHeader); const requestOptions = { method: 'GET', headers: myHeaders, redirect: 'follow' }; const res = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?select=*", requestOptions); const data = await res.json(); const uniqueMap = new Map(); (Array.isArray(data) ? data : []).forEach(r => { if (r && r.id) uniqueMap.set(r.id, r); }); const unique = Array.from(uniqueMap.values()) .sort((a, b) => new Date(b.created_at || 0) - new Date(a.created_at || 0)); if (mounted) { setRelatoriosOriginais(unique); setRelatoriosFiltrados(unique); setRelatoriosFinais(unique); } } catch (err) { console.error('Erro listar relatórios', err); if (mounted) { setRelatoriosOriginais([]); setRelatoriosFiltrados([]); setRelatoriosFinais([]); } } }; fetchReports(); const refreshHandler = () => fetchReports(); window.addEventListener('reports:refresh', refreshHandler); return () => { mounted = false; window.removeEventListener('reports:refresh', refreshHandler); }; }, [authHeader]); useEffect(() => { const fetchRelData = async () => { const pacientes = []; const medicos = []; for (let i = 0; i < relatoriosFiltrados.length; i++) { const rel = relatoriosFiltrados[i]; try { const pacienteRes = await GetPatientByID(rel.patient_id, authHeader); pacientes.push(Array.isArray(pacienteRes) ? pacienteRes[0] : pacienteRes); } catch (err) { pacientes.push(null); } try { const doctorId = rel.created_by || rel.requested_by || null; if (doctorId) { const docRes = await GetDoctorByID(doctorId, authHeader); medicos.push(Array.isArray(docRes) ? docRes[0] : docRes); } else { medicos.push({ full_name: rel.requested_by || '' }); } } catch (err) { medicos.push({ full_name: rel.requested_by || '' }); } } setPacientesComRelatorios(pacientes); setMedicosComRelatorios(medicos); }; if (relatoriosFiltrados.length > 0) fetchRelData(); else { setPacientesComRelatorios([]); setMedicosComRelatorios([]); } }, [relatoriosFiltrados, authHeader]); const abrirModal = (relatorio, index) => { setRelatorioModal(relatorio); setModalIndex(index); setShowModal(true); }; const limparFiltros = () => { setTermoPesquisa(''); setFiltroExame(''); setRelatoriosFinais(relatoriosOriginais); }; const BaixarPDFdoRelatorio = (nome_paciente, idx) => { const elemento = document.getElementById(`folhaA4-${idx}`); if (!elemento) { console.error('Elemento para gerar PDF não encontrado:', `folhaA4-${idx}`); return; } const opt = { margin: 0, filename: `relatorio_${nome_paciente || "paciente"}.pdf`, html2canvas: { scale: 2 }, jsPDF: { unit: "mm", format: "a4", orientation: "portrait" } }; html2pdf().set(opt).from(elemento).save(); }; const handleEditClick = (relatorio) => { if (isSecretary) { setNoPermissionText('Sem permissão para editar/criar laudo.'); return; } navigate(`/medico/relatorios/${relatorio.id}/edit`); }; const handleOpenProtocol = (relatorio, index) => { setProtocolForIndex({ relatorio, index }); setShowProtocolModal(true); }; const handleLiberarLaudo = async (relatorio) => { if (isSecretary) { setNoPermissionText('Ainda não implementado'); return; } try { const myHeaders = new Headers(); myHeaders.append('apikey', API_KEY); if (authHeader) myHeaders.append('Authorization', authHeader); myHeaders.append('Content-Type', 'application/json'); myHeaders.append('Prefer', 'return=representation'); const body = JSON.stringify({ status: 'liberado' }); const res = await fetch(`https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?id=eq.${relatorio.id}`, { method: 'PATCH', headers: myHeaders, body }); if (!res.ok) { const txt = await res.text().catch(()=> ''); throw new Error('Erro ao liberar laudo: ' + res.status + ' ' + txt); } const refreshed = await fetch("https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/reports?select=*", { method: 'GET', headers: (() => { const h=new Headers(); h.append('apikey', API_KEY); if(authHeader) h.append('Authorization', authHeader); return h; })(), }); const data = await refreshed.json(); setRelatoriosOriginais(Array.isArray(data)? data : []); setRelatoriosFiltrados(Array.isArray(data)? data : []); setRelatoriosFinais(Array.isArray(data)? data : []); alert('Laudo liberado com sucesso.'); } catch (err) { console.error(err); alert('Erro ao liberar laudo. Veja console.'); } }; useEffect(() => { const q = (termoPesquisa || '').toLowerCase().trim(); const ex = (filtroExame || '').toLowerCase().trim(); let items = relatoriosOriginais || []; if (q) { items = items.filter(r => { const patientName = (r.patient_name || r.patient_fullname || '').toString().toLowerCase(); const pedido = (r.id || r.request_id || r.request || '').toString().toLowerCase(); return patientName.includes(q) || pedido.includes(q) || (r.patient_id && r.patient_id.toString().includes(q)); }); } if (ex) items = items.filter(r => (r.exam || r.exame || '').toLowerCase().includes(ex)); setRelatoriosFiltrados(items); setRelatoriosFinais(items); setPaginaAtual(1); }, [termoPesquisa, filtroExame, relatoriosOriginais]); const irParaPagina = (pagina) => setPaginaAtual(pagina); const avancarPagina = () => { if (paginaAtual < totalPaginas) setPaginaAtual(paginaAtual + 1); }; const voltarPagina = () => { if (paginaAtual > 1) setPaginaAtual(paginaAtual - 1); }; const gerarNumerosPaginas = () => { const paginas = []; const paginasParaMostrar = 5; let inicio = Math.max(1, paginaAtual - Math.floor(paginasParaMostrar / 2)); let fim = Math.min(totalPaginas, inicio + paginasParaMostrar - 1); inicio = Math.max(1, fim - paginasParaMostrar + 1); for (let i = inicio; i <= fim; i++) paginas.push(i); return paginas; }; return (

Lista de Relatórios

Relatórios Cadastrados

Filtros
setTermoPesquisa(e.target.value)} />
setFiltroExame(e.target.value)} />
{relatoriosFinais.length} DE {relatoriosOriginais.length} RELATÓRIOS ENCONTRADOS
{relatoriosPaginados.length > 0 ? ( relatoriosPaginados.map((relatorio, index) => { const paciente = pacientesComRelatorios[index] || {}; return ( ); }) ) : ( )}
Paciente CPF Exame
{paciente?.full_name || relatorio.patient_name || 'Carregando...'} {paciente?.cpf || 'Carregando...'} {relatorio.exam || relatorio.exame || '—'}
Nenhum relatório encontrado.
{relatoriosFinais.length > 0 && (
Itens por página:
Página {paginaAtual} de {totalPaginas} • Mostrando {indiceInicial + 1}-{Math.min(indiceFinal, relatoriosFinais.length)} de {relatoriosFinais.length} itens
)}
{showModal && relatorioModal && (
Relatório de {pacientesComRelatorios[modalIndex]?.full_name || relatorioModal.patient_name || 'Paciente'}

Clinica Rise up

Dr - CRM/SP 123456

Avenida - (79) 9 4444-4444

Paciente: {pacientesComRelatorios[modalIndex]?.full_name || relatorioModal.patient_name || '—'}

Data de nascimento: {pacientesComRelatorios[modalIndex]?.birth_date || '—'}

Data do exame: {relatorioModal?.due_at || relatorioModal?.date || '—'}

Conteúdo do Relatório:

Dr {medicosComRelatorios[modalIndex]?.full_name || relatorioModal?.requested_by || '—'}

Emitido em: {relatorioModal?.created_at || '—'}

)} {showProtocolModal && protocolForIndex && (
Protocolo de Entrega - {protocolForIndex.relatorio?.patient_name || 'Paciente'}

Pedido: {protocolForIndex.relatorio?.id || protocolForIndex.relatorio?.pedido}

Paciente: {protocolForIndex.relatorio?.patient_name || '—'}

Data: {protocolForIndex.relatorio?.due_at || protocolForIndex.relatorio?.date || '—'}


Protocolo de entrega gerado automaticamente. (Substitua pelo endpoint real se houver)

)} {noPermissionText && (
Aviso

{noPermissionText}

)}
); }; export default LaudoManager;