// ============================================ // SECTIONS 2 — Modules (bento), Growth Timeline, Excel Comparator, Product Carousel, Roles, Testimonials // ============================================ const { useState: useS2, useEffect: useE2, useRef: useR2 } = React; // ---------- MODULES (bento grid) ---------- function Modules() { const [filter, setFilter] = useS2('todos'); const [hover, setHover] = useS2(null); const mods = [ { id: 'M01', n: 'Dashboard', d: 'KPIs en tiempo real y resumen ejecutivo', c: 'cyan', cat: 'activos', big: true }, { id: 'M02', n: 'Activos Fijos', d: 'Inventario con foto, QR único, estados y responsables', c: 'lime', cat: 'activos' }, { id: 'M03', n: 'Hoja de Vida', d: 'Historial completo de cada activo', c: 'amber', cat: 'activos' }, { id: 'M04', n: 'Códigos QR', d: 'Identifica y rastrea con el celular', c: 'violet', cat: 'activos' }, { id: 'M05', n: 'Exportar QR PDF', d: 'Imprime QR de activos seleccionados', c: 'cyan', cat: 'activos' }, { id: 'M06', n: 'Carga Masiva Excel', d: 'Importa cientos de activos con plantilla', c: 'magenta', cat: 'activos', new: true }, { id: 'M07', n: 'Asignaciones', d: 'Responsables y custodia', c: 'lime', cat: 'activos' }, { id: 'M08', n: 'Baja de Activos', d: 'Retiro con motivo y trazabilidad', c: 'red', cat: 'activos' }, { id: 'M09', n: 'Depreciación', d: '5 métodos: línea recta, saldo dec., suma dígitos y más', c: 'magenta', cat: 'dep', big: true }, { id: 'M10', n: 'Proyección 5 Años', d: 'Valor futuro en libros', c: 'cyan', cat: 'dep' }, { id: 'M11', n: 'Mantenimiento', d: 'Preventivo, correctivo y predictivo', c: 'amber', cat: 'mant' }, { id: 'M12', n: 'Técnicos', d: 'Usuarios de rol técnico con mantenimientos asignados', c: 'cyan', cat: 'mant' }, { id: 'M13', n: 'Consumibles', d: 'Papelería e insumos con trazabilidad total', c: 'lime', cat: 'cons', new: true, big: true }, { id: 'M14', n: 'Asignar a Usuario', d: 'Con confirmación de recibido', c: 'amber', cat: 'cons', new: true }, { id: 'M15', n: 'Historial Trazable', d: 'Saldo anterior → nuevo por cada consumo', c: 'violet', cat: 'cons', new: true }, { id: 'M16', n: 'Reportes & PDF', d: '10 reportes con gráficas y exportación PDF', c: 'cyan', cat: 'rep' }, { id: 'M17', n: 'Alertas Tiempo Real', d: 'Sonido + toast + badge. Polling cada 30s', c: 'magenta', cat: 'rep' }, { id: 'M18', n: 'Auditoría', d: 'Trazabilidad completa de cada cambio', c: 'lime', cat: 'rep' }, ]; const filtered = filter === 'todos' ? mods : mods.filter(m => m.cat === filter); return (
MÓDULOS · 16 DISPONIBLES

Todo en una plataforma

Activa solo los módulos que necesitás. Crece cuando tu operación crece.

