diff --git a/frontend/src/components/StatsRing.tsx b/frontend/src/components/StatsRing.tsx
index 697a746..baf1edf 100644
--- a/frontend/src/components/StatsRing.tsx
+++ b/frontend/src/components/StatsRing.tsx
@@ -10,13 +10,14 @@ interface Props {
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 all = exact + tendency + wrong;
+ const hasData = all > 0;
- 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' },
- ];
+ const segments = hasData ? [
+ { value: exact / all, color: 'var(--gold)', label: 'Exakt', count: exact },
+ { value: tendency / all, color: 'var(--success)', label: 'Tendenz', count: tendency },
+ { value: wrong / all, color: 'var(--error)', label: 'Falsch', count: wrong },
+ ] : [];
let offset = 0;
@@ -49,17 +50,19 @@ export default function StatsRing({ exact, tendency, wrong, total }: Props) {
- Punkte
+ {hasData ? 'Punkte' : 'Keine Tipps'}
-
- {segments.map((seg, i) => (
-
-
- {seg.label}: {Math.round(seg.value * all)}
-
- ))}
-
+ {hasData && (
+
+ {segments.map((seg, i) => (
+
+
+ {seg.label}: {seg.count}
+
+ ))}
+
+ )}
);
}
diff --git a/frontend/src/components/Toast.tsx b/frontend/src/components/Toast.tsx
index 78a6577..bdcc09f 100644
--- a/frontend/src/components/Toast.tsx
+++ b/frontend/src/components/Toast.tsx
@@ -1,4 +1,4 @@
-import { useEffect } from 'react';
+import { useEffect, useRef } from 'react';
import styles from './Toast.module.css';
interface Props {
@@ -8,10 +8,13 @@ interface Props {
}
export default function Toast({ message, onDismiss, duration = 5000 }: Props) {
+ const onDismissRef = useRef(onDismiss);
+ onDismissRef.current = onDismiss;
+
useEffect(() => {
- const timer = setTimeout(onDismiss, duration);
+ const timer = setTimeout(() => onDismissRef.current(), duration);
return () => clearTimeout(timer);
- }, [onDismiss, duration]);
+ }, [duration]);
return (
diff --git a/frontend/src/hooks/useRankChange.ts b/frontend/src/hooks/useRankChange.ts
index 7227ea8..e131880 100644
--- a/frontend/src/hooks/useRankChange.ts
+++ b/frontend/src/hooks/useRankChange.ts
@@ -2,11 +2,15 @@ import { useState, useEffect } from 'react';
import { api } from '../api/client';
const RANK_KEY = 'tippspiel_last_rank';
+const SHOWN_KEY = 'tippspiel_rank_toast_shown';
export function useRankChange() {
const [message, setMessage] = useState(null);
useEffect(() => {
+ // Only show once per session
+ if (sessionStorage.getItem(SHOWN_KEY)) return;
+
api.getMyStats().then(stats => {
if (!stats.rank) return;
const lastRank = parseInt(localStorage.getItem(RANK_KEY) || '0');
@@ -16,6 +20,7 @@ export function useRankChange() {
} else {
setMessage(`⬇️ Du bist auf Platz ${stats.rank} gerutscht — hol dir die Punkte zurück!`);
}
+ sessionStorage.setItem(SHOWN_KEY, '1');
}
localStorage.setItem(RANK_KEY, String(stats.rank));
}).catch(() => {});