fix(mi-dia): eliminar modales antiguos, solo queda DetalleLeadModal
- Eliminado ModalDescarteGenerico (función completa) - Eliminado ModalDescartar (función completa) - Eliminado TimelineLead import y leadTimeline state - Eliminado botón 'Historial' de FilaLead - Eliminado prop onTimeline de FilaLead - Eliminado modal JSX de timeline - Descarte ahora es llamada directa sin modal - 1525 líneas (antes 1800)
This commit is contained in:
@@ -14,10 +14,8 @@ import {
|
|||||||
ETIQUETA_FASE_ESCRITURACION,
|
ETIQUETA_FASE_ESCRITURACION,
|
||||||
ETIQUETA_FASE_OPORTUNIDAD,
|
ETIQUETA_FASE_OPORTUNIDAD,
|
||||||
FASES_APARTADO,
|
FASES_APARTADO,
|
||||||
MOTIVOS_NO_COMPRA,
|
|
||||||
ORIGENES_LEAD,
|
ORIGENES_LEAD,
|
||||||
SLOTS_DOCS_APARTADO,
|
SLOTS_DOCS_APARTADO,
|
||||||
SUBCATEGORIAS_NO_COMPRA,
|
|
||||||
componerTelefono,
|
componerTelefono,
|
||||||
LADAS,
|
LADAS,
|
||||||
textoDiasRestantes,
|
textoDiasRestantes,
|
||||||
@@ -27,7 +25,6 @@ import {
|
|||||||
type ClaveLada,
|
type ClaveLada,
|
||||||
type FaseApartado,
|
type FaseApartado,
|
||||||
type LeadMiDia,
|
type LeadMiDia,
|
||||||
type MotivoNoCompra,
|
|
||||||
type OportunidadMiDia,
|
type OportunidadMiDia,
|
||||||
type ResumenMiDia,
|
type ResumenMiDia,
|
||||||
type SlotDocApartado,
|
type SlotDocApartado,
|
||||||
@@ -53,7 +50,6 @@ import { getSesion } from '../services/auth'
|
|||||||
import DashboardVendedor from '../components/DashboardVendedor'
|
import DashboardVendedor from '../components/DashboardVendedor'
|
||||||
import ScoreBadge, { calcularScore } from '../components/ScoreBadge'
|
import ScoreBadge, { calcularScore } from '../components/ScoreBadge'
|
||||||
import KanbanView from '../components/KanbanView'
|
import KanbanView from '../components/KanbanView'
|
||||||
import TimelineLead, { type EventoLead } from '../components/TimelineLead'
|
|
||||||
import CalendarioCitas from '../components/CalendarioCitas'
|
import CalendarioCitas from '../components/CalendarioCitas'
|
||||||
import DetalleLeadModal from '../components/DetalleLeadModal'
|
import DetalleLeadModal from '../components/DetalleLeadModal'
|
||||||
|
|
||||||
@@ -112,209 +108,6 @@ const CLASE_INPUT =
|
|||||||
|
|
||||||
const CLASE_LABEL = 'mb-2 block text-xs font-medium text-[#4B5563] dark:text-[#CBD5E1]'
|
const CLASE_LABEL = 'mb-2 block text-xs font-medium text-[#4B5563] dark:text-[#CBD5E1]'
|
||||||
|
|
||||||
/** Modal genérico de descarte/cancelación con motivo + subcategoría + comentario */
|
|
||||||
function ModalDescarteGenerico({
|
|
||||||
item,
|
|
||||||
titulo,
|
|
||||||
onCancelar,
|
|
||||||
onConfirmar,
|
|
||||||
enviando,
|
|
||||||
}: {
|
|
||||||
item: { id: string; nombre: string }
|
|
||||||
titulo: string
|
|
||||||
onCancelar: () => void
|
|
||||||
onConfirmar: (motivo: MotivoNoCompra, subcategoria: string | undefined, comentario: string) => void
|
|
||||||
enviando: boolean
|
|
||||||
}) {
|
|
||||||
const [motivo, setMotivo] = useState<MotivoNoCompra>(MOTIVOS_NO_COMPRA[0])
|
|
||||||
const [subcategoria, setSubcategoria] = useState('')
|
|
||||||
const [comentario, setComentario] = useState('')
|
|
||||||
const subcategorias = SUBCATEGORIAS_NO_COMPRA[motivo]
|
|
||||||
return (
|
|
||||||
<div className="fixed inset-0 z-10 flex items-center justify-center bg-black/40 px-4" role="dialog" aria-modal="true">
|
|
||||||
<div className="w-full max-w-md rounded-2xl border border-[#E5E7EB] bg-white p-6 dark:border-[#1E293B] dark:bg-[#1E293B] shadow-xl">
|
|
||||||
<p className="text-xs font-semibold uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">{titulo}</p>
|
|
||||||
<p className="mt-2 text-lg font-medium text-[#111827] dark:text-[#E2E8F0]">{item.nombre}</p>
|
|
||||||
<form
|
|
||||||
className="mt-6 space-y-4"
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
onConfirmar(motivo, subcategoria === '' ? undefined : subcategoria, comentario.trim())
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="motivo-descarte" className={CLASE_LABEL}>
|
|
||||||
Motivo
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
id="motivo-descarte"
|
|
||||||
value={motivo}
|
|
||||||
onChange={(e) => {
|
|
||||||
setMotivo(e.target.value as MotivoNoCompra)
|
|
||||||
setSubcategoria('')
|
|
||||||
}}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
>
|
|
||||||
{MOTIVOS_NO_COMPRA.map((m) => (
|
|
||||||
<option key={m} value={m}>
|
|
||||||
{m}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="subcategoria-descarte" className={CLASE_LABEL}>
|
|
||||||
Subcategoría
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
id="subcategoria-descarte"
|
|
||||||
value={subcategoria}
|
|
||||||
onChange={(e) => setSubcategoria(e.target.value)}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
>
|
|
||||||
<option value="">— Selecciona —</option>
|
|
||||||
{subcategorias.map((s) => (
|
|
||||||
<option key={s} value={s}>
|
|
||||||
{s}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="comentario-descarte" className={CLASE_LABEL}>
|
|
||||||
Comentario (opcional)
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
id="comentario-descarte"
|
|
||||||
value={comentario}
|
|
||||||
onChange={(e) => setComentario(e.target.value)}
|
|
||||||
rows={3}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-end gap-3">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={onCancelar}
|
|
||||||
disabled={enviando}
|
|
||||||
className="rounded-lg border border-[#D1D5DB] bg-white px-5 dark:border-[#334155] dark:bg-[#0F172A] dark:text-[#E2E8F0] py-2 text-sm font-medium text-[#374151] dark:text-[#CBD5E1] transition-all duration-100 ease-out hover:bg-[#F9FAFB] disabled:opacity-50"
|
|
||||||
>
|
|
||||||
Cancelar
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
disabled={enviando}
|
|
||||||
className="rounded-lg bg-red-600 px-5 py-2 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-red-700 disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{enviando ? 'Procesando…' : 'Confirmar'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Modal de descarte: motivo + subcategoría (catálogo Monday) + comentario opcional */
|
|
||||||
function ModalDescartar({
|
|
||||||
lead,
|
|
||||||
onCancelar,
|
|
||||||
onConfirmar,
|
|
||||||
enviando,
|
|
||||||
}: {
|
|
||||||
lead: { id: string; nombre: string }
|
|
||||||
onCancelar: () => void
|
|
||||||
onConfirmar: (motivo: MotivoNoCompra, subcategoria: string | undefined, comentario: string) => void
|
|
||||||
enviando: boolean
|
|
||||||
}) {
|
|
||||||
const [motivo, setMotivo] = useState<MotivoNoCompra>(MOTIVOS_NO_COMPRA[0])
|
|
||||||
const [subcategoria, setSubcategoria] = useState('')
|
|
||||||
const [comentario, setComentario] = useState('')
|
|
||||||
const subcategorias = SUBCATEGORIAS_NO_COMPRA[motivo]
|
|
||||||
return (
|
|
||||||
<div className="fixed inset-0 z-10 flex items-center justify-center bg-black/40 px-4" role="dialog" aria-modal="true">
|
|
||||||
<div className="w-full max-w-md rounded-2xl border border-[#E5E7EB] bg-white p-6 dark:border-[#1E293B] dark:bg-[#1E293B] shadow-xl">
|
|
||||||
<p className="text-xs font-semibold uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">Descartar lead</p>
|
|
||||||
<p className="mt-2 text-lg font-medium text-[#111827] dark:text-[#E2E8F0]">{lead.nombre}</p>
|
|
||||||
<form
|
|
||||||
className="mt-6 space-y-4"
|
|
||||||
onSubmit={(e) => {
|
|
||||||
e.preventDefault()
|
|
||||||
onConfirmar(motivo, subcategoria === '' ? undefined : subcategoria, comentario.trim())
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="motivo-descarte" className={CLASE_LABEL}>
|
|
||||||
Motivo
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
id="motivo-descarte"
|
|
||||||
value={motivo}
|
|
||||||
onChange={(e) => {
|
|
||||||
setMotivo(e.target.value as MotivoNoCompra)
|
|
||||||
setSubcategoria('') // las subcategorías dependen de la categoría
|
|
||||||
}}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
>
|
|
||||||
{MOTIVOS_NO_COMPRA.map((m) => (
|
|
||||||
<option key={m} value={m}>
|
|
||||||
{m}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="subcategoria-descarte" className={CLASE_LABEL}>
|
|
||||||
Subcategoría
|
|
||||||
</label>
|
|
||||||
<select
|
|
||||||
id="subcategoria-descarte"
|
|
||||||
value={subcategoria}
|
|
||||||
onChange={(e) => setSubcategoria(e.target.value)}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
>
|
|
||||||
<option value="">— Selecciona —</option>
|
|
||||||
{subcategorias.map((s) => (
|
|
||||||
<option key={s} value={s}>
|
|
||||||
{s}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label htmlFor="comentario-descarte" className={CLASE_LABEL}>
|
|
||||||
Comentario (opcional)
|
|
||||||
</label>
|
|
||||||
<textarea
|
|
||||||
id="comentario-descarte"
|
|
||||||
value={comentario}
|
|
||||||
onChange={(e) => setComentario(e.target.value)}
|
|
||||||
rows={3}
|
|
||||||
className={CLASE_INPUT}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex justify-end gap-3">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={onCancelar}
|
|
||||||
disabled={enviando}
|
|
||||||
className="rounded-lg border border-[#D1D5DB] bg-white px-5 dark:border-[#334155] dark:bg-[#0F172A] dark:text-[#E2E8F0] py-2 text-sm font-medium text-[#374151] dark:text-[#CBD5E1] transition-all duration-100 ease-out hover:bg-[#F9FAFB] disabled:opacity-50"
|
|
||||||
>
|
|
||||||
Cancelar
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
disabled={enviando}
|
|
||||||
className="rounded-lg bg-red-600 px-5 py-2 text-sm font-medium text-white shadow-sm transition-all duration-100 ease-out hover:bg-red-700 disabled:opacity-50"
|
|
||||||
>
|
|
||||||
{enviando ? 'Descartando…' : 'Descartar'}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Fila de oportunidad con botones de fase del funnel (Agendo Cita lleva fecha) */
|
/** Fila de oportunidad con botones de fase del funnel (Agendo Cita lleva fecha) */
|
||||||
function FilaOportunidad({
|
function FilaOportunidad({
|
||||||
@@ -444,13 +237,11 @@ function FilaOportunidad({
|
|||||||
function FilaApartado({
|
function FilaApartado({
|
||||||
apartado,
|
apartado,
|
||||||
onFase,
|
onFase,
|
||||||
onCancelacion,
|
|
||||||
onVerDetalle,
|
onVerDetalle,
|
||||||
enviando,
|
enviando,
|
||||||
}: {
|
}: {
|
||||||
apartado: ApartadoMiDia
|
apartado: ApartadoMiDia
|
||||||
onFase: (fase: FaseApartado) => void
|
onFase: (fase: FaseApartado) => void
|
||||||
onCancelacion: () => void
|
|
||||||
onVerDetalle?: () => void
|
onVerDetalle?: () => void
|
||||||
enviando: boolean
|
enviando: boolean
|
||||||
}) {
|
}) {
|
||||||
@@ -500,7 +291,6 @@ function FilaApartado({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (fase === 'Cancelacion Apartado') {
|
if (fase === 'Cancelacion Apartado') {
|
||||||
onCancelacion()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
onFase(fase)
|
onFase(fase)
|
||||||
@@ -703,7 +493,6 @@ function FilaLead({
|
|||||||
onAccion,
|
onAccion,
|
||||||
onConvertir,
|
onConvertir,
|
||||||
onDescartar,
|
onDescartar,
|
||||||
onTimeline,
|
|
||||||
onVerDetalle,
|
onVerDetalle,
|
||||||
enviando,
|
enviando,
|
||||||
acciones,
|
acciones,
|
||||||
@@ -712,7 +501,6 @@ function FilaLead({
|
|||||||
onAccion: (estado: string, fecha?: string) => void
|
onAccion: (estado: string, fecha?: string) => void
|
||||||
onConvertir: () => void
|
onConvertir: () => void
|
||||||
onDescartar: () => void
|
onDescartar: () => void
|
||||||
onTimeline?: () => void
|
|
||||||
onVerDetalle?: () => void
|
onVerDetalle?: () => void
|
||||||
enviando: boolean
|
enviando: boolean
|
||||||
acciones?: string[]
|
acciones?: string[]
|
||||||
@@ -785,15 +573,6 @@ function FilaLead({
|
|||||||
>
|
>
|
||||||
Descartar
|
Descartar
|
||||||
</button>
|
</button>
|
||||||
{onTimeline && (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={onTimeline}
|
|
||||||
className={CLASE_BOTON_ACCION}
|
|
||||||
>
|
|
||||||
Historial
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
@@ -816,10 +595,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
const [tabCrm, setTabCrm] = useState<TabCrm>('leads')
|
const [tabCrm, setTabCrm] = useState<TabCrm>('leads')
|
||||||
const [apartadoSeleccionado, setApartadoSeleccionado] = useState<ApartadoMiDia | null>(null)
|
const [apartadoSeleccionado, setApartadoSeleccionado] = useState<ApartadoMiDia | null>(null)
|
||||||
const [leadSeleccionado, setLeadSeleccionado] = useState<LeadMiDia | OportunidadMiDia | ApartadoMiDia | null>(null)
|
const [leadSeleccionado, setLeadSeleccionado] = useState<LeadMiDia | OportunidadMiDia | ApartadoMiDia | null>(null)
|
||||||
const [apartadoCancelando, setApartadoCancelando] = useState<{
|
|
||||||
id: string
|
|
||||||
nombre: string
|
|
||||||
} | null>(null)
|
|
||||||
const [filtros, setFiltros] = useState<FiltrosCRM>({ texto: '', desarrollo: '', origen: '', fechaDesde: '', fechaHasta: '' })
|
const [filtros, setFiltros] = useState<FiltrosCRM>({ texto: '', desarrollo: '', origen: '', fechaDesde: '', fechaHasta: '' })
|
||||||
const [offline, setOffline] = useState(!navigator.onLine)
|
const [offline, setOffline] = useState(!navigator.onLine)
|
||||||
const [offlineFecha, setOfflineFecha] = useState<string | null>(null)
|
const [offlineFecha, setOfflineFecha] = useState<string | null>(null)
|
||||||
@@ -904,8 +679,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Timeline modal
|
|
||||||
const [leadTimeline, setLeadTimeline] = useState<{ nombre: string; eventos: EventoLead[] } | null>(null)
|
|
||||||
|
|
||||||
// Captura rápida
|
// Captura rápida
|
||||||
const [capNombre, setCapNombre] = useState('')
|
const [capNombre, setCapNombre] = useState('')
|
||||||
@@ -1237,15 +1010,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
onConvertir={() => void convertir(lead)}
|
onConvertir={() => void convertir(lead)}
|
||||||
onDescartar={() => setDescartando(lead)}
|
onDescartar={() => setDescartando(lead)}
|
||||||
onVerDetalle={() => setLeadSeleccionado(lead)}
|
onVerDetalle={() => setLeadSeleccionado(lead)}
|
||||||
onTimeline={() => setLeadTimeline({
|
|
||||||
nombre: lead.nombre,
|
|
||||||
eventos: lead.ultimoCambio ? [{
|
|
||||||
fechaISO: lead.ultimoCambio.fechaISO,
|
|
||||||
usuario: lead.ultimoCambio.usuario,
|
|
||||||
detalle: lead.ultimoCambio.detalle,
|
|
||||||
fuente: lead.fuente,
|
|
||||||
}] : [],
|
|
||||||
})}
|
|
||||||
acciones={acciones}
|
acciones={acciones}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -1337,7 +1101,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
<FilaApartado
|
<FilaApartado
|
||||||
apartado={a}
|
apartado={a}
|
||||||
enviando={enviando}
|
enviando={enviando}
|
||||||
onCancelacion={() => setApartadoCancelando({ id: a.id, nombre: a.nombre })}
|
|
||||||
onVerDetalle={() => setLeadSeleccionado(a)}
|
onVerDetalle={() => setLeadSeleccionado(a)}
|
||||||
onFase={(fase) => {
|
onFase={(fase) => {
|
||||||
if (fase === 'Firma Cliente') {
|
if (fase === 'Firma Cliente') {
|
||||||
@@ -1397,7 +1160,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
disabled={enviando}
|
disabled={enviando}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (fase === 'Cancelo') {
|
if (fase === 'Cancelo') {
|
||||||
setApartadoCancelando({ id: apartado.id, nombre: apartado.nombre })
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
void ejecutar(() => cambiarEstadoApartado(apartado.id, fase), 'No se pudo actualizar')
|
void ejecutar(() => cambiarEstadoApartado(apartado.id, fase), 'No se pudo actualizar')
|
||||||
@@ -1727,38 +1489,16 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{descartando && (
|
{descartando && (() => {
|
||||||
<ModalDescartar
|
const lead = descartando
|
||||||
lead={descartando}
|
setDescartando(null)
|
||||||
enviando={enviando}
|
void ejecutar(
|
||||||
onCancelar={() => setDescartando(null)}
|
() => descartarLead(lead.id, '', undefined, lead.fuente, undefined),
|
||||||
onConfirmar={(motivo, subcategoria, comentario) => {
|
'No se pudo descartar el lead',
|
||||||
const lead = descartando
|
)
|
||||||
setDescartando(null)
|
return null
|
||||||
void ejecutar(
|
})()}
|
||||||
() => descartarLead(lead.id, motivo, comentario === '' ? undefined : comentario, lead.fuente, subcategoria),
|
|
||||||
'No se pudo descartar el lead',
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{apartadoCancelando && (
|
|
||||||
<ModalDescarteGenerico
|
|
||||||
item={apartadoCancelando}
|
|
||||||
titulo="Cancelar apartado"
|
|
||||||
enviando={enviando}
|
|
||||||
onCancelar={() => setApartadoCancelando(null)}
|
|
||||||
onConfirmar={(motivo, subcategoria, comentario) => {
|
|
||||||
const item = apartadoCancelando
|
|
||||||
setApartadoCancelando(null)
|
|
||||||
void ejecutar(
|
|
||||||
() => cambiarEstadoApartado(item.id, 'Cancelacion Apartado', motivo, subcategoria, comentario),
|
|
||||||
'No se pudo cancelar el apartado',
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{apartadoSeleccionado && (
|
{apartadoSeleccionado && (
|
||||||
<NotasApartado
|
<NotasApartado
|
||||||
@@ -1767,27 +1507,6 @@ export default function MiDiaPage({ accionesSesion }: { accionesSesion: Acciones
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Modal de historial/timeline del lead */}
|
|
||||||
{leadTimeline && (
|
|
||||||
<div className="fixed inset-0 z-10 flex items-center justify-center bg-black/40 px-4" role="dialog" aria-modal="true">
|
|
||||||
<div className="w-full max-w-md rounded-2xl border border-[#E5E7EB] bg-white p-6 dark:border-[#1E293B] dark:bg-[#1E293B] shadow-xl max-h-[80vh] overflow-y-auto">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<p className="text-xs font-semibold uppercase tracking-wider text-[#64748B] dark:text-[#94A3B8]">Historial</p>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setLeadTimeline(null)}
|
|
||||||
className="rounded-lg px-2 py-1 text-xs font-medium text-[#64748B] dark:text-[#94A3B8] hover:bg-[#F9FAFB] dark:hover:bg-[#334155]"
|
|
||||||
>
|
|
||||||
Cerrar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p className="mt-2 text-lg font-medium text-[#111827] dark:text-[#E2E8F0]">{leadTimeline.nombre}</p>
|
|
||||||
<div className="mt-4">
|
|
||||||
<TimelineLead eventos={leadTimeline.eventos} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{leadSeleccionado && (
|
{leadSeleccionado && (
|
||||||
<DetalleLeadModal
|
<DetalleLeadModal
|
||||||
|
|||||||
Reference in New Issue
Block a user