Files
worldcup/components/match-card.tsx
T
valknar 2e284ec49e fix: show penalty score as headline result, FT score as footnote
For shootout games the FT score (e.g. 2–2) was the main display, which
was misleading. Now the penalty score is the headline (4–2) with
"2–2 a.e.t." below it. Winner highlighting also uses the penalty score.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 19:39:01 +02:00

110 lines
4.9 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 }
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
// Penalty score determines the winner when present
const decisive = match.scoreP ?? 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="bg-[#0a1810] border border-[rgba(34,197,94,0.08)] rounded-xl p-3.5 hover:border-[rgba(34,197,94,0.22)] transition-colors">
<div className="text-[9px] text-[#2a5c35] 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-[#dff5e8]' : 'text-[#4a7a55]'}`}>
{match.team1.name}
</span>
</div>
<div className="flex-shrink-0 min-w-[52px] text-center">
<div className="font-['Bebas_Neue'] text-xl text-[#22c55e]">
{hasScore
? match.scoreP
? `${match.scoreP[0]} ${match.scoreP[1]}`
: `${ft![0]} ${ft![1]}`
: match.isLive ? <LiveBadge label="•" /> : ''}
</div>
{match.scoreP && (
<div className="text-[8px] text-[#2a5c35] leading-none">
{ft![0]}{ft![1]} 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-[#dff5e8]' : 'text-[#4a7a55]'}`}>
{match.team2.name}
</span>
<TeamFlag name={match.team2.name} iso2={match.team2.iso2} size="sm" />
</div>
</div>
{match.scoreEt && !match.scoreP && (
<div className="text-[9px] text-[#2a5c35] mt-1 text-center">a.e.t.</div>
)}
</div>
</Link>
)
}
return (
<Link href={`/tournaments/${match.year}#match-${match.id}`} className="block">
<div className="bg-gradient-to-br from-[#0d2016] to-[#102a1c] border border-[rgba(34,197,94,0.28)] rounded-2xl p-9 hover:border-[rgba(34,197,94,0.45)] transition-colors">
{match.isLive && <div className="mb-4"><LiveBadge label="Live Now" /></div>}
<div className="flex items-center justify-center gap-8 flex-wrap">
<div className="text-center flex-1 min-w-[100px]">
<TeamFlag name={match.team1.name} iso2={match.team1.iso2} size="xl" className="mb-2.5" />
<div className="font-['Bebas_Neue'] text-xl tracking-[0.07em] text-[#dff5e8]">{match.team1.name}</div>
</div>
<div className="text-center flex-shrink-0">
<div className="font-['Bebas_Neue'] text-[76px] text-[#22c55e] leading-none">
{hasScore
? match.scoreP
? `${match.scoreP[0]} ${match.scoreP[1]}`
: `${ft![0]} ${ft![1]}`
: '? ?'}
</div>
{match.scoreP && (
<div className="text-[11px] text-[#2a5c35] mt-0.5">{ft![0]}{ft![1]} a.e.t.</div>
)}
<div className="text-[10px] text-[#2a5c35] tracking-[0.12em] uppercase mt-1.5">{match.round}</div>
<div className="text-xs text-[#1a3a22] mt-1">{match.date ? formatDate(match.date) : ''}</div>
{match.scoreEt && !match.scoreP && (
<div className="text-[10px] text-[#2a5c35] mt-1">a.e.t. {match.scoreEt[0]}{match.scoreEt[1]}</div>
)}
</div>
<div className="text-center flex-1 min-w-[100px]">
<TeamFlag name={match.team2.name} iso2={match.team2.iso2} size="xl" className="mb-2.5" />
<div className="font-['Bebas_Neue'] text-xl tracking-[0.07em] text-[#dff5e8]">{match.team2.name}</div>
</div>
</div>
</div>
</Link>
)
}