Skjul HCP på offentlig leaderboard for rene bruttoslagspill-turneringer
Bruker: "når det er brutto som er hovedkonkurransen trenger vi ikke se hcp i leaderboarden" -- HCP er kun meningsfullt der den faktisk brukes til slagfordeling (netto/stableford/Københavner/BBB), ikke ren brutto/ eclectic-gross. PublicTournamentInfo += scoring_method (manglet før), leaderboard-raden skjuler nå HCP-teksten når turneringens scoring_method er stroke_gross eller eclectic_gross. Verifisert mot ekte Klubbmesterskap 2026 (bekreftet stroke_gross) i scratch før utrulling. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
3a9ae02841
commit
dd974678fa
3 changed files with 26 additions and 7 deletions
|
|
@ -135,6 +135,12 @@ class PublicTournamentInfo(BaseModel):
|
||||||
# individuell turnering, se ARCHITECTURE_DECISIONS.md/CHANGELOG.md
|
# individuell turnering, se ARCHITECTURE_DECISIONS.md/CHANGELOG.md
|
||||||
# samme dag).
|
# samme dag).
|
||||||
format_type: str
|
format_type: str
|
||||||
|
# 2026-08-21: for offentlig visning av HCP på leaderboardet -- bruker:
|
||||||
|
# "når det er brutto som er hovedkonkurransen trenger vi ikke se hcp".
|
||||||
|
# HCP er kun meningsfullt der den faktisk brukes til slagfordeling
|
||||||
|
# (netto/stableford/Københavner/BBB), ikke ren bruttoslagspill/eclectic
|
||||||
|
# gross. `None` for lagturneringer (scoring_method er individuell-kun).
|
||||||
|
scoring_method: str | None
|
||||||
visibility: str
|
visibility: str
|
||||||
description: str | None
|
description: str | None
|
||||||
start_date: date | None
|
start_date: date | None
|
||||||
|
|
@ -158,7 +164,7 @@ async def get_public_tournament(
|
||||||
row = await conn.fetchrow(
|
row = await conn.fetchrow(
|
||||||
"""
|
"""
|
||||||
SELECT t.id::text, t.name, o.name AS organization_name, t.status::text,
|
SELECT t.id::text, t.name, o.name AS organization_name, t.status::text,
|
||||||
t.format_type::text, t.visibility, t.description, t.hero_image_key, t.join_code,
|
t.format_type::text, t.scoring_method, t.visibility, t.description, t.hero_image_key, t.join_code,
|
||||||
t.start_date, t.end_date, t.registration_deadline,
|
t.start_date, t.end_date, t.registration_deadline,
|
||||||
t.registration_capacity,
|
t.registration_capacity,
|
||||||
(SELECT count(*)::int FROM tournament_registration tr
|
(SELECT count(*)::int FROM tournament_registration tr
|
||||||
|
|
@ -190,6 +196,7 @@ async def get_public_tournament(
|
||||||
organization_name=row["organization_name"],
|
organization_name=row["organization_name"],
|
||||||
status=row["status"],
|
status=row["status"],
|
||||||
format_type=row["format_type"],
|
format_type=row["format_type"],
|
||||||
|
scoring_method=row["scoring_method"],
|
||||||
visibility=row["visibility"],
|
visibility=row["visibility"],
|
||||||
description=row["description"],
|
description=row["description"],
|
||||||
start_date=row["start_date"],
|
start_date=row["start_date"],
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,16 @@ type ApiLeaderboardEntry = {
|
||||||
|
|
||||||
type ApiHole = { hole_number: number; par: number; gross_strokes: number | null }
|
type ApiHole = { hole_number: number; par: number; gross_strokes: number | null }
|
||||||
|
|
||||||
type ApiTournamentInfo = { name: string; format_type: string; status: string }
|
type ApiTournamentInfo = { name: string; format_type: string; status: string; scoring_method: string | null }
|
||||||
|
|
||||||
|
// HCP er kun meningsfullt der den faktisk brukes til slagfordeling --
|
||||||
|
// ren bruttoslagspill (og brutto-eclectic) har ingen HCP-avhengighet.
|
||||||
|
// Bruker 2026-08-21: "når det er brutto som er hovedkonkurransen trenger
|
||||||
|
// vi ikke se hcp i leaderboarden".
|
||||||
|
const GROSS_ONLY_METHODS = new Set(["stroke_gross", "eclectic_gross"])
|
||||||
|
function shouldShowHcp(scoringMethod: string | null): boolean {
|
||||||
|
return scoringMethod != null && !GROSS_ONLY_METHODS.has(scoringMethod)
|
||||||
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ *
|
/* ------------------------------------------------------------------ *
|
||||||
* Visningstyper for hull-rutenettet (per runde, hentes lat ved utvidelse)
|
* Visningstyper for hull-rutenettet (per runde, hentes lat ved utvidelse)
|
||||||
|
|
@ -265,10 +274,12 @@ function LeaderboardRow({
|
||||||
entry,
|
entry,
|
||||||
organizationlessBase,
|
organizationlessBase,
|
||||||
roundId,
|
roundId,
|
||||||
|
showHcp,
|
||||||
}: {
|
}: {
|
||||||
entry: ApiLeaderboardEntry
|
entry: ApiLeaderboardEntry
|
||||||
organizationlessBase: string
|
organizationlessBase: string
|
||||||
roundId: string | null
|
roundId: string | null
|
||||||
|
showHcp: boolean
|
||||||
}) {
|
}) {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [holes, setHoles] = useState<HoleResult[] | null>(null)
|
const [holes, setHoles] = useState<HoleResult[] | null>(null)
|
||||||
|
|
@ -312,8 +323,8 @@ function LeaderboardRow({
|
||||||
Undertittelen (HCP/klasse, mindre viktig) beholder truncate. */}
|
Undertittelen (HCP/klasse, mindre viktig) beholder truncate. */}
|
||||||
<span className="text-pretty text-[15px] font-bold leading-tight text-foreground">{entry.player_name}</span>
|
<span className="text-pretty text-[15px] font-bold leading-tight text-foreground">{entry.player_name}</span>
|
||||||
<span className="truncate text-xs text-muted-foreground">
|
<span className="truncate text-xs text-muted-foreground">
|
||||||
{entry.handicap_index != null && `HCP ${entry.handicap_index.toFixed(1).replace(".", ",")}`}
|
{showHcp && entry.handicap_index != null && `HCP ${entry.handicap_index.toFixed(1).replace(".", ",")}`}
|
||||||
{entry.handicap_index != null && entry.class_name ? " · " : ""}
|
{showHcp && entry.handicap_index != null && entry.class_name ? " · " : ""}
|
||||||
{entry.class_name}
|
{entry.class_name}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
@ -496,6 +507,7 @@ export function PublicIndividualLive({ tournamentId, code }: { tournamentId: str
|
||||||
const hasCut = belowCut.length > 0
|
const hasCut = belowCut.length > 0
|
||||||
|
|
||||||
const isFinished = tournament?.status === "completed" || tournament?.status === "archived"
|
const isFinished = tournament?.status === "completed" || tournament?.status === "archived"
|
||||||
|
const showHcp = shouldShowHcp(tournament?.scoring_method ?? null)
|
||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
|
|
@ -619,7 +631,7 @@ export function PublicIndividualLive({ tournamentId, code }: { tournamentId: str
|
||||||
) : (
|
) : (
|
||||||
<ol className="divide-y divide-border overflow-hidden rounded-2xl border border-border bg-card shadow-md shadow-black/[0.06]">
|
<ol className="divide-y divide-border overflow-hidden rounded-2xl border border-border bg-card shadow-md shadow-black/[0.06]">
|
||||||
{advancing.map((e) => (
|
{advancing.map((e) => (
|
||||||
<LeaderboardRow key={e.tournament_participant_id} entry={e} organizationlessBase={base} roundId={selectedRoundId} />
|
<LeaderboardRow key={e.tournament_participant_id} entry={e} organizationlessBase={base} roundId={selectedRoundId} showHcp={showHcp} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{hasCut && (
|
{hasCut && (
|
||||||
|
|
@ -633,7 +645,7 @@ export function PublicIndividualLive({ tournamentId, code }: { tournamentId: str
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{belowCut.map((e) => (
|
{belowCut.map((e) => (
|
||||||
<LeaderboardRow key={e.tournament_participant_id} entry={e} organizationlessBase={base} roundId={selectedRoundId} />
|
<LeaderboardRow key={e.tournament_participant_id} entry={e} organizationlessBase={base} roundId={selectedRoundId} showHcp={showHcp} />
|
||||||
))}
|
))}
|
||||||
</ol>
|
</ol>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue