Spaces:
Running
Running
File size: 2,362 Bytes
bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 b5e8a53 bf04727 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | "use client";
import { motion } from "framer-motion";
interface CircularProgressProps {
score: number;
label: string;
size?: number;
strokeWidth?: number;
}
function getScoreColor(score: number): string {
if (score >= 70) return "#0070f3";
if (score >= 40) return "#00d4ff";
return "#666";
}
export default function CircularProgress({
score,
label,
size = 96,
strokeWidth = 8,
}: CircularProgressProps) {
const radius = (size - strokeWidth * 2) / 2;
const circumference = 2 * Math.PI * radius;
const progress = (score / 100) * circumference;
const color = getScoreColor(score);
const cx = size / 2;
const cy = size / 2;
return (
<div className="flex flex-col items-center gap-2">
<div className="relative" style={{ width: size, height: size }}>
<svg
width={size}
height={size}
className="-rotate-90"
style={{ transform: "rotate(-90deg)" }}
>
{/* Background track */}
<circle
cx={cx}
cy={cy}
r={radius}
fill="none"
stroke="rgba(255,255,255,0.05)"
strokeWidth={strokeWidth}
/>
{/* Progress arc */}
<motion.circle
cx={cx}
cy={cy}
r={radius}
fill="none"
stroke={color}
strokeWidth={strokeWidth}
strokeDasharray={`${progress} ${circumference}`}
strokeLinecap="round"
initial={{ strokeDasharray: `0 ${circumference}` }}
animate={{ strokeDasharray: `${progress} ${circumference}` }}
transition={{ duration: 1, ease: "easeOut" }}
style={{
filter: `drop-shadow(0 0 8px ${color}60)`,
}}
/>
</svg>
{/* Center score */}
<div className="absolute inset-0 flex flex-col items-center justify-center">
<motion.span
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ delay: 0.5, duration: 0.3 }}
className="text-xl font-bold text-white leading-none"
>
{score}
</motion.span>
</div>
</div>
<span className="text-xs font-medium text-vercel-fg/60 tracking-wide uppercase">{label}</span>
</div>
);
}
|