import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { api, DashboardData } from '../api/client'; import styles from './DashboardPage.module.css'; interface Props { devUser?: number; } function formatStreak(streak: number): string { if (streak >= 20) return `⚡${streak}`; if (streak >= 10) return `🔥🔥${streak}`; if (streak >= 3) return `🔥${streak}`; if (streak > 0) return String(streak); return '0'; } function formatCountdown(minutes: number): string { if (minutes < 60) return `in ${minutes} Min`; if (minutes < 60 * 24) return `in ${Math.floor(minutes / 60)}h`; return `in ${Math.floor(minutes / (60 * 24))} Tagen`; } export default function DashboardPage(_props: Props) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); const navigate = useNavigate(); useEffect(() => { setLoading(true); setError(false); api.getDashboard() .then(d => { setData(d); setLoading(false); }) .catch(() => { setError(true); setLoading(false); }); }, []); if (loading) return
Laden...
; if (error || !data) return
Dashboard konnte nicht geladen werden.
; const { hero, stats, nudges } = data; return (
{/* Hero Card */}
navigate('/spiele')}>
Nächstes Spiel {hero && ( {formatCountdown(hero.match.minutesUntilKickoff)} )}
{hero ? ( <>
{hero.match.homeTeam.crest ? ( {hero.match.homeTeam.name} ) : (
)} {hero.match.homeTeam.shortName}
vs
{hero.match.awayTeam.crest ? ( {hero.match.awayTeam.name} ) : (
)} {hero.match.awayTeam.shortName}
{hero.userTip ? (
Dein Tipp: {hero.userTip.home}:{hero.userTip.away} ✓
) : hero.tippable ? ( ) : null} ) : (

Keine anstehenden Spiele

)}
{/* Stats Row */}
{stats.rank !== null ? stats.rank : '—'} Dein Rang
{stats.totalPoints} Punkte
{formatStreak(stats.streak)} Streak
{/* Nudges */} {nudges.length > 0 && (
{nudges.map((nudge, i) => (
{ if (nudge.type === 'untipped') navigate('/spiele'); else if (nudge.type === 'leader') navigate('/rangliste'); }} > {nudge.text}
))}
)}
); }