dashboard.tsx sitt datalag skrevet om fra V0s mock-useState til ekte kall: /auth/me (organisasjoner), /orgs/{id}/tournaments (turneringer per valgt org), POST /orgs og POST /orgs/{id}/tournaments (opprettelse), POST /auth/logout.
/verify sender deg nå videre til /dashboard etter innlogging (fantes ingen dit å gå før).
login-form.tsx fikk kun en kirurgisk patch (Wordmark flyttet til egen fil, som V0 selv gjorde) — din egen fetch-/feillogikk urørt.
Verifisert: ekte typesjekket build, redeploy av kun teecup_frontend (ingen Caddy-endring trengtes denne gangen — mønsteret fra sist holder), /dashboard → 200 live, teeoff.no upåvirket.
62 lines
2.1 KiB
TypeScript
62 lines
2.1 KiB
TypeScript
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 }: { tournament: Tournament }) {
|
||
const dateRange = formatDateRange(tournament.startDate, tournament.endDate)
|
||
|
||
return (
|
||
<button
|
||
type="button"
|
||
className="group flex w-full items-center gap-4 rounded-2xl border border-border bg-card p-4 text-left shadow-sm shadow-black/5 transition-colors 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} />
|
||
</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"
|
||
/>
|
||
</button>
|
||
)
|
||
}
|