// ============================================
// 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) => (
))}
);
}
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 */}
{/* Left overlay — excel */}
{/* 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) => (
))}
⚠ 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('')}
))}
);
}
window.Modules = Modules;
window.GrowthTimeline = GrowthTimeline;
window.Comparator = Comparator;
window.Roles = Roles;
window.Testimonials = Testimonials;