Files
worldcup/components/match-card.tsx
T
valknar 886523173b fix: use grid layout for full match card so teams stay in one row on mobile
Replaced flex-wrap with grid-cols-[1fr_auto_1fr] so team columns fill
equally on either side of the score. Score font scales down on mobile,
padding tightens, team names truncate instead of wrapping.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-14 20:10:55 +02:00

114 lines
5.0 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 px-5 py-6 sm:px-9 sm:py-9 hover:border-[rgba(34,197,94,0.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">
<div className="text-center">
<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 ${winner === 'home' ? 'text-[#dff5e8]' : 'text-[#6abf7a]'}`}>
{match.team1.name}
</div>
</div>
<div className="text-center flex-shrink-0">
<div className="font-['Bebas_Neue'] text-[48px] sm: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-[10px] text-[#2a5c35] mt-0.5">{ft![0]}{ft![1]} a.e.t.</div>
)}
{match.scoreEt && !match.scoreP && (
<div className="text-[10px] text-[#2a5c35] mt-0.5">a.e.t.</div>
)}
<div className="text-[9px] text-[#2a5c35] tracking-[0.12em] uppercase mt-1.5">{match.round}</div>
<div className="text-[10px] text-[#1a3a22] mt-0.5">{match.date ? formatDate(match.date) : ''}</div>
</div>
<div className="text-center">
<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 ${winner === 'away' ? 'text-[#dff5e8]' : 'text-[#6abf7a]'}`}>
{match.team2.name}
</div>
</div>
</div>
</div>
</Link>
)
}