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 (
{/* Background circle */} {/* Progress circle */} {percentage}%
) } interface RingSegment { color: string value: number } interface MultiSegmentRingProps { segments: RingSegment[] total: number size?: number strokeWidth?: number centerLabel?: string } export function MultiSegmentRing({ segments, total, size = 64, strokeWidth = 10, centerLabel }: MultiSegmentRingProps) { const radius = (size - strokeWidth) / 2 const circumference = 2 * Math.PI * radius let cumulative = 0 const drawn = segments.filter((s) => s.value > 0) return (
{total > 0 && drawn.map((seg, i) => { const segLen = (seg.value / total) * circumference const offset = circumference - cumulative cumulative += segLen return ( ) })} {centerLabel && {centerLabel}}
) }