From 3db00e72db5af55b1744bcd15bee604f386e74db Mon Sep 17 00:00:00 2001 From: Erol Haagenrud Date: Tue, 11 Aug 2026 08:01:42 +0200 Subject: [PATCH] =?UTF-8?q?=C3=85tte=20brukerrapporterte=20UX-funn:=20ny-r?= =?UTF-8?q?unde=20og=20score-registrering?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fire rettet direkte (reelle logikkfeil/tekstvalg): round-card.tsx sin "Hull"-celle viste alltid planlagt antall, aldri faktisk spilt for tidlig avsluttede runder; putt-avstand-etiketter gjort konsekvente ("X-Ym" i stedet for blandet " --- ARCHITECTURE_DECISIONS.md | 78 ++++++ CHANGELOG.md | 42 ++++ frontend/components/dashboard.tsx | 5 +- frontend/components/ny-runde/step2-format.tsx | 43 ++-- frontend/components/round-card.tsx | 8 +- frontend/components/round-detail.tsx | 237 ++++++++++++++---- 6 files changed, 342 insertions(+), 71 deletions(-) diff --git a/ARCHITECTURE_DECISIONS.md b/ARCHITECTURE_DECISIONS.md index 25fae7e..ee77ca0 100644 --- a/ARCHITECTURE_DECISIONS.md +++ b/ARCHITECTURE_DECISIONS.md @@ -5842,6 +5842,84 @@ og en tilsvarende fullstendighetssjekk PÅ TVERS AV `round-detail.tsx`/ komponentfiler som ville krevd en helt annen testtilnærming enn ren lib-import — egen, fremtidig vurdering). +--- + +## ADR-062: Åtte brukerrapporterte UX-funn — "Ny runde" og score-registrering — 2026-08-11 + +Bruker sendte åtte konkrete, skjermbilde-dokumenterte problemer fra +faktisk bruk (dashbord, ny-runde-veiviseren, score-registrering, feed). +Delt i to spor etter samme prinsipp som tidligere runder: reelle +logikkfeil rettet direkte, reelt interaksjonsdesign sendt via V0. + +**Direkte rettet, ingen V0 (4 av 8):** +1. **`round-card.tsx`: "Hull"-cellen viste alltid PLANLAGT antall hull + (`holes_planned`), aldri antall FAKTISK spilt** — en runde markert + "Fullført" etter f.eks. 9 av 18 hull viste fortsatt "18". Data fantes + allerede (`my_holes_played` sendes for alle runder, uansett status); + selve "X/Y hull spilt"-indikatoren var bare feilaktig gatet til + `status === "active"`. Rettet til `played < round.holes` (viser + avviket uansett status, skjuler seg selv når spilt == planlagt). +2. **Putt-avstand-knappenes etiketter** (`round-detail.tsx`) — + fem av seks brukte "<Xm"-mønster, den sjette ("8m+") brøt mønsteret + med et "+"-suffiks og ble dermed lett oversett. Etikettene endret til + konsekvent "X-Ym"-format (kun `label`, ikke `value`/`PuttBucket`- + kontrakten — ingen backend-endring). Bekreftet via git-historikk at + dette var Claude-forfattet, ikke V0 (brukeren spurte eksplisitt). +3. **"Se feed" på dashbordet** — for anonymt/uspesifikt. Endret til "Se + venneaktivitet", knyttet direkte til seksjonens egen kontekst + ("Venner på banen"). +4. **@-tagging av medspillere i feeden** — vurdert, IKKE bygget denne + runden (egen, betydelig funksjon: datamodell + søk + rendering). + Anbefalt regel hvis/når den bygges: treff begrenset til faktiske + relasjoner (medspillere/venner, ikke hele brukerbasen — personvern), + og en ekte søkbar nedtrekksliste ved "@" fremfor fritekst-tolkning + (upålitelig med flere like navn). + +**Sendt via V0, mottatt som "tee-cup (9).zip", diffet mot live-treet FØR +noe ble tatt inn (samme rutine som alltid — kun `delivery/`-mappen var +den faktiske leveransen, resten var V0s egen sandbox-scaffolding, ikke +tatt inn):** + +5. **Ny-runde steg 2: "Antall hull" og "Avanserte handicap- + innstillinger" flyttet FØR det store 18-knappers formatrutenettet** + (var sist, lett oversett bak noe man må skrolle forbi). Ren + rekkefølge-endring, ingen ny funksjonalitet. +6. **Score-registreringens "detaljer"-steg delt i to synlige seksjoner** + ("Retning" / "Detaljer per hull") med overskrift+divider, og en ny + `ScrollFade`-hjelpekomponent (bunn-fade + nedoverpil, ResizeObserver- + drevet, skjuler seg selv ved bunn) som løser at brukere ikke visste + de måtte skrolle for å finne Chip/Bunker/Straffeslag/Anywayslag. +7. **Anywayslag endret fra tall-rutenett til +/−-stepper** — samme + inndatamønster som Chip/Bunker/Straffeslag nå (alle fire er + konseptuelt samme type data, brøt tidligere mønster uten grunn). +8. **Netto par-markør på Slag-knappene**: en liten oransje prikk (med + kontrastring, synlig i BÅDE valgt og uvalgt tilstand) på knappen som + tilsvarer spillerens personlige netto par (rå par + `strokesReceived`, + allerede tilgjengelig i komponenten), pluss en tekstlig + "Ditt netto par (N)"-forklaring over selve rutenettet (tilgjengelighet + — ikke avhengig av fargesyn alene). `aria-label` utvidet tilsvarende. +9. **Putter-velgeren fikk egen visuell identitet** (oransje venstre- + aksentkant + flagg-ikon på tittelraden) for å skille den fra Slag- + velgeren, som ellers er nøyaktig samme rutenett-komponent. Selve + tallknappenes etablerte grønne "valgt"-stil er UENDRET. + +**Verifisering:** `tsc --noEmit` rent på alle endringer. Full scratch- +stack bygget (scratch-DB med alle 63 migrasjoner, egen scratch-MinIO, +scratch-API- og scratch-frontend-container, ekte produksjonsbuild av +frontend — ikke bare `tsc`). Ekte bruker opprettet og logget inn via +magic-link-bypass (`DEV_LOG_MAGIC_LINKS`), egen bane opprettet via ekte +API-kall (`POST /personal-courses`) med HCP 24 satt på spilleren for å +garantere `strokes_received > 0` på hull 1 — nødvendig for faktisk å se +netto-par-markøren i bruk, ikke bare anta at koden er riktig. +Browserverifisert (Chrome DevTools MCP, mobil viewport 390×844) i BÅDE +lys og mørk modus: ny-runde steg 2 sin nye rekkefølge, seksjonsdeling og +scroll-hint (bekreftet `opacity-100`→`opacity-0` ved faktisk scroll til +bunn, ikke bare visuell antagelse), netto-par-prikk (både alene og +samtidig med "valgt"-tilstand), Putter-aksent, de nye "X-Ym"-putt- +avstand-etikettene. Ingen konsollfeil. Scratch-miljøet ryddet opp +fullstendig (containere, images, database, rolle), `teecup_db`s +rolleoppsett bekreftet uendret. + Disse må avklares før eller under de relevante fasene: 1. **Sesjons-secret:** TeeOff lar `PUBLIC_SESSION_SECRET` falle tilbake på diff --git a/CHANGELOG.md b/CHANGELOG.md index 69a3118..4a91b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10386,3 +10386,45 @@ Neste steg: `corepack enable` + `pnpm install --frozen-lockfile` + `pnpm test`. **Verifisert:** 30/30 grønt lokalt. Ingen produksjonskode endret. + +71. **Åtte brukerrapporterte UX-funn — "Ny runde" og score-registrering + — 2026-08-11, se ADR-062.** Bruker sendte åtte konkrete, skjermbilde- + dokumenterte problemer. Delt i to spor: fire rettet direkte (reelle + logikkfeil/tekstvalg), fire sendt via V0 (reelt interaksjonsdesign). + + **Direkte:** `round-card.tsx` sin "Hull"-celle viste alltid planlagt + antall hull, aldri faktisk spilt, selv for tidlig avsluttede + "Fullført"-runder — rettet (`played < round.holes` avgjør nå om + avviket vises, uansett status). Putt-avstand-knappenes etiketter + endret fra et blandet "<Xm ... 8m+"-mønster til konsekvent + "X-Ym" (kun visningstekst, ikke backend-kontrakten) — bekreftet via + git-historikk at dette var Claude-forfattet, ikke V0. "Se feed" på + dashbordet endret til "Se venneaktivitet". @-tagging av medspillere + i feeden vurdert og UTSATT (egen fremtidig funksjon) — anbefalt + personvern-begrensning (kun faktiske relasjoner) og ekte søkbar + nedtrekksliste (ikke fritekst-tolkning) notert til den runden. + + **Via V0** (`tee-cup (9).zip`, kun `delivery/`-mappen tatt inn, diffet + mot live-treet først): ny-runde steg 2 sin "Antall hull"/"Avanserte + handicap-innstillinger" flyttet FØR formatrutenettet (var sist, lett + oversett). Score-registreringens "detaljer"-steg delt i "Retning"/ + "Detaljer per hull"-seksjoner + en ny `ScrollFade`-hjelpekomponent + (bunn-fade + nedoverpil, ResizeObserver, auto-skjuler ved bunn) -- + løser at brukere ikke visste de måtte skrolle. Anywayslag endret fra + tall-rutenett til +/−-stepper (samme mønster som Chip/Bunker/ + Straffeslag nå). Netto par-markør (oransje prikk + kontrastring + + tekstlig forklaring, tilgjengelig uten fargesyn) på Slag-knappene, + kan opptre samtidig med "valgt"-tilstand. Putter-velgeren fikk egen + oransje aksent + flagg-ikon for å skille den fra Slag-velgeren. + + **Verifisert:** `tsc --noEmit` rent. Full scratch-stack (DB, MinIO, + API, frontend — ekte produksjonsbuild). Ekte testbruker, egen bane + opprettet via API med HCP 24 for å garantere synlig netto-par- + markør. Browserverifisert (mobil viewport, lys+mørk modus): ny + rekkefølge, seksjonsdeling, scroll-hint (bekreftet både synlig og + auto-skjult), netto-par-prikk alene og kombinert med valgt-tilstand, + Putter-aksent, nye putt-avstand-etiketter. Ingen konsollfeil. + Scratch-miljøet ryddet opp fullstendig, `teecup_db` bekreftet uendret. + + **Ikke rullet ut ennå** — venter på eksplisitt bekreftelse per + CLAUDE.md. diff --git a/frontend/components/dashboard.tsx b/frontend/components/dashboard.tsx index 15c6a86..37439a1 100644 --- a/frontend/components/dashboard.tsx +++ b/frontend/components/dashboard.tsx @@ -929,7 +929,10 @@ function friendOnCourseInitials(name: string): string { function LiveFriends({ friends }: { friends: ApiFriendOnCourse[] }) { return (
- } /> + {/* "Se feed" var for anonymt/uspesifikt til å si hva som faktisk + venter bak lenken (2026-08-11, brukertilbakemelding) -- knyttet + teksten til seksjonens egen kontekst i stedet. */} + } /> {friends.length > 0 ? (
{friends.map((friend, i) => { diff --git a/frontend/components/ny-runde/step2-format.tsx b/frontend/components/ny-runde/step2-format.tsx index 5fdad03..05df3ca 100644 --- a/frontend/components/ny-runde/step2-format.tsx +++ b/frontend/components/ny-runde/step2-format.tsx @@ -43,6 +43,30 @@ export function Step2Format() {
+ {/* Antall hull -- et grunnleggende oppsettsvalg, derfor FØR det store + formatrutenettet, ikke etter (2026-08-11, brukertilbakemelding: ble + tidligere lett oversett fordi den lå sist, bak et 18-knappers + rutenett man må skrolle forbi først). */} +
+

Antall hull

+
+ patch({ numHoles: v === "9" ? 9 : 18 })} + options={[ + { value: "9", label: "9 hull" }, + { value: "18", label: "18 hull" }, + ]} + /> +
+
+ + {/* Avanserte HCP-innstillinger (skjult for scramble mot solo) -- fortsatt + kollapset som standard, KUN rekkefølgen flyttet opp, samme grunn som + Antall hull over. */} + {!svs ? : null} + {/* Format grid */}

Spilleform

@@ -86,25 +110,6 @@ export function Step2Format() {
) : null} - - {/* Advanced HCP (hidden for scramble vs solo) */} - {!svs ? : null} - - {/* Number of holes */} -
-

Antall hull

-
- patch({ numHoles: v === "9" ? 9 : 18 })} - options={[ - { value: "9", label: "9 hull" }, - { value: "18", label: "18 hull" }, - ]} - /> -
-
) } diff --git a/frontend/components/round-card.tsx b/frontend/components/round-card.tsx index cae78f5..52b0196 100644 --- a/frontend/components/round-card.tsx +++ b/frontend/components/round-card.tsx @@ -214,7 +214,13 @@ export function RoundCard({ round }: { round: Round }) { )} - {round.status === "active" && ( + {/* Vis "spilt av planlagt" når det faktisk AVVIKER fra planen -- + ikke bare mens runden pågår. En runde markert Fullført etter + f.eks. 9 av 18 planlagte hull skal fortsatt vise det avviket + her, ikke bare stille bytte til status-teksten (2026-08-11, + reelt funn: "Hull"-cellen under viser uansett kun PLANLAGT + antall, aldri hvor mange som faktisk ble spilt). */} + {played < round.holes && ( {played}/{round.holes} hull spilt diff --git a/frontend/components/round-detail.tsx b/frontend/components/round-detail.tsx index 65a91e5..9463c14 100644 --- a/frontend/components/round-detail.tsx +++ b/frontend/components/round-detail.tsx @@ -1929,7 +1929,8 @@ function ScoringWizard({

)} -
+
+
{step === "strokes" && ( <> @@ -1941,6 +1942,7 @@ function ScoringWizard({ expandLabel="10+" parValue={hole.par} showGolfTerms + strokesReceived={strokesReceived} onChange={(v) => onUpdate({ strokes: v, played: true, pickedUp: false })} readOnly={readOnly} /> @@ -1981,6 +1983,7 @@ function ScoringWizard({ expandValues={[7, 8, 9, 10]} expandLabel="7+" maxValue={stat.strokes ?? undefined} + accent="orange" onChange={(v) => onUpdate({ putts: v })} readOnly={readOnly} /> @@ -1989,12 +1992,18 @@ function ScoringWizard({ {step === "puttDistance" && ( - {hole.par !== 3 && ( + {/* Seksjon 1 -- retning (2026-08-11): retningskorsene utgjør nå + en tydelig egen gruppe med overskrift, adskilt fra tellerne + under, så det er visuelt klart at skjermen består av to + ulike typer inndata (brukertilbakemelding: umulig å vite at + man måtte skrolle for å finne resten). */} + + {hole.par !== 3 && ( + onUpdate({ teeShot: v as TeeShot })} + readOnly={readOnly} + /> + )} + onUpdate({ teeShot: v as TeeShot })} + label="Innspill" + variant="full" + centerLabel="Traff" + value={stat.approach} + onChange={(v) => onUpdate({ approach: v as Approach })} readOnly={readOnly} /> - )} + - onUpdate({ approach: v as Approach })} - readOnly={readOnly} - /> - - {/* Alltid stablet, ALDRI et sm:grid-cols-3-sprang: denne wizard- - seksjonen er fast begrenset til max-w-sm (384px, se - containeren over) uansett hvor bred selve VIEWPORTET er -- - et viewport-basert grid-cols-3-brudd ved 640px trigges - derfor på skjermer godt over 640px bredde mens - innholdskolonnen fortsatt kun er 384px, som får de tre - stepperne (hver ~190px minimum pga. faste 44px-knapper) til - å overlappe hverandre i stedet for å faktisk ha plass. */} -
- onUpdate({ chip: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> - onUpdate({ bunker: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> - onUpdate({ penalty: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> -
- - onUpdate({ anywayStrokes: v })} - readOnly={readOnly} - /> + {/* Seksjon 2 -- detaljer per hull (2026-08-11): egen overskrift + + divider fra "Retning" over. Alle FIRE tellerne (Chip/ + Bunker/Straffeslag/Anywayslag) er konseptuelt samme type + data (antall småhendelser per hull, typisk 0-3) og bruker nå + ETT konsistent +/--stepper-mønster -- Anywayslag var + tidligere det eneste tall-rutenettet, som brøt mønsteret + uten grunn. Alltid stablet, ALDRI et sm:grid-cols-3-sprang: + denne wizard-seksjonen er fast begrenset til max-w-sm + (384px, se containeren over) uansett hvor bred selve + VIEWPORTET er -- et viewport-basert grid-cols-3-brudd ved + 640px trigges derfor på skjermer godt over 640px bredde mens + innholdskolonnen fortsatt kun er 384px, som får stepperne + (hver ~190px minimum pga. faste 44px-knapper) til å + overlappe hverandre i stedet for å faktisk ha plass. */} + +
+ onUpdate({ chip: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> + onUpdate({ bunker: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> + onUpdate({ penalty: v })} readOnly={readOnly} max={stat.strokes ?? undefined} /> + onUpdate({ anywayStrokes: v })} + readOnly={readOnly} + max={stat.strokes ?? undefined} + /> +
+
)}
+