/* ── CRM VISUAL — light theme, used on login page left side ────────── */ function CRMVisual() { // The "card" we move through a mini pipeline: New → Qualified → Won const [cardCol, setCardCol] = useState(0); // 0,1,2 useEffect(() => { const t = setInterval(() => setCardCol(c => (c + 1) % 4), 1900); // 4 phases incl reset return () => clearInterval(t); }, []); // Live activity feed const ACTIVITY = [ { who: "Priya S.", text: "captured a new lead from", src: "Meta Ads", color: "#1877F2", icon: "spark" }, { who: "Auto-flow", text: "sent WhatsApp follow-up to", src: "Rahul M.", color: "#25D366", icon: "chat" }, { who: "Arjun K.", text: "moved deal to", src: "Closed Won", color: "#10b981", icon: "check" }, { who: "Pipeline", text: "scored hot lead from", src: "Google Ads", color: "#EA4335", icon: "fire" }, { who: "Sara R.", text: "booked demo via", src: "Booking link", color: "#8b5cf6", icon: "cal" }, ]; const [feed, setFeed] = useState([0, 1, 2]); // visible indices, newest first useEffect(() => { const t = setInterval(() => { setFeed(f => [(f[0] + 1) % ACTIVITY.length, f[0], f[1]]); }, 2400); return () => clearInterval(t); }, []); // Animated counters const [leadsToday, setLeadsToday] = useState(128); const [conv, setConv] = useState(34); useEffect(() => { const t = setInterval(() => { setLeadsToday(v => v + Math.floor(Math.random() * 3)); setConv(v => Math.max(28, Math.min(42, v + (Math.random() - 0.5) * 1.2))); }, 2800); return () => clearInterval(t); }, []); // Sparkline const sparkPath = "M 0 30 L 24 22 L 48 26 L 72 12 L 96 18 L 120 6 L 144 14 L 168 4"; const sparkArea = "M 0 30 L 24 22 L 48 26 L 72 12 L 96 18 L 120 6 L 144 14 L 168 4 L 168 40 L 0 40 Z"; // ring math const ringR = 38; const ringC = 2 * Math.PI * ringR; const dash = ringC * (1 - Math.round(conv) / 100); return (
Pipeline · Today
3 teammates viewing
Leads · 7d
{leadsToday}
Activity feed
LIVE{a.who} {a.text}
{a.src}
Conversion
↑ this week
vs 27% last week
+ {leadsToday} new leads
today, auto-captured