feat: team pages with match/tournament history, mobile padding fixes, linked scorers and nations

- Team page: add Tournament Participations (year pills → /tournaments/[year]) and
  Match History (grouped by year, W/D/L badge, opponent, score from team's perspective,
  PSO/AET annotations, each row → match anchor)
- GraphQL: extend matches() query with teamId filter (OR team1_id/team2_id)
- Match card: link team names to /teams/[slug]; fix ET score display — show scoreEt
  as headline for AET matches, scoreFt as footnote; winner determination uses
  scoreP ?? scoreEt ?? scoreFt
- Tournament page: scorer names below each match linked to /players/[name] with
  dotted underline (solid + green on hover)
- Stats page: reduce mobile padding on Goals chart, Top Scorers, Titles, Goals by
  Minute — hide progress bars and trophy emojis on small screens
- Homepage: Golden Boot Race same mobile padding/bar treatment; add slug to match
  team queries

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-14 21:07:56 +02:00
parent f1b5328b78
commit 9b8e266f88
9 changed files with 210 additions and 77 deletions
+12 -4
View File
@@ -49,12 +49,20 @@ function GoalList({ match }: { match: MatchData }) {
if (!match.goals?.length) return null
const t1Goals = match.goals.filter(g => !g.isOwnGoal ? g.team.id === match.team1.id : g.team.id !== match.team1.id)
const t2Goals = match.goals.filter(g => !g.isOwnGoal ? g.team.id === match.team2.id : g.team.id !== match.team2.id)
const renderGoal = (g: MatchData['goals'][0]) =>
`${g.playerName} ${g.minute ?? ''}${g.minuteOffset ? `+${g.minuteOffset}` : ''}'${g.isPenalty ? ' (P)' : g.isOwnGoal ? ' (OG)' : ''}`
const renderGoal = (g: MatchData['goals'][0], i: number) => (
<span key={i}>
{i > 0 && <span className="mx-0.5">,</span>}
<Link href={`/players/${encodeURIComponent(g.playerName)}`}
className="underline decoration-dotted underline-offset-2 hover:text-[#22c55e] hover:decoration-solid transition-colors">
{g.playerName}
</Link>
{' '}{g.minute ?? ''}{g.minuteOffset ? `+${g.minuteOffset}` : ''}'{g.isPenalty ? ' (P)' : g.isOwnGoal ? ' (OG)' : ''}
</span>
)
return (
<div className="flex justify-between gap-4 px-4 pb-2 text-[10px] text-[#2a5c35]">
<div className="text-left">{t1Goals.map(renderGoal).join(', ')}</div>
<div className="text-right">{t2Goals.map(renderGoal).join(', ')}</div>
<div className="text-left">{t1Goals.map(renderGoal)}</div>
<div className="text-right">{t2Goals.map(renderGoal)}</div>
</div>
)
}