feat(alta): separar en Alta Afluencia y Alta de Cliente

- Nueva pantalla de entrada en /client con dos opciones:
  · Alta Afluencia: captura ligera (nombre, teléfono, email, origen,
    desarrollo de interés, notas) → POST /api/leads (lead + oportunidad
    Afluencia + round-robin, todo ya existente en el API)
  · Alta de Cliente: formato completo actual (picker + wizard intactos)
- Manejo de duplicado por teléfono (409 con nombre del lead existente)
- ?cotizacion=<id> sigue saltando directo al wizard
- Tests: 107 verdes (11 nuevos); smoke en vivo OK y limpio
This commit is contained in:
2026-09-01 20:24:26 +00:00
parent 98fedbd8d3
commit 2b87bf66a7
6 changed files with 515 additions and 7 deletions

View File

@@ -183,6 +183,57 @@ export async function buscarLeads(q: string): Promise<LeadResumen[]> {
return (await res.json()) as LeadResumen[]
}
export interface LeadCreado {
id: string
estado: string
oportunidadId: string | null
}
/** Resultado del alta de afluencia: distingue duplicado (409) de fallo de red */
export type ResultadoCrearLead =
| { ok: true; lead: LeadCreado }
| { ok: false; motivo: 'duplicado'; leadId: string; nombre: string }
| { ok: false; motivo: 'conexion' }
/**
* POST /leads — captura ligera de afluencia: crea el lead en Monday y su
* oportunidad en etapa Afluencia (round-robin). Si el teléfono ya existe el
* API responde 409 con el lead existente (motivo 'duplicado').
*/
export async function crearLead(payload: {
nombre: string
telefono: string
email?: string
origen?: string
desarrollo?: string
notas?: string
}): Promise<ResultadoCrearLead> {
let res: Response
try {
res = await fetch(
`${API_URL}/leads`,
conAuth({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
}),
)
} catch (err) {
console.warn('[api] crearLead: sin conexión al servidor', err)
return { ok: false, motivo: 'conexion' }
}
manejar401(res)
if (res.status === 201) {
return { ok: true, lead: (await res.json()) as LeadCreado }
}
if (res.status === 409) {
const cuerpo = (await res.json()) as { leadId: string; nombre: string }
return { ok: false, motivo: 'duplicado', leadId: cuerpo.leadId, nombre: cuerpo.nombre }
}
console.warn(`[api] crearLead: HTTP ${res.status}`)
return { ok: false, motivo: 'conexion' }
}
// ---------- Liga remota de firma (auth) ----------
export interface LigaRemota {