project-standalo-todo-super/app/components/PointsDisplay.tsx

71 lines
2.1 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
interface PointsDisplayProps {
points: number;
size?: "small" | "medium" | "large";
}
export default function PointsDisplay({ points, size = "medium" }: PointsDisplayProps) {
const [displayPoints, setDisplayPoints] = useState(0);
useEffect(() => {
const duration = 1000;
const steps = 30;
const increment = points / steps;
let current = 0;
let step = 0;
const timer = setInterval(() => {
step++;
current += increment;
if (step >= steps) {
setDisplayPoints(points);
clearInterval(timer);
} else {
setDisplayPoints(Math.floor(current));
}
}, duration / steps);
return () => clearInterval(timer);
}, [points]);
const sizeClasses = {
small: "text-lg",
medium: "text-3xl",
large: "text-5xl",
};
const iconSizes = {
small: "w-6 h-6",
medium: "w-10 h-10",
large: "w-16 h-16",
};
return (
<div className="flex items-center gap-3 bg-gradient-to-r from-yellow-500/20 to-orange-500/20 border border-yellow-500/30 rounded-xl px-6 py-4">
<div className={`${iconSizes[size]} flex items-center justify-center bg-gradient-to-br from-yellow-400 to-orange-500 rounded-full shadow-lg`}>
<svg
className="w-2/3 h-2/3 text-white"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z" />
<path
fillRule="evenodd"
d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm9.707 5.707a1 1 0 00-1.414-1.414L9 12.586l-1.293-1.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
</div>
<div>
<p className="text-gray-400 text-xs uppercase tracking-wide">Your Points</p>
<p className={`${sizeClasses[size]} font-bold text-transparent bg-clip-text bg-gradient-to-r from-yellow-400 to-orange-500`}>
{displayPoints.toLocaleString()}
</p>
</div>
</div>
);
}