fix: mostra arquivo anexado no laudo, exporta laudo completo em PDF

This commit is contained in:
pedrogomes5913 2025-09-30 21:53:36 -03:00
parent 80aa1c3401
commit 3969d0dc86

View File

@ -1626,7 +1626,7 @@ const ProfissionalPage = () => {
<LaudoEditor /> <LaudoEditor />
</section> </section>
); );
// --- LaudoEditor COMPONENT ---
function LaudoEditor() { function LaudoEditor() {
const [showHistorico, setShowHistorico] = useState(false); const [showHistorico, setShowHistorico] = useState(false);
const [file, setFile] = useState<File | null>(null); const [file, setFile] = useState<File | null>(null);
@ -1648,7 +1648,7 @@ function LaudoEditor() {
const [laudos, setLaudos] = useState<any[]>([]); const [laudos, setLaudos] = useState<any[]>([]);
const [preview, setPreview] = useState(false); const [preview, setPreview] = useState(false);
// Função para selecionar paciente e preencher dados automaticamente
function handleSelectPaciente(p: { nome: string; cpf: string; idade: string; sexo?: string }) { function handleSelectPaciente(p: { nome: string; cpf: string; idade: string; sexo?: string }) {
setPaciente(p.nome); setPaciente(p.nome);
setCpf(p.cpf); setCpf(p.cpf);
@ -1680,7 +1680,7 @@ function LaudoEditor() {
return ( return (
<div className="min-h-screen bg-muted p-6"> <div className="min-h-screen bg-muted p-6">
{/* Se ainda não selecionou paciente, mostra seleção */}
{!paciente ? ( {!paciente ? (
<div className="bg-white rounded-xl shadow p-8 flex flex-col items-center"> <div className="bg-white rounded-xl shadow p-8 flex flex-col items-center">
<span className="text-6xl text-gray-400 mb-2"> <span className="text-6xl text-gray-400 mb-2">
@ -1725,7 +1725,7 @@ function LaudoEditor() {
</div> </div>
</div> </div>
) : ( ) : (
// Após selecionar paciente, mostra o editor de laudo completo
<div className="bg-white rounded-xl shadow p-8 flex flex-col items-center w-full max-w-4xl mx-auto"> <div className="bg-white rounded-xl shadow p-8 flex flex-col items-center w-full max-w-4xl mx-auto">
<div className="w-full mb-6 flex flex-col items-center"> <div className="w-full mb-6 flex flex-col items-center">
<span className="text-4xl text-blue-400 mb-2"> <span className="text-4xl text-blue-400 mb-2">
@ -1742,7 +1742,7 @@ function LaudoEditor() {
Trocar paciente Trocar paciente
</button> </button>
</div> </div>
{/* Campo de CID */}
<div className="w-full mb-4"> <div className="w-full mb-4">
<label className="block font-semibold mb-1">CID:</label> <label className="block font-semibold mb-1">CID:</label>
<input <input
@ -1752,7 +1752,7 @@ function LaudoEditor() {
placeholder="Ex: I10, E11, etc." placeholder="Ex: I10, E11, etc."
/> />
</div> </div>
{/* Editor de laudo */}
<div className="w-full mb-4"> <div className="w-full mb-4">
<label className="block font-semibold mb-1">Conteúdo do Laudo:</label> <label className="block font-semibold mb-1">Conteúdo do Laudo:</label>
<textarea <textarea
@ -1763,7 +1763,7 @@ function LaudoEditor() {
placeholder="Digite o conteúdo do laudo aqui..." placeholder="Digite o conteúdo do laudo aqui..."
/> />
</div> </div>
{/* Campo de assinatura */}
<div className="w-full mb-6"> <div className="w-full mb-6">
<label className="block font-semibold mb-1">Assinatura do Profissional:</label> <label className="block font-semibold mb-1">Assinatura do Profissional:</label>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
@ -1791,7 +1791,7 @@ function LaudoEditor() {
const canvas = sigCanvasRef.current; const canvas = sigCanvasRef.current;
if (!canvas) return; if (!canvas) return;
canvas.isDrawing = false; canvas.isDrawing = false;
// Salva a assinatura como imagem base64
setAssinatura(canvas.toDataURL()); setAssinatura(canvas.toDataURL());
}} }}
onMouseLeave={e => { onMouseLeave={e => {
@ -1821,8 +1821,8 @@ function LaudoEditor() {
</div> </div>
)} )}
</div> </div>
{/* Botão para salvar laudo */}
{/* Upload de arquivos */}
<div className="w-full mb-4 flex flex-col gap-2"> <div className="w-full mb-4 flex flex-col gap-2">
<label className="block font-semibold mb-1">Anexar Arquivo:</label> <label className="block font-semibold mb-1">Anexar Arquivo:</label>
<div className="flex gap-2 items-center"> <div className="flex gap-2 items-center">
@ -1830,20 +1830,12 @@ function LaudoEditor() {
id="upload-arquivo" id="upload-arquivo"
type="file" type="file"
onChange={handleFileChange} onChange={handleFileChange}
className="hidden" className="file:bg-blue-600 file:text-white file:px-6 file:py-2 file:rounded-lg file:font-semibold file:hover:bg-blue-700 file:transition-all file:shadow file:border-none file:cursor-pointer"
style={{}}
/> />
<label htmlFor="upload-arquivo">
<button
type="button"
className="flex items-center gap-2 bg-blue-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-blue-700 transition-all shadow"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v2a2 2 0 002 2h12a2 2 0 002-2v-2M7 10l5 5m0 0l5-5m-5 5V4" /></svg>
Selecionar Arquivo
</button>
</label>
{file && <span className="ml-2 text-sm text-gray-600">{file.name}</span>} {file && <span className="ml-2 text-sm text-gray-600">{file.name}</span>}
</div> </div>
{/* Pré-visualização do laudo */}
<div className="w-full my-6 p-4 bg-gray-50 border rounded-lg shadow"> <div className="w-full my-6 p-4 bg-gray-50 border rounded-lg shadow">
<h3 className="text-lg font-bold mb-2 text-blue-700">Pré-visualização do Laudo</h3> <h3 className="text-lg font-bold mb-2 text-blue-700">Pré-visualização do Laudo</h3>
<div className="mb-1"><span className="font-semibold">Paciente:</span> {paciente}</div> <div className="mb-1"><span className="font-semibold">Paciente:</span> {paciente}</div>
@ -1857,7 +1849,7 @@ function LaudoEditor() {
</div> </div>
</div> </div>
{/* Botão para salvar laudo */}
<div className="w-full flex justify-end gap-4"> <div className="w-full flex justify-end gap-4">
<button <button
className="flex items-center gap-2 bg-blue-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-blue-700 transition-all shadow" className="flex items-center gap-2 bg-blue-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-blue-700 transition-all shadow"
@ -1873,9 +1865,16 @@ function LaudoEditor() {
> >
Histórico de Laudos Histórico de Laudos
</button> </button>
<button
className="flex items-center gap-2 bg-green-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-green-700 transition-all shadow"
onClick={() => window.print()}
type="button"
>
Exportar Laudo em PDF
</button>
</div> </div>
{/* Modal de histórico de laudos */}
{showHistorico && ( {showHistorico && (
<div className="fixed inset-0 bg-black bg-opacity-40 flex justify-center items-center z-50"> <div className="fixed inset-0 bg-black bg-opacity-40 flex justify-center items-center z-50">
<div className="bg-white p-8 rounded-xl shadow-2xl w-full max-w-lg border border-gray-200"> <div className="bg-white p-8 rounded-xl shadow-2xl w-full max-w-lg border border-gray-200">
@ -1896,21 +1895,14 @@ function LaudoEditor() {
<div className="text-sm text-gray-600 mb-1">CID: <span className="font-semibold">{laudo.cid}</span></div> <div className="text-sm text-gray-600 mb-1">CID: <span className="font-semibold">{laudo.cid}</span></div>
<div className="text-base text-gray-700 whitespace-pre-line">{laudo.conteudo}</div> <div className="text-base text-gray-700 whitespace-pre-line">{laudo.conteudo}</div>
{laudo.arquivo && ( {laudo.arquivo && (
<div className="flex items-center gap-2 mt-2"> <div className="flex flex-col gap-2 mt-2">
<span className="text-xs text-blue-600">Arquivo: {laudo.arquivo.name}</span> <span className="text-xs text-blue-600">Arquivo: {laudo.arquivo.name}</span>
<button {laudo.arquivo.type.startsWith('image/') && (
className="px-2 py-1 bg-green-600 text-white rounded text-xs hover:bg-green-700" <img src={URL.createObjectURL(laudo.arquivo)} alt={laudo.arquivo.name} className="max-h-40 border rounded" onLoad={e => URL.revokeObjectURL((e.target as HTMLImageElement).src)} />
onClick={() => { )}
const url = URL.createObjectURL(laudo.arquivo); {laudo.arquivo.type === 'application/pdf' && (
const link = document.createElement('a'); <iframe src={URL.createObjectURL(laudo.arquivo)} title={laudo.arquivo.name} className="w-full h-64 border rounded" onLoad={e => URL.revokeObjectURL((e.target as HTMLIFrameElement).src)} />
link.href = url; )}
link.download = laudo.arquivo.name;
link.click();
setTimeout(() => URL.revokeObjectURL(url), 1000);
}}
>
Baixar PDF
</button>
</div> </div>
)} )}
</li> </li>