"use client"; import React, { useState, useRef, useEffect } from "react"; import SignatureCanvas from "react-signature-canvas"; import Link from "next/link"; import ProtectedRoute from "@/components/ProtectedRoute"; import { useAuth } from "@/hooks/useAuth"; import { buscarPacientes, listarPacientes, buscarPacientePorId, type Paciente } from "@/lib/api"; import { useReports } from "@/hooks/useReports"; import { CreateReportData } from "@/types/report-types"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { SimpleThemeToggle } from "@/components/simple-theme-toggle"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar" import { User, FolderOpen, X, Users, MessageSquare, ClipboardList, Plus, Edit, Trash2, ChevronLeft, ChevronRight, Clock, FileCheck, Upload, Download, Eye, History, Stethoscope, Pill, Activity, Search } from "lucide-react" import { Calendar as CalendarIcon, FileText, Settings } from "lucide-react"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip"; import dynamic from "next/dynamic"; import dayGridPlugin from "@fullcalendar/daygrid"; import timeGridPlugin from "@fullcalendar/timegrid"; import interactionPlugin from "@fullcalendar/interaction"; import ptBrLocale from "@fullcalendar/core/locales/pt-br"; const FullCalendar = dynamic(() => import("@fullcalendar/react"), { ssr: false, }); const pacientes = [ { nome: "Ana Souza", cpf: "123.456.789-00", idade: 42, statusLaudo: "Finalizado" }, { nome: "Bruno Lima", cpf: "987.654.321-00", idade: 33, statusLaudo: "Pendente" }, { nome: "Carla Menezes", cpf: "111.222.333-44", idade: 67, statusLaudo: "Rascunho" }, ]; const medico = { nome: "Dr. Carlos Andrade", identificacao: "CRM 000000 • Cardiologia e Dermatologia", fotoUrl: "", } const colorsByType = { Rotina: "#4dabf7", Cardiologia: "#f76c6c", Otorrino: "#f7b84d", Pediatria: "#6cf78b", Dermatologia: "#9b59b6", Oftalmologia: "#2ecc71" }; // Helpers para normalizar dados de paciente (suporta schema antigo e novo) const getPatientName = (p: any) => p?.full_name ?? p?.nome ?? ''; const getPatientCpf = (p: any) => p?.cpf ?? ''; const getPatientSex = (p: any) => p?.sex ?? p?.sexo ?? ''; const getPatientId = (p: any) => p?.id ?? ''; const getPatientAge = (p: any) => { if (!p) return ''; // Prefer birth_date (ISO) to calcular idade const bd = p?.birth_date ?? p?.data_nascimento ?? p?.birthDate; if (bd) { const d = new Date(bd); if (!isNaN(d.getTime())) { const age = Math.floor((Date.now() - d.getTime()) / (1000 * 60 * 60 * 24 * 365.25)); return `${age}`; } } // Fallback para campo idade/idade_anterior return p?.idade ?? p?.age ?? ''; }; const ProfissionalPage = () => { const { logout, user } = useAuth(); const [activeSection, setActiveSection] = useState('calendario'); const [pacienteSelecionado, setPacienteSelecionado] = useState(null); // Estados para edição de laudo const [isEditingLaudoForPatient, setIsEditingLaudoForPatient] = useState(false); const [patientForLaudo, setPatientForLaudo] = useState(null); // Estados para o perfil do médico const [isEditingProfile, setIsEditingProfile] = useState(false); const [profileData, setProfileData] = useState({ nome: "Dr. Carlos Andrade", email: user?.email || "carlos.andrade@hospital.com", telefone: "(11) 99999-9999", endereco: "Rua das Flores, 123 - Centro", cidade: "São Paulo", cep: "01234-567", crm: "CRM 000000", especialidade: "Cardiologia e Dermatologia", biografia: "Médico especialista em cardiologia e dermatologia com mais de 15 anos de experiência em tratamentos clínicos e cirúrgicos." }); // Estados para campos principais da consulta const [consultaAtual, setConsultaAtual] = useState({ patient_id: "", order_number: "", exam: "", diagnosis: "", conclusion: "", cid_code: "", content_html: "", content_json: {}, status: "draft", requested_by: "", due_at: new Date().toISOString(), hide_date: true, hide_signature: true }); const [events, setEvents] = useState([ { id: 1, title: "Ana Souza", type: "Cardiologia", time: "09:00", date: new Date().toISOString().split('T')[0], pacienteId: "123.456.789-00", color: colorsByType.Cardiologia }, { id: 2, title: "Bruno Lima", type: "Cardiologia", time: "10:30", date: new Date().toISOString().split('T')[0], pacienteId: "987.654.321-00", color: colorsByType.Cardiologia }, { id: 3, title: "Carla Menezes", type: "Dermatologia", time: "14:00", date: new Date().toISOString().split('T')[0], pacienteId: "111.222.333-44", color: colorsByType.Dermatologia } ]); const [editingEvent, setEditingEvent] = useState(null); const [showPopup, setShowPopup] = useState(false); const [showActionModal, setShowActionModal] = useState(false); const [step, setStep] = useState(1); const [newEvent, setNewEvent] = useState({ title: "", type: "", time: "", pacienteId: "" }); const [selectedDate, setSelectedDate] = useState(null); const [selectedEvent, setSelectedEvent] = useState(null); const [currentCalendarDate, setCurrentCalendarDate] = useState(new Date()); const handleSave = (event: React.MouseEvent) => { event.preventDefault(); console.log("Laudo salvo!"); window.scrollTo({ top: 0, behavior: "smooth" }); }; const handleEditarLaudo = (paciente: any) => { setPatientForLaudo(paciente); setIsEditingLaudoForPatient(true); setActiveSection('laudos'); }; const navigateDate = (direction: 'prev' | 'next') => { const newDate = new Date(currentCalendarDate); newDate.setDate(newDate.getDate() + (direction === 'next' ? 1 : -1)); setCurrentCalendarDate(newDate); }; const goToToday = () => { setCurrentCalendarDate(new Date()); }; const formatDate = (date: Date) => { return date.toLocaleDateString('pt-BR', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' }); }; // Filtrar eventos do dia atual const getTodayEvents = () => { const today = currentCalendarDate.toISOString().split('T')[0]; return events .filter(event => event.date === today) .sort((a, b) => a.time.localeCompare(b.time)); }; const getStatusColor = (type: string) => { return colorsByType[type as keyof typeof colorsByType] || "#4dabf7"; }; // Funções para o perfil const handleProfileChange = (field: string, value: string) => { setProfileData(prev => ({ ...prev, [field]: value })); }; const handleSaveProfile = () => { setIsEditingProfile(false); alert('Perfil atualizado com sucesso!'); }; const handleCancelEdit = () => { setIsEditingProfile(false); }; const handleDateClick = (arg: any) => { setSelectedDate(arg.dateStr); setNewEvent({ title: "", type: "", time: "", pacienteId: "" }); setStep(1); setEditingEvent(null); setShowPopup(true); }; const handleAddEvent = () => { const paciente = pacientes.find(p => p.nome === newEvent.title); const eventToAdd = { id: Date.now(), title: newEvent.title, type: newEvent.type, time: newEvent.time, date: selectedDate || currentCalendarDate.toISOString().split('T')[0], pacienteId: paciente ? paciente.cpf : "", color: colorsByType[newEvent.type as keyof typeof colorsByType] || "#4dabf7" }; setEvents((prev) => [...prev, eventToAdd]); setShowPopup(false); }; const handleEditEvent = () => { setEvents((prevEvents) => prevEvents.map((ev) => ev.id.toString() === editingEvent.id.toString() ? { ...ev, title: newEvent.title, type: newEvent.type, time: newEvent.time, color: colorsByType[newEvent.type as keyof typeof colorsByType] || "#4dabf7" } : ev ) ); setEditingEvent(null); setShowPopup(false); setShowActionModal(false); }; const handleNextStep = () => { if (step < 3) setStep(step + 1); else editingEvent ? handleEditEvent() : handleAddEvent(); }; const handleEventClick = (clickInfo: any) => { setSelectedEvent(clickInfo.event); setShowActionModal(true); }; const handleDeleteEvent = () => { if (!selectedEvent) return; setEvents((prevEvents) => prevEvents.filter((ev: any) => ev.id.toString() !== selectedEvent.id.toString()) ); setShowActionModal(false); }; const handleStartEdit = () => { if (!selectedEvent) return; setEditingEvent(selectedEvent); setNewEvent({ title: selectedEvent.title, type: selectedEvent.extendedProps.type, time: selectedEvent.extendedProps.time, pacienteId: selectedEvent.extendedProps.pacienteId || "" }); setStep(1); setShowActionModal(false); setShowPopup(true); }; const renderEventContent = (eventInfo: any) => { const bg = eventInfo.event.backgroundColor || eventInfo.event.extendedProps?.color || "#4dabf7"; return (
{eventInfo.event.title} {eventInfo.event.extendedProps.type} {eventInfo.event.extendedProps.time}
); }; const renderCalendarioSection = () => { const todayEvents = getTodayEvents(); return (

Agenda do Dia

{/* Navegação de Data */}

{formatDate(currentCalendarDate)}

{todayEvents.length} consulta{todayEvents.length !== 1 ? 's' : ''} agendada{todayEvents.length !== 1 ? 's' : ''}
{/* Lista de Pacientes do Dia */}
{todayEvents.length === 0 ? (

Nenhuma consulta agendada para este dia

Agenda livre para este dia

) : ( todayEvents.map((appointment) => { const paciente = pacientes.find(p => p.nome === appointment.title); return (
{appointment.title}
{paciente && (
CPF: {getPatientCpf(paciente)} • {getPatientAge(paciente)} anos
)}
{appointment.time}
{appointment.type}
Ver informações do paciente
); }) )}
); }; const renderLaudosSection = () => (
{ setIsEditingLaudoForPatient(false); setPatientForLaudo(null); }} />
); // --- NOVO SISTEMA DE LAUDOS COMPLETO --- function LaudoManager({ isEditingForPatient, selectedPatientForLaudo, onClosePatientEditor }: { isEditingForPatient?: boolean; selectedPatientForLaudo?: any; onClosePatientEditor?: () => void }) { const [pacientesDisponiveis] = useState([ { 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: "92953542", nome: "Carla Menezes", cpf: "111.222.333-44", idade: 67, sexo: "Feminino" }, ]); const [laudos] = useState([ { id: "306494942", data: "29/07/2025", prazo: "29/07/2025", paciente: { id: "95170038", nome: "Ana Souza", cpf: "123.456.789-00", idade: 42, sexo: "Feminino" }, executante: "Carlos Andrade", exame: "Ecocardiograma", status: "Entregue", urgente: true, especialidade: "Cardiologia", conteudo: `**ECOCARDIOGRAMA TRANSTORÁCICO** **Dados do Paciente:** Nome: Ana Souza Idade: 42 anos Sexo: Feminino **Indicação Clínica:** Investigação de sopro cardíaco **Técnica:** Ecocardiograma transtorácico bidimensional com Doppler colorido e espectral. **Resultados:** - Átrio esquerdo: dimensões normais - Ventrículo esquerdo: função sistólica preservada, FEVE = 65% - Valvas cardíacas: sem alterações significativas - Pericárdio: sem derrame **Conclusão:** Exame ecocardiográfico dentro dos limites da normalidade. **CID:** I25.9`, cid: "I25.9", diagnostico: "Exame ecocardiográfico normal", conclusao: "Função cardíaca preservada, sem alterações estruturais significativas." }, { id: "306463987", data: "29/07/2025", prazo: "29/07/2025", paciente: { id: "93203056", nome: "Bruno Lima", cpf: "987.654.321-00", idade: 33, sexo: "Masculino" }, executante: "Carlos Andrade", exame: "Eletrocardiograma", status: "Entregue", urgente: true, especialidade: "Cardiologia", conteudo: `**ELETROCARDIOGRAMA DE REPOUSO** **Dados do Paciente:** Nome: Bruno Lima Idade: 33 anos Sexo: Masculino **Indicação Clínica:** Dor precordial atípica **Técnica:** Eletrocardiograma de 12 derivações em repouso. **Resultados:** - Ritmo: sinusal regular - Frequência cardíaca: 72 bpm - Eixo elétrico: normal - Intervalos PR, QRS e QT: dentro dos limites normais - Ondas Q patológicas: ausentes - Alterações de ST-T: não observadas **Conclusão:** Eletrocardiograma normal. **CID:** Z01.8`, cid: "Z01.8", diagnostico: "ECG normal", conclusao: "Traçado eletrocardiográfico dentro dos parâmetros de normalidade." }, { id: "306452545", data: "29/07/2025", prazo: "29/07/2025", paciente: { id: "92953542", nome: "Carla Menezes", cpf: "111.222.333-44", idade: 67, sexo: "Feminino" }, executante: "Carlos Andrade", exame: "Dermatoscopia", status: "Entregue", urgente: true, especialidade: "Dermatologia", conteudo: `**DERMATOSCOPIA DIGITAL** **Dados do Paciente:** Nome: Carla Menezes Idade: 67 anos Sexo: Feminino **Indicação Clínica:** Avaliação de lesão pigmentada em dorso **Técnica:** Dermatoscopia digital com magnificação de 10x e 20x. **Localização:** Região dorsal, região escapular direita **Achados Dermatoscópicos:** - Lesão melanocítica benigna - Padrão reticular típico - Bordas regulares e simétricas - Pigmentação homogênea - Ausência de estruturas atípicas **Conclusão:** Nevo melanocítico benigno. Seguimento clínico recomendado. **CID:** D22.5`, cid: "D22.5", diagnostico: "Nevo melanocítico benigno", conclusao: "Lesão benigna, recomenda-se acompanhamento dermatológico de rotina." }, ]); const [activeTab, setActiveTab] = useState("entregue"); const [laudoSelecionado, setLaudoSelecionado] = useState(null); const [isViewing, setIsViewing] = useState(false); const [isCreatingNew, setIsCreatingNew] = useState(false); return (
{/* Header */}

