fix: mostra arquivo anexado no laudo, exporta laudo completo em PDF
This commit is contained in:
parent
80aa1c3401
commit
3969d0dc86
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user