feat(mejoras): 25 mejoras UX en todos los módulos + purga Monday

Backend: mi-dia siempre local, vocabulario canónico, AplicacionPago con usuario
Mi día: modal español real, cita desde modal, score falso eliminado
Cotizador: barra sticky, persistencia local con folio
Alta Clientes: redirect eliminado, foto conectada, asesor desde sesión, refs dinámicas
Cobranza: contrato Mora arreglado, link a Plan, abono próximo pago, WhatsApp
Landing: contactos locales, ModalContacto eliminado, ModoTrabajo eliminado
Dashboards: MiTablero unificado, funnel con descartados, drill-down, rango fechas
Chat FRASA: corpus 5 desarrollos, 6 herramientas, historial conversaciones

69 archivos, 7 apps construidas
This commit is contained in:
2026-09-11 06:52:37 +00:00
parent 075d47c304
commit 64b01246d6
69 changed files with 1600 additions and 1133 deletions

View File

@@ -31,7 +31,7 @@ export interface EventoHistorialContacto {
}
export interface DetalleContacto {
contacto: Record<string, string> // columnas del board por título ('nombre' incluido)
contacto: Record<string, string> // campos nombrados del modelo local (nombre, telefono, email, …)
/** Apartado relacionado más reciente (la propiedad comprada o en proceso) */
propiedad: {
id: string
@@ -57,6 +57,32 @@ export function claveTelefono(telefono: string): string {
return digitos.length >= 10 ? digitos.slice(-10) : ''
}
/**
* Mapeo título de columna del board Contactos (Monday) → campo nombrado del
* modelo local. Los títulos sin entrada se conservan tal cual.
*/
const CAMPOS_CONTACTO: Record<string, string> = {
nombre: 'nombre',
'Teléfono': 'telefono',
Email: 'email',
Estado: 'estado',
CURP: 'curp',
RFC: 'rfc',
'Estado Civil': 'estadoCivil',
'Fecha Nacimiento': 'fechaNacimiento',
'Actividad Economica': 'actividadEconomica',
'Dirección': 'direccion',
}
/** Normaliza un record por título de columna a campos nombrados del modelo local */
export function normalizarCamposContacto(contacto: Record<string, string>): Record<string, string> {
const normalizado: Record<string, string> = {}
for (const [titulo, valor] of Object.entries(contacto)) {
normalizado[CAMPOS_CONTACTO[titulo] ?? titulo] = valor
}
return normalizado
}
type MondayDetalle = Pick<
MondayService,
| 'getContactoDetalle'
@@ -169,7 +195,7 @@ export async function detalleContacto(
].sort((a, b) => b.fechaISO.localeCompare(a.fechaISO))
return {
contacto,
contacto: normalizarCamposContacto(contacto),
propiedad,
relaciones: {
leads: relLeads.map((l) => ({