Gerenciamento de Laudo

Nesta seção você pode gerenciar todos os laudos gerados através da integração.

{/* Tabs */}
{/* Filtros */}
01/07/2025 - 31/07/2025
{/* Tabela */}
Pedido Data Prazo Paciente Executante/Solicitante Exame/Classificação Ação {laudos.map((laudo) => (
{laudo.urgente && (
)} {laudo.id}
{laudo.data}
11:48
{laudo.prazo}
11:48
{laudo.paciente.id}
{laudo.paciente.nome}
{laudo.executante} {laudo.exame || "-"}
))}
{/* Visualizador de Laudo */} {isViewing && laudoSelecionado && ( setIsViewing(false)} /> )} {/* Editor para Novo Laudo */} {isCreatingNew && ( setIsCreatingNew(false)} isNewLaudo={true} /> )} {/* Editor para Paciente Específico */} {isEditingForPatient && selectedPatientForLaudo && ( {})} isNewLaudo={!selectedPatientForLaudo.conteudo} preSelectedPatient={selectedPatientForLaudo.paciente || selectedPatientForLaudo} /> )}
); } // Visualizador de Laudo (somente leitura) function LaudoViewer({ laudo, onClose }: { laudo: any; onClose: () => void }) { return (
{/* Header */}

Visualizar Laudo

