// interactive.jsx. Pool calculator, checkout flow, animated counters const { useState, useEffect, useRef, useMemo } = React; /* ────────────────────────────────────────────────────────────── AnimatedNumber. counts up to target when in view ────────────────────────────────────────────────────────────── */ function AnimatedNumber({ value, prefix = "", suffix = "", duration = 1200, decimals = 0, format }) { const [n, setN] = useState(0); const ref = useRef(null); const startedRef = useRef(false); useEffect(() => { const el = ref.current; if (!el) return; const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting && !startedRef.current) { startedRef.current = true; const t0 = performance.now(); const step = (t) => { const p = Math.min(1, (t - t0) / duration); const eased = 1 - Math.pow(1 - p, 3); setN(value * eased); if (p < 1) requestAnimationFrame(step); else setN(value); }; requestAnimationFrame(step); } }); }, { threshold: 0.4 }); io.observe(el); return () => io.disconnect(); }, [value, duration]); const display = format ? format(n) : n.toFixed(decimals); return {prefix}{display}{suffix}; } /* ────────────────────────────────────────────────────────────── PoolCalculator. interactive widget in the hero ────────────────────────────────────────────────────────────── */ function PoolCalculator({ onCta, variant = "vertical" }) { const [amount, setAmount] = useState(500); const fmtUSD = (v) => v.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); const periods = [ { rate: 0.01, period: "/ dia", label: "1%" }, { rate: 0.07, period: "/ Mês", label: "7%" }, { rate: 0.33, period: "/ ano", label: "33%" }, ]; const chips = [100, 500, 1000, 5000]; return (
Simulação ilustrativa. Taxas de pool variam por liquidez, par e momento de mercado. Não é garantia de rendimento.
Quero montar minha pool →