diff --git a/apps/alta-clientes/src/components/AltaAfluenciaForm.tsx b/apps/alta-clientes/src/components/AltaAfluenciaForm.tsx index 476bdb0..165f3a8 100644 --- a/apps/alta-clientes/src/components/AltaAfluenciaForm.tsx +++ b/apps/alta-clientes/src/components/AltaAfluenciaForm.tsx @@ -155,7 +155,12 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor nombrePila, apellidoPaterno, apellidoMaterno, - telefono: numero, + telefono: (() => { + // Normaliza a dígitos y toma los últimos 10 (limpia ladas duplicadas, + // espacios inseparables y marcas invisibles de copiar/pegar) + const soloDigitos = numero.replace(/\D/g, '') + return soloDigitos.length > 10 ? soloDigitos.slice(-10) : soloDigitos + })(), email: lead.email, origen: (ORIGENES_LEAD as readonly string[]).includes(lead.origen) ? lead.origen : prev.origen, desarrollo, @@ -173,6 +178,9 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor const nombreCompuesto = nombreCompleto() if (nombreCompuesto === '') nuevos.nombrePila = 'El nombre es obligatorio' if (!form.telefono.trim()) nuevos.telefono = 'El teléfono es obligatorio' + else if (form.telefono.replace(/\D/g, '').length !== 10) { + nuevos.telefono = 'El teléfono debe tener exactamente 10 dígitos' + } if (form.email.trim() && !emailSchema.safeParse(form.email).success) { nuevos.email = 'Correo electrónico inválido' } @@ -423,13 +431,19 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor { + setForm((prev) => ({ ...prev, telefono: e.target.value.replace(/\D/g, '').slice(0, 10) })) + setErrores((prev) => ({ ...prev, telefono: undefined })) + }} required className={`${inputClase} ${errores.telefono ? 'border-red-400' : ''}`} /> +

10 dígitos, sin lada (la lada va en el selector)

{errores.telefono &&

{errores.telefono}

} diff --git a/apps/alta-clientes/src/components/Campos.tsx b/apps/alta-clientes/src/components/Campos.tsx index a284eca..2c19c18 100644 --- a/apps/alta-clientes/src/components/Campos.tsx +++ b/apps/alta-clientes/src/components/Campos.tsx @@ -117,10 +117,17 @@ export function CampoTelefono({ nombre, etiqueta, requerido, className }: CampoB const { watch, setValue, formState: { errors } } = useFormContext() const valor = ((watch(nombre) as string) ?? '').trim() const lada = valor.startsWith('+1') ? '+1' : '+52' - const numero = valor.startsWith('+1') ? valor.slice(2).trim() : valor.startsWith('+52') ? valor.slice(3).trim() : valor + // Normaliza lo que se muestra: dígitos, últimos 10 (limpia ladas duplicadas + // o caracteres invisibles heredados de registros viejos) + const numero = (() => { + const crudo = valor.startsWith('+1') ? valor.slice(2).trim() : valor.startsWith('+52') ? valor.slice(3).trim() : valor + const d = crudo.replace(/\D/g, '') + return d.length > 10 ? d.slice(-10) : d + })() const actualizar = (nuevaLada: string, nuevoNumero: string) => { - const limpio = nuevoNumero.trim() + // Sólo dígitos y máximo 10 (la lada va en el selector) + const limpio = nuevoNumero.replace(/\D/g, '').slice(0, 10) // Vacío se guarda vacío (sin prefijo huérfano); con número, compuesto setValue(nombre, limpio === '' ? '' : `${nuevaLada} ${limpio}`, { shouldValidate: true }) } @@ -144,12 +151,15 @@ export function CampoTelefono({ nombre, etiqueta, requerido, className }: CampoB actualizar(lada, e.target.value)} className={claseInput(nombre, errors)} /> +

10 dígitos, sin lada

) diff --git a/apps/alta-clientes/src/lib/schemas.ts b/apps/alta-clientes/src/lib/schemas.ts index b1af13a..cee4387 100644 --- a/apps/alta-clientes/src/lib/schemas.ts +++ b/apps/alta-clientes/src/lib/schemas.ts @@ -62,8 +62,16 @@ export const datosGeneralesSchema = z peso: textoOpcional, estatura: textoOpcional, email: z.string().trim().email('Correo electrónico inválido'), - telCasa: textoOpcional, - celular: z.string().trim().min(8, 'El celular es requerido'), + // Teléfonos: 10 dígitos (con o sin lada compuesta; el campo sólo acepta + // dígitos en la UI, así que aquí sólo se valida la longitud mínima) + telCasa: z + .string() + .trim() + .refine((v) => v === '' || v.replace(/\D/g, '').length >= 10, 'El teléfono debe tener 10 dígitos'), + celular: z + .string() + .trim() + .refine((v) => v.replace(/\D/g, '').length >= 10, 'El celular debe tener 10 dígitos'), viviendaAnios: textoOpcional, tipoVivienda: z.enum(['PRESTADA', 'RENTADA', 'FAMILIAR', 'PROPIA', '']), tipoCompra: z.enum(['INVERSION', 'VIVIR_AHI', '']),