feat(api): implementações e ajustes nas APIs de médicos e pacientes
This commit is contained in:
parent
ea815ff96c
commit
ea63a73b43
@ -21,8 +21,10 @@ import {
|
|||||||
listarAnexosMedico,
|
listarAnexosMedico,
|
||||||
adicionarAnexoMedico,
|
adicionarAnexoMedico,
|
||||||
removerAnexoMedico,
|
removerAnexoMedico,
|
||||||
MedicoInput,
|
MedicoInput, // 👈 importado do lib/api
|
||||||
|
Medico, // 👈 adicionado import do tipo Medico
|
||||||
} from "@/lib/api";
|
} from "@/lib/api";
|
||||||
|
;
|
||||||
|
|
||||||
import { buscarCepAPI } from "@/lib/api";
|
import { buscarCepAPI } from "@/lib/api";
|
||||||
|
|
||||||
@ -39,32 +41,9 @@ type DadosBancarios = {
|
|||||||
tipo_conta: string;
|
tipo_conta: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Medico = {
|
|
||||||
id: string;
|
|
||||||
nome?: string;
|
|
||||||
nome_social?: string | null;
|
|
||||||
cpf?: string;
|
|
||||||
rg?: string | null;
|
|
||||||
sexo?: string | null;
|
|
||||||
data_nascimento?: string | null;
|
|
||||||
telefone?: string;
|
|
||||||
celular?: string;
|
|
||||||
contato_emergencia?: string;
|
|
||||||
email?: string;
|
|
||||||
crm?: string;
|
|
||||||
estado_crm?: string;
|
|
||||||
rqe?: string;
|
|
||||||
formacao_academica?: FormacaoAcademica[];
|
|
||||||
curriculo_url?: string | null;
|
|
||||||
especialidade?: string;
|
|
||||||
observacoes?: string | null;
|
|
||||||
foto_url?: string | null;
|
|
||||||
tipo_vinculo?: string;
|
|
||||||
dados_bancarios?: DadosBancarios;
|
|
||||||
|
|
||||||
agenda_horario?: string;
|
|
||||||
valor_consulta?: number | string;
|
|
||||||
};
|
|
||||||
|
|
||||||
type Mode = "create" | "edit";
|
type Mode = "create" | "edit";
|
||||||
|
|
||||||
@ -80,7 +59,7 @@ export interface DoctorRegistrationFormProps {
|
|||||||
|
|
||||||
type FormData = {
|
type FormData = {
|
||||||
photo: File | null;
|
photo: File | null;
|
||||||
nome: string;
|
full_name: string; // Substitua 'nome' por 'full_name'
|
||||||
nome_social: string;
|
nome_social: string;
|
||||||
crm: string;
|
crm: string;
|
||||||
estado_crm: string;
|
estado_crm: string;
|
||||||
@ -107,14 +86,13 @@ type FormData = {
|
|||||||
anexos: File[];
|
anexos: File[];
|
||||||
tipo_vinculo: string;
|
tipo_vinculo: string;
|
||||||
dados_bancarios: DadosBancarios;
|
dados_bancarios: DadosBancarios;
|
||||||
|
|
||||||
agenda_horario: string;
|
agenda_horario: string;
|
||||||
valor_consulta: string;
|
valor_consulta: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const initial: FormData = {
|
const initial: FormData = {
|
||||||
photo: null,
|
photo: null,
|
||||||
nome: "",
|
full_name: "",
|
||||||
nome_social: "",
|
nome_social: "",
|
||||||
crm: "",
|
crm: "",
|
||||||
estado_crm: "",
|
estado_crm: "",
|
||||||
@ -128,7 +106,7 @@ const initial: FormData = {
|
|||||||
data_nascimento: "",
|
data_nascimento: "",
|
||||||
email: "",
|
email: "",
|
||||||
telefone: "",
|
telefone: "",
|
||||||
celular: "",
|
celular: "", // Aqui, 'celular' pode ser 'phone_mobile'
|
||||||
contato_emergencia: "",
|
contato_emergencia: "",
|
||||||
cep: "",
|
cep: "",
|
||||||
logradouro: "",
|
logradouro: "",
|
||||||
@ -152,6 +130,7 @@ const initial: FormData = {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function DoctorRegistrationForm({
|
export function DoctorRegistrationForm({
|
||||||
open = true,
|
open = true,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
@ -179,7 +158,7 @@ export function DoctorRegistrationForm({
|
|||||||
if (!alive) return;
|
if (!alive) return;
|
||||||
setForm({
|
setForm({
|
||||||
photo: null,
|
photo: null,
|
||||||
nome: medico.nome ?? "",
|
full_name: medico.full_name ?? "",
|
||||||
nome_social: medico.nome_social ?? "",
|
nome_social: medico.nome_social ?? "",
|
||||||
crm: medico.crm ?? "",
|
crm: medico.crm ?? "",
|
||||||
estado_crm: medico.estado_crm ?? "",
|
estado_crm: medico.estado_crm ?? "",
|
||||||
@ -222,10 +201,11 @@ export function DoctorRegistrationForm({
|
|||||||
}, [mode, doctorId]);
|
}, [mode, doctorId]);
|
||||||
|
|
||||||
|
|
||||||
function setField<T extends keyof FormData>(k: T, v: FormData[T]) {
|
function setField<T extends keyof FormData>(k: T, v: FormData[T]) {
|
||||||
setForm((s) => ({ ...s, [k]: v }));
|
setForm((s) => ({ ...s, [k]: v }));
|
||||||
if (errors[k as string]) setErrors((e) => ({ ...e, [k]: "" }));
|
if (errors[k as string]) setErrors((e) => ({ ...e, [k]: "" }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function addFormacao() {
|
function addFormacao() {
|
||||||
@ -301,74 +281,79 @@ export function DoctorRegistrationForm({
|
|||||||
|
|
||||||
function validateLocal(): boolean {
|
function validateLocal(): boolean {
|
||||||
const e: Record<string, string> = {};
|
const e: Record<string, string> = {};
|
||||||
if (!form.nome.trim()) e.nome = "Nome é obrigatório";
|
|
||||||
|
if (!form.full_name.trim()) e.full_name = "Nome é obrigatório";
|
||||||
if (!form.cpf.trim()) e.cpf = "CPF é obrigatório";
|
if (!form.cpf.trim()) e.cpf = "CPF é obrigatório";
|
||||||
if (!form.crm.trim()) e.crm = "CRM é obrigatório";
|
if (!form.crm.trim()) e.crm = "CRM é obrigatório";
|
||||||
if (!form.especialidade.trim()) e.especialidade = "Especialidade é obrigatória";
|
if (!form.especialidade.trim()) e.especialidade = "Especialidade é obrigatória";
|
||||||
|
if (!form.cep.trim()) e.cep = "CEP é obrigatório"; // Verifique se o CEP está preenchido
|
||||||
|
if (!form.bairro.trim()) e.bairro = "Bairro é obrigatório"; // Verifique se o bairro está preenchido
|
||||||
|
if (!form.cidade.trim()) e.cidade = "Cidade é obrigatória"; // Verifique se a cidade está preenchida
|
||||||
|
|
||||||
setErrors(e);
|
setErrors(e);
|
||||||
return Object.keys(e).length === 0;
|
return Object.keys(e).length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubmit(ev: React.FormEvent) {
|
|
||||||
|
|
||||||
|
async function handleSubmit(ev: React.FormEvent) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (!validateLocal()) return;
|
console.log("Submitting the form..."); // Verifique se a função está sendo chamada
|
||||||
|
|
||||||
|
if (!validateLocal()) {
|
||||||
|
console.log("Validation failed");
|
||||||
|
return; // Se a validação falhar, saia da função.
|
||||||
|
}
|
||||||
|
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
setErrors((e) => ({ ...e, submit: "" }));
|
setErrors((e) => ({ ...e, submit: "" }));
|
||||||
|
|
||||||
try {
|
const payload: MedicoInput = {
|
||||||
const payload: MedicoInput = {
|
full_name: form.full_name,
|
||||||
nome: form.nome,
|
|
||||||
nome_social: form.nome_social || null,
|
nome_social: form.nome_social || null,
|
||||||
cpf: form.cpf || null,
|
cpf: form.cpf || "",
|
||||||
rg: form.rg || null,
|
rg: form.rg || null,
|
||||||
sexo: form.sexo || null,
|
sexo: form.sexo || null,
|
||||||
data_nascimento: form.data_nascimento || null,
|
data_nascimento: form.data_nascimento || null,
|
||||||
telefone: form.telefone || null,
|
celular: form.celular || "",
|
||||||
celular: form.celular || null,
|
email: form.email || undefined,
|
||||||
contato_emergencia: form.contato_emergencia || null,
|
|
||||||
email: form.email || null,
|
|
||||||
crm: form.crm,
|
crm: form.crm,
|
||||||
estado_crm: form.estado_crm || null,
|
crm_uf: form.estado_crm || null,
|
||||||
rqe: form.rqe || null,
|
rqe: form.rqe || null,
|
||||||
formacao_academica: form.formacao_academica ?? [],
|
formacao_academica: form.formacao_academica,
|
||||||
curriculo_url: null,
|
especialidade: form.especialidade || "",
|
||||||
especialidade: form.especialidade,
|
|
||||||
observacoes: form.observacoes || null,
|
observacoes: form.observacoes || null,
|
||||||
tipo_vinculo: form.tipo_vinculo || null,
|
tipo_vinculo: form.tipo_vinculo || null,
|
||||||
dados_bancarios: form.dados_bancarios ?? null,
|
dados_bancarios: form.dados_bancarios || null, // Remova se não for necessário
|
||||||
agenda_horario: form.agenda_horario || null,
|
|
||||||
valor_consulta: form.valor_consulta || null,
|
valor_consulta: form.valor_consulta || null,
|
||||||
};
|
active: true,
|
||||||
|
cep: form.cep || null,
|
||||||
|
city: form.cidade || null,
|
||||||
|
complement: form.complemento || null,
|
||||||
|
neighborhood: form.bairro || null,
|
||||||
|
number: form.numero || null,
|
||||||
|
phone2: form.telefone || null, // Ajustar conforme necessário
|
||||||
|
state: form.estado || null,
|
||||||
|
street: form.logradouro || null,
|
||||||
|
created_by: 'user_id',
|
||||||
|
updated_by: 'user_id',
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
console.log("Payload being sent:", payload); // Verifique se o payload está correto
|
||||||
|
|
||||||
|
try {
|
||||||
const saved = mode === "create"
|
const saved = mode === "create"
|
||||||
? await criarMedico(payload)
|
? await criarMedico(payload)
|
||||||
: await atualizarMedico(doctorId as number, payload);
|
: await atualizarMedico(doctorId as number, payload);
|
||||||
|
|
||||||
const medicoId = saved.id;
|
console.log("Médico salvo com sucesso", saved); // Verifique se o médico foi salvo
|
||||||
|
|
||||||
if (form.photo) {
|
|
||||||
try {
|
|
||||||
await uploadFotoMedico(medicoId, form.photo);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Falha ao enviar foto:", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (form.anexos?.length) {
|
|
||||||
for (const f of form.anexos) {
|
|
||||||
try {
|
|
||||||
await adicionarAnexoMedico(medicoId, f);
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Falha ao enviar anexo:", f.name, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onSaved?.(saved);
|
onSaved?.(saved);
|
||||||
if (inline) onClose?.();
|
setSubmitting(false);
|
||||||
else onOpenChange?.(false);
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
|
console.error("Erro ao salvar médico:", err);
|
||||||
setErrors((e) => ({ ...e, submit: err?.message || "Erro ao salvar médico" }));
|
setErrors((e) => ({ ...e, submit: err?.message || "Erro ao salvar médico" }));
|
||||||
} finally {
|
} finally {
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
@ -376,6 +361,10 @@ export function DoctorRegistrationForm({
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function handlePhoto(e: React.ChangeEvent<HTMLInputElement>) {
|
function handlePhoto(e: React.ChangeEvent<HTMLInputElement>) {
|
||||||
const f = e.target.files?.[0];
|
const f = e.target.files?.[0];
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
@ -449,8 +438,10 @@ export function DoctorRegistrationForm({
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Nome *</Label>
|
<Label>Nome *</Label>
|
||||||
<Input value={form.nome} onChange={(e) => setField("nome", e.target.value)} className={errors.nome ? "border-destructive" : ""} />
|
<Input value={form.full_name} onChange={(e) => setField("full_name", e.target.value)} />
|
||||||
{errors.nome && <p className="text-sm text-destructive">{errors.nome}</p>}
|
|
||||||
|
|
||||||
|
{errors.full_name && <p className="text-sm text-destructive">{errors.full_name}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Nome Social</Label>
|
<Label>Nome Social</Label>
|
||||||
@ -473,14 +464,19 @@ export function DoctorRegistrationForm({
|
|||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Especialidade *</Label>
|
<Label>Especialidade *</Label>
|
||||||
<Input value={form.especialidade} onChange={(e) => setField("especialidade", e.target.value)} className={errors.especialidade ? "border-destructive" : ""} />
|
<Input
|
||||||
|
value={form.especialidade} // Mantenha o nome no form como 'especialidade'
|
||||||
|
onChange={(e) => setField("especialidade", e.target.value)} // Envia o valor correto
|
||||||
|
className={errors.especialidade ? "border-destructive" : ""}
|
||||||
|
/>
|
||||||
{errors.especialidade && <p className="text-sm text-destructive">{errors.especialidade}</p>}
|
{errors.especialidade && <p className="text-sm text-destructive">{errors.especialidade}</p>}
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>RQE</Label>
|
<Label>RQE</Label>
|
||||||
<Input value={form.rqe} onChange={(e) => setField("rqe", e.target.value)} />
|
<Input value={form.rqe} onChange={(e) => setField("rqe", e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Currículo</Label>
|
<Label>Currículo</Label>
|
||||||
@ -629,6 +625,7 @@ export function DoctorRegistrationForm({
|
|||||||
<Label>E-mail</Label>
|
<Label>E-mail</Label>
|
||||||
<Input value={form.email} onChange={(e) => setField("email", e.target.value)} />
|
<Input value={form.email} onChange={(e) => setField("email", e.target.value)} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Telefone</Label>
|
<Label>Telefone</Label>
|
||||||
<Input
|
<Input
|
||||||
@ -637,6 +634,16 @@ export function DoctorRegistrationForm({
|
|||||||
placeholder="(XX) XXXXX-XXXX"
|
placeholder="(XX) XXXXX-XXXX"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Label>Celular</Label>
|
||||||
|
<Input
|
||||||
|
value={form.celular}
|
||||||
|
onChange={(e) => setField("celular", formatPhone(e.target.value))}
|
||||||
|
placeholder="(XX) XXXXX-XXXX"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-2 gap-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
@ -703,11 +710,14 @@ export function DoctorRegistrationForm({
|
|||||||
|
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Agenda/Horário</Label>
|
<Label>Agenda/Horário</Label>
|
||||||
<Textarea
|
// Dentro do form, apenas exiba o campo se precisar dele visualmente, mas não envie
|
||||||
|
<textarea
|
||||||
value={form.agenda_horario}
|
value={form.agenda_horario}
|
||||||
onChange={(e) => setField("agenda_horario", e.target.value)}
|
onChange={(e) => setField("agenda_horario", e.target.value)}
|
||||||
placeholder="Descreva os dias e horários de atendimento"
|
placeholder="Descreva os dias e horários de atendimento"
|
||||||
/>
|
disabled={true} // Torne o campo apenas visual, sem enviar
|
||||||
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
|
|||||||
@ -51,7 +51,7 @@ type FormData = {
|
|||||||
cpf: string;
|
cpf: string;
|
||||||
rg: string;
|
rg: string;
|
||||||
sexo: string;
|
sexo: string;
|
||||||
data_nascimento: string;
|
birth_date: string; // 👈 corrigido
|
||||||
email: string;
|
email: string;
|
||||||
telefone: string;
|
telefone: string;
|
||||||
cep: string;
|
cep: string;
|
||||||
@ -72,7 +72,7 @@ const initial: FormData = {
|
|||||||
cpf: "",
|
cpf: "",
|
||||||
rg: "",
|
rg: "",
|
||||||
sexo: "",
|
sexo: "",
|
||||||
data_nascimento: "",
|
birth_date: "", // 👈 corrigido
|
||||||
email: "",
|
email: "",
|
||||||
telefone: "",
|
telefone: "",
|
||||||
cep: "",
|
cep: "",
|
||||||
@ -86,6 +86,8 @@ const initial: FormData = {
|
|||||||
anexos: [],
|
anexos: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function PatientRegistrationForm({
|
export function PatientRegistrationForm({
|
||||||
open = true,
|
open = true,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
@ -113,23 +115,27 @@ export function PatientRegistrationForm({
|
|||||||
const p = await buscarPacientePorId(String(patientId));
|
const p = await buscarPacientePorId(String(patientId));
|
||||||
setForm((s) => ({
|
setForm((s) => ({
|
||||||
...s,
|
...s,
|
||||||
nome: p.nome || "",
|
nome: p.full_name || "", // 👈 trocar nome → full_name
|
||||||
nome_social: p.nome_social || "",
|
nome_social: p.social_name || "",
|
||||||
cpf: p.cpf || "",
|
cpf: p.cpf || "",
|
||||||
rg: p.rg || "",
|
rg: p.rg || "",
|
||||||
sexo: p.sexo || "",
|
sexo: p.sex || "",
|
||||||
data_nascimento: (p.data_nascimento as string) || "",
|
birth_date: p.birth_date || "", // 👈 trocar data_nascimento → birth_date
|
||||||
telefone: p.telefone || "",
|
telefone: p.phone_mobile || "",
|
||||||
email: p.email || "",
|
email: p.email || "",
|
||||||
cep: p.endereco?.cep || "",
|
cep: p.cep || "",
|
||||||
logradouro: p.endereco?.logradouro || "",
|
logradouro: p.street || "",
|
||||||
numero: p.endereco?.numero || "",
|
numero: p.number || "",
|
||||||
complemento: p.endereco?.complemento || "",
|
complemento: p.complement || "",
|
||||||
bairro: p.endereco?.bairro || "",
|
bairro: p.neighborhood || "",
|
||||||
cidade: p.endereco?.cidade || "",
|
cidade: p.city || "",
|
||||||
estado: p.endereco?.estado || "",
|
estado: p.state || "",
|
||||||
observacoes: p.observacoes || "",
|
observacoes: p.notes || "",
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const ax = await listarAnexos(String(patientId)).catch(() => []);
|
const ax = await listarAnexos(String(patientId)).catch(() => []);
|
||||||
setServerAnexos(Array.isArray(ax) ? ax : []);
|
setServerAnexos(Array.isArray(ax) ? ax : []);
|
||||||
} catch {
|
} catch {
|
||||||
@ -187,26 +193,26 @@ export function PatientRegistrationForm({
|
|||||||
|
|
||||||
function toPayload(): PacienteInput {
|
function toPayload(): PacienteInput {
|
||||||
return {
|
return {
|
||||||
nome: form.nome,
|
full_name: form.nome, // 👈 troca 'nome' por 'full_name'
|
||||||
nome_social: form.nome_social || null,
|
social_name: form.nome_social || null,
|
||||||
cpf: form.cpf,
|
cpf: form.cpf,
|
||||||
rg: form.rg || null,
|
rg: form.rg || null,
|
||||||
sexo: form.sexo || null,
|
sex: form.sexo || null,
|
||||||
data_nascimento: form.data_nascimento || null,
|
birth_date: form.birth_date || null, // 👈 troca data_nascimento → birth_date
|
||||||
telefone: form.telefone || null,
|
phone_mobile: form.telefone || null,
|
||||||
email: form.email || null,
|
email: form.email || null,
|
||||||
endereco: {
|
cep: form.cep || null,
|
||||||
cep: form.cep || undefined,
|
street: form.logradouro || null,
|
||||||
logradouro: form.logradouro || undefined,
|
number: form.numero || null,
|
||||||
numero: form.numero || undefined,
|
complement: form.complemento || null,
|
||||||
complemento: form.complemento || undefined,
|
neighborhood: form.bairro || null,
|
||||||
bairro: form.bairro || undefined,
|
city: form.cidade || null,
|
||||||
cidade: form.cidade || undefined,
|
state: form.estado || null,
|
||||||
estado: form.estado || undefined,
|
notes: form.observacoes || null,
|
||||||
},
|
|
||||||
observacoes: form.observacoes || null,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function handleSubmit(ev: React.FormEvent) {
|
async function handleSubmit(ev: React.FormEvent) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
@ -418,7 +424,8 @@ export function PatientRegistrationForm({
|
|||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Data de Nascimento</Label>
|
<Label>Data de Nascimento</Label>
|
||||||
<Input type="date" value={form.data_nascimento} onChange={(e) => setField("data_nascimento", e.target.value)} />
|
<Input type="date" value={form.birth_date} onChange={(e) => setField("birth_date", e.target.value)} />
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|||||||
@ -26,32 +26,44 @@ export type Endereco = {
|
|||||||
// ===== PACIENTES =====
|
// ===== PACIENTES =====
|
||||||
export type Paciente = {
|
export type Paciente = {
|
||||||
id: string;
|
id: string;
|
||||||
nome?: string;
|
full_name: string;
|
||||||
nome_social?: string | null;
|
social_name?: string | null;
|
||||||
cpf?: string;
|
cpf?: string;
|
||||||
rg?: string | null;
|
rg?: string | null;
|
||||||
sexo?: string | null;
|
sex?: string | null;
|
||||||
data_nascimento?: string | null;
|
birth_date?: string | null;
|
||||||
telefone?: string;
|
phone_mobile?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
endereco?: Endereco;
|
cep?: string | null;
|
||||||
observacoes?: string | null;
|
street?: string | null;
|
||||||
foto_url?: string | null;
|
number?: string | null;
|
||||||
|
complement?: string | null;
|
||||||
|
neighborhood?: string | null;
|
||||||
|
city?: string | null;
|
||||||
|
state?: string | null;
|
||||||
|
notes?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PacienteInput = {
|
export type PacienteInput = {
|
||||||
nome: string;
|
full_name: string;
|
||||||
nome_social?: string | null;
|
social_name?: string | null;
|
||||||
cpf: string;
|
cpf: string;
|
||||||
rg?: string | null;
|
rg?: string | null;
|
||||||
sexo?: string | null;
|
sex?: string | null;
|
||||||
data_nascimento?: string | null;
|
birth_date?: string | null;
|
||||||
telefone?: string | null;
|
phone_mobile?: string | null;
|
||||||
email?: string | null;
|
email?: string | null;
|
||||||
endereco?: Endereco;
|
cep?: string | null;
|
||||||
observacoes?: string | null;
|
street?: string | null;
|
||||||
|
number?: string | null;
|
||||||
|
complement?: string | null;
|
||||||
|
neighborhood?: string | null;
|
||||||
|
city?: string | null;
|
||||||
|
state?: string | null;
|
||||||
|
notes?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ===== MÉDICOS =====
|
// ===== MÉDICOS =====
|
||||||
export type FormacaoAcademica = {
|
export type FormacaoAcademica = {
|
||||||
instituicao: string;
|
instituicao: string;
|
||||||
@ -66,9 +78,10 @@ export type DadosBancarios = {
|
|||||||
tipo_conta: string;
|
tipo_conta: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ===== MÉDICOS =====
|
||||||
export type Medico = {
|
export type Medico = {
|
||||||
id: string;
|
id: string;
|
||||||
nome?: string;
|
full_name: string; // Altere 'nome' para 'full_name'
|
||||||
nome_social?: string | null;
|
nome_social?: string | null;
|
||||||
cpf?: string;
|
cpf?: string;
|
||||||
rg?: string | null;
|
rg?: string | null;
|
||||||
@ -90,21 +103,37 @@ export type Medico = {
|
|||||||
dados_bancarios?: DadosBancarios;
|
dados_bancarios?: DadosBancarios;
|
||||||
agenda_horario?: string;
|
agenda_horario?: string;
|
||||||
valor_consulta?: number | string;
|
valor_consulta?: number | string;
|
||||||
|
active?: boolean;
|
||||||
|
cep?: string;
|
||||||
|
city?: string;
|
||||||
|
complement?: string;
|
||||||
|
neighborhood?: string;
|
||||||
|
number?: string;
|
||||||
|
phone2?: string;
|
||||||
|
state?: string;
|
||||||
|
street?: string;
|
||||||
|
created_at?: string;
|
||||||
|
created_by?: string;
|
||||||
|
updated_at?: string;
|
||||||
|
updated_by?: string;
|
||||||
|
user_id?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ===== MÉDICOS =====
|
||||||
export type MedicoInput = {
|
export type MedicoInput = {
|
||||||
nome: string;
|
full_name: string;
|
||||||
nome_social?: string | null;
|
nome_social?: string | null;
|
||||||
cpf?: string | null;
|
cpf: string;
|
||||||
rg?: string | null;
|
rg?: string | null;
|
||||||
sexo?: string | null;
|
sexo?: string | null;
|
||||||
data_nascimento?: string | null;
|
data_nascimento?: string | null;
|
||||||
telefone?: string | null;
|
telefone?: string;
|
||||||
celular?: string | null;
|
celular?: string; // Este é o celular no seu código, mas talvez tenha que ser 'phone_mobile'
|
||||||
contato_emergencia?: string | null;
|
contato_emergencia?: string;
|
||||||
email?: string | null;
|
email?: string;
|
||||||
crm: string;
|
crm: string;
|
||||||
estado_crm?: string | null;
|
crm_uf?: string | null;
|
||||||
rqe?: string | null;
|
rqe?: string | null;
|
||||||
formacao_academica?: FormacaoAcademica[];
|
formacao_academica?: FormacaoAcademica[];
|
||||||
curriculo_url?: string | null;
|
curriculo_url?: string | null;
|
||||||
@ -114,8 +143,25 @@ export type MedicoInput = {
|
|||||||
dados_bancarios?: DadosBancarios | null;
|
dados_bancarios?: DadosBancarios | null;
|
||||||
agenda_horario?: string | null;
|
agenda_horario?: string | null;
|
||||||
valor_consulta?: number | string | null;
|
valor_consulta?: number | string | null;
|
||||||
|
active?: boolean;
|
||||||
|
cep?: string | null;
|
||||||
|
city?: string | null;
|
||||||
|
complement?: string | null;
|
||||||
|
neighborhood?: string | null;
|
||||||
|
number?: string | null;
|
||||||
|
phone2?: string | null; // Talvez seja o campo correto para o segundo telefone
|
||||||
|
state?: string | null;
|
||||||
|
street?: string | null;
|
||||||
|
created_at?: string;
|
||||||
|
created_by?: string | null;
|
||||||
|
updated_at?: string;
|
||||||
|
updated_by?: string | null;
|
||||||
|
user_id?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ===== CONFIG =====
|
// ===== CONFIG =====
|
||||||
const API_BASE =
|
const API_BASE =
|
||||||
process.env.NEXT_PUBLIC_API_BASE ?? "https://yuanqfswhberkoevtmfr.supabase.co";
|
process.env.NEXT_PUBLIC_API_BASE ?? "https://yuanqfswhberkoevtmfr.supabase.co";
|
||||||
@ -150,20 +196,26 @@ function withPrefer(h: Record<string, string>, prefer: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse genérico
|
// Parse genérico
|
||||||
|
// Dentro de lib/api.ts
|
||||||
async function parse<T>(res: Response): Promise<T> {
|
async function parse<T>(res: Response): Promise<T> {
|
||||||
let json: any = null;
|
let json: any = null;
|
||||||
try {
|
try {
|
||||||
json = await res.json();
|
json = await res.json();
|
||||||
} catch {}
|
} catch (err) {
|
||||||
|
console.error("Erro ao parsear a resposta:", err); // Coloque esse log aqui
|
||||||
|
}
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
console.error("[API ERROR]", res.url, res.status, json);
|
console.error("[API ERROR]", res.url, res.status, json); // Coloque esse log aqui
|
||||||
const code = (json && (json.error?.code || json.code)) ?? res.status;
|
const code = (json && (json.error?.code || json.code)) ?? res.status;
|
||||||
const msg = (json && (json.error?.message || json.message)) ?? res.statusText;
|
const msg = (json && (json.error?.message || json.message)) ?? res.statusText;
|
||||||
throw new Error(`${code}: ${msg}`);
|
throw new Error(`${code}: ${msg}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (json?.data ?? json) as T;
|
return (json?.data ?? json) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Helper de paginação (Range/Range-Unit)
|
// Helper de paginação (Range/Range-Unit)
|
||||||
function rangeHeaders(page?: number, limit?: number): Record<string, string> {
|
function rangeHeaders(page?: number, limit?: number): Record<string, string> {
|
||||||
if (!page || !limit) return {};
|
if (!page || !limit) return {};
|
||||||
@ -270,17 +322,24 @@ export async function buscarMedicoPorId(id: string | number): Promise<Medico> {
|
|||||||
return arr[0];
|
return arr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dentro de lib/api.ts
|
||||||
export async function criarMedico(input: MedicoInput): Promise<Medico> {
|
export async function criarMedico(input: MedicoInput): Promise<Medico> {
|
||||||
const url = `${REST}/doctors`;
|
console.log("Enviando os dados para a API:", input); // Log para depuração
|
||||||
|
|
||||||
|
const url = `${REST}/doctors`; // Endpoint de médicos
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: withPrefer({ ...baseHeaders(), "Content-Type": "application/json" }, "return=representation"),
|
headers: withPrefer({ ...baseHeaders(), "Content-Type": "application/json" }, "return=representation"),
|
||||||
body: JSON.stringify(input),
|
body: JSON.stringify(input), // Enviando os dados padronizados
|
||||||
});
|
});
|
||||||
const arr = await parse<Medico[] | Medico>(res);
|
|
||||||
return Array.isArray(arr) ? arr[0] : (arr as Medico);
|
const arr = await parse<Medico[] | Medico>(res); // Resposta da API
|
||||||
|
return Array.isArray(arr) ? arr[0] : (arr as Medico); // Retorno do médico
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export async function atualizarMedico(id: string | number, input: MedicoInput): Promise<Medico> {
|
export async function atualizarMedico(id: string | number, input: MedicoInput): Promise<Medico> {
|
||||||
const url = `${REST}/doctors?id=eq.${id}`;
|
const url = `${REST}/doctors?id=eq.${id}`;
|
||||||
const res = await fetch(url, {
|
const res = await fetch(url, {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user