InterviewAI / src /components /ScoreRing.tsx
viraj-421's picture
Initial commit: AI-Powered Mock Interview Platform with Auth, Certificates, and Timer
a0da743
Raw History Blame Contribute Delete
2.49 kB
'use client';
interface ScoreRingProps {
score: number;
maxScore: number;
size?: number;
strokeWidth?: number;
label?: string;
showPercentage?: boolean;
color?: string;
}
export default function ScoreRing({
score,
maxScore,
size = 120,
strokeWidth = 8,
label,
showPercentage = true,
color,
}: ScoreRingProps) {
const radius = (size - strokeWidth) / 2;
const circumference = 2 * Math.PI * radius;
const percentage = Math.min((score / maxScore) * 100, 100);
const offset = circumference - (percentage / 100) * circumference;
const getColor = () => {
if (color) return color;
if (percentage >= 80) return 'var(--success)';
if (percentage >= 60) return 'var(--primary)';
if (percentage >= 40) return 'var(--warning)';
return 'var(--danger)';
};
const ringColor = getColor();
return (
<div className="flex flex-col items-center gap-2">
<div className="relative" style={{ width: size, height: size }}>
<svg
width={size}
height={size}
className="score-ring"
>
{/* Background circle */}
<circle
cx={size / 2}
cy={size / 2}
r={radius}
fill="none"
stroke="var(--border)"
strokeWidth={strokeWidth}
/>
{/* Score circle */}
<circle
cx={size / 2}
cy={size / 2}
r={radius}
fill="none"
stroke={ringColor}
strokeWidth={strokeWidth}
strokeLinecap="round"
strokeDasharray={circumference}
strokeDashoffset={offset}
style={{
filter: `drop-shadow(0 0 6px ${ringColor}40)`,
}}
/>
</svg>
{/* Center text */}
<div
className="absolute inset-0 flex flex-col items-center justify-center"
>
<span
className="font-bold"
style={{ fontSize: size * 0.22, color: ringColor }}
>
{showPercentage ? `${Math.round(percentage)}%` : score.toFixed(1)}
</span>
{!showPercentage && (
<span className="text-xs" style={{ color: 'var(--muted)' }}>
/ {maxScore}
</span>
)}
</div>
</div>
{label && (
<span className="text-sm font-medium" style={{ color: 'var(--muted-light)' }}>
{label}
</span>
)}
</div>
);
}