Paciente: {laudo.paciente.nome} | Pedido: {laudo.id} | {laudo.especialidade}

{/* Content */}
{/* Header do Laudo */}

LAUDO MÉDICO - {laudo.especialidade.toUpperCase()}

Data: {laudo.data}

{/* Dados do Paciente */}

Dados do Paciente:

Nome: {getPatientName(laudo.paciente)}

ID: {getPatientId(laudo.paciente)}

CPF: {getPatientCpf(laudo.paciente)}

Idade: {getPatientAge(laudo.paciente)} anos

Sexo: {getPatientSex(laudo.paciente)}

CID: {laudo.cid}

{/* Conteúdo do Laudo */}
') }} />
{/* Diagnóstico e Conclusão */} {laudo.diagnostico && (

Diagnóstico:

{laudo.diagnostico}

)} {laudo.conclusao && (

Conclusão:

{laudo.conclusao}

)} {/* Assinatura */}

Dr. Carlos Andrade

CRM 000000 - {laudo.especialidade}

Data: {laudo.data}

{/* Footer */}
Status: {laudo.status} | Executante: {laudo.executante}
); } // Editor de Laudo Avançado (para novos laudos) function LaudoEditor({ pacientes, laudo, onClose, isNewLaudo, preSelectedPatient }: { pacientes?: any[]; laudo?: any; onClose: () => void; isNewLaudo?: boolean; preSelectedPatient?: any }) { // Import useToast at the top level of the component const { toast } = require('@/hooks/use-toast').useToast(); const [activeTab, setActiveTab] = useState("editor"); const [content, setContent] = useState(laudo?.conteudo || ""); const [showPreview, setShowPreview] = useState(false); const [pacienteSelecionado, setPacienteSelecionado] = useState(preSelectedPatient || null); const [listaPacientes, setListaPacientes] = useState([]); // Pega token do usuário logado (passado explicitamente para listarPacientes) const { token } = useAuth(); // Carregar pacientes reais do Supabase ao abrir o modal ou quando o token mudar useEffect(() => { async function fetchPacientes() { try { if (!token) { setListaPacientes([]); return; } const pacientes = await listarPacientes(); setListaPacientes(pacientes || []); } catch (err) { console.warn('Erro ao carregar pacientes:', err); setListaPacientes([]); } } fetchPacientes(); }, [token]); const [campos, setCampos] = useState({ cid: laudo?.cid || "", diagnostico: laudo?.diagnostico || "", conclusao: laudo?.conclusao || "", exame: laudo?.exame || "", especialidade: laudo?.especialidade || "", mostrarData: true, mostrarAssinatura: true }); const [imagens, setImagens] = useState([]); const [templates] = useState([ "Exame normal, sem alterações significativas", "Paciente em acompanhamento ambulatorial", "Recomenda-se retorno em 30 dias", "Alterações compatíveis com processo inflamatório", "Resultado dentro dos parâmetros de normalidade", "Recomendo seguimento com especialista" ]); const sigCanvasRef = useRef(null); // Estado para imagem da assinatura const [assinaturaImg, setAssinaturaImg] = useState(null); useEffect(() => { if (!sigCanvasRef.current) return; const handleEnd = () => { const url = sigCanvasRef.current.getTrimmedCanvas().toDataURL('image/png'); setAssinaturaImg(url); }; const canvas = sigCanvasRef.current; if (canvas && canvas.canvas) { canvas.canvas.addEventListener('mouseup', handleEnd); canvas.canvas.addEventListener('touchend', handleEnd); } return () => { if (canvas && canvas.canvas) { canvas.canvas.removeEventListener('mouseup', handleEnd); canvas.canvas.removeEventListener('touchend', handleEnd); } }; }, [sigCanvasRef]); const handleClearSignature = () => { if (sigCanvasRef.current) { sigCanvasRef.current.clear(); } setAssinaturaImg(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); if (laudo.assinaturaImg) { setAssinaturaImg(laudo.assinaturaImg); } } }, [laudo, isNewLaudo]); // Histórico para desfazer/refazer const [history, setHistory] = useState([]); const [historyIndex, setHistoryIndex] = useState(-1); // Atualiza histórico ao digitar useEffect(() => { if (history[historyIndex] !== content) { const newHistory = history.slice(0, historyIndex + 1); setHistory([...newHistory, content]); setHistoryIndex(newHistory.length); } // eslint-disable-next-line }, [content]); const handleUndo = () => { if (historyIndex > 0) { setContent(history[historyIndex - 1]); setHistoryIndex(historyIndex - 1); } }; const handleRedo = () => { if (historyIndex < history.length - 1) { setContent(history[historyIndex + 1]); setHistoryIndex(historyIndex + 1); } }; // Formatação avançada const formatText = (type: string, value?: any) => { const textarea = document.querySelector('textarea') as HTMLTextAreaElement; if (!textarea) return; const start = textarea.selectionStart; const end = textarea.selectionEnd; const selectedText = textarea.value.substring(start, end); let formattedText = ""; switch(type) { case "bold": formattedText = selectedText ? `**${selectedText}**` : "**texto em negrito**"; break; case "italic": formattedText = selectedText ? `*${selectedText}*` : "*texto em itálico*"; break; case "underline": formattedText = selectedText ? `__${selectedText}__` : "__texto sublinhado__"; break; case "list-ul": formattedText = selectedText ? selectedText.split('\n').map(l => `• ${l}`).join('\n') : "• item da lista"; break; case "list-ol": formattedText = selectedText ? selectedText.split('\n').map((l,i) => `${i+1}. ${l}`).join('\n') : "1. item da lista"; break; case "indent": formattedText = selectedText ? selectedText.split('\n').map(l => ` ${l}`).join('\n') : " "; break; case "outdent": formattedText = selectedText ? selectedText.split('\n').map(l => l.replace(/^\s{1,4}/, "")).join('\n') : ""; break; case "align-left": formattedText = selectedText ? `[left]${selectedText}[/left]` : "[left]Texto à esquerda[/left]"; break; case "align-center": formattedText = selectedText ? `[center]${selectedText}[/center]` : "[center]Texto centralizado[/center]"; break; case "align-right": formattedText = selectedText ? `[right]${selectedText}[/right]` : "[right]Texto à direita[/right]"; break; case "align-justify": formattedText = selectedText ? `[justify]${selectedText}[/justify]` : "[justify]Texto justificado[/justify]"; break; case "font-size": formattedText = selectedText ? `[size=${value}]${selectedText}[/size]` : `[size=${value}]Texto tamanho ${value}[/size]`; break; case "font-family": formattedText = selectedText ? `[font=${value}]${selectedText}[/font]` : `[font=${value}]${value}[/font]`; break; case "font-color": formattedText = selectedText ? `[color=${value}]${selectedText}[/color]` : `[color=${value}]${value}[/color]`; break; default: return; } const newText = textarea.value.substring(0, start) + formattedText + textarea.value.substring(end); setContent(newText); }; const insertTemplate = (template: string) => { setContent((prev: string) => prev ? `${prev}\n\n${template}` : template); }; const handleImageUpload = (e: React.ChangeEvent) => { const files = Array.from(e.target.files || []); files.forEach(file => { const reader = new FileReader(); reader.onload = (e) => { setImagens(prev => [...prev, { id: Date.now() + Math.random(), name: file.name, url: e.target?.result, type: file.type }]); }; reader.readAsDataURL(file); }); }; const processContent = (content: string) => { return content .replace(/\*\*(.*?)\*\*/g, '$1') .replace(/\*(.*?)\*/g, '$1') .replace(/__(.*?)__/g, '$1') .replace(/\[left\]([\s\S]*?)\[\/left\]/g, '
$1
') .replace(/\[center\]([\s\S]*?)\[\/center\]/g, '
$1
') .replace(/\[right\]([\s\S]*?)\[\/right\]/g, '
$1
') .replace(/\[justify\]([\s\S]*?)\[\/justify\]/g, '
$1
') .replace(/\[size=(\d+)\]([\s\S]*?)\[\/size\]/g, '$2') .replace(/\[font=([^\]]+)\]([\s\S]*?)\[\/font\]/g, '$2') .replace(/\[color=([^\]]+)\]([\s\S]*?)\[\/color\]/g, '$2') .replace(/{{sexo_paciente}}/g, pacienteSelecionado?.sexo || laudo?.paciente?.sexo || '[SEXO]') .replace(/{{diagnostico}}/g, campos.diagnostico || '[DIAGNÓSTICO]') .replace(/{{conclusao}}/g, campos.conclusao || '[CONCLUSÃO]') .replace(/\n/g, '
'); }; return (
{/* Header */}

