diff --git a/susconecta/app/profissional/page.tsx b/susconecta/app/profissional/page.tsx index a2bbc4e..dffa3ac 100644 --- a/susconecta/app/profissional/page.tsx +++ b/susconecta/app/profissional/page.tsx @@ -5,7 +5,9 @@ import SignatureCanvas from "react-signature-canvas"; import Link from "next/link"; import ProtectedRoute from "@/components/ProtectedRoute"; import { useAuth } from "@/hooks/useAuth"; -import { buscarPacientes } from "@/lib/api"; +import { buscarPacientes, listarPacientes, buscarPacientePorId, type Paciente } from "@/lib/api"; +import { useReports } from "@/hooks/useReports"; +import { CreateReportData, ReportFormData } from "@/types/report"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; @@ -108,11 +110,20 @@ const ProfissionalPage = () => { prognostico: "", tratamentosRealizados: "", recomendacoes: "", + cid: "", dataRelatorio: new Date().toISOString().split('T')[0] }); const [relatoriosMedicos, setRelatoriosMedicos] = useState([]); const [editandoRelatorio, setEditandoRelatorio] = useState(null); + // Estados para integração com API de Relatórios + const [pacientesReais, setPacientesReais] = useState([]); + const [carregandoPacientes, setCarregandoPacientes] = useState(false); + const [pacienteSelecionadoReport, setPacienteSelecionadoReport] = useState(null); + + // Hook personalizado para relatórios + const reportsApi = useReports(); + // Estados para funcionalidades do prontuário const [consultasRegistradas, setConsultasRegistradas] = useState([]); const [historicoMedico, setHistoricoMedico] = useState([]); @@ -306,6 +317,7 @@ const ProfissionalPage = () => { prognostico: "", tratamentosRealizados: "", recomendacoes: "", + cid: "", dataRelatorio: new Date().toISOString().split('T')[0] }); }; @@ -339,10 +351,271 @@ const ProfissionalPage = () => { prognostico: "", tratamentosRealizados: "", recomendacoes: "", + cid: "", dataRelatorio: new Date().toISOString().split('T')[0] }); }; + // ===== FUNÇÕES PARA INTEGRAÇÃO COM API DE RELATÓRIOS ===== + + // Carregar pacientes reais do Supabase + const carregarPacientesReais = async () => { + setCarregandoPacientes(true); + try { + console.log('📋 [REPORTS] Carregando pacientes do Supabase...'); + + // Tentar primeiro usando a função da API que já existe + try { + console.log('📋 [REPORTS] Tentando função listarPacientes...'); + const pacientes = await listarPacientes({ limit: 50 }); + console.log('✅ [REPORTS] Pacientes do Supabase via API:', pacientes); + + if (pacientes && pacientes.length > 0) { + setPacientesReais(pacientes); + console.log('✅ [REPORTS] Usando pacientes do Supabase:', pacientes.length); + return; + } + } catch (apiError) { + console.warn('⚠️ [REPORTS] Erro na função listarPacientes:', apiError); + } + + // Se a função da API falhar, tentar diretamente + console.log('📋 [REPORTS] Tentando buscar diretamente do Supabase...'); + const supabaseUrl = 'https://yuanqfswhberkoevtmfr.supabase.co/rest/v1/patients'; + console.log('📋 [REPORTS] URL do Supabase:', supabaseUrl); + + // Verificar se há token de autenticação + const token = localStorage.getItem("auth_token") || localStorage.getItem("token") || + sessionStorage.getItem("auth_token") || sessionStorage.getItem("token"); + + console.log('🔑 [REPORTS] Token encontrado:', token ? 'SIM' : 'NÃO'); + + const headers: Record = { + 'apikey': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inl1YW5xZnN3aGJlcmtvZXZ0bWZyIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQ5NTQzNjksImV4cCI6MjA3MDUzMDM2OX0.g8Fm4XAvtX46zifBZnYVH4tVuQkqUH6Ia9CXQj4DztQ', + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }; + + if (token) { + headers['Authorization'] = `Bearer ${token}`; + } + + const response = await fetch(supabaseUrl, { + method: 'GET', + headers + }); + + console.log('📡 [REPORTS] Status da resposta do Supabase:', response.status, response.statusText); + + if (!response.ok) { + const errorText = await response.text(); + console.error('❌ [REPORTS] Erro detalhado do Supabase:', errorText); + throw new Error(`Supabase HTTP ${response.status}: ${response.statusText} - ${errorText}`); + } + + const data = await response.json(); + console.log('✅ [REPORTS] Resposta completa do Supabase:', data); + console.log('✅ [REPORTS] Tipo da resposta:', Array.isArray(data) ? 'Array' : typeof data); + + let pacientes: Paciente[] = []; + + if (Array.isArray(data)) { + pacientes = data; + } else if (data.data && Array.isArray(data.data)) { + pacientes = data.data; + } else { + console.warn('⚠️ [REPORTS] Formato de resposta inesperado do Supabase:', data); + pacientes = []; + } + + console.log('✅ [REPORTS] Pacientes encontrados no Supabase:', pacientes.length); + if (pacientes.length > 0) { + console.log('✅ [REPORTS] Primeiro paciente:', pacientes[0]); + console.log('✅ [REPORTS] Últimos 3 pacientes:', pacientes.slice(-3)); + } + + setPacientesReais(pacientes); + + if (pacientes.length === 0) { + console.warn('⚠️ [REPORTS] Nenhum paciente encontrado no Supabase - verifique se há dados na tabela patients'); + } + } catch (error) { + console.error('❌ [REPORTS] Erro detalhado ao carregar pacientes:', { + error, + message: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + + setPacientesReais([]); + alert('Erro ao carregar pacientes do Supabase: ' + (error instanceof Error ? error.message : String(error))); + } finally { + setCarregandoPacientes(false); + } + }; + + // Calcular idade do paciente baseado na data de nascimento + const calcularIdade = (birthDate: string | null | undefined): string => { + if (!birthDate) return ''; + + const hoje = new Date(); + const nascimento = new Date(birthDate); + let idade = hoje.getFullYear() - nascimento.getFullYear(); + const mesAtual = hoje.getMonth(); + const mesNascimento = nascimento.getMonth(); + + if (mesAtual < mesNascimento || (mesAtual === mesNascimento && hoje.getDate() < nascimento.getDate())) { + idade--; + } + + return idade.toString(); + }; + + // Selecionar paciente para o relatório + const selecionarPacienteParaRelatorio = (paciente: Paciente) => { + setPacienteSelecionadoReport(paciente); + + // Atualizar o formulário de relatório com dados do paciente + setRelatorioMedico(prev => ({ + ...prev, + pacienteNome: paciente.full_name, + pacienteCpf: paciente.cpf || '', + pacienteIdade: calcularIdade(paciente.birth_date), + })); + + console.log('👤 [REPORTS] Paciente selecionado:', paciente); + }; + + // Salvar relatório usando a API + const salvarRelatorioAPI = async () => { + if (!pacienteSelecionadoReport) { + alert('Por favor, selecione um paciente.'); + return; + } + + if (!relatorioMedico.motivoRelatorio.trim()) { + alert('Por favor, preencha o motivo do relatório.'); + return; + } + + try { + console.log('💾 [REPORTS] Salvando relatório...'); + + // Dados para enviar à API + const reportData: CreateReportData = { + patient_id: pacienteSelecionadoReport.id, + doctor_id: user?.id || 'temp-doctor-id', // Usar ID do usuário logado + report_type: 'Relatório Médico', + chief_complaint: relatorioMedico.motivoRelatorio, + clinical_history: relatorioMedico.historicoClinico, + symptoms_and_signs: relatorioMedico.sinaisSintomas, + physical_examination: '', // Pode adicionar campo no formulário se necessário + complementary_exams: relatorioMedico.examesRealizados, + exam_results: relatorioMedico.resultadosExames, + diagnosis: relatorioMedico.diagnosticos, + prognosis: relatorioMedico.prognostico, + treatment_performed: relatorioMedico.tratamentosRealizados, + objective_recommendations: relatorioMedico.recomendacoes || '', + icd_code: relatorioMedico.cid, + report_date: relatorioMedico.dataRelatorio, + }; + + const novoRelatorio = await reportsApi.createNewReport(reportData); + + console.log('✅ [REPORTS] Relatório salvo com sucesso:', novoRelatorio); + + // Recarregar a lista de relatórios para garantir que está sincronizada + await reportsApi.loadReports(); + + alert('Relatório médico salvo com sucesso!'); + + // Limpar formulário + limparFormularioRelatorio(); + + } catch (error) { + console.error('❌ [REPORTS] Erro ao salvar relatório:', error); + alert('Erro ao salvar relatório: ' + error); + } + }; + + // Limpar formulário de relatório + const limparFormularioRelatorio = () => { + setRelatorioMedico({ + pacienteNome: "", + pacienteCpf: "", + pacienteIdade: "", + profissionalNome: medico.nome, + profissionalCrm: medico.identificacao, + motivoRelatorio: "", + historicoClinico: "", + sinaisSintomas: "", + examesRealizados: "", + resultadosExames: "", + diagnosticos: "", + prognostico: "", + tratamentosRealizados: "", + recomendacoes: "", + cid: "", + dataRelatorio: new Date().toISOString().split('T')[0] + }); + setPacienteSelecionadoReport(null); + }; + + // Carregar relatórios existentes + const carregarRelatorios = async () => { + try { + await reportsApi.loadReports(); + console.log('✅ [REPORTS] Relatórios carregados:', reportsApi.reports.length); + } catch (error) { + console.error('❌ [REPORTS] Erro ao carregar relatórios:', error); + } + }; + + + // useEffect para carregar dados iniciais + useEffect(() => { + if (activeSection === 'relatorios-medicos') { + console.log('🔄 [REPORTS] Seção de relatórios ativada - carregando dados...'); + carregarPacientesReais(); + carregarRelatorios(); + } + }, [activeSection]); + + // Buscar pacientes faltantes por patient_id após carregar relatórios e pacientes + useEffect(() => { + if (activeSection !== 'relatorios-medicos') return; + if (!reportsApi.reports || reportsApi.reports.length === 0) return; + + // IDs de pacientes já carregados + const idsPacientesReais = new Set(pacientesReais.map(p => String(p.id))); + // IDs de pacientes presentes nos relatórios + const idsRelatorios = Array.from(new Set(reportsApi.reports.map(r => String(r.patient_id)).filter(Boolean))); + // IDs que faltam + const idsFaltantes = idsRelatorios.filter(id => !idsPacientesReais.has(id)); + + if (idsFaltantes.length === 0) return; + + // Buscar pacientes faltantes individualmente, apenas se o ID for string/UUID + (async () => { + const novosPacientes: Paciente[] = []; + for (const id of idsFaltantes) { + // Só busca se for string e não for número + if (typeof id === 'string' && isNaN(Number(id))) { + try { + const paciente = await buscarPacientePorId(id); + if (paciente) novosPacientes.push(paciente); + } catch (e) { + console.warn('⚠️ [REPORTS] Paciente não encontrado para o relatório:', id); + } + } else { + console.warn('⚠️ [REPORTS] Ignorando busca de paciente por ID não-string/UUID:', id); + } + } + if (novosPacientes.length > 0) { + setPacientesReais(prev => ([...prev, ...novosPacientes])); + } + })(); + }, [activeSection, reportsApi.reports, pacientesReais]); + const handleDateClick = (arg: any) => { setSelectedDate(arg.dateStr); @@ -2883,32 +3156,54 @@ Nevo melanocítico benigno. Seguimento clínico recomendado. - {/* Identificação do Paciente */} + {/* Identificação do Paciente - USANDO API REAL */}
-

Identificação do Paciente

+
+

Identificação do Paciente

+ +
@@ -2917,27 +3212,50 @@ Nevo melanocítico benigno. Seguimento clínico recomendado. handleRelatorioChange('pacienteCpf', e.target.value)} - placeholder="000.000.000-00" + disabled + className="bg-muted" + placeholder="CPF será preenchido automaticamente" />
handleRelatorioChange('pacienteIdade', e.target.value)} - placeholder="Idade do paciente" + disabled + className="bg-muted" + placeholder="Idade será calculada automaticamente" />
+ + {/* Informações adicionais do paciente selecionado */} + {pacienteSelecionadoReport && ( +
+
Informações do Paciente Selecionado:
+
+
+ Nome Completo:
+ {pacienteSelecionadoReport.full_name} +
+
+ Email:
+ {pacienteSelecionadoReport.email || 'Não informado'} +
+
+ Telefone:
+ {pacienteSelecionadoReport.phone_mobile || 'Não informado'} +
+
+
+ )} {/* Informações do Relatório */}

Informações do Relatório

-
+