This repository has been archived on 2026-05-06. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
tippspiel/frontend/src/components/StatsRing.tsx
T
Ronny 2dc55f29db feat: rich profile page with stats ring, tip history, fun stats
Donut chart showing exact/tendency/wrong distribution.
Scrollable tip history with point badges.
Fun stats: favorite tip, home win percentage.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-11 19:14:41 +02:00

66 lines
2.0 KiB
TypeScript

import styles from './StatsRing.module.css';
interface Props {
exact: number;
tendency: number;
wrong: number;
total: number;
}
export default function StatsRing({ exact, tendency, wrong, total }: Props) {
const radius = 55;
const circumference = 2 * Math.PI * radius;
const all = exact + tendency + wrong || 1;
const segments = [
{ value: exact / all, color: 'var(--gold)', label: 'Exakt' },
{ value: tendency / all, color: 'var(--success)', label: 'Tendenz' },
{ value: wrong / all, color: 'var(--error)', label: 'Falsch' },
];
let offset = 0;
return (
<div className={styles.ring}>
<svg viewBox="0 0 140 140" className={styles.svg}>
{/* Background circle */}
<circle cx="70" cy="70" r={radius} fill="none" stroke="var(--surface-high)" strokeWidth="12" />
{segments.map((seg, i) => {
if (seg.value === 0) return null;
const dashArray = `${seg.value * circumference} ${circumference}`;
const rotation = offset * 360 - 90;
offset += seg.value;
return (
<circle
key={i}
cx="70" cy="70" r={radius}
fill="none"
stroke={seg.color}
strokeWidth="12"
strokeDasharray={dashArray}
transform={`rotate(${rotation} 70 70)`}
strokeLinecap="round"
/>
);
})}
<text x="70" y="65" textAnchor="middle" dominantBaseline="central"
fill="var(--text-primary)" fontSize="28" fontWeight="700">
{total}
</text>
<text x="70" y="85" textAnchor="middle"
fill="var(--text-secondary)" fontSize="11">
Punkte
</text>
</svg>
<div className={styles.legend}>
{segments.map((seg, i) => (
<span key={i} className={styles.legendItem}>
<span className={styles.dot} style={{ background: seg.color }} />
{seg.label}: {Math.round(seg.value * all)}
</span>
))}
</div>
</div>
);
}