From 48dc841b948acb1341eef97dd8480415a30944ff Mon Sep 17 00:00:00 2001 From: Lucas Rodrigues Date: Sat, 27 Sep 2025 14:53:24 -0300 Subject: [PATCH 1/7] =?UTF-8?q?criando=20p=C3=A1gina=20inicial=20do=20site?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/cadastro/page.tsx | 156 +++++++++++++++++++++++++ app/page.tsx | 257 ++++++++++++++++++------------------------ 2 files changed, 264 insertions(+), 149 deletions(-) create mode 100644 app/cadastro/page.tsx diff --git a/app/cadastro/page.tsx b/app/cadastro/page.tsx new file mode 100644 index 0000000..5aefa10 --- /dev/null +++ b/app/cadastro/page.tsx @@ -0,0 +1,156 @@ +import Link from "next/link" +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" +import { Calendar, Clock, User, Shield, Stethoscope, Receipt, IdCard } from "lucide-react" + +export default function HomePage() { + return ( +
+
+
+

Sistema de Consultas Médicas

+

+ Gerencie suas consultas médicas de forma simples e eficiente +

+
+ +
+ + + + Área do Paciente + Acesse sua área pessoal para agendar consultas e gerenciar seus dados + + +
+
+ + Agendar consultas +
+
+ + Ver histórico de consultas +
+
+ + Gerenciar dados pessoais +
+
+ + + +
+
+ + + + + Área da Secretária + Gerencie consultas, pacientes e agenda médica + + +
+
+ + Gerenciar consultas +
+
+ + Cadastrar pacientes +
+
+ + Controlar agenda +
+
+ + + +
+
+ + + + + Área Médica + Acesso restrito para profissionais de saúde + + +
+
+ + Gerenciar agenda +
+
+ + Ver pacientes +
+
+ + Histórico de atendimentos +
+
+ + + +
+
+ + + + + Área do Gestor + Acesso restrito para gestores e coordenadores + + +
+
+ + Relatórios gerenciais +
+
+ + Configurações do sistema +
+
+ + Gestão de usuários +
+
+ + + +
+
+ + + + + Área de Finanças + Acesso restrito para profissionais do setor financeiro + + +
+
+ + Relatórios financeiros +
+
+ + Faturamento +
+
+ + Controle de pagamentos +
+
+ + + +
+
+
+
+
+ ) +} diff --git a/app/page.tsx b/app/page.tsx index 5aefa10..2b9099e 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,156 +1,115 @@ + +"use client"; + import Link from "next/link" import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Calendar, Clock, User, Shield, Stethoscope, Receipt, IdCard } from "lucide-react" -export default function HomePage() { + +export default function InicialPage() { return ( -
-
-
-

Sistema de Consultas Médicas

-

- Gerencie suas consultas médicas de forma simples e eficiente -

-
- -
- - - - Área do Paciente - Acesse sua área pessoal para agendar consultas e gerenciar seus dados - - -
-
- - Agendar consultas -
-
- - Ver histórico de consultas -
-
- - Gerenciar dados pessoais -
-
- - - -
-
- - - - - Área da Secretária - Gerencie consultas, pacientes e agenda médica - - -
-
- - Gerenciar consultas -
-
- - Cadastrar pacientes -
-
- - Controlar agenda -
-
- - - -
-
- - - - - Área Médica - Acesso restrito para profissionais de saúde - - -
-
- - Gerenciar agenda -
-
- - Ver pacientes -
-
- - Histórico de atendimentos -
-
- - - -
-
- - - - - Área do Gestor - Acesso restrito para gestores e coordenadores - - -
-
- - Relatórios gerenciais -
-
- - Configurações do sistema -
-
- - Gestão de usuários -
-
- - - -
-
- - - - - Área de Finanças - Acesso restrito para profissionais do setor financeiro - - -
-
- - Relatórios financeiros -
-
- - Faturamento -
-
- - Controle de pagamentos -
-
- - - -
-
-
+
+ {} +
+ Horário: 08h00 - 21h00 + Email: contato@midconnecta.com
+ + {} +
+

MidConnecta

+ +
+ {} + + + + +
+
+ + {} +
+
+

Bem-vindo à Saúde Digital

+

+ Soluções Médicas
& Cuidados com a Saúde +

+

+ São mais de 25 anos de experiência em serviços médicos com qualidade e confiança. +

+
+ + +
+
+
+ Médico +
+
+ + {} +
+

Nossos Serviços

+

Serviços médicos que oferecemos

+ +
+
+

Clínica Geral

+

+ Atendimento médico geral com foco na prevenção e diagnóstico. +

+ +
+
+

Pediatria

+

+ Cuidado especializado para crianças e adolescentes. +

+ +
+
+

Exames

+

+ Exames laboratoriais e de imagem com precisão e agilidade. +

+ +
+
+
+ + {} +
+

© 2025 MidConnecta

+
- ) + ); } + From 8130ce47ecd57a4413004589527f18ccf534ce9d Mon Sep 17 00:00:00 2001 From: DaniloSts Date: Sun, 28 Sep 2025 19:24:59 -0300 Subject: [PATCH 2/7] adicionado leitura ao CRUD com a nova API --- app/secretary/pacientes/page.tsx | 96 +++++++++++++++----------------- components/secretary-layout.tsx | 4 +- services/api.mjs | 10 ++-- services/patientsApi.mjs | 2 +- 4 files changed, 53 insertions(+), 59 deletions(-) diff --git a/app/secretary/pacientes/page.tsx b/app/secretary/pacientes/page.tsx index c72bb85..29f4fef 100644 --- a/app/secretary/pacientes/page.tsx +++ b/app/secretary/pacientes/page.tsx @@ -8,6 +8,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Plus, Edit, Trash2, Eye, Calendar, Filter } from "lucide-react"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"; import SecretaryLayout from "@/components/secretary-layout"; +import { patientsService } from "@/services/patientsApi.mjs" export default function PacientesPage() { const [searchTerm, setSearchTerm] = useState(""); @@ -28,40 +29,43 @@ export default function PacientesPage() { setDetailsDialogOpen(true); setPatientDetails(null); try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}`); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const json = await res.json(); - setPatientDetails(json?.data ?? null); + const res = await patientsService.getById(patientId); + console.log(res) + setPatientDetails(res[0]); } catch (e: any) { setPatientDetails({ error: e?.message || "Erro ao buscar detalhes" }); } }; - + const fetchPacientes = useCallback( async (pageToFetch: number) => { if (isFetching || !hasNext) return; setIsFetching(true); setError(null); try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes?page=${pageToFetch}&limit=20`); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const json = await res.json(); - const items = Array.isArray(json?.data) ? json.data : []; - const mapped = items.map((p: any) => ({ - id: String(p.id ?? ""), - nome: p.nome ?? "", - telefone: p?.contato?.celular ?? p?.contato?.telefone1 ?? p?.telefone ?? "", - cidade: p?.endereco?.cidade ?? p?.cidade ?? "", - estado: p?.endereco?.estado ?? p?.estado ?? "", - ultimoAtendimento: p.ultimo_atendimento ?? p.ultimoAtendimento ?? undefined, - proximoAtendimento: p.proximo_atendimento ?? p.proximoAtendimento ?? undefined, - convenio: p.convenio ?? "", - vip: Boolean(p.vip ?? false), - status: p.status ?? undefined, - })); - setPatients((prev) => [...prev, ...mapped]); - setHasNext(Boolean(json?.pagination?.has_next)); - setPage(pageToFetch + 1); + const res = await patientsService.list(); + console.log(res) + const mapped = res.map((p: any) => ({ + id: String(p.id ?? ""), + nome: p.full_name ?? "", + telefone: p.phone_mobile ?? p.phone1 ?? "", + cidade: p.city ?? "", + estado: p.state ?? "", + ultimoAtendimento: p.last_visit_at ?? "", + proximoAtendimento: p.next_appointment_at ?? "", + vip: Boolean(p.vip ?? false), + convenio: p.convenio ?? "", // se não existir, fica vazio + status: p.status ?? undefined, + })); + + setPatients((prev) => { + const all = [...prev, ...mapped]; + const unique = Array.from(new Map(all.map(p => [p.id, p])).values()); + return unique; + }); + + if (mapped.length === 0) setHasNext(false); // parar carregamento + else setPage(prev => prev + 1); } catch (e: any) { setError(e?.message || "Erro ao buscar pacientes"); } finally { @@ -311,33 +315,23 @@ export default function PacientesPage() {
{patientDetails.error}
) : (
-
- Nome: {patientDetails.nome} -
-
- Telefone: {patientDetails?.contato?.celular ?? patientDetails?.contato?.telefone1 ?? patientDetails?.telefone ?? ""} -
-
- Cidade: {patientDetails?.endereco?.cidade ?? patientDetails?.cidade ?? ""} -
-
- Estado: {patientDetails?.endereco?.estado ?? patientDetails?.estado ?? ""} -
-
- Convênio: {patientDetails.convenio ?? ""} -
-
- VIP: {patientDetails.vip ? "Sim" : "Não"} -
-
- Status: {patientDetails.status ?? ""} -
-
- Último atendimento: {patientDetails.ultimo_atendimento ?? patientDetails.ultimoAtendimento ?? ""} -
-
- Próximo atendimento: {patientDetails.proximo_atendimento ?? patientDetails.proximoAtendimento ?? ""} -
+

Nome: {patientDetails.full_name}

+

CPF: {patientDetails.cpf}

+

Email: {patientDetails.email}

+

Telefone: {patientDetails.phone_mobile ?? patientDetails.phone1 ?? patientDetails.phone2 ?? "-"}

+

Nome social: {patientDetails.social_name ?? "-"}

+

Sexo: {patientDetails.sex ?? "-"}

+

Tipo sanguíneo: {patientDetails.blood_type ?? "-"}

+

Peso: {patientDetails.weight_kg ?? "-"}{patientDetails.weight_kg ? "kg": ""}

+

Altura: {patientDetails.height_m ?? "-"}{patientDetails.height_m ? "m": ""}

+

IMC: {patientDetails.bmi ?? "-"}

+

Endereço: {patientDetails.street ?? "-"}

+

Bairro: {patientDetails.neighborhood ?? "-"}

+

Cidade: {patientDetails.city ?? "-"}

+

Estado: {patientDetails.state ?? "-"}

+

CEP: {patientDetails.cep ?? "-"}

+

Criado em: {patientDetails.created_at ?? "-"}

+

Atualizado em: {patientDetails.updated_at ?? "-"}

)} diff --git a/components/secretary-layout.tsx b/components/secretary-layout.tsx index c7805dc..78d817c 100644 --- a/components/secretary-layout.tsx +++ b/components/secretary-layout.tsx @@ -66,13 +66,13 @@ export default function SecretaryLayout({ children }: PatientLayoutProps) { const menuItems = [ { - href: "#", + href: "##", icon: Home, label: "Dashboard", // Botão para o dashboard da secretária }, { - href: "#", + href: "###", icon: Calendar, label: "Consultas", // Botão para página de consultas marcadas diff --git a/services/api.mjs b/services/api.mjs index 493d8c8..319a96d 100644 --- a/services/api.mjs +++ b/services/api.mjs @@ -11,13 +11,11 @@ async function login() { "Content-Type": "application/json", "apikey": API_KEY, // valor fixo }, - body: JSON.stringify({ email: "hugo@popcode.com.br", password: "hdoria" }), + body: JSON.stringify({ email: "riseup@popcode.com.br", password: "riseup" }), }); const data = await response.json(); - - console.log("Resposta da API:", data); - console.log("Token:", data.access_token); + console.log(data.access_token) // salvar o token do usuário //localStorage.setItem("token", data.access_token); tempToken = data.access_token @@ -30,10 +28,12 @@ async function request(endpoint, options = {}) { //const token = localStorage.getItem("token"); // token do usuário, salvo no login const token = tempToken; + console.log(`endpoint: ${endpoint}`) + const headers = { "Content-Type": "application/json", "apikey": API_KEY, // obrigatório sempre - ...(token ? { Authorization: `Bearer ${token}` } : {}), // obrigatório em todas EXCETO login + ...(token ? { "Authorization": `Bearer ${token}` } : {}), // obrigatório em todas EXCETO login ...options.headers, }; diff --git a/services/patientsApi.mjs b/services/patientsApi.mjs index 5f0571b..c50e3f9 100644 --- a/services/patientsApi.mjs +++ b/services/patientsApi.mjs @@ -2,7 +2,7 @@ import { api } from "./api.mjs"; export const patientsService = { list: () => api.get("/rest/v1/patients"), - getById: (id) => api.get(`/rest/v1/patients/${id}`), + getById: (id) => api.get(`/rest/v1/patients?id=eq.${id}`), create: (data) => api.post("/rest/v1/patients", data), update: (id, data) => api.patch(`/rest/v1/patients/${id}`, data), delete: (id) => api.delete(`/rest/v1/patients/${id}`), From 7455a578917599fa2e637c67eda5fa8069c8951a Mon Sep 17 00:00:00 2001 From: DaniloSts Date: Sun, 28 Sep 2025 19:30:04 -0300 Subject: [PATCH 3/7] pequenos ajustes --- app/secretary/pacientes/page.tsx | 1 - services/api.mjs | 8 +++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/secretary/pacientes/page.tsx b/app/secretary/pacientes/page.tsx index 29f4fef..59f86e8 100644 --- a/app/secretary/pacientes/page.tsx +++ b/app/secretary/pacientes/page.tsx @@ -30,7 +30,6 @@ export default function PacientesPage() { setPatientDetails(null); try { const res = await patientsService.getById(patientId); - console.log(res) setPatientDetails(res[0]); } catch (e: any) { setPatientDetails({ error: e?.message || "Erro ao buscar detalhes" }); diff --git a/services/api.mjs b/services/api.mjs index 319a96d..4d97c42 100644 --- a/services/api.mjs +++ b/services/api.mjs @@ -17,18 +17,16 @@ async function login() { const data = await response.json(); console.log(data.access_token) // salvar o token do usuário - //localStorage.setItem("token", data.access_token); - tempToken = data.access_token + localStorage.setItem("token", data.access_token); + return data; } await login() async function request(endpoint, options = {}) { - //const token = localStorage.getItem("token"); // token do usuário, salvo no login - const token = tempToken; + const token = localStorage.getItem("token"); // token do usuário, salvo no login - console.log(`endpoint: ${endpoint}`) const headers = { "Content-Type": "application/json", From 140c4249859e0a5b938d092f3a614906bcdb446e Mon Sep 17 00:00:00 2001 From: DaniloSts Date: Sun, 28 Sep 2025 20:23:22 -0300 Subject: [PATCH 4/7] =?UTF-8?q?adicionado=20fun=C3=A7=C3=A3o=20delete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/secretary/pacientes/novo/page.tsx | 138 +++++++++++--------------- app/secretary/pacientes/page.tsx | 17 +++- services/api.mjs | 1 - services/patientsApi.mjs | 4 +- 4 files changed, 72 insertions(+), 88 deletions(-) diff --git a/app/secretary/pacientes/novo/page.tsx b/app/secretary/pacientes/novo/page.tsx index 61158d6..8865473 100644 --- a/app/secretary/pacientes/novo/page.tsx +++ b/app/secretary/pacientes/novo/page.tsx @@ -15,6 +15,7 @@ import { Upload, Plus, X, ChevronDown } from "lucide-react"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { useToast } from "@/hooks/use-toast"; import SecretaryLayout from "@/components/secretary-layout"; +import { patientsService } from "@/services/patientsApi.mjs"; export default function NovoPacientePage() { const [anexosOpen, setAnexosOpen] = useState(false); @@ -35,79 +36,64 @@ export default function NovoPacientePage() { e.preventDefault(); if (isLoading) return; setIsLoading(true); - const form = e.currentTarget; const formData = new FormData(form); const apiPayload = { - nome: formData.get("nome") as string, - nome_social: (formData.get("nomeSocial") as string) || null, - cpf: formData.get("cpf") as string, - rg: (formData.get("rg") as string) || null, - outros_documentos: - (formData.get("outrosDocumentosTipo") as string) || (formData.get("outrosDocumentosNumero") as string) - ? { - tipo: (formData.get("outrosDocumentosTipo") as string) || undefined, - numero: (formData.get("outrosDocumentosNumero") as string) || undefined, - } - : null, - sexo: (formData.get("sexo") as string) || null, - data_nascimento: (formData.get("dataNascimento") as string) || null, - etnia: (formData.get("etnia") as string) || null, - raca: (formData.get("raca") as string) || null, - naturalidade: (formData.get("naturalidade") as string) || null, - nacionalidade: (formData.get("nacionalidade") as string) || null, - profissao: (formData.get("profissao") as string) || null, - estado_civil: (formData.get("estadoCivil") as string) || null, - nome_mae: (formData.get("nomeMae") as string) || null, - profissao_mae: (formData.get("profissaoMae") as string) || null, - nome_pai: (formData.get("nomePai") as string) || null, - profissao_pai: (formData.get("profissaoPai") as string) || null, - nome_responsavel: (formData.get("nomeResponsavel") as string) || null, - cpf_responsavel: (formData.get("cpfResponsavel") as string) || null, - nome_esposo: (formData.get("nomeEsposo") as string) || null, - rn_na_guia_convenio: Boolean(formData.get("rnGuia")), - codigo_legado: (formData.get("codigoLegado") as string) || null, - contato: { - email: (formData.get("email") as string) || null, - celular: (formData.get("celular") as string) || null, - telefone1: (formData.get("telefone1") as string) || null, - telefone2: (formData.get("telefone2") as string) || null, - }, - endereco: { - cep: (formData.get("cep") as string) || null, - logradouro: (formData.get("endereco") as string) || null, - numero: (formData.get("numero") as string) || null, - complemento: (formData.get("complemento") as string) || null, - bairro: (formData.get("bairro") as string) || null, - cidade: (formData.get("cidade") as string) || null, - estado: (formData.get("estado") as string) || null, - referencia: null, - }, - observacoes: (formData.get("observacoes") as string) || null, - // Campos de convênio (opcionais, se a API aceitar) - convenio: (formData.get("convenio") as string) || null, - plano: (formData.get("plano") as string) || null, - numero_matricula: (formData.get("numeroMatricula") as string) || null, - validade_carteira: (formData.get("validadeCarteira") as string) || null, + full_name: (formData.get("nome") as string) || "", // obrigatório + social_name: (formData.get("nomeSocial") as string) || undefined, + cpf: (formData.get("cpf") as string) || "", // obrigatório + email: (formData.get("email") as string) || "", // obrigatório + phone_mobile: (formData.get("celular") as string) || "", // obrigatório + birth_date: formData.get("dataNascimento") ? new Date(formData.get("dataNascimento") as string) : undefined, + sex: (formData.get("sexo") as string) || undefined, + blood_type: (formData.get("tipoSanguineo") as string) || undefined, + weight_kg: formData.get("peso") ? parseFloat(formData.get("peso") as string) : undefined, + height_m: formData.get("altura") ? parseFloat(formData.get("altura") as string) : undefined, + cep: (formData.get("cep") as string) || undefined, + street: (formData.get("endereco") as string) || undefined, + number: (formData.get("numero") as string) || undefined, + complement: (formData.get("complemento") as string) || undefined, + neighborhood: (formData.get("bairro") as string) || undefined, + city: (formData.get("cidade") as string) || undefined, + state: (formData.get("estado") as string) || undefined, }; const errors: string[] = []; - const nome = apiPayload.nome?.trim() || ""; - if (!nome || nome.length < 2 || nome.length > 255) errors.push("Nome deve ter entre 2 e 255 caracteres."); - const cpf = apiPayload.cpf || ""; - if (!/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(cpf)) errors.push("CPF deve estar no formato XXX.XXX.XXX-XX."); - const sexo = apiPayload.sexo; - const allowedSexo = ["masculino", "feminino", "outro"]; - if (!sexo || !allowedSexo.includes(sexo)) errors.push("Sexo é obrigatório e deve ser masculino, feminino ou outro."); - if (!apiPayload.data_nascimento) errors.push("Data de nascimento é obrigatória."); - const celular = apiPayload.contato?.celular || ""; - if (celular && !/^\+55 \(\d{2}\) \d{4,5}-\d{4}$/.test(celular)) errors.push("Celular deve estar no formato +55 (XX) XXXXX-XXXX."); - const cep = apiPayload.endereco?.cep || ""; - if (cep && !/^\d{5}-\d{3}$/.test(cep)) errors.push("CEP deve estar no formato XXXXX-XXX."); - const uf = apiPayload.endereco?.estado || ""; - if (uf && uf.length !== 2) errors.push("Estado (UF) deve ter 2 caracteres."); + const fullName = apiPayload.full_name?.trim() || ""; + if (!fullName || fullName.length < 2 || fullName.length > 255) { + errors.push("Nome deve ter entre 2 e 255 caracteres."); + } + const cpf = apiPayload.cpf || ""; + if (!/^\d{3}\.\d{3}\.\d{3}-\d{2}$/.test(cpf)) { + errors.push("CPF deve estar no formato XXX.XXX.XXX-XX."); + } + + const sex = apiPayload.sex; + const allowedSex = ["masculino", "feminino", "outro"]; + if (!sex || !allowedSex.includes(sex)) { + errors.push("Sexo é obrigatório e deve ser masculino, feminino ou outro."); + } + + if (!apiPayload.birth_date) { + errors.push("Data de nascimento é obrigatória."); + } + + const phoneMobile = apiPayload.phone_mobile || ""; + if (phoneMobile && !/^\+55 \(\d{2}\) \d{4,5}-\d{4}$/.test(phoneMobile)) { + errors.push("Celular deve estar no formato +55 (XX) XXXXX-XXXX."); + } + + const cep = apiPayload.cep || ""; + if (cep && !/^\d{5}-\d{3}$/.test(cep)) { + errors.push("CEP deve estar no formato XXXXX-XXX."); + } + + const state = apiPayload.state || ""; + if (state && state.length !== 2) { + errors.push("Estado (UF) deve ter 2 caracteres."); + } if (errors.length) { toast({ title: "Corrija os campos", description: errors[0] }); setIsLoading(false); @@ -115,27 +101,15 @@ export default function NovoPacientePage() { } try { - const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes", { - method: "POST", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - body: JSON.stringify(apiPayload), - }); - - if (!res.ok) { - const msg = `Erro ao salvar (HTTP ${res.status})`; - throw new Error(msg); - } + const res = await patientsService.create(apiPayload); let message = "Paciente cadastrado com sucesso"; try { - const payload = await res.json(); - if (payload?.success === false) { - throw new Error(payload?.message || "A API retornou erro"); + if (!res[0].id) { + throw new Error(`${res.error} ${res.message}`|| "A API retornou erro"); + } else { + console.log(message) } - if (payload?.message) message = String(payload.message); } catch {} toast({ diff --git a/app/secretary/pacientes/page.tsx b/app/secretary/pacientes/page.tsx index 59f86e8..8d3746f 100644 --- a/app/secretary/pacientes/page.tsx +++ b/app/secretary/pacientes/page.tsx @@ -43,7 +43,6 @@ export default function PacientesPage() { setError(null); try { const res = await patientsService.list(); - console.log(res) const mapped = res.map((p: any) => ({ id: String(p.id ?? ""), nome: p.full_name ?? "", @@ -92,9 +91,21 @@ export default function PacientesPage() { }; }, [fetchPacientes, page, hasNext, isFetching]); - const handleDeletePatient = (patientId: string) => { + const handleDeletePatient = async (patientId: string) => { // Remove from current list (client-side deletion) - setPatients((prev) => prev.filter((p) => String(p.id) !== String(patientId))); + try{ + const res = await patientsService.delete(patientId); + + if(res){ + alert(`${res.error} ${res.message}`) + } + + setPatients((prev) => prev.filter((p) => String(p.id) !== String(patientId))); + + + } catch (e: any) { + setError(e?.message || "Erro ao deletar paciente"); + } setDeleteDialogOpen(false); setPatientToDelete(null); }; diff --git a/services/api.mjs b/services/api.mjs index 4d97c42..b36cebe 100644 --- a/services/api.mjs +++ b/services/api.mjs @@ -15,7 +15,6 @@ async function login() { }); const data = await response.json(); - console.log(data.access_token) // salvar o token do usuário localStorage.setItem("token", data.access_token); diff --git a/services/patientsApi.mjs b/services/patientsApi.mjs index c50e3f9..2a5ba54 100644 --- a/services/patientsApi.mjs +++ b/services/patientsApi.mjs @@ -4,6 +4,6 @@ export const patientsService = { list: () => api.get("/rest/v1/patients"), getById: (id) => api.get(`/rest/v1/patients?id=eq.${id}`), create: (data) => api.post("/rest/v1/patients", data), - update: (id, data) => api.patch(`/rest/v1/patients/${id}`, data), - delete: (id) => api.delete(`/rest/v1/patients/${id}`), + update: (id, data) => api.patch(`/rest/v1/patients?id=eq.${id}`, data), + delete: (id) => api.delete(`/rest/v1/patients?id=eq.${id}`), }; From 0f263e12dcae93d5e995d042d8edd5e635798767 Mon Sep 17 00:00:00 2001 From: StsDanilo Date: Mon, 29 Sep 2025 20:02:59 +0000 Subject: [PATCH 5/7] merge --- app/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 3b85401..5aefa10 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -117,7 +117,7 @@ export default function HomePage() { Gestão de usuários
- + @@ -144,7 +144,7 @@ export default function HomePage() { Controle de pagamentos - + From 9ed0952d321a3ff1036694f26de4a8d836f36bd9 Mon Sep 17 00:00:00 2001 From: DaniloSts Date: Tue, 30 Sep 2025 11:19:39 -0300 Subject: [PATCH 6/7] =?UTF-8?q?fun=C3=A7=C3=A3o=20editar=20incompleta?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/secretary/pacientes/[id]/editar/page.tsx | 581 +++++++------------ app/secretary/pacientes/novo/page.tsx | 9 +- app/secretary/pacientes/page.tsx | 1 + services/api.mjs | 20 +- 4 files changed, 242 insertions(+), 369 deletions(-) diff --git a/app/secretary/pacientes/[id]/editar/page.tsx b/app/secretary/pacientes/[id]/editar/page.tsx index fea3ad6..b9881e2 100644 --- a/app/secretary/pacientes/[id]/editar/page.tsx +++ b/app/secretary/pacientes/[id]/editar/page.tsx @@ -14,56 +14,13 @@ import { ArrowLeft, Save, Trash2, Paperclip, Upload } from "lucide-react"; import Link from "next/link"; import { useToast } from "@/hooks/use-toast"; import SecretaryLayout from "@/components/secretary-layout"; - -// Mock data - in a real app, this would come from an API -const mockPatients = [ - { - id: 1, - nome: "Aaron Avalos Perez", - cpf: "123.456.789-00", - rg: "12.345.678-9", - sexo: "masculino", - dataNascimento: "1990-01-15", - etnia: "branca", - raca: "caucasiana", - naturalidade: "Aracaju", - nacionalidade: "brasileira", - profissao: "Engenheiro", - estadoCivil: "solteiro", - nomeMae: "Maria Perez", - profissaoMae: "Professora", - nomePai: "João Perez", - profissaoPai: "Médico", - nomeResponsavel: "", - cpfResponsavel: "", - nomeEsposo: "", - email: "aaron@email.com", - celular: "(79) 99943-2499", - telefone1: "(79) 3214-5678", - telefone2: "", - cep: "49000-000", - endereco: "Rua das Flores, 123", - numero: "123", - complemento: "Apt 101", - bairro: "Centro", - cidade: "Aracaju", - estado: "SE", - tipoSanguineo: "O+", - peso: "75", - altura: "1.75", - alergias: "Nenhuma alergia conhecida", - convenio: "Particular", - plano: "Premium", - numeroMatricula: "123456789", - validadeCarteira: "2025-12-31", - observacoes: "Paciente colaborativo", - }, -]; +import { patientsService } from "@/services/patientsApi.mjs"; +import { json } from "stream/consumers"; export default function EditarPacientePage() { const router = useRouter(); const params = useParams(); - const patientId = Number.parseInt(params.id as string); + const patientId = params.id; const { toast } = useToast(); // Photo upload state @@ -75,45 +32,107 @@ export default function EditarPacientePage() { const [isUploadingAnexo, setIsUploadingAnexo] = useState(false); const anexoInputRef = useRef(null); - const [formData, setFormData] = useState({ + type FormData = { + nome: string; // full_name + cpf: string; + dataNascimento: string; // birth_date + sexo: string; // sex + id?: string; + nomeSocial?: string; // social_name + rg?: string; + documentType?: string; // document_type + documentNumber?: string; // document_number + ethnicity?: string; + race?: string; + naturality?: string; + nationality?: string; + profession?: string; + maritalStatus?: string; // marital_status + motherName?: string; // mother_name + motherProfession?: string; // mother_profession + fatherName?: string; // father_name + fatherProfession?: string; // father_profession + guardianName?: string; // guardian_name + guardianCpf?: string; // guardian_cpf + spouseName?: string; // spouse_name + rnInInsurance?: boolean; // rn_in_insurance + legacyCode?: string; // legacy_code + notes?: string; + email?: string; + phoneMobile?: string; // phone_mobile + phone1?: string; + phone2?: string; + cep?: string; + street?: string; + number?: string; + complement?: string; + neighborhood?: string; + city?: string; + state?: string; + reference?: string; + vip?: boolean; + lastVisitAt?: string; + nextAppointmentAt?: string; + createdAt?: string; + updatedAt?: string; + createdBy?: string; + updatedBy?: string; + weightKg?: string; + heightM?: string; + bmi?: string; + bloodType?: string; + }; + + + const [formData, setFormData] = useState({ nome: "", cpf: "", - rg: "", - sexo: "", dataNascimento: "", - etnia: "", - raca: "", - naturalidade: "", - nacionalidade: "", - profissao: "", - estadoCivil: "", - nomeMae: "", - profissaoMae: "", - nomePai: "", - profissaoPai: "", - nomeResponsavel: "", - cpfResponsavel: "", - nomeEsposo: "", + sexo: "", + id: "", + nomeSocial: "", + rg: "", + documentType: "", + documentNumber: "", + ethnicity: "", + race: "", + naturality: "", + nationality: "", + profession: "", + maritalStatus: "", + motherName: "", + motherProfession: "", + fatherName: "", + fatherProfession: "", + guardianName: "", + guardianCpf: "", + spouseName: "", + rnInInsurance: false, + legacyCode: "", + notes: "", email: "", - celular: "", - telefone1: "", - telefone2: "", + phoneMobile: "", + phone1: "", + phone2: "", cep: "", - endereco: "", - numero: "", - complemento: "", - bairro: "", - cidade: "", - estado: "", - tipoSanguineo: "", - peso: "", - altura: "", - alergias: "", - convenio: "", - plano: "", - numeroMatricula: "", - validadeCarteira: "", - observacoes: "", + street: "", + number: "", + complement: "", + neighborhood: "", + city: "", + state: "", + reference: "", + vip: false, + lastVisitAt: "", + nextAppointmentAt: "", + createdAt: "", + updatedAt: "", + createdBy: "", + updatedBy: "", + weightKg: "", + heightM: "", + bmi: "", + bloodType: "", }); const [isGuiaConvenio, setIsGuiaConvenio] = useState(false); @@ -122,169 +141,66 @@ export default function EditarPacientePage() { useEffect(() => { async function fetchPatient() { try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}`); - if (!res.ok) throw new Error(`HTTP ${res.status}`); - const json = await res.json(); - const p = json?.data || json; + const res = await patientsService.getById(patientId); // Map API snake_case/nested to local camelCase form setFormData({ - nome: p?.nome ?? "", - cpf: p?.cpf ?? "", - rg: p?.rg ?? "", - sexo: p?.sexo ?? "", - dataNascimento: p?.data_nascimento ?? p?.dataNascimento ?? "", - etnia: p?.etnia ?? "", - raca: p?.raca ?? "", - naturalidade: p?.naturalidade ?? "", - nacionalidade: p?.nacionalidade ?? "", - profissao: p?.profissao ?? "", - estadoCivil: p?.estado_civil ?? p?.estadoCivil ?? "", - nomeMae: p?.nome_mae ?? p?.nomeMae ?? "", - profissaoMae: p?.profissao_mae ?? p?.profissaoMae ?? "", - nomePai: p?.nome_pai ?? p?.nomePai ?? "", - profissaoPai: p?.profissao_pai ?? p?.profissaoPai ?? "", - nomeResponsavel: p?.nome_responsavel ?? p?.nomeResponsavel ?? "", - cpfResponsavel: p?.cpf_responsavel ?? p?.cpfResponsavel ?? "", - nomeEsposo: p?.nome_esposo ?? p?.nomeEsposo ?? "", - email: p?.contato?.email ?? p?.email ?? "", - celular: p?.contato?.celular ?? p?.celular ?? "", - telefone1: p?.contato?.telefone1 ?? p?.telefone1 ?? "", - telefone2: p?.contato?.telefone2 ?? p?.telefone2 ?? "", - cep: p?.endereco?.cep ?? p?.cep ?? "", - endereco: p?.endereco?.logradouro ?? p?.endereco ?? "", - numero: p?.endereco?.numero ?? p?.numero ?? "", - complemento: p?.endereco?.complemento ?? p?.complemento ?? "", - bairro: p?.endereco?.bairro ?? p?.bairro ?? "", - cidade: p?.endereco?.cidade ?? p?.cidade ?? "", - estado: p?.endereco?.estado ?? p?.estado ?? "", - tipoSanguineo: p?.tipo_sanguineo ?? p?.tipoSanguineo ?? "", - peso: p?.peso ? String(p.peso) : "", - altura: p?.altura ? String(p.altura) : "", - alergias: p?.alergias ?? "", - convenio: p?.convenio ?? "", - plano: p?.plano ?? "", - numeroMatricula: p?.numero_matricula ?? p?.numeroMatricula ?? "", - validadeCarteira: p?.validade_carteira ?? p?.validadeCarteira ?? "", - observacoes: p?.observacoes ?? "", + id: res[0]?.id ?? "", + nome: res[0]?.full_name ?? "", + nomeSocial: res[0]?.social_name ?? "", + cpf: res[0]?.cpf ?? "", + rg: res[0]?.rg ?? "", + documentType: res[0]?.document_type ?? "", + documentNumber: res[0]?.document_number ?? "", + sexo: res[0]?.sex ?? "", + dataNascimento: res[0]?.birth_date ?? "", + ethnicity: res[0]?.ethnicity ?? "", + race: res[0]?.race ?? "", + naturality: res[0]?.naturality ?? "", + nationality: res[0]?.nationality ?? "", + profession: res[0]?.profession ?? "", + maritalStatus: res[0]?.marital_status ?? "", + motherName: res[0]?.mother_name ?? "", + motherProfession: res[0]?.mother_profession ?? "", + fatherName: res[0]?.father_name ?? "", + fatherProfession: res[0]?.father_profession ?? "", + guardianName: res[0]?.guardian_name ?? "", + guardianCpf: res[0]?.guardian_cpf ?? "", + spouseName: res[0]?.spouse_name ?? "", + rnInInsurance: res[0]?.rn_in_insurance ?? false, + legacyCode: res[0]?.legacy_code ?? "", + notes: res[0]?.notes ?? "", + email: res[0]?.email ?? "", + phoneMobile: res[0]?.phone_mobile ?? "", + phone1: res[0]?.phone1 ?? "", + phone2: res[0]?.phone2 ?? "", + cep: res[0]?.cep ?? "", + street: res[0]?.street ?? "", + number: res[0]?.number ?? "", + complement: res[0]?.complement ?? "", + neighborhood: res[0]?.neighborhood ?? "", + city: res[0]?.city ?? "", + state: res[0]?.state ?? "", + reference: res[0]?.reference ?? "", + vip: res[0]?.vip ?? false, + lastVisitAt: res[0]?.last_visit_at ?? "", + nextAppointmentAt: res[0]?.next_appointment_at ?? "", + createdAt: res[0]?.created_at ?? "", + updatedAt: res[0]?.updated_at ?? "", + createdBy: res[0]?.created_by ?? "", + updatedBy: res[0]?.updated_by ?? "", + weightKg: res[0]?.weight_kg ? String(res[0].weight_kg) : "", + heightM: res[0]?.height_m ? String(res[0].height_m) : "", + bmi: res[0]?.bmi ? String(res[0].bmi) : "", + bloodType: res[0]?.blood_type ?? "", }); - const foto = p?.foto_url || p?.fotoUrl; - if (foto) setPhotoUrl(foto); + } catch (e: any) { toast({ title: "Erro", description: e?.message || "Falha ao carregar paciente" }); } } - async function fetchAnexos() { - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/anexos`); - if (!res.ok) return; - const json = await res.json(); - const items = Array.isArray(json?.data) ? json.data : json; - setAnexos(Array.isArray(items) ? items : []); - } catch {} - } fetchPatient(); - fetchAnexos(); }, [patientId, toast]); - const onPickPhoto = () => fileInputRef.current?.click(); - - const onPhotoSelected = async (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (!file) return; - try { - setIsUploadingPhoto(true); - const form = new FormData(); - // Common field name: 'foto'; also append 'file' for compatibility with some mocks - form.append("foto", file); - form.append("file", file); - - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/foto`, { - method: "POST", - body: form, - }); - if (!res.ok) { - throw new Error(`Falha no upload (HTTP ${res.status})`); - } - let msg = "Foto enviada com sucesso"; - try { - const payload = await res.json(); - if (payload?.success === false) { - throw new Error(payload?.message || "A API retornou erro"); - } - if (payload?.message) msg = String(payload.message); - if (payload?.data?.foto_url || payload?.foto_url || payload?.url) { - setPhotoUrl(payload.data?.foto_url ?? payload.foto_url ?? payload.url); - } - } catch { - // Ignore JSON parse errors - } - toast({ title: "Sucesso", description: msg }); - } catch (err: any) { - toast({ title: "Erro", description: err?.message || "Não foi possível enviar a foto" }); - } finally { - setIsUploadingPhoto(false); - // clear the input to allow re-selecting the same file - if (fileInputRef.current) fileInputRef.current.value = ""; - } - }; - - // Remove patient photo via API - const onRemovePhoto = async () => { - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/foto`, { - method: "DELETE", - }); - if (!res.ok) throw new Error(`Falha ao remover foto (HTTP ${res.status})`); - setPhotoUrl(null); - toast({ title: "Sucesso", description: "Foto removida" }); - } catch (err: any) { - toast({ title: "Erro", description: err?.message || "Não foi possível remover a foto" }); - } - }; - - // Anexos helpers - const onPickAnexo = () => anexoInputRef.current?.click(); - - const onAnexoSelected = async (e: React.ChangeEvent) => { - const file = e.target.files?.[0]; - if (!file) return; - try { - setIsUploadingAnexo(true); - const form = new FormData(); - form.append("anexo", file); - form.append("file", file); - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/anexos`, { - method: "POST", - body: form, - }); - if (!res.ok) throw new Error(`Falha ao enviar anexo (HTTP ${res.status})`); - // Refresh anexos list - try { - const refreshed = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/anexos`); - const json = await refreshed.json(); - const items = Array.isArray(json?.data) ? json.data : json; - setAnexos(Array.isArray(items) ? items : []); - } catch {} - toast({ title: "Sucesso", description: "Anexo adicionado" }); - } catch (err: any) { - toast({ title: "Erro", description: err?.message || "Não foi possível enviar o anexo" }); - } finally { - setIsUploadingAnexo(false); - if (anexoInputRef.current) anexoInputRef.current.value = ""; - } - }; - - const onDeleteAnexo = async (anexoId: string | number) => { - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}/anexos/${anexoId}`, { method: "DELETE" }); - if (!res.ok) throw new Error(`Falha ao remover anexo (HTTP ${res.status})`); - setAnexos((prev) => prev.filter((a) => String(a.id) !== String(anexoId))); - toast({ title: "Sucesso", description: "Anexo removido" }); - } catch (err: any) { - toast({ title: "Erro", description: err?.message || "Não foi possível remover o anexo" }); - } - }; - const handleInputChange = (field: string, value: string) => { setFormData((prev) => ({ ...prev, [field]: value })); }; @@ -293,97 +209,38 @@ export default function EditarPacientePage() { e.preventDefault(); // Build API payload (snake_case) const payload = { - nome: formData.nome, - cpf: formData.cpf, - rg: formData.rg || null, - sexo: formData.sexo || null, - data_nascimento: formData.dataNascimento || null, - etnia: formData.etnia || null, - raca: formData.raca || null, - naturalidade: formData.naturalidade || null, - nacionalidade: formData.nacionalidade || null, - profissao: formData.profissao || null, - estado_civil: formData.estadoCivil || null, - nome_mae: formData.nomeMae || null, - profissao_mae: formData.profissaoMae || null, - nome_pai: formData.nomePai || null, - profissao_pai: formData.profissaoPai || null, - nome_responsavel: formData.nomeResponsavel || null, - cpf_responsavel: formData.cpfResponsavel || null, - contato: { - email: formData.email || null, - celular: formData.celular || null, - telefone1: formData.telefone1 || null, - telefone2: formData.telefone2 || null, - }, - endereco: { - cep: formData.cep || null, - logradouro: formData.endereco || null, - numero: formData.numero || null, - complemento: formData.complemento || null, - bairro: formData.bairro || null, - cidade: formData.cidade || null, - estado: formData.estado || null, - }, - observacoes: formData.observacoes || null, - convenio: formData.convenio || null, - plano: formData.plano || null, - numero_matricula: formData.numeroMatricula || null, - validade_carteira: formData.validadeCarteira || null, + full_name: formData.nome || null, + cpf: formData.cpf || null, + email: formData.email || null, + phone_mobile: formData.phoneMobile || null, + birth_date: formData.dataNascimento || null, + social_name: formData.nomeSocial || null, + sex: formData.sexo || null, + blood_type: formData.bloodType || null, + weight_kg: formData.weightKg ? Number(formData.weightKg) : null, + height_m: formData.heightM ? Number(formData.heightM) : null, + street: formData.street || null, + number: formData.number || null, + complement: formData.complement || null, + neighborhood: formData.neighborhood || null, + city: formData.city || null, + state: formData.state || null, + cep: formData.cep || null, }; + + console.log(payload) + console.log(JSON.stringify(payload)) + try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/pacientes/${patientId}`, { - method: "PUT", - headers: { "Content-Type": "application/json", Accept: "application/json" }, - body: JSON.stringify(payload), - }); - if (!res.ok) throw new Error(`Falha ao atualizar (HTTP ${res.status})`); - toast({ title: "Sucesso", description: "Paciente atualizado com sucesso" }); - router.push("/pacientes"); + const res = await patientsService.update(patientId, JSON.stringify(payload)); + console.log(res[0]) + router.push("/secretary/pacientes"); } catch (err: any) { toast({ title: "Erro", description: err?.message || "Não foi possível atualizar o paciente" }); + console.log("deu ruim") } }; - // Validate CPF on blur - const validateCpf = async (cpf: string) => { - if (!cpf) return; - try { - const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes/validar-cpf", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ cpf }), - }); - const json = await res.json(); - if (json?.success === false) { - throw new Error(json?.message || "CPF inválido"); - } - if (json?.message) toast({ title: "CPF", description: String(json.message) }); - } catch (err: any) { - toast({ title: "CPF inválido", description: err?.message || "Falha na validação de CPF" }); - } - }; - - // CEP lookup on blur - const lookupCep = async (cep: string) => { - const onlyDigits = cep?.replace(/\D/g, ""); - if (!onlyDigits) return; - try { - const res = await fetch(`https://mock.apidog.com/m1/1053378-0-default/utils/cep/${onlyDigits}`); - if (!res.ok) return; - const data = await res.json(); - const d = data?.data || data; - setFormData((prev) => ({ - ...prev, - endereco: d?.logradouro ?? prev.endereco, - bairro: d?.bairro ?? prev.bairro, - cidade: d?.localidade ?? d?.cidade ?? prev.cidade, - estado: d?.uf ?? d?.estado ?? prev.estado, - complemento: d?.complemento ?? prev.complemento, - })); - } catch {} - }; - return (
@@ -403,8 +260,8 @@ export default function EditarPacientePage() {

Anexos

- -
@@ -418,7 +275,7 @@ export default function EditarPacientePage() { {a.nome || a.filename || `Anexo ${a.id}`}
- @@ -446,12 +303,12 @@ export default function EditarPacientePage() { )}
- - {photoUrl && ( - )} @@ -465,7 +322,7 @@ export default function EditarPacientePage() {
- handleInputChange("cpf", e.target.value)} onBlur={() => validateCpf(formData.cpf)} placeholder="000.000.000-00" required /> + handleInputChange("cpf", e.target.value)} placeholder="000.000.000-00" required />
@@ -477,12 +334,12 @@ export default function EditarPacientePage() {
- handleInputChange("sexo", e.target.value)} className="w-4 h-4 text-blue-600" /> - + handleInputChange("sexo", e.target.value)} className="w-4 h-4 text-blue-600" /> +
- handleInputChange("sexo", e.target.value)} className="w-4 h-4 text-blue-600" /> - + handleInputChange("sexo", e.target.value)} className="w-4 h-4 text-blue-600" /> +
@@ -494,7 +351,7 @@ export default function EditarPacientePage() {
- handleInputChange("ethnicity", value)}> @@ -510,7 +367,7 @@ export default function EditarPacientePage() {
- handleInputChange("race", value)}> @@ -524,12 +381,12 @@ export default function EditarPacientePage() {
- handleInputChange("naturalidade", e.target.value)} /> + handleInputChange("naturality", e.target.value)} />
- handleInputChange("nationality", value)}> @@ -542,12 +399,12 @@ export default function EditarPacientePage() {
- handleInputChange("profissao", e.target.value)} /> + handleInputChange("profession", e.target.value)} />
- handleInputChange("maritalStatus", value)}> @@ -562,37 +419,37 @@ export default function EditarPacientePage() {
- handleInputChange("nomeMae", e.target.value)} /> + handleInputChange("motherName", e.target.value)} />
- handleInputChange("profissaoMae", e.target.value)} /> + handleInputChange("motherProfession", e.target.value)} />
- handleInputChange("nomePai", e.target.value)} /> + handleInputChange("fatherName", e.target.value)} />
- handleInputChange("profissaoPai", e.target.value)} /> + handleInputChange("fatherProfession", e.target.value)} />
- handleInputChange("nomeResponsavel", e.target.value)} /> + handleInputChange("guardianName", e.target.value)} />
- handleInputChange("cpfResponsavel", e.target.value)} placeholder="000.000.000-00" /> + handleInputChange("guardianCpf", e.target.value)} placeholder="000.000.000-00" />
- handleInputChange("nomeEsposo", e.target.value)} /> + handleInputChange("spouseName", e.target.value)} />
@@ -605,7 +462,7 @@ export default function EditarPacientePage() {
-