- GET /api/contactos/:id/detalle: todas las columnas del contacto, la propiedad comprada/en proceso (apartado relacionado por teléfono/email, enriquecido con el desarrollo de la unidad), quién atiende cada item relacionado (leads/oportunidades/apartados, columna people) y el historial completo de atención (activity log de los 4 tableros + capturas y alta local con nombre del capturista) - monday.service: getContactoDetalle (columnas por título), getHistorialItems (todos los eventos del activity log por items) y ApartadoMonday enriquecido (teléfono, email, precio final, fecha compra) - Landing: la lista de Contactos abre un modal por cliente con datos, propiedad, relaciones CRM (con quién atiende) y timeline de historial - Tests: 465 API + 12 landing, verde
103 lines
3.1 KiB
TypeScript
103 lines
3.1 KiB
TypeScript
import { API_URL, conAuth, manejar401, type UsuarioSesion } from './auth'
|
|
|
|
export interface UsuarioMonday {
|
|
id: number
|
|
nombre: string
|
|
email: string
|
|
}
|
|
|
|
/** GET /auth/me — perfil del usuario autenticado (incluye mondayUserId y modulos) */
|
|
export async function getMe(): Promise<UsuarioSesion> {
|
|
const resp = await fetch(`${API_URL}/auth/me`, conAuth())
|
|
manejar401(resp)
|
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
|
|
return (await resp.json()) as UsuarioSesion
|
|
}
|
|
|
|
export interface Contacto {
|
|
id: string
|
|
nombre: string
|
|
telefono: string
|
|
email: string
|
|
estado: string
|
|
updatedAt: string
|
|
}
|
|
|
|
/** GET /contactos — contactos del tablero Contactos de Monday (máx 100) */
|
|
export async function getContactos(): Promise<Contacto[]> {
|
|
const resp = await fetch(`${API_URL}/contactos`, conAuth())
|
|
manejar401(resp)
|
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
|
|
return (await resp.json()) as Contacto[]
|
|
}
|
|
|
|
/** GET /monday/usuarios — usuarios activos del workspace para el dropdown */
|
|
export async function getUsuariosMonday(): Promise<UsuarioMonday[]> {
|
|
const resp = await fetch(`${API_URL}/monday/usuarios`, conAuth())
|
|
manejar401(resp)
|
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
|
|
return (await resp.json()) as UsuarioMonday[]
|
|
}
|
|
|
|
/** PATCH /usuarios/me/monday — vincula (number) o desvincula (null) la cuenta Monday */
|
|
export async function guardarVinculoMonday(mondayUserId: number | null): Promise<UsuarioSesion> {
|
|
const resp = await fetch(
|
|
`${API_URL}/usuarios/me/monday`,
|
|
conAuth({
|
|
method: 'PATCH',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ mondayUserId }),
|
|
}),
|
|
)
|
|
manejar401(resp)
|
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
|
|
return (await resp.json()) as UsuarioSesion
|
|
}
|
|
|
|
// ---------- Detalle de contacto (modal del módulo Contactos) ----------
|
|
|
|
export interface RelacionCrm {
|
|
id: string
|
|
nombre: string
|
|
estado: string
|
|
/** Quién lo atiende ahora (columna people del tablero); null si sin asignar */
|
|
atendidoPor: string | null
|
|
detalle: string
|
|
}
|
|
|
|
export interface EventoHistorialContacto {
|
|
fechaISO: string
|
|
usuario: string | null
|
|
detalle: string
|
|
fuente: string // 'Contactos' | 'Leads' | 'Oportunidades' | 'Apartado' | 'App'
|
|
}
|
|
|
|
export interface DetalleContacto {
|
|
/** Columnas del board por título ('nombre' incluido); '' si vacía */
|
|
contacto: Record<string, string>
|
|
propiedad: {
|
|
id: string
|
|
unidadCodigo: string
|
|
desarrollo: string
|
|
estado: string
|
|
precioFinal: number
|
|
fechaCompra: string
|
|
fechaLimite: string
|
|
atendidoPor: string | null
|
|
} | null
|
|
relaciones: {
|
|
leads: RelacionCrm[]
|
|
oportunidades: RelacionCrm[]
|
|
apartados: RelacionCrm[]
|
|
}
|
|
historial: EventoHistorialContacto[]
|
|
}
|
|
|
|
/** GET /contactos/:id/detalle — ficha completa: info, propiedad, quién atiende e historial */
|
|
export async function getContactoDetalle(id: string): Promise<DetalleContacto> {
|
|
const resp = await fetch(`${API_URL}/contactos/${id}/detalle`, conAuth())
|
|
manejar401(resp)
|
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`)
|
|
return (await resp.json()) as DetalleContacto
|
|
}
|