{[ { k: 'todos', l: 'Todos', n: mods.length }, { k: 'activos', l: 'Activos', n: mods.filter(m => m.cat === 'activos').length }, { k: 'dep', l: 'Depreciación', n: mods.filter(m => m.cat === 'dep').length }, { k: 'mant', l: 'Mantenimiento', n: mods.filter(m => m.cat === 'mant').length }, { k: 'cons', l: 'Consumibles', n: mods.filter(m => m.cat === 'cons').length }, { k: 'rep', l: 'Reportes', n: mods.filter(m => m.cat === 'rep').length }, ].map(t => ( ))}
{filtered.map(m => (
setHover(m.id)} onMouseLeave={() => setHover(null)} style={{'--c': `var(--${m.c})`}} >
{m.id} {m.new && NUEVO}
{m.n}
{m.d}
))}
); } function ModIcon({name}) { const icons = { 'Dashboard': 'M4 20V10M10 20V4M16 20v-8M22 20v-4', 'Activos Fijos': 'M4 8l8-4 8 4v10l-8 4-8-4V8zM4 8l8 4M12 12v10M20 8l-8 4', 'Depreciación': 'M4 18l5-5 4 4 7-9M20 8h-5M20 8v5', 'Mantenimiento': 'M14 6l4 4-12 12H2v-4L14 6zM14 6l2-2 4 4-2 2', 'Códigos QR': 'M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h3v3h-3zM18 18h3M14 21v-3', 'Asignaciones': 'M12 12a4 4 0 100-8 4 4 0 000 8zM4 21v-2a6 6 0 0116 0v2', 'Reportes': 'M8 4h8l4 4v12a2 2 0 01-2 2H8a2 2 0 01-2-2V6a2 2 0 012-2zM8 13h8M8 17h6M8 9h4', 'Alertas': 'M12 3a6 6 0 00-6 6v5l-2 3h16l-2-3V9a6 6 0 00-6-6zM10 20a2 2 0 004 0', 'Hoja de Vida': 'M12 21a9 9 0 100-18 9 9 0 000 18zM12 7v5l3 3', 'Exportar QR PDF': 'M3 3h7v7H3zM14 3h7v7h-7zM3 14h7v7H3zM14 14h3v3h-3zM18 18h3M14 21v-3', 'Carga Masiva Excel': 'M12 3v13M8 11l4 4 4-4M4 19h16v2H4z', 'Baja de Activos': 'M4 8h16l-2 12H6L4 8zM9 8V5a2 2 0 012-2h2a2 2 0 012 2v3M10 12v5M14 12v5', 'Proyección 5 Años': 'M4 18l4-5 4 3 6-9M20 7h-4M20 7v4', 'Técnicos': 'M12 12a4 4 0 100-8 4 4 0 000 8zM4 21v-2a6 6 0 0116 0v2M16 8l4-2M16 8l3 3', 'Consumibles': 'M6 7h12l-1 13H7L6 7zM9 7V5a3 3 0 016 0v2', 'Asignar a Usuario': 'M12 12a4 4 0 100-8 4 4 0 000 8zM4 21v-1a6 6 0 0110 0M17 18l3 3 3-5', 'Historial Trazable': 'M12 3a9 9 0 109 9h-2M12 3V1M12 3l-3 3M12 8v4l3 2', 'Alertas Tiempo Real': 'M12 3a6 6 0 00-6 6v5l-2 3h16l-2-3V9a6 6 0 00-6-6zM10 20a2 2 0 004 0', 'Auditoría': 'M12 5c-5 0-9 7-9 7s4 7 9 7 9-7 9-7-4-7-9-7zM12 12a3 3 0 100-6 3 3 0 000 6z', }; const d = icons[name] || 'M4 4h16v16H4z'; return ( ); } // ---------- GROWTH TIMELINE ---------- function GrowthTimeline() { const [year, setYear] = useS2(1); const milestones = [ { y: 1, t: 'Mes 1', assets: 120, val: 2.1, event: 'Carga masiva Excel inicial' }, { y: 2, t: 'Mes 3', assets: 180, val: 3.4, event: 'QR desplegados en todas las sedes' }, { y: 3, t: 'Mes 6', assets: 260, val: 4.8, event: 'Mantenimientos preventivos activados' }, { y: 4, t: 'Mes 12', assets: 420, val: 7.2, event: 'Consumibles con trazabilidad total' }, { y: 5, t: 'Año 2', assets: 680, val: 11.5, event: 'Expansión a 5 sedes' }, ]; useE2(() => { const id = setInterval(() => { setYear(y => (y % milestones.length) + 1); }, 2600); return () => clearInterval(id); }, []); const current = milestones[year-1]; return (
CRECIMIENTO · TIMELINE

