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() {
-