add-dark-mode-and-removing-pages #35
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useState, useRef } from "react";
|
import React, { useState, useRef, useEffect } from "react";
|
||||||
import SignatureCanvas from "react-signature-canvas";
|
import SignatureCanvas from "react-signature-canvas";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import ProtectedRoute from "@/components/ProtectedRoute";
|
import ProtectedRoute from "@/components/ProtectedRoute";
|
||||||
@ -73,6 +73,10 @@ const ProfissionalPage = () => {
|
|||||||
const [activeSection, setActiveSection] = useState('calendario');
|
const [activeSection, setActiveSection] = useState('calendario');
|
||||||
const [pacienteSelecionado, setPacienteSelecionado] = useState<any>(null);
|
const [pacienteSelecionado, setPacienteSelecionado] = useState<any>(null);
|
||||||
|
|
||||||
|
// Estados para edição de laudo
|
||||||
|
const [isEditingLaudoForPatient, setIsEditingLaudoForPatient] = useState(false);
|
||||||
|
const [patientForLaudo, setPatientForLaudo] = useState<any>(null);
|
||||||
|
|
||||||
// Estados para o perfil do médico
|
// Estados para o perfil do médico
|
||||||
const [isEditingProfile, setIsEditingProfile] = useState(false);
|
const [isEditingProfile, setIsEditingProfile] = useState(false);
|
||||||
const [profileData, setProfileData] = useState({
|
const [profileData, setProfileData] = useState({
|
||||||
@ -199,6 +203,12 @@ const ProfissionalPage = () => {
|
|||||||
setPacienteSelecionado(null);
|
setPacienteSelecionado(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleEditarLaudo = (paciente: any) => {
|
||||||
|
setPatientForLaudo(paciente);
|
||||||
|
setIsEditingLaudoForPatient(true);
|
||||||
|
setActiveSection('laudos');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const navigateDate = (direction: 'prev' | 'next') => {
|
const navigateDate = (direction: 'prev' | 'next') => {
|
||||||
const newDate = new Date(currentCalendarDate);
|
const newDate = new Date(currentCalendarDate);
|
||||||
@ -553,6 +563,7 @@ const ProfissionalPage = () => {
|
|||||||
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -688,6 +699,7 @@ const ProfissionalPage = () => {
|
|||||||
<p className="font-medium">{paciente.nome}</p>
|
<p className="font-medium">{paciente.nome}</p>
|
||||||
<p className="text-sm text-muted-foreground">CPF: {paciente.cpf} • Idade: {paciente.idade} anos</p>
|
<p className="text-sm text-muted-foreground">CPF: {paciente.cpf} • Idade: {paciente.idade} anos</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
@ -697,8 +709,18 @@ const ProfissionalPage = () => {
|
|||||||
className="flex items-center gap-2"
|
className="flex items-center gap-2"
|
||||||
>
|
>
|
||||||
<FolderOpen className="h-4 w-4" />
|
<FolderOpen className="h-4 w-4" />
|
||||||
Abrir Prontuário
|
Prontuário
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
onClick={() => handleEditarLaudo(paciente)}
|
||||||
|
className="flex items-center gap-2 border-green-600 text-green-600 hover:bg-green-600 hover:text-white"
|
||||||
|
>
|
||||||
|
<FileText className="h-4 w-4" />
|
||||||
|
Editar Laudo
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -732,7 +754,7 @@ const ProfissionalPage = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
className="border-primary text-primary hover:bg-primary hover:text-white cursor-pointer"
|
className="border-primary text-primary hover:bg-primary hover:text-white cursor-pointer mr-2"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handleAbrirProntuario(paciente);
|
handleAbrirProntuario(paciente);
|
||||||
setActiveSection('prontuario');
|
setActiveSection('prontuario');
|
||||||
@ -745,6 +767,20 @@ const ProfissionalPage = () => {
|
|||||||
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="relative group">
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className="border-green-600 text-green-600 hover:bg-green-600 hover:text-white cursor-pointer"
|
||||||
|
onClick={() => handleEditarLaudo(paciente)}
|
||||||
|
>
|
||||||
|
<FileText className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
<div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-1 bg-gray-900 dark:bg-gray-100 text-white dark:text-gray-900 text-xs rounded-md opacity-0 group-hover:opacity-100 transition-opacity duration-200 pointer-events-none whitespace-nowrap z-50">
|
||||||
|
Editar laudo do paciente
|
||||||
|
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-transparent border-t-gray-900 dark:border-t-gray-100"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@ -1651,12 +1687,19 @@ const ProfissionalPage = () => {
|
|||||||
|
|
||||||
const renderLaudosSection = () => (
|
const renderLaudosSection = () => (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<LaudoManager />
|
<LaudoManager
|
||||||
|
isEditingForPatient={isEditingLaudoForPatient}
|
||||||
|
selectedPatientForLaudo={patientForLaudo}
|
||||||
|
onClosePatientEditor={() => {
|
||||||
|
setIsEditingLaudoForPatient(false);
|
||||||
|
setPatientForLaudo(null);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
// --- NOVO SISTEMA DE LAUDOS COMPLETO ---
|
// --- NOVO SISTEMA DE LAUDOS COMPLETO ---
|
||||||
function LaudoManager() {
|
function LaudoManager({ isEditingForPatient, selectedPatientForLaudo, onClosePatientEditor }: { isEditingForPatient?: boolean; selectedPatientForLaudo?: any; onClosePatientEditor?: () => void }) {
|
||||||
const [pacientesDisponiveis] = useState([
|
const [pacientesDisponiveis] = useState([
|
||||||
{ id: "95170038", nome: "Ana Souza", cpf: "123.456.789-00", idade: 42, sexo: "Feminino" },
|
{ id: "95170038", nome: "Ana Souza", cpf: "123.456.789-00", idade: 42, sexo: "Feminino" },
|
||||||
{ id: "93203056", nome: "Bruno Lima", cpf: "987.654.321-00", idade: 33, sexo: "Masculino" },
|
{ id: "93203056", nome: "Bruno Lima", cpf: "987.654.321-00", idade: 33, sexo: "Masculino" },
|
||||||
@ -1788,6 +1831,9 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
const [isViewing, setIsViewing] = useState(false);
|
const [isViewing, setIsViewing] = useState(false);
|
||||||
const [isCreatingNew, setIsCreatingNew] = useState(false);
|
const [isCreatingNew, setIsCreatingNew] = useState(false);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
@ -1938,6 +1984,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
<TableCell className="text-sm">{laudo.executante}</TableCell>
|
<TableCell className="text-sm">{laudo.executante}</TableCell>
|
||||||
<TableCell className="text-sm">{laudo.exame || "-"}</TableCell>
|
<TableCell className="text-sm">{laudo.exame || "-"}</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -1950,6 +1997,20 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
<Eye className="w-4 h-4" />
|
<Eye className="w-4 h-4" />
|
||||||
Ver Laudo
|
Ver Laudo
|
||||||
</Button>
|
</Button>
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => {
|
||||||
|
setPatientForLaudo(laudo);
|
||||||
|
setIsEditingLaudoForPatient(true);
|
||||||
|
}}
|
||||||
|
className="flex items-center gap-1 bg-green-600 hover:bg-green-700 text-white"
|
||||||
|
title="Editar laudo para este paciente"
|
||||||
|
>
|
||||||
|
<Edit className="w-4 h-4" />
|
||||||
|
Editar Laudo
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
@ -1971,6 +2032,17 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
isNewLaudo={true}
|
isNewLaudo={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Editor para Paciente Específico */}
|
||||||
|
{isEditingForPatient && selectedPatientForLaudo && (
|
||||||
|
<LaudoEditor
|
||||||
|
pacientes={[selectedPatientForLaudo.paciente || selectedPatientForLaudo]}
|
||||||
|
laudo={selectedPatientForLaudo.conteudo ? selectedPatientForLaudo : null}
|
||||||
|
onClose={onClosePatientEditor || (() => {})}
|
||||||
|
isNewLaudo={!selectedPatientForLaudo.conteudo}
|
||||||
|
preSelectedPatient={selectedPatientForLaudo.paciente || selectedPatientForLaudo}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2069,17 +2141,17 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Editor de Laudo Avançado (para novos laudos)
|
// Editor de Laudo Avançado (para novos laudos)
|
||||||
function LaudoEditor({ pacientes, laudo, onClose, isNewLaudo }: { pacientes?: any[]; laudo?: any; onClose: () => void; isNewLaudo?: boolean }) {
|
function LaudoEditor({ pacientes, laudo, onClose, isNewLaudo, preSelectedPatient }: { pacientes?: any[]; laudo?: any; onClose: () => void; isNewLaudo?: boolean; preSelectedPatient?: any }) {
|
||||||
const [activeTab, setActiveTab] = useState("editor");
|
const [activeTab, setActiveTab] = useState("editor");
|
||||||
const [content, setContent] = useState("");
|
const [content, setContent] = useState(laudo?.conteudo || "");
|
||||||
const [showPreview, setShowPreview] = useState(false);
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
const [pacienteSelecionado, setPacienteSelecionado] = useState<any>(null);
|
const [pacienteSelecionado, setPacienteSelecionado] = useState<any>(preSelectedPatient || null);
|
||||||
const [campos, setCampos] = useState({
|
const [campos, setCampos] = useState({
|
||||||
cid: "",
|
cid: laudo?.cid || "",
|
||||||
diagnostico: "",
|
diagnostico: laudo?.diagnostico || "",
|
||||||
conclusao: "",
|
conclusao: laudo?.conclusao || "",
|
||||||
exame: "",
|
exame: laudo?.exame || "",
|
||||||
especialidade: "",
|
especialidade: laudo?.especialidade || "",
|
||||||
mostrarData: true,
|
mostrarData: true,
|
||||||
mostrarAssinatura: true
|
mostrarAssinatura: true
|
||||||
});
|
});
|
||||||
@ -2095,6 +2167,23 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
|
|
||||||
const sigCanvasRef = useRef<any>(null);
|
const sigCanvasRef = useRef<any>(null);
|
||||||
|
|
||||||
|
// Carregar dados do laudo existente quando disponível
|
||||||
|
useEffect(() => {
|
||||||
|
if (laudo && !isNewLaudo) {
|
||||||
|
setContent(laudo.conteudo || "");
|
||||||
|
setCampos({
|
||||||
|
cid: laudo.cid || "",
|
||||||
|
diagnostico: laudo.diagnostico || "",
|
||||||
|
conclusao: laudo.conclusao || "",
|
||||||
|
exame: laudo.exame || "",
|
||||||
|
especialidade: laudo.especialidade || "",
|
||||||
|
mostrarData: true,
|
||||||
|
mostrarAssinatura: true
|
||||||
|
});
|
||||||
|
setPacienteSelecionado(laudo.paciente);
|
||||||
|
}
|
||||||
|
}, [laudo, isNewLaudo]);
|
||||||
|
|
||||||
const formatText = (type: string) => {
|
const formatText = (type: string) => {
|
||||||
const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
|
const textarea = document.querySelector('textarea') as HTMLTextAreaElement;
|
||||||
if (!textarea) return;
|
if (!textarea) return;
|
||||||
@ -2124,12 +2213,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
};
|
};
|
||||||
|
|
||||||
const insertTemplate = (template: string) => {
|
const insertTemplate = (template: string) => {
|
||||||
setContent(prev => prev ? `${prev}\n\n${template}` : template);
|
setContent((prev: string) => prev ? `${prev}\n\n${template}` : template);
|
||||||
};
|
|
||||||
|
|
||||||
const insertCampo = (campo: string) => {
|
|
||||||
const placeholder = `{{${campo}}}`;
|
|
||||||
setContent(prev => prev ? `${prev} ${placeholder}` : placeholder);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const handleImageUpload = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
@ -2149,15 +2233,11 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
};
|
};
|
||||||
|
|
||||||
const processContent = (content: string) => {
|
const processContent = (content: string) => {
|
||||||
const paciente = isNewLaudo ? pacienteSelecionado : laudo?.paciente;
|
|
||||||
return content
|
return content
|
||||||
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||||||
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
.replace(/\*(.*?)\*/g, '<em>$1</em>')
|
||||||
.replace(/<u>(.*?)<\/u>/g, '<u>$1</u>')
|
.replace(/<u>(.*?)<\/u>/g, '<u>$1</u>')
|
||||||
.replace(/{{nome_paciente}}/g, paciente?.nome || '[NOME_PACIENTE]')
|
.replace(/{{sexo_paciente}}/g, pacienteSelecionado?.sexo || laudo?.paciente?.sexo || '[SEXO]')
|
||||||
.replace(/{{idade_paciente}}/g, paciente?.idade?.toString() || '[IDADE]')
|
|
||||||
.replace(/{{sexo_paciente}}/g, paciente?.sexo || '[SEXO]')
|
|
||||||
.replace(/{{cid}}/g, campos.cid || '[CID]')
|
|
||||||
.replace(/{{diagnostico}}/g, campos.diagnostico || '[DIAGNÓSTICO]')
|
.replace(/{{diagnostico}}/g, campos.diagnostico || '[DIAGNÓSTICO]')
|
||||||
.replace(/{{conclusao}}/g, campos.conclusao || '[CONCLUSÃO]')
|
.replace(/{{conclusao}}/g, campos.conclusao || '[CONCLUSÃO]')
|
||||||
.replace(/\n/g, '<br>');
|
.replace(/\n/g, '<br>');
|
||||||
@ -2171,7 +2251,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
<div className="flex items-center justify-between p-4">
|
<div className="flex items-center justify-between p-4">
|
||||||
<div>
|
<div>
|
||||||
<h2 className="text-xl font-bold text-foreground">
|
<h2 className="text-xl font-bold text-foreground">
|
||||||
{isNewLaudo ? "Novo Laudo Médico" : "Editor de Laudo"}
|
{isNewLaudo ? "Novo Laudo Médico" : "Editar Laudo Existente"}
|
||||||
</h2>
|
</h2>
|
||||||
{isNewLaudo ? (
|
{isNewLaudo ? (
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
@ -2179,7 +2259,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-muted-foreground">
|
<p className="text-sm text-muted-foreground">
|
||||||
Paciente: {laudo?.paciente?.nome} | Pedido: {laudo?.id}
|
Paciente: {laudo?.paciente?.nome} | Pedido: {laudo?.id} | {laudo?.especialidade}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -2220,6 +2300,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
CPF: {pacienteSelecionado.cpf} | Idade: {pacienteSelecionado.idade} anos | Sexo: {pacienteSelecionado.sexo}
|
CPF: {pacienteSelecionado.cpf} | Idade: {pacienteSelecionado.idade} anos | Sexo: {pacienteSelecionado.sexo}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{!preSelectedPatient && (
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
@ -2227,6 +2308,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
>
|
>
|
||||||
Trocar Paciente
|
Trocar Paciente
|
||||||
</Button>
|
</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
@ -2412,32 +2494,6 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
•
|
•
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="h-6 w-px bg-border mx-1"></div>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => insertCampo("nome_paciente")}
|
|
||||||
title="Nome do Paciente"
|
|
||||||
>
|
|
||||||
Nome
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => insertCampo("idade_paciente")}
|
|
||||||
title="Idade do Paciente"
|
|
||||||
>
|
|
||||||
Idade
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="outline"
|
|
||||||
size="sm"
|
|
||||||
onClick={() => insertCampo("cid")}
|
|
||||||
title="CID"
|
|
||||||
>
|
|
||||||
CID
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Templates */}
|
{/* Templates */}
|
||||||
@ -2699,7 +2755,7 @@ Nevo melanocítico benigno. Seguimento clínico recomendado.
|
|||||||
Salvar Rascunho
|
Salvar Rascunho
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="default">
|
<Button variant="default">
|
||||||
Liberar Laudo
|
{isNewLaudo ? "Liberar Laudo" : "Atualizar Laudo"}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user