Trekkspillet på statistikk-siden viser nå sammenslått som default — alle seksjonene (Scorer, Fairway, GIR, osv.) er kollapset til man trykker på dem. Rullet ut live.
Notert i FEATURE_BACKLOG.md: Flaggturnering lagt til som et femte fremtidig turneringsformat, med kravet om en gjenstående-slag-visning (oppdatert per hull) og den betingede fremtidsideen om GPS-basert markering av hvor langt spilleren kom — ingenting bygget, bare fanget opp slik at det ikke går i glemmeboken.
This commit is contained in:
parent
bba63b6cc9
commit
714c64e82e
4 changed files with 87 additions and 42 deletions
|
|
@ -2570,16 +2570,27 @@ uendret bortsett fra å rette `/rounds/...`-hrefs til `/my-rounds/...`.
|
||||||
Anywayslag manglet helt fra `round-stats.tsx` sin "Chip, bunker og
|
Anywayslag manglet helt fra `round-stats.tsx` sin "Chip, bunker og
|
||||||
straffeslag"-seksjon (verken `anyway_strokes` i `ApiHole`-typen eller
|
straffeslag"-seksjon (verken `anyway_strokes` i `ApiHole`-typen eller
|
||||||
noe utledet total fantes). Lagt til `anyway_strokes` i typen, ny
|
noe utledet total fantes). Lagt til `anyway_strokes` i typen, ny
|
||||||
`anywayPerRound`-aggregat i `computeStats()`, ny generalisert
|
`anywayPerRound`-aggregat i `computeStats()`.
|
||||||
`StatTileRow`-komponent (2 ELLER 3 fliser -- `StatTilePair` var fast to)
|
**Feilrettet SAMME dag, rett etterpå:** min første fiks slo sammen
|
||||||
brukt for Bunkerslag/Straffeslag/(Anywayslag når tilgjengelig).
|
Anywayslag-tallet INN I den eksisterende "Chip, bunker og
|
||||||
Seksjonen omdøpt fra "Chip, bunker og straffeslag" til "Annet" (bredere
|
straffeslag"-seksjonen og omdøpte HELE seksjonen til "Annet" -- feil,
|
||||||
navn, bruker nevnte at et fritekst-notatfelt trolig havner der senere).
|
påpekt av bruker. Rettet: "Chip, bunker og straffeslag" beholder sitt
|
||||||
|
opprinnelige navn og innhold UENDRET (Bunkerslag/Straffeslag-flisene
|
||||||
|
tilbake til to, ikke tre). Ny, EGEN "Annet"-seksjon lagt til RETT ETTER
|
||||||
|
den (ikke slått sammen), med kun Anywayslag-statistikk: total per runde
|
||||||
|
+ andel hull med minst ett anywayslag (samme "andel hull med..."-mønster
|
||||||
|
som straffeslag-statistikken). Ny `pctHolesWithAnyway`-beregning i
|
||||||
|
`computeStats()`. Den midlertidige `StatTileRow`-komponenten (bygget for
|
||||||
|
den feilaktig sammenslåtte tre-flis-varianten) fjernet igjen som dødt
|
||||||
|
kode -- `StatTilePair` (fast to fliser) er tilstrekkelig for begge
|
||||||
|
seksjonene nå. Notert for senere: brukeren ser for seg at et
|
||||||
|
fritekst-notatfelt havner i "Annet"-seksjonen etter hvert.
|
||||||
**Verifisert:** ekte typesjekket produksjonsbuild kjørt og bekreftet,
|
**Verifisert:** ekte typesjekket produksjonsbuild kjørt og bekreftet,
|
||||||
ny rute `/my-rounds/[id]/scorecard` listet. Ingen ny backend-endring
|
ny rute `/my-rounds/[id]/scorecard` listet. Ingen ny backend-endring
|
||||||
(`anyway_strokes`/`strokes_received` fantes allerede i `RoundHoleOut`).
|
(`anyway_strokes`/`strokes_received` fantes allerede i `RoundHoleOut`).
|
||||||
**Rullet ut live 2026-07-25**, ren frontend-endring, ingen migrasjon,
|
**Rullet ut live 2026-07-25** (to runder, feilrettingen rullet ut rett
|
||||||
`teeoff.no` upåvirket.
|
etter originalen), ren frontend-endring, ingen migrasjon, `teeoff.no`
|
||||||
|
upåvirket.
|
||||||
|
|
||||||
**Motor-komponenten (punkt 1-11) er ✅ BYGGET OG TESTET 2026-07-22,**
|
**Motor-komponenten (punkt 1-11) er ✅ BYGGET OG TESTET 2026-07-22,**
|
||||||
som første, isolerte byggesteg (ren Python, ingen DB/API/frontend ennå —
|
som første, isolerte byggesteg (ren Python, ingen DB/API/frontend ennå —
|
||||||
|
|
|
||||||
29
CLAUDE.md
29
CLAUDE.md
|
|
@ -2533,12 +2533,29 @@ Ferdig og verifisert:
|
||||||
til en "Se scorekort"-knapp i `CompletedBanner` (round-detail.tsx) ved
|
til en "Se scorekort"-knapp i `CompletedBanner` (round-detail.tsx) ved
|
||||||
siden av den eksisterende "Se full rundestatistikk" -- tatt inn.
|
siden av den eksisterende "Se full rundestatistikk" -- tatt inn.
|
||||||
**Samtidig, rapportert av bruker:** Anywayslag manglet helt fra
|
**Samtidig, rapportert av bruker:** Anywayslag manglet helt fra
|
||||||
rundestatistikk-siden sin "Chip, bunker og straffeslag"-seksjon --
|
rundestatistikk-siden sin "Chip, bunker og straffeslag"-seksjon.
|
||||||
lagt til som en tredje per-runde-flis, og seksjonen omdøpt til "Annet"
|
**Feilrettet rett etterpå, samme dag:** min første fiks slo feilaktig
|
||||||
(bredere navn, siden et notatfelt trolig havner der senere også).
|
sammen Anywayslag-tallet i DEN eksisterende seksjonen og omdøpte hele
|
||||||
Ekte typesjekket build kjørt og bekreftet (ny rute
|
seksjonen til "Annet" -- brukeren påpekte at "Chip, bunker og
|
||||||
`/my-rounds/[id]/scorecard` listet). Rullet ut, ren frontend-endring,
|
straffeslag" skulle beholde navn+innhold uendret, og at "Annet" skulle
|
||||||
ingen backend/migrasjon, `teeoff.no` upåvirket.
|
være en EGEN, ny seksjon RETT ETTER med kun anywayslag-tall (total per
|
||||||
|
runde + andel hull med anywayslag). Rettet umiddelbart. Notert at et
|
||||||
|
fritekst-notatfelt trolig havner i "Annet" senere. Ekte typesjekket
|
||||||
|
build kjørt og bekreftet (ny rute `/my-rounds/[id]/scorecard` listet).
|
||||||
|
Rullet ut (to runder), ren frontend-endring, ingen backend/migrasjon,
|
||||||
|
`teeoff.no` upåvirket.
|
||||||
|
- **Rundestatistikk-seksjonene starter nå kollapset, LIVE samme dag
|
||||||
|
(2026-07-25):** brukeren ba om at "trekkspillet" (StatCard-seksjonene
|
||||||
|
på `/my-rounds/[id]/stats`) skal vises sammenslått -- må klikkes for å
|
||||||
|
se innholdet. `StatCard` sin `defaultOpen` endret fra `true` til
|
||||||
|
`false` (ingen kallsted overstyrte den, så én linje dekket alle
|
||||||
|
seksjonene). Ekte typesjekket build, rullet ut, `teeoff.no` upåvirket.
|
||||||
|
- **Notert i FEATURE_BACKLOG.md, IKKE bygget:** brukeren ba om et notat
|
||||||
|
om et femte fremtidig turneringsformat, "Flaggturnering" (utover de
|
||||||
|
fire fra 2026-07-19-runden) -- krever en visning av GJENSTÅENDE slag
|
||||||
|
for spilleren, oppdatert etter hvert hull, pluss en fremtidig idé om
|
||||||
|
å bruke GPS (når/hvis integrert) til å markere hvor langt spilleren
|
||||||
|
faktisk kom. Lagt til i samme seksjon som de fire andre formatene.
|
||||||
|
|
||||||
Neste steg:
|
Neste steg:
|
||||||
1. **Pauset, venter på retning:** dashbordets tom-tilstand ved første
|
1. **Pauset, venter på retning:** dashbordets tom-tilstand ved første
|
||||||
|
|
|
||||||
|
|
@ -545,6 +545,21 @@
|
||||||
poengmodell, bare en annen fremgangsmåte de to første slagene) — trenger
|
poengmodell, bare en annen fremgangsmåte de to første slagene) — trenger
|
||||||
trolig ikke ny datamodell, bare en presisering i regelverket/UI-teksten.
|
trolig ikke ny datamodell, bare en presisering i regelverket/UI-teksten.
|
||||||
|
|
||||||
|
**«Flaggturnering»** (Flag tournament), reist av bruker 2026-07-25 —
|
||||||
|
IKKE del av den opprinnelige fire-formater-listen over, notert som et
|
||||||
|
eget femte format. Hver spiller får et fast antall slag (typisk par +
|
||||||
|
handicap for hele runden) og spiller til slagene er brukt opp — den som
|
||||||
|
kommer lengst rundt banen før slagene tar slutt, vinner ("planter
|
||||||
|
flagget" der siste slag ble brukt). **Konkret krav fra bruker, eksplisitt
|
||||||
|
formulert:** en visning som viser GJENSTÅENDE slag for spilleren,
|
||||||
|
oppdatert etter hvert spilte hull (nedtelling, ikke bare et sluttall).
|
||||||
|
**Fremtidig idé, uttrykkelig betinget av at GPS er integrert i appen
|
||||||
|
først** (se GPS/avstandsmåling-notatet lenger opp i denne filen, ADR-033-
|
||||||
|
seksjonen — samme avhengighet): bruk GPS til å markere/registrere HVOR på
|
||||||
|
banen spilleren faktisk endte opp når slagene tok slutt, ikke bare hvilket
|
||||||
|
hull. Ingen datamodell eller UI designet ennå for noen del av dette —
|
||||||
|
rent notat.
|
||||||
|
|
||||||
- **Ingenting av dette er designet eller bygget ennå** — kun fanget her slik
|
- **Ingenting av dette er designet eller bygget ennå** — kun fanget her slik
|
||||||
at det ikke går i glemmeboken. Naturlig neste steg når dette tas fatt på:
|
at det ikke går i glemmeboken. Naturlig neste steg når dette tas fatt på:
|
||||||
vurder de fire hver for seg (ikke som én stor runde), start med «Try all»
|
vurder de fire hver for seg (ikke som én stor runde), start med «Try all»
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import {
|
||||||
ChevronRight,
|
ChevronRight,
|
||||||
Flag,
|
Flag,
|
||||||
Info,
|
Info,
|
||||||
|
MoreHorizontal,
|
||||||
MoveHorizontal,
|
MoveHorizontal,
|
||||||
Target,
|
Target,
|
||||||
Wind,
|
Wind,
|
||||||
|
|
@ -56,7 +57,10 @@ const C = {
|
||||||
function StatCard({
|
function StatCard({
|
||||||
title,
|
title,
|
||||||
icon: Icon,
|
icon: Icon,
|
||||||
defaultOpen = true,
|
// Alle seksjonene starter kollapset (etterspurt av bruker 2026-07-25:
|
||||||
|
// "trekkspillet skal vises sammenslått") -- må trykkes på hver enkelt
|
||||||
|
// for å se innholdet, i stedet for at hele siden lastes åpen.
|
||||||
|
defaultOpen = false,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
|
|
@ -252,22 +256,6 @@ function ProgressRow({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Row of N stat tiles (2 eller 3 -- StatTilePair er en fast to-tiles-
|
|
||||||
// variant, denne generaliserer for "Annet"-seksjonens tre per-runde-tall) ---
|
|
||||||
|
|
||||||
function StatTileRow({ tiles }: { tiles: { label: string; value: string }[] }) {
|
|
||||||
return (
|
|
||||||
<div className={cn("grid gap-3", tiles.length === 3 ? "grid-cols-3" : "grid-cols-2")}>
|
|
||||||
{tiles.map((t) => (
|
|
||||||
<div key={t.label} className="flex flex-col gap-1 rounded-2xl border border-border bg-muted/40 p-4">
|
|
||||||
<span className="text-3xl font-extrabold tabular-nums text-foreground">{t.value}</span>
|
|
||||||
<span className="text-sm font-semibold leading-snug text-muted-foreground text-pretty">{t.label}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Paired stat tiles -----------------------------------------------------
|
// --- Paired stat tiles -----------------------------------------------------
|
||||||
|
|
||||||
function StatTilePair({
|
function StatTilePair({
|
||||||
|
|
@ -519,6 +507,10 @@ function computeStats(holes: ApiHole[]) {
|
||||||
const anywayEligible = played.filter((h) => h.anyway_strokes !== null)
|
const anywayEligible = played.filter((h) => h.anyway_strokes !== null)
|
||||||
const anywayPerRound =
|
const anywayPerRound =
|
||||||
anywayEligible.length > 0 ? anywayEligible.reduce((s, h) => s + (h.anyway_strokes as number), 0) : null
|
anywayEligible.length > 0 ? anywayEligible.reduce((s, h) => s + (h.anyway_strokes as number), 0) : null
|
||||||
|
const pctHolesWithAnyway =
|
||||||
|
anywayEligible.length > 0
|
||||||
|
? (anywayEligible.filter((h) => (h.anyway_strokes as number) >= 1).length / anywayEligible.length) * 100
|
||||||
|
: null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
playedCount: played.length,
|
playedCount: played.length,
|
||||||
|
|
@ -560,6 +552,7 @@ function computeStats(holes: ApiHole[]) {
|
||||||
avgToParWithoutBunker,
|
avgToParWithoutBunker,
|
||||||
pctHolesWithPenalty,
|
pctHolesWithPenalty,
|
||||||
anywayPerRound,
|
anywayPerRound,
|
||||||
|
pctHolesWithAnyway,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -939,12 +932,8 @@ export function RoundStats({ roundId }: { roundId: string }) {
|
||||||
</StatCard>
|
</StatCard>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 7. Annet -- "catch all" for chip/bunker/straffeslag/anywayslag
|
{/* 7. Chip, bunker og straffeslag */}
|
||||||
(het tidligere "Chip, bunker og straffeslag", men Anywayslag
|
<StatCard title="Chip, bunker og straffeslag" icon={Waves}>
|
||||||
manglet helt fra oppsummeringen -- rettet + omdøpt til noe
|
|
||||||
bredere 2026-07-25, siden et fritekst-notatfelt trolig havner
|
|
||||||
her senere også). */}
|
|
||||||
<StatCard title="Annet" icon={Waves}>
|
|
||||||
{(s.scramblingPct !== null || s.sandSavePct !== null) && (
|
{(s.scramblingPct !== null || s.sandSavePct !== null) && (
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<InfoStat
|
<InfoStat
|
||||||
|
|
@ -979,12 +968,9 @@ export function RoundStats({ roundId }: { roundId: string }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<StatTileRow
|
<StatTilePair
|
||||||
tiles={[
|
a={{ label: "Bunkerslag per runde", value: String(s.bunkerPerRound) }}
|
||||||
{ label: "Bunkerslag per runde", value: String(s.bunkerPerRound) },
|
b={{ label: "Straffeslag per runde", value: String(s.penaltyPerRound) }}
|
||||||
{ label: "Straffeslag per runde", value: String(s.penaltyPerRound) },
|
|
||||||
...(s.anywayPerRound !== null ? [{ label: "Anywayslag per runde", value: String(s.anywayPerRound) }] : []),
|
|
||||||
]}
|
|
||||||
/>
|
/>
|
||||||
{(s.avgToParWithBunker !== null || s.avgToParWithoutBunker !== null) && (
|
{(s.avgToParWithBunker !== null || s.avgToParWithoutBunker !== null) && (
|
||||||
<StatTilePair
|
<StatTilePair
|
||||||
|
|
@ -999,6 +985,22 @@ export function RoundStats({ roundId }: { roundId: string }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</StatCard>
|
</StatCard>
|
||||||
|
|
||||||
|
{/* 8. Annet -- egen seksjon for rundens anywayslag, ETTER
|
||||||
|
chip/bunker/straffeslag (rettet 2026-07-25 -- feilaktig slått
|
||||||
|
sammen med den seksjonen i forrige runde). Notatfelt kommer
|
||||||
|
trolig hit senere. */}
|
||||||
|
{s.anywayPerRound !== null && (
|
||||||
|
<StatCard title="Annet" icon={MoreHorizontal}>
|
||||||
|
<StatTilePair
|
||||||
|
a={{ label: "Anywayslag per runde", value: String(s.anywayPerRound) }}
|
||||||
|
b={{
|
||||||
|
label: "Andel hull med anywayslag",
|
||||||
|
value: s.pctHolesWithAnyway !== null ? pct(s.pctHolesWithAnyway) : "–",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</StatCard>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue