Spaces:
Sleeping
Sleeping
Download src/components/ScoreRing.tsx from viraj-421/InterviewAI: direct link, hf CLI and curl.
- Browser
- Download file 2.49 kB
-
https://huggingface.co/spaces/viraj-421/InterviewAI/resolve/main/src/components/ScoreRing.tsx
- Command line
-
hf download hf://spaces/viraj-421/InterviewAI/src/components/ScoreRing.tsx
-
curl -L -o ScoreRing.tsx https://huggingface.co/spaces/viraj-421/InterviewAI/resolve/main/src/components/ScoreRing.tsx
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> | |
| ); | |
| } | |