Files
worldcup/components/match-card.tsx
T
valknarandClaude Sonnet 4.6 36f324e53f fix: remove duplicate a.e.t. label in compact match card
ET matches rendered a.e.t. twice — once inside the score column and once
below the full team row. Removed the outer one.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-04 11:19:26 +02:00

120 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from 'next/link'
import { TeamFlag } from './team-flag'
import { LiveBadge } from './live-badge'
interface Team { name: string; iso2?: string | null; slug?: string | null }
interface Match {
id: number
year: number
round: string
group?: string | null
date?: string | null
time?: string | null
team1: Team
team2: Team
scoreFt?: number[] | null
scoreEt?: number[] | null
scoreP?: number[] | null
isLive: boolean
}
function formatDate(d: string) {
return new Date(d).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' })
}
export function MatchCard({ match, compact = false }: { match: Match; compact?: boolean }) {
const ft = match.scoreFt
const hasScore = ft != null
// Winner: penalties first, then ET, then FT
const decisive = match.scoreP ?? match.scoreEt ?? ft
const winner = decisive ? (decisive[0] > decisive[1] ? 'home' : decisive[0] < decisive[1] ? 'away' : 'draw') : null
if (compact) {
return (
<Link href={`/tournaments/${match.year}#match-${match.id}`} className="block">
<div className="glass-card rounded-xl p-3.5 hover:border-green/[22%] transition-colors">
<div className="text-[9px] text-green-muted tracking-[0.1em] uppercase mb-2.5">
{match.round}{match.group ? ` · ${match.group}` : ''} · {match.date ? formatDate(match.date) : ''}
</div>
<div className="flex items-center gap-2">
<div className="flex-1 flex items-center gap-2 overflow-hidden">
<TeamFlag name={match.team1.name} iso2={match.team1.iso2} size="sm" />
<span className={`text-sm font-medium truncate ${winner === 'home' ? 'text-text' : 'text-green-mid'}`}>
{match.team1.name}
</span>
</div>
<div className="flex-shrink-0 min-w-[52px] text-center">
<div className="font-['Bebas_Neue'] text-xl text-green">
{hasScore
? match.scoreP
? `${match.scoreP[0]} ${match.scoreP[1]}`
: match.scoreEt
? `${match.scoreEt[0]} ${match.scoreEt[1]}`
: `${ft![0]} ${ft![1]}`
: match.isLive ? '0 0' : ''}
</div>
{match.scoreP && (
<div className="text-[8px] text-green-muted leading-none">
{ft![0]}{ft![1]} a.e.t.
</div>
)}
{match.scoreEt && !match.scoreP && (
<div className="text-[8px] text-green-muted leading-none">a.e.t.</div>
)}
</div>
<div className="flex-1 flex items-center justify-end gap-2 overflow-hidden">
<span className={`text-sm font-medium truncate ${winner === 'away' ? 'text-text' : 'text-green-mid'}`}>
{match.team2.name}
</span>
<TeamFlag name={match.team2.name} iso2={match.team2.iso2} size="sm" />
</div>
</div>
</div>
</Link>
)
}
const matchHref = `/tournaments/${match.year}#match-${match.id}`
return (
<div className="glass-card-hero rounded-2xl px-5 py-6 sm:px-9 sm:py-9 hover:border-green/45 transition-colors">
{match.isLive && <div className="mb-4"><LiveBadge label="Live Now" /></div>}
<div className="grid grid-cols-[1fr_auto_1fr] items-center gap-3 sm:gap-8">
<Link href={match.team1.slug ? `/teams/${match.team1.slug}` : matchHref}
className={`text-center block transition-colors hover:text-green ${winner === 'home' ? 'text-text' : 'text-green-sec'}`}>
<TeamFlag name={match.team1.name} iso2={match.team1.iso2} size="xl" className="mb-2" />
<div className="font-['Bebas_Neue'] text-base sm:text-xl tracking-[0.07em] truncate">
{match.team1.name}
</div>
</Link>
<Link href={matchHref} className="text-center flex-shrink-0 block">
<div className="font-['Bebas_Neue'] text-[48px] sm:text-[76px] text-green leading-none hover:opacity-80 transition-opacity">
{hasScore
? match.scoreP
? `${match.scoreP[0]}${match.scoreP[1]}`
: match.scoreEt
? `${match.scoreEt[0]}${match.scoreEt[1]}`
: `${ft![0]}${ft![1]}`
: match.isLive ? '00' : '??'}
</div>
{match.scoreP && (
<div className="text-[10px] text-green-muted mt-0.5">{ft![0]}{ft![1]} a.e.t.</div>
)}
{match.scoreEt && !match.scoreP && (
<div className="text-[10px] text-green-muted mt-0.5">{ft![0]}{ft![1]} (a.e.t.)</div>
)}
<div className="text-[9px] text-green-muted tracking-[0.12em] uppercase mt-1.5">{match.round}</div>
<div className="text-[10px] text-green-dark mt-0.5">{match.date ? formatDate(match.date) : ''}</div>
</Link>
<Link href={match.team2.slug ? `/teams/${match.team2.slug}` : matchHref}
className={`text-center block transition-colors hover:text-green ${winner === 'away' ? 'text-text' : 'text-green-sec'}`}>
<TeamFlag name={match.team2.name} iso2={match.team2.iso2} size="xl" className="mb-2" />
<div className="font-['Bebas_Neue'] text-base sm:text-xl tracking-[0.07em] truncate">
{match.team2.name}
</div>
</Link>
</div>
</div>
)
}