'use client' import { useQuery, gql } from '@/lib/graphql/hooks' import { use, useEffect } from 'react' import Link from 'next/link' import { TeamFlag } from '@/components/team-flag' const TEAM_QUERY = gql` query Team($slug: String!) { team(slug: $slug) { id name iso2 slug fifaCode continent confederation stats { appearances wins draws losses goalsFor goalsAgainst goalDiff titles winPct } } } ` const TEAM_MATCHES_QUERY = gql` query TeamMatches($teamId: Int!) { matches(teamId: $teamId, isQuali: false) { id year round group date isLive scoreFt scoreEt scoreP team1 { name iso2 slug } team2 { name iso2 slug } } } ` interface TeamData { id: number; name: string; iso2?: string | null; slug: string fifaCode?: string | null; continent?: string | null; confederation?: string | null stats?: { appearances: number; wins: number; draws: number; losses: number goalsFor: number; goalsAgainst: number; goalDiff: number; titles: number; winPct: number } | null } interface MatchRow { id: number; year: number; round: string; group?: string | null date?: string | null; isLive: boolean scoreFt?: number[] | null; scoreEt?: number[] | null; scoreP?: number[] | null team1: { name: string; iso2?: string | null; slug?: string | null } team2: { name: string; iso2?: string | null; slug?: string | null } } function formatDate(d: string) { return new Date(d).toLocaleDateString('en-GB', { day: 'numeric', month: 'short' }) } export default function TeamPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = use(params) const { data: teamData, loading } = useQuery(TEAM_QUERY, { variables: { slug } }) const team: TeamData | null = teamData?.team ?? null useEffect(() => { document.title = team ? `${team.name} · World Cup` : 'Team · World Cup' }, [team]) const { data: matchesData } = useQuery(TEAM_MATCHES_QUERY, { variables: { teamId: team?.id }, skip: !team?.id, }) const { data: scorerData } = useQuery(gql` query TeamScorers($teamId: Int!) { topScorers(teamId: $teamId, limit: 30) { playerName goals penalties ownGoals tournaments team { id name iso2 } } } `, { variables: { teamId: team?.id ?? 0 }, skip: !team?.id }) const teamScorers = scorerData?.topScorers ?? [] const teamMatches: MatchRow[] = matchesData?.matches ?? [] // Group matches by year for the history display const matchesByYear = teamMatches.reduce((acc: Record, m) => { ;(acc[m.year] ??= []).push(m) return acc }, {}) const years = Object.keys(matchesByYear).map(Number).sort((a, b) => b - a) if (loading && !teamData) { return
Loading team…
} if (!team) { return
Team not found.
} const s = team.stats const played = (s?.wins ?? 0) + (s?.draws ?? 0) + (s?.losses ?? 0) const maxScorer = Math.max(...teamScorers.map((sc: { goals: number }) => sc.goals), 1) return (
{/* Hero */}

{team.name}

{team.fifaCode && {team.fifaCode}} {team.confederation && {team.confederation}} {team.continent && {team.continent}} {(s?.titles ?? 0) > 0 && ( {Array.from({ length: s?.titles ?? 0 }).map(() => '🏆').join('')} {s?.titles} title{(s?.titles ?? 0) !== 1 ? 's' : ''} )}
{/* Stats grid */} {s && (

World Cup Record

{[ { label: 'Appearances', value: s.appearances }, { label: 'Matches', value: played }, { label: 'Win %', value: `${s.winPct}%` }, { label: 'Goals For', value: s.goalsFor }, ].map(item => (
{item.label}
{item.value}
))}
TeamWD LGF GAGD
{team.name}
{[s.wins, s.draws, s.losses, s.goalsFor, s.goalsAgainst].map((v, i) => ( {v} ))} {s.goalDiff >= 0 ? `+${s.goalDiff}` : s.goalDiff}
)} {/* Tournament participations */} {years.length > 0 && (

Tournament Participations

{years.map(year => ( {year} ))}
)} {/* Match history by year */} {years.length > 0 && (

Match History

{years.map(year => { const yMatches = matchesByYear[year] return (
{year}
{yMatches.map((m, i) => { const isHome = m.team1.name === team.name const opponent = isHome ? m.team2 : m.team1 const ft = m.scoreFt const scoreEt = m.scoreEt const scoreP = m.scoreP // Winner: PSO first, then ET, then FT const decisive = scoreP ?? scoreEt ?? ft const myScore = decisive ? (isHome ? decisive[0] : decisive[1]) : null const theirScore = decisive ? (isHome ? decisive[1] : decisive[0]) : null const result = myScore != null && theirScore != null ? myScore > theirScore ? 'W' : myScore < theirScore ? 'L' : 'D' : null const resultColor = result === 'W' ? 'text-[#22c55e]' : result === 'L' ? 'text-[#ef4444]' : 'text-[#6abf7a]' // Display the decisive score (ET score for AET matches, FT for normal, PSO for shootouts) const displayScore = scoreP ? null : (scoreEt ?? ft) return (
{result ?? '–'}
{opponent.name}
{m.round}{m.group ? ` · ${m.group}` : ''}{m.date ? ` · ${formatDate(m.date)}` : ''}
{scoreP ? `${isHome ? scoreP[0] : scoreP[1]}–${isHome ? scoreP[1] : scoreP[0]}` : displayScore ? `${isHome ? displayScore[0] : displayScore[1]}–${isHome ? displayScore[1] : displayScore[0]}` : '–'}
{scoreP && ft && (
{`${isHome ? ft[0] : ft[1]}–${isHome ? ft[1] : ft[0]}`} a.e.t.
)} {scoreEt && !scoreP && (
a.e.t.
)}
) })}
) })}
)}
{/* Sidebar: top scorers */}
{teamScorers.length > 0 && (

Top Scorers

{teamScorers.map((sc: { playerName: string; goals: number; penalties: number; tournaments: number }, i: number) => (
{i + 1}
{sc.playerName}
{sc.tournaments} WC{sc.tournaments !== 1 ? 's' : ''}{sc.penalties > 0 ? ` · ${sc.penalties}P` : ''}
{sc.goals}
))}
)}
) }