dev_arc_aws/src/components/ProgressRing.tsx

52 lines
1.5 KiB
TypeScript
Raw Normal View History

2026-06-18 08:14:00 -04:00
import { useEffect, useState } from 'react'
interface ProgressRingProps {
percentage: number
size?: number
strokeWidth?: number
}
export default function ProgressRing({ percentage, size = 56, strokeWidth = 4 }: ProgressRingProps) {
const [animatedPercentage, setAnimatedPercentage] = useState(0)
const radius = (size - strokeWidth) / 2
const circumference = 2 * Math.PI * radius
const offset = circumference - (animatedPercentage / 100) * circumference
useEffect(() => {
const timer = setTimeout(() => setAnimatedPercentage(percentage), 100)
return () => clearTimeout(timer)
}, [percentage])
return (
<div className="relative flex items-center justify-center" style={{ width: size, height: size }}>
<svg width={size} height={size} className="-rotate-90">
{/* Background circle */}
<circle
cx={size / 2}
cy={size / 2}
r={radius}
fill="none"
stroke="#1E2025"
strokeWidth={strokeWidth}
/>
{/* Progress circle */}
<circle
cx={size / 2}
cy={size / 2}
r={radius}
fill="none"
stroke="#C8A434"
strokeWidth={strokeWidth}
strokeDasharray={circumference}
strokeDashoffset={offset}
strokeLinecap="round"
className="transition-all duration-1000 ease-out"
/>
</svg>
<span className="absolute text-xs font-bold text-text-primary">
{percentage}%
</span>
</div>
)
}