{isNewLaudo ? "Novo Laudo Médico" : "Editar Laudo Existente"}

{isNewLaudo ? (

Crie um novo laudo selecionando um paciente

) : (

Paciente: {laudo?.paciente?.nome} | Pedido: {laudo?.id} | {laudo?.especialidade}

)}
{/* Seleção de Paciente (apenas para novos laudos) */} {isNewLaudo && (
{!pacienteSelecionado ? (
) : (
{getPatientName(pacienteSelecionado)}
{getPatientCpf(pacienteSelecionado) ? `CPF: ${getPatientCpf(pacienteSelecionado)} | ` : ''} {pacienteSelecionado?.birth_date ? `Nascimento: ${pacienteSelecionado.birth_date}` : (getPatientAge(pacienteSelecionado) ? `Idade: ${getPatientAge(pacienteSelecionado)} anos` : '')} {getPatientSex(pacienteSelecionado) ? ` | Sexo: ${getPatientSex(pacienteSelecionado)}` : ''}
{!preSelectedPatient && ( )}
)}
)}
{/* Tabs */}
{/* Informações tab removed - only Editor/Imagens/Campos/Pré-visualização remain */}
{/* Content */}
{/* Left Panel */}
{/* 'Informações' section removed to keep editor-only experience */} {activeTab === "editor" && (
{/* Toolbar */}
{/* Tamanho da fonte */} formatText('font-size', e.target.value)} className="w-14 border rounded px-1 py-0.5 text-xs mr-2" title="Tamanho da fonte" /> {/* Família da fonte */} {/* Cor da fonte */} formatText('font-color', e.target.value)} className="w-6 h-6 border rounded mr-2" title="Cor da fonte" /> {/* Alinhamento */} {/* Listas */} {/* Recuo */} {/* Desfazer/Refazer */} {/* Negrito, itálico, sublinhado */}
{/* Templates */}

Frases rápidas:

{templates.map((template, idx) => ( ))}
{/* Editor */}