feat(8-mejoras): cancelar+motivo, brocker, etapas, calendario, modal cliente

1. Cancelar con motivo: Mis apartados y Escrituración piden motivo (modal reutilizado)
2. Origen BROCKER agregado en alta afluencia y captura rápida
3. Etapas oportunidades reordenadas: Agendo Cita → Afluencia → Cotizador
4. Cotizador: mensualidades diferibles (6, 12, 14, 18, 24 meses)
5. Calendario semanal por vendedor en Mi día
6. Hora en citas (datetime-local en vez de solo fecha)
7. Click en nombre → modal DetalleLeadModal (info + notas + historial)
This commit is contained in:
2026-09-09 10:26:36 +00:00
parent 6db9662838
commit d546460ba4
11 changed files with 808 additions and 26 deletions

View File

@@ -88,11 +88,22 @@ export function convertirLead(itemId: string): Promise<{ oportunidadId: string }
}
/** POST /apartados/:itemId/estado — botones de fase de "Mis apartados" */
export function cambiarEstadoApartado(itemId: string, estado: string): Promise<unknown> {
export function cambiarEstadoApartado(
itemId: string,
estado: string,
motivo?: string,
subcategoria?: string,
comentario?: string,
): Promise<unknown> {
return fetchJson(`/apartados/${itemId}/estado`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ estado }),
body: JSON.stringify({
estado,
...(motivo !== undefined && motivo !== '' ? { motivo } : {}),
...(subcategoria !== undefined && subcategoria !== '' ? { subcategoria } : {}),
...(comentario !== undefined && comentario !== '' ? { comentario } : {}),
}),
})
}

View File

@@ -0,0 +1,44 @@
import { conAuth, manejar401 } from './auth'
const API_URL = import.meta.env.VITE_API_URL ?? '/api'
export interface Recordatorio {
id: string
titulo: string
descripcion: string | null
leadId: string | null
fechaRecordar: string // ISO
completado: boolean
createdAt: string
}
/** GET /api/recordatorios — listar recordatorios del usuario actual */
export async function listarRecordatorios(): Promise<Recordatorio[]> {
const res = await fetch(`${API_URL}/recordatorios`, conAuth())
manejar401(res)
if (!res.ok) {
const body = (await res.json().catch(() => null)) as { error?: string } | null
throw new Error(body?.error ?? `Error ${res.status}`)
}
return (await res.json()) as Recordatorio[]
}
/** POST /api/recordatorios — crear un recordatorio para un lead */
export async function crearRecordatorio(data: {
titulo: string
descripcion?: string
leadId: string
fechaRecordar: string
}): Promise<Recordatorio> {
const res = await fetch(`${API_URL}/recordatorios`, conAuth({
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
}))
manejar401(res)
if (!res.ok) {
const body = (await res.json().catch(() => null)) as { error?: string } | null
throw new Error(body?.error ?? `Error ${res.status}`)
}
return (await res.json()) as Recordatorio
}