feat: rol manager, arreglos de reportes (cancelacion/afluencias), credito unico, cliente enkontrol, vendedor en bitacora y actualizar afluencia existente

This commit is contained in:
2026-09-18 15:25:34 +00:00
parent 9630893974
commit 4965a4488a
35 changed files with 303 additions and 90 deletions

View File

@@ -259,8 +259,11 @@ export default function DetalleLeadModal({
{tab === 'notas' && (
<div className="space-y-4">
{/* Barra de herramientas */}
<div className="flex items-center gap-3">
<div className="flex flex-wrap items-center gap-3">
<h3 className="text-lg font-semibold text-[#111827] dark:text-[#E2E8F0]">Notas</h3>
<span className="rounded-full bg-[#F1F5F9] px-2.5 py-0.5 text-xs font-medium text-[#374151] dark:bg-[#0F172A] dark:text-[#CBD5E1]">
Vendedor asignado: <strong className="font-semibold">{item.vendedor?.trim() !== '' ? item.vendedor : 'sin asignar'}</strong>
</span>
<div className="ml-auto flex items-center gap-2">
<div className="relative">
<Search className="absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-[#94A3B8]" />

View File

@@ -29,6 +29,7 @@ const apartadoFake: ApartadoMiDia = {
telefono: '6641234567',
email: 'juan@example.com',
origen: 'PASE',
vendedor: 'Martin Zavala',
desarrollo: 'DIAGONAL',
unidadCodigo: 'D-101',
estado: 'En proceso',

View File

@@ -80,6 +80,7 @@ describe('urlCotizadorParaOportunidad', () => {
etapa: 'Afluencia',
desarrollo: 'SENDA',
modeloInteres: 'SOHO',
vendedor: 'Martin Zavala',
unidadCodigo: 'U-9',
updatedAt: '2026-09-04T10:00:00Z',
ultimoCambio: null,
@@ -118,6 +119,7 @@ describe('urlAfluenciaParaOportunidad', () => {
etapa: 'Agendo Cita',
desarrollo: 'SENDA',
modeloInteres: 'SOHO',
vendedor: 'Martin Zavala',
unidadCodigo: '',
updatedAt: '2026-09-04T10:00:00Z',
ultimoCambio: null,

View File

@@ -8,6 +8,8 @@ export interface LeadMiDia {
estado: string
origen: string
desarrollo?: string
/** Vendedor asignado (nombre); '' si no tiene */
vendedor: string
updatedAt: string
/** Tablero del item: 'lead' (captura ligera) u 'oportunidad' (afluencia) */
fuente: 'lead' | 'oportunidad'
@@ -61,6 +63,8 @@ export interface OportunidadMiDia {
etapa: string
desarrollo: string
modeloInteres: string
/** Vendedor asignado (nombre); '' si no tiene */
vendedor: string
unidadCodigo: string
updatedAt: string
ultimoCambio: { fechaISO: string; usuario: string | null; detalle: string } | null
@@ -76,6 +80,8 @@ export interface ApartadoMiDia {
email: string
origen: string
desarrollo: string
/** Vendedor asignado (nombre); '' si no tiene */
vendedor: string
unidadCodigo: string
estado: string
fechaLimite: string // 'YYYY-MM-DD' ('' si no tiene)

View File

@@ -1313,7 +1313,7 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
onDescartar={() => setDescartando(lead)}
onVerDetalle={() => setLeadSeleccionado(lead)}
acciones={acciones}
esAdmin={rol === 'admin'}
esAdmin={rol === 'admin' || rol === 'manager'}
vendedores={resumen.equipo?.porVendedor.map((v) => ({ id: v.usuarioId, nombre: v.nombre ?? '' }))}
onReasignar={(usuarioId) => void reasignar(lead, usuarioId)}
onMover={() => void mover(lead)}

View File

@@ -33,6 +33,7 @@ const leadFake: LeadMiDia = {
email: 'juan@test.com',
estado: 'CONTACTADO',
origen: 'PASE',
vendedor: 'Martin Zavala',
updatedAt: '2026-09-01T10:00:00Z',
fuente: 'lead',
ultimoCambio: { fechaISO: '2026-09-01T10:00:00Z', usuario: 'Admin', detalle: 'Lead creado' },
@@ -46,6 +47,7 @@ const opFake: OportunidadMiDia = {
etapa: 'Agendo Cita',
desarrollo: 'DIAGONAL',
modeloInteres: 'Modelo A',
vendedor: 'Martin Zavala',
unidadCodigo: 'D-101',
updatedAt: '2026-09-02T12:00:00Z',
ultimoCambio: { fechaISO: '2026-09-02T12:00:00Z', usuario: 'Admin', detalle: 'Etapa cambiada' },
@@ -57,6 +59,7 @@ const apartadoFake: ApartadoMiDia = {
telefono: '6641234567',
email: 'carlos@example.com',
origen: 'REFERIDO',
vendedor: 'Martin Zavala',
desarrollo: 'ESTANZA',
unidadCodigo: 'E-202',
estado: 'En proceso',