feat(purga): Monday eliminado completamente del sistema
14 servicios eliminados, 7 controllers local-only, crons locales, config sin MONDAY_*, frontend sin banners/avisos Monday. 552 tests API + 7 apps construidas.
This commit is contained in:
@@ -20,7 +20,7 @@ interface Props {
|
||||
onPasarAAltaCliente: (lead: LeadResumen) => void
|
||||
/** Prefill desde Mis oportunidades (Mi día): valores iniciales del formulario */
|
||||
valoresIniciales?: Partial<typeof FORM_INICIAL>
|
||||
/** Oportunidad de Monday a ACTUALIZAR al enviar (sin duplicar el item) */
|
||||
/** Oportunidad a ACTUALIZAR al enviar (sin duplicar el registro) */
|
||||
oportunidadId?: string
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ const FORM_INICIAL = {
|
||||
|
||||
/**
|
||||
* Captura ligera del interesado al entrar al embudo (POST /leads): crea el
|
||||
* lead en Monday y su oportunidad en etapa Afluencia. El alta completa de
|
||||
* lead y su oportunidad en etapa Afluencia. El alta completa de
|
||||
* cliente sigue siendo el wizard del picker.
|
||||
*/
|
||||
export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valoresIniciales, oportunidadId }: Props) {
|
||||
@@ -90,7 +90,7 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor
|
||||
MODELOS_POR_PROYECTO[form.desarrollo as keyof typeof MODELOS_POR_PROYECTO] ?? []
|
||||
|
||||
/**
|
||||
* Jala los datos de un lead u oportunidad ya capturados en Monday:
|
||||
* Jala los datos de un lead u oportunidad ya capturados:
|
||||
* nombre/contacto siempre; origen, desarrollo y modelo solo si el valor del
|
||||
* lead existe entre las opciones del formulario.
|
||||
*/
|
||||
@@ -267,13 +267,13 @@ export default function AltaAfluenciaForm({ onVolver, onPasarAAltaCliente, valor
|
||||
className="mb-6 rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-xs font-medium text-blue-800"
|
||||
>
|
||||
Estás completando la afluencia de {form.nombre || 'esta oportunidad'} — al enviar se actualiza su
|
||||
oportunidad en Monday (no se duplica).
|
||||
oportunidad ya capturada (no se duplica).
|
||||
</p>
|
||||
) : (
|
||||
<div className="mb-6 border-b border-[#E5E7EB] pb-6">
|
||||
<BusquedaLead onSeleccion={prellenarDesdeLead} />
|
||||
<p className="mt-2 text-xs text-[#64748B] dark:text-[#94A3B8]">
|
||||
Si el interesado ya está en Monday (lead u oportunidad), sus datos se prellenan solos.
|
||||
Si el interesado ya está capturado (lead u oportunidad), sus datos se prellenan solos.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { fetchEstadoSistema } from '../services/sistema'
|
||||
|
||||
const INTERVALO_POLL_MS = 60_000
|
||||
|
||||
export function useModoLocal(): boolean {
|
||||
const [modoLocal, setModoLocal] = useState(false)
|
||||
useEffect(() => {
|
||||
let activo = true
|
||||
const consultar = () => {
|
||||
void fetchEstadoSistema().then((estado) => {
|
||||
if (activo) setModoLocal(estado !== null && !estado.mondayOk)
|
||||
})
|
||||
}
|
||||
consultar()
|
||||
const id = setInterval(consultar, INTERVALO_POLL_MS)
|
||||
return () => { activo = false; clearInterval(id) }
|
||||
}, [])
|
||||
return modoLocal
|
||||
}
|
||||
|
||||
export default function BannerModoLocal() {
|
||||
const modoLocal = useModoLocal()
|
||||
if (!modoLocal) return null
|
||||
return (
|
||||
<div role="status" className="border-b border-amber-200 bg-amber-50">
|
||||
<p className="mx-auto max-w-[1280px] px-4 py-2 text-xs font-medium text-amber-700 sm:px-6">
|
||||
Modo local — Monday no disponible. Tus capturas se guardan y se sincronizarán automáticamente.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -67,6 +67,6 @@ describe('BusquedaLead', () => {
|
||||
|
||||
fetchMock.mockRejectedValueOnce(new Error('red caída'))
|
||||
fireEvent.change(screen.getByLabelText(/Buscar lead/), { target: { value: 'otro' } })
|
||||
expect((await screen.findByRole('alert')).textContent).toContain('No se pudo buscar en Monday')
|
||||
expect((await screen.findByRole('alert')).textContent).toContain('No se pudo buscar')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
}
|
||||
|
||||
/**
|
||||
* Buscador con debounce de leads/afluencias de Monday (GET /leads/buscar,
|
||||
* Buscador con debounce de leads/afluencias (GET /leads/buscar,
|
||||
* búsqueda dual: tablero Leads histórico + Oportunidades). No llama al API
|
||||
* con menos de 2 caracteres; al elegir un resultado avisa con onSeleccion.
|
||||
*/
|
||||
@@ -35,7 +35,7 @@ export default function BusquedaLead({ onSeleccion }: Props) {
|
||||
})
|
||||
.catch(() => {
|
||||
setResultados(null)
|
||||
setError('No se pudo buscar en Monday. Intenta de nuevo.')
|
||||
setError('No se pudo buscar. Intenta de nuevo.')
|
||||
})
|
||||
.finally(() => setBuscando(false))
|
||||
}, DEBOUNCE_MS)
|
||||
|
||||
Reference in New Issue
Block a user