backup/fix-patient-page #59
@ -19,14 +19,48 @@ import { listarMedicos, excluirMedico, buscarMedicos, buscarMedicoPorId, buscarP
|
|||||||
import { listAssignmentsForUser } from '@/lib/assignment';
|
import { listAssignmentsForUser } from '@/lib/assignment';
|
||||||
|
|
||||||
function normalizeMedico(m: any): Medico {
|
function normalizeMedico(m: any): Medico {
|
||||||
|
const normalizeSex = (v: any) => {
|
||||||
|
if (v === null || typeof v === 'undefined') return null;
|
||||||
|
const s = String(v || '').trim().toLowerCase();
|
||||||
|
if (!s) return null;
|
||||||
|
const male = new Set(['m','masc','male','masculino','homem','h','1','mas']);
|
||||||
|
const female = new Set(['f','fem','female','feminino','mulher','mul','2','fem']);
|
||||||
|
const other = new Set(['o','outro','other','3','nb','nonbinary','nao binario','não binário']);
|
||||||
|
if (male.has(s)) return 'masculino';
|
||||||
|
if (female.has(s)) return 'feminino';
|
||||||
|
if (other.has(s)) return 'outro';
|
||||||
|
if (['masculino','feminino','outro'].includes(s)) return s;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatBirth = (v: any) => {
|
||||||
|
if (!v && typeof v !== 'string') return null;
|
||||||
|
const s = String(v || '').trim();
|
||||||
|
if (!s) return null;
|
||||||
|
const iso = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
||||||
|
if (iso) {
|
||||||
|
const [, y, mth, d] = iso;
|
||||||
|
return `${d.padStart(2,'0')}/${mth.padStart(2,'0')}/${y}`;
|
||||||
|
}
|
||||||
|
const ddmmyyyy = s.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
||||||
|
if (ddmmyyyy) return s;
|
||||||
|
const parsed = new Date(s);
|
||||||
|
if (!isNaN(parsed.getTime())) {
|
||||||
|
const d = String(parsed.getDate()).padStart(2,'0');
|
||||||
|
const mth = String(parsed.getMonth() + 1).padStart(2,'0');
|
||||||
|
const y = String(parsed.getFullYear());
|
||||||
|
return `${d}/${mth}/${y}`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
return {
|
return {
|
||||||
id: String(m.id ?? m.uuid ?? ""),
|
id: String(m.id ?? m.uuid ?? ""),
|
||||||
full_name: m.full_name ?? m.nome ?? "", // 👈 Correção: usar full_name como padrão
|
full_name: m.full_name ?? m.nome ?? "", // 👈 Correção: usar full_name como padrão
|
||||||
nome_social: m.nome_social ?? m.social_name ?? null,
|
nome_social: m.nome_social ?? m.social_name ?? null,
|
||||||
cpf: m.cpf ?? "",
|
cpf: m.cpf ?? "",
|
||||||
rg: m.rg ?? m.document_number ?? null,
|
rg: m.rg ?? m.document_number ?? null,
|
||||||
sexo: m.sexo ?? m.sex ?? null,
|
sexo: normalizeSex(m.sexo ?? m.sex ?? m.sexualidade ?? null),
|
||||||
data_nascimento: m.data_nascimento ?? m.birth_date ?? null,
|
data_nascimento: formatBirth(m.data_nascimento ?? m.birth_date ?? m.birthDate ?? null),
|
||||||
telefone: m.telefone ?? m.phone_mobile ?? "",
|
telefone: m.telefone ?? m.phone_mobile ?? "",
|
||||||
celular: m.celular ?? m.phone2 ?? null,
|
celular: m.celular ?? m.phone2 ?? null,
|
||||||
contato_emergencia: m.contato_emergencia ?? null,
|
contato_emergencia: m.contato_emergencia ?? null,
|
||||||
|
|||||||
@ -202,37 +202,78 @@ export function DoctorRegistrationForm({
|
|||||||
"";
|
"";
|
||||||
console.log('🎯 Especialidade encontrada:', especialidade);
|
console.log('🎯 Especialidade encontrada:', especialidade);
|
||||||
|
|
||||||
|
const m: any = medico as any;
|
||||||
|
|
||||||
|
const normalizeSex = (v: any): string | null => {
|
||||||
|
if (v === null || typeof v === 'undefined') return null;
|
||||||
|
const s = String(v).trim().toLowerCase();
|
||||||
|
if (!s) return null;
|
||||||
|
const male = new Set(['m','masc','male','masculino','homem','h','1','mas']);
|
||||||
|
const female = new Set(['f','fem','female','feminino','mulher','mul','2','fem']);
|
||||||
|
const other = new Set(['o','outro','other','3','nb','nonbinary','nao binario','não binário']);
|
||||||
|
if (male.has(s)) return 'masculino';
|
||||||
|
if (female.has(s)) return 'feminino';
|
||||||
|
if (other.has(s)) return 'outro';
|
||||||
|
// Already canonical?
|
||||||
|
if (['masculino','feminino','outro'].includes(s)) return s;
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatBirth = (v: any) => {
|
||||||
|
if (!v && typeof v !== 'string') return '';
|
||||||
|
const s = String(v).trim();
|
||||||
|
if (!s) return '';
|
||||||
|
// Accept ISO YYYY-MM-DD or full ISO datetime
|
||||||
|
const isoMatch = s.match(/^(\d{4})-(\d{2})-(\d{2})/);
|
||||||
|
if (isoMatch) {
|
||||||
|
const [, y, mth, d] = isoMatch;
|
||||||
|
return `${d.padStart(2,'0')}/${mth.padStart(2,'0')}/${y}`;
|
||||||
|
}
|
||||||
|
// If already dd/mm/yyyy, return as-is
|
||||||
|
const ddmmyyyy = s.match(/^(\d{2})\/(\d{2})\/(\d{4})$/);
|
||||||
|
if (ddmmyyyy) return s;
|
||||||
|
// Try parsing other common formats
|
||||||
|
const maybe = new Date(s);
|
||||||
|
if (!isNaN(maybe.getTime())) {
|
||||||
|
const d = String(maybe.getDate()).padStart(2,'0');
|
||||||
|
const mm = String(maybe.getMonth() + 1).padStart(2,'0');
|
||||||
|
const y = String(maybe.getFullYear());
|
||||||
|
return `${d}/${mm}/${y}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
const formData = {
|
const formData = {
|
||||||
photo: null,
|
photo: null,
|
||||||
full_name: String(medico.full_name || ""),
|
full_name: String(m.full_name || m.nome || ""),
|
||||||
nome_social: String(medico.nome_social || ""),
|
nome_social: String(m.nome_social || m.social_name || ""),
|
||||||
crm: String(medico.crm || ""),
|
crm: String(m.crm || ""),
|
||||||
estado_crm: String(medico.estado_crm || ""),
|
estado_crm: String(m.estado_crm || m.crm_uf || m.crm_state || ""),
|
||||||
rqe: String(medico.rqe || ""),
|
rqe: String(m.rqe || ""),
|
||||||
formacao_academica: Array.isArray(medico.formacao_academica) ? medico.formacao_academica : [],
|
formacao_academica: Array.isArray(m.formacao_academica) ? m.formacao_academica : [],
|
||||||
curriculo: null,
|
curriculo: null,
|
||||||
especialidade: String(especialidade),
|
especialidade: String(especialidade),
|
||||||
cpf: String(medico.cpf || ""),
|
cpf: String(m.cpf || ""),
|
||||||
rg: String(medico.rg || ""),
|
rg: String(m.rg || m.document_number || ""),
|
||||||
sexo: String(medico.sexo || ""),
|
sexo: normalizeSex(m.sexo || m.sex || m.sexualidade || null) ?? "",
|
||||||
data_nascimento: String(medico.data_nascimento || ""),
|
data_nascimento: String(formatBirth(m.data_nascimento || m.birth_date || m.birthDate || "")),
|
||||||
email: String(medico.email || ""),
|
email: String(m.email || ""),
|
||||||
telefone: String(medico.telefone || ""),
|
telefone: String(m.telefone || m.phone_mobile || m.phone || m.mobile || ""),
|
||||||
celular: String(medico.celular || ""),
|
celular: String(m.celular || m.phone2 || ""),
|
||||||
contato_emergencia: String(medico.contato_emergencia || ""),
|
contato_emergencia: String(m.contato_emergencia || ""),
|
||||||
cep: String(medico.cep || ""),
|
cep: String(m.cep || ""),
|
||||||
logradouro: String(medico.street || ""),
|
logradouro: String(m.street || m.logradouro || ""),
|
||||||
numero: String(medico.number || ""),
|
numero: String(m.number || m.numero || ""),
|
||||||
complemento: String(medico.complement || ""),
|
complemento: String(m.complement || m.complemento || ""),
|
||||||
bairro: String(medico.neighborhood || ""),
|
bairro: String(m.neighborhood || m.bairro || ""),
|
||||||
cidade: String(medico.city || ""),
|
cidade: String(m.city || m.cidade || ""),
|
||||||
estado: String(medico.state || ""),
|
estado: String(m.state || m.estado || ""),
|
||||||
observacoes: String(medico.observacoes || ""),
|
observacoes: String(m.observacoes || m.notes || ""),
|
||||||
anexos: [],
|
anexos: [],
|
||||||
tipo_vinculo: String(medico.tipo_vinculo || ""),
|
tipo_vinculo: String(m.tipo_vinculo || ""),
|
||||||
dados_bancarios: medico.dados_bancarios || { banco: "", agencia: "", conta: "", tipo_conta: "" },
|
dados_bancarios: m.dados_bancarios || { banco: "", agencia: "", conta: "", tipo_conta: "" },
|
||||||
agenda_horario: String(medico.agenda_horario || ""),
|
agenda_horario: String(m.agenda_horario || ""),
|
||||||
valor_consulta: medico.valor_consulta ? String(medico.valor_consulta) : "",
|
valor_consulta: m.valor_consulta ? String(m.valor_consulta) : "",
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("[DoctorForm] Dados do formulário preparados:", formData);
|
console.log("[DoctorForm] Dados do formulário preparados:", formData);
|
||||||
@ -355,9 +396,12 @@ function setField<T extends keyof FormData>(k: T, v: FormData[T]) {
|
|||||||
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
|
// During edit, avoid forcing address fields. They are required on create only.
|
||||||
if (!form.bairro.trim()) e.bairro = "Bairro é obrigatório"; // Verifique se o bairro está preenchido
|
if (mode !== 'edit') {
|
||||||
if (!form.cidade.trim()) e.cidade = "Cidade é obrigatória"; // Verifique se a cidade está preenchida
|
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;
|
||||||
@ -426,7 +470,15 @@ function toPayload(): MedicoInput {
|
|||||||
|
|
||||||
async function handleSubmit(ev: React.FormEvent) {
|
async function handleSubmit(ev: React.FormEvent) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (!validateLocal()) return;
|
console.debug('[DoctorForm] handleSubmit invoked. mode=', mode, 'doctorId=', doctorId);
|
||||||
|
if (!validateLocal()) {
|
||||||
|
try {
|
||||||
|
const { toast } = require('@/hooks/use-toast').useToast();
|
||||||
|
const msgs = Object.entries(errors).map(([k,v]) => v).filter(Boolean).join('\n') || 'Preencha os campos obrigatórios';
|
||||||
|
toast({ title: 'Erro de validação', description: msgs, variant: 'destructive' });
|
||||||
|
} catch {}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
setErrors({});
|
setErrors({});
|
||||||
|
|||||||
@ -2086,17 +2086,41 @@ export async function atualizarMedico(id: string | number, input: MedicoInput):
|
|||||||
|
|
||||||
// Criar um payload limpo apenas com campos básicos que sabemos que existem
|
// Criar um payload limpo apenas com campos básicos que sabemos que existem
|
||||||
const cleanPayload = {
|
const cleanPayload = {
|
||||||
|
// Basic identification / contact
|
||||||
full_name: input.full_name,
|
full_name: input.full_name,
|
||||||
|
nome_social: (input as any).nome_social || undefined,
|
||||||
crm: input.crm,
|
crm: input.crm,
|
||||||
|
crm_uf: (input as any).crm_uf || (input as any).crmUf || undefined,
|
||||||
|
rqe: (input as any).rqe || undefined,
|
||||||
specialty: input.specialty,
|
specialty: input.specialty,
|
||||||
email: input.email,
|
email: input.email,
|
||||||
phone_mobile: input.phone_mobile,
|
phone_mobile: input.phone_mobile,
|
||||||
|
phone2: (input as any).phone2 ?? (input as any).telefone ?? undefined,
|
||||||
cpf: input.cpf,
|
cpf: input.cpf,
|
||||||
|
rg: (input as any).rg ?? undefined,
|
||||||
|
|
||||||
|
// Address
|
||||||
cep: input.cep,
|
cep: input.cep,
|
||||||
street: input.street,
|
street: input.street,
|
||||||
number: input.number,
|
number: input.number,
|
||||||
|
complement: (input as any).complement ?? undefined,
|
||||||
|
neighborhood: (input as any).neighborhood ?? (input as any).bairro ?? undefined,
|
||||||
city: input.city,
|
city: input.city,
|
||||||
state: input.state,
|
state: input.state,
|
||||||
|
|
||||||
|
// Personal / professional
|
||||||
|
birth_date: (input as any).birth_date ?? (input as any).data_nascimento ?? undefined,
|
||||||
|
sexo: (input as any).sexo ?? undefined,
|
||||||
|
formacao_academica: (input as any).formacao_academica ?? undefined,
|
||||||
|
observacoes: (input as any).observacoes ?? undefined,
|
||||||
|
|
||||||
|
// Administrative / financial
|
||||||
|
tipo_vinculo: (input as any).tipo_vinculo ?? undefined,
|
||||||
|
dados_bancarios: (input as any).dados_bancarios ?? undefined,
|
||||||
|
valor_consulta: (input as any).valor_consulta ?? undefined,
|
||||||
|
agenda_horario: (input as any).agenda_horario ?? undefined,
|
||||||
|
|
||||||
|
// Flags
|
||||||
active: input.active ?? true
|
active: input.active ?? true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user