105 lines
2.5 KiB
TypeScript
105 lines
2.5 KiB
TypeScript
import { createClient } from '@/lib/supabase/server'
|
|
import { redirect, notFound } from 'next/navigation'
|
|
import { ScorecardView } from '@/components/scorecard/scorecard-view'
|
|
|
|
export type Hole = {
|
|
id: string
|
|
hole_number: number
|
|
par: number
|
|
stroke_index: number
|
|
}
|
|
|
|
export type Player = {
|
|
user_id: string
|
|
course_handicap: number | null
|
|
handicap_index: number | null
|
|
profile: { id: string; display_name: string; avatar_url: string | null } | null
|
|
}
|
|
|
|
export type ScoreRow = {
|
|
hole_id: string
|
|
player_id: string
|
|
strokes: number
|
|
}
|
|
|
|
export type RoundInfo = {
|
|
id: string
|
|
name: string | null
|
|
date: string
|
|
status: string
|
|
holes_count: number
|
|
created_by: string
|
|
course: { name: string } | null
|
|
tee: { name: string; color: string } | null
|
|
}
|
|
|
|
export default async function ScorecardPage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ id: string }>
|
|
}) {
|
|
const { id } = await params
|
|
const supabase = await createClient()
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const db = supabase as any
|
|
|
|
const {
|
|
data: { user },
|
|
} = await supabase.auth.getUser()
|
|
if (!user) redirect('/login')
|
|
|
|
const { data: round } = await db
|
|
.from('rounds')
|
|
.select(
|
|
`id, name, date, status, holes_count, created_by,
|
|
course:courses (name),
|
|
tee:tees (name, color)`,
|
|
)
|
|
.eq('id', id)
|
|
.single()
|
|
|
|
if (!round) notFound()
|
|
if (round.status === 'lobby') redirect(`/rounds/${id}`)
|
|
|
|
// Holes ordered by hole_number, limited to holes_count
|
|
const { data: holes } = await db
|
|
.from('holes')
|
|
.select('id, hole_number, par, stroke_index')
|
|
.eq('course_id', await getCourseId(db, id))
|
|
.order('hole_number')
|
|
.limit(round.holes_count)
|
|
|
|
const { data: players } = await db
|
|
.from('round_players')
|
|
.select(
|
|
`user_id, course_handicap, handicap_index,
|
|
profile:profiles (id, display_name, avatar_url)`,
|
|
)
|
|
.eq('round_id', id)
|
|
.order('joined_at')
|
|
|
|
const { data: scores } = await db
|
|
.from('scores')
|
|
.select('hole_id, player_id, strokes')
|
|
.eq('round_id', id)
|
|
|
|
return (
|
|
<ScorecardView
|
|
round={round as RoundInfo}
|
|
holes={(holes as Hole[]) ?? []}
|
|
players={(players as Player[]) ?? []}
|
|
initialScores={(scores as ScoreRow[]) ?? []}
|
|
currentUserId={user.id}
|
|
/>
|
|
)
|
|
}
|
|
|
|
async function getCourseId(db: any, roundId: string): Promise<string> {
|
|
const { data } = await db
|
|
.from('rounds')
|
|
.select('course_id')
|
|
.eq('id', roundId)
|
|
.single()
|
|
return data?.course_id ?? ''
|
|
}
|