86 lines
3 KiB
TypeScript
86 lines
3 KiB
TypeScript
import Link from "next/link"
|
||
import { Calendar, ChevronRight } from "lucide-react"
|
||
import { TournamentStatusBadge, type TournamentStatus } from "@/components/tournament-status-badge"
|
||
|
||
export type Tournament = {
|
||
id: string
|
||
name: string
|
||
status: TournamentStatus
|
||
startDate?: string
|
||
endDate?: string
|
||
}
|
||
|
||
const dateFormatter = new Intl.DateTimeFormat("no-NO", {
|
||
day: "numeric",
|
||
month: "short",
|
||
year: "numeric",
|
||
})
|
||
|
||
function formatDate(value?: string) {
|
||
if (!value) return null
|
||
const parsed = new Date(value)
|
||
if (Number.isNaN(parsed.getTime())) return null
|
||
return dateFormatter.format(parsed)
|
||
}
|
||
|
||
function formatDateRange(start?: string, end?: string) {
|
||
const from = formatDate(start)
|
||
const to = formatDate(end)
|
||
if (from && to) return from === to ? from : `${from} – ${to}`
|
||
return from ?? to ?? null
|
||
}
|
||
|
||
export function TournamentCard({
|
||
tournament,
|
||
orgId,
|
||
organizer = false,
|
||
}: {
|
||
tournament: Tournament
|
||
// Satt (dashbordet, innlogget) -> lenker til den innloggede detaljsiden.
|
||
// Utelatt (klubb-landingsside, offentlig) -> lenker til den offentlige
|
||
// /t/{id}-ruten i stedet. Samme kort, to kontekster.
|
||
orgId?: string
|
||
// Vis en "Arrangør"-merkelapp (dashbordets slåtte-sammen "Kommende
|
||
// turneringer"-liste, 2026-07-25 -- deltaker- og arrangør-turneringer i
|
||
// ÉN liste, merkelappen skiller dem visuelt).
|
||
organizer?: boolean
|
||
}) {
|
||
const dateRange = formatDateRange(tournament.startDate, tournament.endDate)
|
||
const href = orgId
|
||
? `/tournaments/${tournament.id}?org=${orgId}&name=${encodeURIComponent(tournament.name)}`
|
||
: `/t/${tournament.id}`
|
||
|
||
return (
|
||
<Link
|
||
href={href}
|
||
className="group flex w-full items-center gap-4 rounded-2xl border border-border bg-card p-4 text-left shadow-md shadow-black/8 transition-all duration-200 ease-in-out hover:border-primary/50 hover:bg-accent/50 sm:p-5"
|
||
>
|
||
<div className="flex min-w-0 flex-1 flex-col gap-2">
|
||
<div className="flex flex-wrap items-center gap-x-3 gap-y-2">
|
||
<h3 className="truncate text-base font-bold text-foreground sm:text-lg">
|
||
{tournament.name}
|
||
</h3>
|
||
<TournamentStatusBadge status={tournament.status} />
|
||
{organizer && (
|
||
<span className="inline-flex items-center gap-1.5 rounded-full bg-brand-orange/15 px-2.5 py-1 text-xs font-semibold text-foreground">
|
||
<span aria-hidden="true" className="size-1.5 rounded-full bg-brand-orange" />
|
||
Arrangør
|
||
</span>
|
||
)}
|
||
</div>
|
||
{dateRange ? (
|
||
<div className="flex items-center gap-1.5 text-sm text-muted-foreground">
|
||
<Calendar aria-hidden="true" className="size-4 shrink-0" />
|
||
<span className="tabular-nums">{dateRange}</span>
|
||
</div>
|
||
) : (
|
||
<span className="text-sm text-muted-foreground">Ingen datoer satt</span>
|
||
)}
|
||
</div>
|
||
<ChevronRight
|
||
aria-hidden="true"
|
||
className="size-5 shrink-0 text-muted-foreground transition-transform group-hover:translate-x-0.5 group-hover:text-foreground"
|
||
/>
|
||
</Link>
|
||
)
|
||
}
|