'use client'; import Image from 'next/image'; import { useState, useEffect, useRef } from 'react'; import styles from './StatsCounter.module.css'; export default function StatsCounter() { const [hasAnimated, setHasAnimated] = useState(false); const sectionRef = useRef(null); // Stats State const [counts, setCounts] = useState({ users: 0, posts: 0, satisfaction: 0 }); const targets = { users: 15, // 15K+ posts: 2, // 2M+ satisfaction: 99 // 99% }; useEffect(() => { const observer = new IntersectionObserver( (entries) => { if (entries[0].isIntersecting && !hasAnimated) { setHasAnimated(true); } }, { threshold: 0.5 } ); if (sectionRef.current) { observer.observe(sectionRef.current); } return () => observer.disconnect(); }, [hasAnimated]); useEffect(() => { if (!hasAnimated) return; const duration = 2000; // 2s const steps = 60; const intervalTime = duration / steps; let currentStep = 0; const timer = setInterval(() => { currentStep++; const progress = Math.min(currentStep / steps, 1); // Easing function for smooth count const easeOutQuart = (x: number) => 1 - Math.pow(1 - x, 4); const value = easeOutQuart(progress); setCounts({ users: Math.floor(targets.users * value), posts: Math.floor(targets.posts * value * 10) / 10, // Keep decimal for smaller numbers if needed, here integers roughly satisfaction: Math.floor(targets.satisfaction * value) }); if (currentStep >= steps) clearInterval(timer); }, intervalTime); return () => clearInterval(timer); }, [hasAnimated]); return (
{/* Stat 1 */}
Growing Community
{hasAnimated ? counts.users : 0}k+

Growing Community

{/* Stat 2 */}
Content Published
{hasAnimated ? '2' : '0'}M+

Content Published

{/* Stat 3 */}
Customer Approval
{hasAnimated ? counts.satisfaction : 0}%

Customer Approval

); }