Tu inventario crece, el sistema escala

Desde 100 activos hasta miles. Un cliente real visto a lo largo de 2 años.

{milestones.map((m, i) => ( ))}
ACTIVOS GESTIONADOS
VALOR EN LIBROS (COP)
$B
HITO
{current.event}
); } function CountUp2({ value, decimals }) { const [d, setD] = useS2(value); const prev = useR2(value); useE2(() => { const s = prev.current, diff = value - s, dur = 800, t0 = performance.now(); let raf; const tick = t => { const p = Math.min(1, (t - t0) / dur); const e = 1 - Math.pow(1 - p, 3); setD(s + diff * e); if (p < 1) raf = requestAnimationFrame(tick); else prev.current = value; }; raf = requestAnimationFrame(tick); return () => cancelAnimationFrame(raf); }, [value]); return {decimals ? (d/10).toFixed(1) : Math.round(d).toLocaleString('es-CO')}; } // ---------- EXCEL vs MI ACTIVO 360 COMPARATOR ---------- function Comparator() { const [pos, setPos] = useS2(50); const dragging = useR2(false); useE2(() => { const onMove = e => { if (!dragging.current) return; const el = document.querySelector('.cmp-stage'); if (!el) return; const r = el.getBoundingClientRect(); const x = (e.clientX || e.touches?.[0]?.clientX) - r.left; setPos(Math.max(0, Math.min(100, (x / r.width) * 100))); }; const onUp = () => { dragging.current = false; }; window.addEventListener('mousemove', onMove); window.addEventListener('mouseup', onUp); window.addEventListener('touchmove', onMove); window.addEventListener('touchend', onUp); return () => { window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); window.removeEventListener('touchmove', onMove); window.removeEventListener('touchend', onUp); }; }, []); return (
ANTES / DESPUÉS

Arrastrá para ver la diferencia

A la izquierda: planilla de Excel típica. A la derecha: Mi Activo 360.

dragging.current = true} onTouchStart={() => dragging.current = true}> {/* Right side — full */}
MI ACTIVO 360
{/* Left overlay — excel */}
EXCEL / MANUAL
{/* Handle */}
); } function BeforeView() { return (
Archivo Edición Ver Formato Datos Ayuda
Calibri 11B I U$%
{['A: ID', 'B: Activo', 'C: Sede', 'D: Costo', 'E: Año', 'F: Dep.'].map(h =>
{h}
)}
{[ ['ACT-001', 'Servidor Dell', '???', '$380,000,000', '2021', '=?'], ['ACT-002', 'Planta Eléctrica', 'sede ppal', '$1.200.000.000', '2022', '=B2*0.1'], ['ACT-003', 'Montacargas', 'bodega', '$220000000', '2020', '#ERROR'], ['act004', 'Compresor', 'Bodega', '$45,000,000 ', '2023', ''], ['ACT-005', '', 'N/A', '?', '?', '?'], ['', 'Impresora HP', 'oficina', '$18M', '2024', ''], ['ACT-007', 'Montacargas', 'Bogotá', '$95,000,000', '2019', '=B7*15%'], ].map((row, i) => (
{row.map((c, j) =>
{c}
)}
))}
⚠ Fórmula inconsistente en F3
⚠ Formato de fecha no válido
⚠ Duplicado en columna A
); } function AfterView() { return (
ACTIVOS FIJOS · LIVE
● SINCRONIZADO
{[ {l:'Total', v:'248', c:'cyan'}, {l:'Valor', v:'$4.2B', c:'lime'}, {l:'Dep/mes', v:'$12.4M', c:'magenta'}, {l:'Mant.', v:'12', c:'amber'}, ].map(s => (
{s.l.toUpperCase()}
{s.v}
))}
{[ {id:'ACT-2021-048', n:'Servidor Dell R-740', s:'Data Center', v:'$380M', st:'lime'}, {id:'ACT-2022-012', n:'Planta Eléctrica 250kVA', s:'Sede Principal', v:'$1.2B', st:'cyan'}, {id:'ACT-2020-033', n:'Montacargas Toyota', s:'Bodega Norte', v:'$220M', st:'amber'}, {id:'ACT-2023-007', n:'Compresor Atlas', s:'Taller', v:'$45M', st:'lime'}, {id:'ACT-2024-091', n:'Impresora HP LaserJet', s:'Oficina 3', v:'$18M', st:'lime'}, {id:'ACT-2019-122', n:'UPS Schneider 10kVA', s:'Bogotá', v:'$95M', st:'lime'}, ].map((r, i) => (
{r.id} {r.n} {r.s} {r.v}
))}
); } // ---------- ROLES ---------- function Roles() { const roles = [ { n: 'Administrador', d: 'Control total, consumibles, usuarios y configuración', c: 'cyan' }, { n: 'Contador', d: 'Ver activos, procesar depreciación mensual y reportes', c: 'magenta' }, { n: 'Técnico', d: 'Crear y gestionar mantenimientos, reportar novedades QR', c: 'amber' }, { n: 'Auditor', d: 'Solo lectura, trazabilidad completa y auditoría', c: 'violet' }, { n: 'Usuario', d: 'Ve sus activos asignados, confirma recibido y reporta consumo', c: 'lime' }, ]; return (
ROLES · PERMISOS GRANULARES

