Initial commit v1
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { createClient } from '@/lib/supabase/server'
|
||||
import { redirect } from 'next/navigation'
|
||||
import Link from 'next/link'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export default async function DashboardPage() {
|
||||
const supabase = await createClient()
|
||||
const {
|
||||
data: { user },
|
||||
} = await supabase.auth.getUser()
|
||||
|
||||
if (!user) redirect('/login')
|
||||
|
||||
type RoundRow = {
|
||||
round: {
|
||||
id: string
|
||||
name: string | null
|
||||
date: string
|
||||
status: string
|
||||
holes_count: number
|
||||
course: { name: string } | null
|
||||
tee: { name: string; color: string } | null
|
||||
} | null
|
||||
}
|
||||
|
||||
// Fetch rounds the user is participating in
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const { data: rounds } = (await (supabase as any)
|
||||
.from('round_players')
|
||||
.select(
|
||||
`
|
||||
round:rounds (
|
||||
id, name, date, status, holes_count,
|
||||
course:courses (name),
|
||||
tee:tees (name, color)
|
||||
)
|
||||
`,
|
||||
)
|
||||
.eq('user_id', user.id)
|
||||
.in('round.status', ['lobby', 'active'])
|
||||
.order('round(date)', { ascending: false })) as { data: RoundRow[] | null }
|
||||
|
||||
return (
|
||||
<div className="p-4 space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<h1 className="text-2xl font-bold">Rounds</h1>
|
||||
<Link href="/rounds/new" className={cn(buttonVariants({ size: 'sm' }))}>
|
||||
New round
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{!rounds?.length && (
|
||||
<p className="text-muted-foreground text-sm py-8 text-center">
|
||||
No active rounds. Start one!
|
||||
</p>
|
||||
)}
|
||||
|
||||
<div className="space-y-3">
|
||||
{rounds?.map(({ round }) => {
|
||||
if (!round) return null
|
||||
return (
|
||||
<Link
|
||||
key={round.id}
|
||||
href={round.status === 'active' ? `/rounds/${round.id}/scorecard` : `/rounds/${round.id}`}
|
||||
className="block rounded-xl border p-4 space-y-1 hover:bg-muted transition-colors"
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<span className="font-semibold">{round.course?.name}</span>
|
||||
<StatusBadge status={round.status} />
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{round.name && <span>{round.name} · </span>}
|
||||
{round.tee?.name} tees · {round.holes_count} holes ·{' '}
|
||||
{new Date(round.date).toLocaleDateString()}
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function StatusBadge({ status }: { status: string }) {
|
||||
const styles = {
|
||||
lobby: 'bg-yellow-100 text-yellow-800',
|
||||
active: 'bg-green-100 text-green-800',
|
||||
completed: 'bg-gray-100 text-gray-600',
|
||||
}
|
||||
return (
|
||||
<span
|
||||
className={`text-xs font-medium px-2 py-0.5 rounded-full ${styles[status as keyof typeof styles] ?? styles.completed}`}
|
||||
>
|
||||
{status}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user