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

@@ -218,7 +218,14 @@ export async function resumenMiDia(
/** mondayUserId -> nombre para mostrar (usuarios del ecosistema ya mapeados) */
nombresPorMondayId: Map<number, string>,
/** Capturas locales del usuario (tabla LeadCaptura), ya filtradas por él */
capturas: { leadId: string; nombreLead: string; telefono: string | null; createdAt: Date }[] = [],
capturas: {
leadId: string
nombreLead: string
telefono: string | null
createdAt: Date
/** Oportunidad ligada (LeadOportunidad); null si la captura aún no convertió */
oportunidadId?: string | null
}[] = [],
/** Clientes cuyo alta inició el usuario (tabla Cliente), ya filtrados por él */
clientes: {
id: string
@@ -332,7 +339,10 @@ export async function resumenMiDia(
)
// Set de oportunidades mías (por LeadCaptura o por vendedorIds)
const miosOportunidadesIds = new Set(
capturas.filter((c) => c.oportunidadId).map((c) => c.oportunidadId),
capturas
.filter((c) => c.oportunidadId)
.map((c) => c.oportunidadId)
.filter((id): id is string => id != null),
)
const miosApartadosTodos = apartados.filter((a) =>
esMio(a.vendedorIds, a.id) || apartadosDeMisClientes.has(a.id) || miosOportunidadesIds.has(a.id),
@@ -387,7 +397,8 @@ export async function resumenMiDia(
estado: a.estado,
fechaLimite: a.fechaLimite,
ultimoCambio: null as { fechaISO: string; usuario: string | null; detalle: string } | null,
pendienteSync: a.pendienteSync,
// Los apartados leídos de Monday ya están sincronizados por definición
pendienteSync: false,
}))
const misApartados: ApartadoMiDia[] = miosApartados
@@ -874,9 +885,9 @@ export function resumenMiDiaLocal(
.map((c) => ({
id: c.leadId,
nombre: c.nombreLead,
unidadCodigo: '',
unidadCodigo: unidadPorApartadoId.get(c.leadId) ?? '',
estado: c.etapa,
fechaLimite: '',
fechaLimite: c.fechaLimite ? c.fechaLimite.toISOString().slice(0, 10) : '',
ultimoCambio: null,
pendienteSync: c.pendienteSync,
})),