'use client';
import {
NEXT_PUBLIC_HOME_LOCATION_COUNT,
NEXT_PUBLIC_HOME_SERVER_COUNT,
NEXT_PUBLIC_HOME_USER_COUNT,
} from '@/config/constants';
import { DotLottieReact } from '@lottiefiles/dotlottie-react';
import LocationsLittie from '@workspace/ui/lotties/locations.json';
import ServersLottie from '@workspace/ui/lotties/servers.json';
import UsersLottie from '@workspace/ui/lotties/users.json';
import { motion } from 'framer-motion';
import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';
export function Stats() {
const t = useTranslations('index');
const list = [
{
name: t('users'),
number: NEXT_PUBLIC_HOME_USER_COUNT,
icon: ,
},
{
name: t('servers'),
number: NEXT_PUBLIC_HOME_SERVER_COUNT,
icon: ,
},
{
name: t('locations'),
number: NEXT_PUBLIC_HOME_LOCATION_COUNT,
icon: ,
},
];
return (
{list.map((item, index) => (
))}
);
}
function CountUp({ end, duration = 2000 }: { end: number; duration?: number }) {
const [count, setCount] = useState(0);
useEffect(() => {
let startTime: number;
let animationFrame: number;
const easeOutQuad = (t: number) => t * (2 - t);
const updateCount = (timestamp: number) => {
if (!startTime) startTime = timestamp;
const progress = timestamp - startTime;
const easedProgress = easeOutQuad(Math.min(progress / duration, 1));
const nextCount = Math.round(easedProgress * end);
setCount(nextCount);
if (progress < duration) {
animationFrame = requestAnimationFrame(updateCount);
}
};
animationFrame = requestAnimationFrame(updateCount);
return () => cancelAnimationFrame(animationFrame);
}, [end, duration]);
return <>{count.toLocaleString()}>;
}