'use client'
import { useQuery, gql } from '@/lib/graphql/hooks'
import Link from 'next/link'
import { TeamFlag } from '@/components/team-flag'
const STATS_QUERY = gql`
query Stats {
tournaments { year host totalGoals matchesCount avgGoalsPerGame winner }
topScorers(limit: 20) {
playerName goals penalties ownGoals tournaments
team { name iso2 slug }
}
teams {
id name iso2 slug
stats { appearances titles wins draws losses goalsFor goalsAgainst winPct }
}
goalsByMinute { bucket count }
confederationStats { confederation appearances titles totalGoals }
hatTricks {
playerName year round goals
team { name iso2 }
opponent { name iso2 }
}
biggestWins(limit: 10) {
id year round date margin totalGoals scoreFt
team1 { name iso2 } team2 { name iso2 }
}
highestScoringMatches(limit: 10) {
id year round date totalGoals scoreFt
team1 { name iso2 } team2 { name iso2 }
}
extraTimeStats {
totalKnockoutMatches wentToExtraTime wentToPenalties extraTimePct penaltiesPct
}
}
`
function SectionTitle({ children }: { children: React.ReactNode }) {
return
Historical Statistics
{loading && !data && (
Loading statistics…
)}
{/* ── Goals per tournament bar chart ── */}
{tournaments.length > 0 && (
⚽ Goals Scored per Tournament
{tournaments.map(t => {
const h = Math.max(4, Math.round(((t.totalGoals ?? 0) / maxGoals) * 140))
const avg = t.avgGoalsPerGame ? Number(t.avgGoalsPerGame).toFixed(1) : null
return (
{t.totalGoals}
)
})}
{tournaments.map(t => (
{t.year}
))}
)}
{/* ── All-time top scorers ── */}
🏅 All-Time Top Scorers
{scorers.map((s, i) => (
{i + 1}
{s.team &&
}
{s.playerName}
{s.team?.name} · {s.tournaments} WC{s.tournaments !== 1 ? 's' : ''}{s.penalties > 0 ? ` · ${s.penalties}P` : ''}
{s.goals}
))}
{/* ── World Cup titles ── */}
🏆 World Cup Titles by Nation
{titlesByNation.map((t, i) => (
{i + 1}
{t.name}
{Array.from({ length: t.stats?.titles ?? 0 }).map((_, j) => (
🏆
))}
{t.stats?.titles}
))}
{/* ── Goals by minute heatmap ── */}
{minuteBuckets.length > 0 && (
⏱ Goals by Minute (All-Time)
{minuteBuckets.map(b => {
const h = Math.max(8, Math.round((b.count / maxMinute) * 80))
return (
)
})}
)}
{/* ── Biggest wins ── */}
💥 Biggest Victories
{biggestWins.map(m => (
{m.team1.name} vs {m.team2.name}
{m.year} · {m.round}
{m.scoreFt?.[0]}–{m.scoreFt?.[1]}
+{m.margin}
))}
{/* ── Highest scoring matches ── */}
🔥 Highest Scoring Matches
{highScoring.map(m => (
{m.team1.name} vs {m.team2.name}
{m.year} · {m.round}
{m.scoreFt?.[0]}–{m.scoreFt?.[1]}
{m.totalGoals} goals
))}
{/* ── Hat-tricks ── */}
{hatTricks.length > 0 && (
🎩 Hat-Tricks
{hatTricks.map((h, i) => (
{h.team &&
}
{h.playerName}
{h.team?.name}
{h.goals}
{h.year} · {h.round}
{h.opponent && vs {h.opponent.name}}
))}
)}
{/* ── ET & Penalty stats ── */}
{etStats && (
⚡ Extra Time & Penalty Shootouts
{[
{ label: 'Knockout Matches', value: etStats.totalKnockoutMatches },
{ label: 'Went to AET', value: `${etStats.wentToExtraTime} (${etStats.extraTimePct}%)` },
{ label: 'Decided by PSO', value: `${etStats.wentToPenalties} (${etStats.penaltiesPct}%)` },
{ label: 'Decided in 90min', value: etStats.totalKnockoutMatches - etStats.wentToExtraTime },
].map(s => (
))}
)}
{/* ── Confederation stats ── */}
{confStats.length > 0 && (
🌍 Performance by Confederation
ConfederationAppearancesTitlesGoals
{confStats.map(c => (
{c.confederation}
{c.appearances}
{c.titles}
{c.totalGoals}
))}
)}
{/* ── All-time team table ── */}
{teams.length > 0 && (
📊 All-Time Team Table
#TeamWC
WDL
GFGAGD
Win%
{teams.slice(0, 40).map((t, i) => (
{i + 1}
{t.name}
{t.stats?.appearances}
{t.stats?.wins}
{t.stats?.draws}
{t.stats?.losses}
{t.stats?.goalsFor}
{t.stats?.goalsAgainst}
{(t.stats?.goalsFor ?? 0) - (t.stats?.goalsAgainst ?? 0) >= 0
? `+${(t.stats?.goalsFor ?? 0) - (t.stats?.goalsAgainst ?? 0)}`
: (t.stats?.goalsFor ?? 0) - (t.stats?.goalsAgainst ?? 0)}
{t.stats?.winPct}%
))}
)}
)
}