Un rol para cada persona

Cada usuario ve y hace exactamente lo que necesita. Sin excepciones.

Solicitar demo →
{roles.map(r => (
{r.n}
{r.d}
{['Dashboard', 'Activos', 'Reportes', 'Config.'].map(a => ( 0.3 ? 'on' : 'off'}>● ))}
))}
); } function RoleIcon({name}) { const icons = { 'Administrador': 'M12 4l-8 4v4c0 5 3 9 8 10 5-1 8-5 8-10V8l-8-4z', 'Contador': 'M4 6h16v12H4zM8 10h4M8 14h8', 'Técnico': 'M14 6l4 4-12 12H2v-4L14 6z', 'Operador': 'M3 17h13l2-6h3l1 3v4M6 17v2M16 17v2', 'Auditor': 'M12 5c-5 0-9 7-9 7s4 7 9 7 9-7 9-7-4-7-9-7zM12 12a3 3 0 100-6 3 3 0 000 6z', 'Usuario': 'M12 12a4 4 0 100-8 4 4 0 000 8zM4 21a8 8 0 0116 0', }; return ( ); } // ---------- TESTIMONIALS ---------- function Testimonials() { const items = [ { t: 'Pasamos de 600 activos en Excel a tenerlos todos en Mi Activo 360 en menos de una semana. La depreciación automática nos ahorra 3 días de trabajo al mes.', n: 'Carlos Mendoza', r: 'Gerente Financiero', co: 'Holding Andina', c: 'cyan' }, { t: 'El módulo de consumibles cambió todo. Ahora cada usuario confirma lo que recibe y vemos el historial completo con saldos.', n: 'Andrea Pizano', r: 'Coord. Administrativa', co: 'HMV Ingeniería', c: 'amber' }, { t: 'El QR desde el celular es increíble. Los técnicos reportan novedades en campo con foto y queda en la hoja de vida del equipo.', n: 'Juan Ríos', r: 'Director de Operaciones', co: 'Equirent S.A.', c: 'magenta' }, ]; return (
TESTIMONIOS · 4.9★

Lo que dicen los clientes

{items.map((t, i) => (
★★★★★
"{t.t}"
{t.n.split(' ').map(s=>s[0]).slice(0,2).join('')}
{t.n}
{t.r} · {t.co}
))}
); } window.Modules = Modules; window.GrowthTimeline = GrowthTimeline; window.Comparator = Comparator; window.Roles = Roles; window.Testimonials = Testimonials;