Flytt "Mer" inn i navnereden, "Mål et slag" inn i "Mer" -- kun scorekortførers eget kort
V0-eksport integrert: PlayerCardMore utvidet med scoreButton/measureShot- props, navnereden er nå en ikke-knapp wrapper med score-knappen og en kompakt "Mer"-pille som søsken (unngår button-i-button). "Mål et slag" er ikke lenger en egen rad -- ligger nå i "Mer"-panelet, og er (som historikk) begrenset til player.isSelf; var tidligere synlig for alle spilleres kort. Se CHANGELOG.md #138. Ikke rullet ut ennå. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
f10121beaf
commit
a52ff91ff1
2 changed files with 126 additions and 50 deletions
43
CHANGELOG.md
43
CHANGELOG.md
|
|
@ -13432,3 +13432,46 @@ Neste steg:
|
||||||
`tsc --noEmit` rent.
|
`tsc --noEmit` rent.
|
||||||
|
|
||||||
**Ikke rullet ut ennå** -- venter på bekreftelse fra bruker.
|
**Ikke rullet ut ennå** -- venter på bekreftelse fra bruker.
|
||||||
|
|
||||||
|
138. **"Mer" flyttet inn i navnereden, "Mål et slag" flyttet inn i "Mer"
|
||||||
|
-- KUN scorekortførers eget kort, 2026-08-20.** Direkte oppfølging av
|
||||||
|
#135/#136 samme dag. Bruker viste skjermbilde med to nye punkter:
|
||||||
|
(1) "Mer" skulle vekk fra sin egen full-bredde-rad og inn i selve
|
||||||
|
navnereden, ved siden av score-knappen. (2) "Mål et slag" skulle vekk
|
||||||
|
fra sin egen rad og inn i "Mer"-panelet. Bruker presiserte i tillegg,
|
||||||
|
uavhengig av skjermbildet: BÅDE hull-historikk OG "Mål et slag" skal
|
||||||
|
være forbeholdt scorekortføreren selv (`player.isSelf`) -- "Mål et
|
||||||
|
slag" var tidligere synlig for ALLE spilleres kort (kun klubbutvalget
|
||||||
|
var allerede begrenset til eget bag via `ownBagClubs`), nå er hele
|
||||||
|
knappen borte for medspillere.
|
||||||
|
|
||||||
|
Claude skrev en V0-prompt (samme mønster som før), bruker kjørte den
|
||||||
|
og lastet opp eksporten (`player-card-more.tsx`, `PlayerCardBody`).
|
||||||
|
Løste DOM-utfordringen riktig: navnereden var tidligere ÉN stor
|
||||||
|
`<button>` (hele raden var trykkflaten som åpner score-registrering)
|
||||||
|
-- HTML tillater ikke en knapp inni en knapp, så eksporten strukturerte
|
||||||
|
om til en YTRE, ikke-knapp rad-wrapper med to SØSKEN: score-knappen og
|
||||||
|
en kompakt "Mer"-pille (44x44px, tekst+chevron).
|
||||||
|
|
||||||
|
`round-detail.tsx`:
|
||||||
|
- `PlayerCardMore` (fra runde 1, se #135) utvidet med en ny
|
||||||
|
`scoreButton`-prop (den eksisterende, rike navnerad-knappen --
|
||||||
|
playerSide-prikk/badges/HCP/dimmed/won/ScorecardCell/StrokeDots,
|
||||||
|
alt UENDRET innhold, kun flyttet til å være denne propen) og en ny
|
||||||
|
`measureShot`-prop. Selve "Mer"-vekslen flyttet fra en egen
|
||||||
|
full-bredde rad til en kompakt pille ved siden av `scoreButton` i en
|
||||||
|
ny, ikke-knapp navnerad-wrapper.
|
||||||
|
- `PlayerHoleCards`: `ShotMeasurementEntry` er ikke lenger en egen rad
|
||||||
|
-- sendes nå inn som `measureShot`, gated `player.isSelf && !readOnly`
|
||||||
|
(før: kun `!readOnly`, altså synlig for alle). `ownBagClubs`-
|
||||||
|
betingelsen forenklet til alltid `ownBagClubs` siden hele knappen nå
|
||||||
|
uansett kun rendres for isSelf.
|
||||||
|
|
||||||
|
**Verifisert i scratch:** mocket `RoundDetail`-forhåndsvisning, tre
|
||||||
|
spillere. Bekreftet: navnerad + kompakt "Mer"-pille ligger side ved
|
||||||
|
side (ingen nøstet knapp, `tsc --noEmit` bekrefter gyldig JSX/DOM),
|
||||||
|
eget kort sitt panel viser Mål et slag -> historikk -> Avslutt/Send i
|
||||||
|
riktig rekkefølge, medspillers panel viser KUN Avslutt/Send (verken
|
||||||
|
Mål et slag eller historikk). Sjekket lys og mørk modus.
|
||||||
|
|
||||||
|
**Ikke rullet ut ennå** -- venter på bekreftelse fra bruker.
|
||||||
|
|
|
||||||
|
|
@ -5949,33 +5949,63 @@ function ParticipantCompletionActions({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tone-ned-mønster for spillerkortets sekundære rader (historikk +
|
// Tone-ned-mønster for spillerkortets sekundære innhold (Mål et slag,
|
||||||
// Avslutt/Send scorekort) på Score-fanen -- V0-eksport (zip, 2026-08-20,
|
// historikk, Avslutt/Send scorekort) på Score-fanen -- V0-eksport (zip,
|
||||||
// brukerkorrigering: disse lå tidligere alltid synlig, uansett hvor sjelden
|
// 2026-08-20). Runde 1: egen "Mer"-rad UNDER navnereden. Runde 2
|
||||||
// brukt). Eier KUN vis/skjul -- selve historikk-panelet og handlingsraden
|
// (brukerønske samme dag): "Mer" flyttet INN i selve navnereden (kompakt
|
||||||
// forblir de ekte, uendrede komponentene (HoleHistoryPanel/
|
// pille ved siden av score-knappen), og "Mål et slag" flyttet INN i
|
||||||
// ParticipantCompletionActions), sendt inn som barn. Brukes KUN i
|
// panelet sammen med historikk/Avslutt/Send -- ingen av de tre var brukt
|
||||||
// PlayerHoleCards (Score-fanen) -- PlayerList ("Spillere og runde") beholder
|
// ofte nok til å fortjene egne, alltid synlige rader.
|
||||||
// ParticipantCompletionActions synlig uten denne vekslen, siden den siden
|
//
|
||||||
// allerede er en ren administrasjonsvisning.
|
// VIKTIG DOM-BEGRENSNING: navnereden var tidligere ÉN stor <button>. HTML
|
||||||
function PlayerCardMore({ history, actions }: { history?: React.ReactNode; actions: React.ReactNode }) {
|
// tillater ikke en knapp inni en knapp, så "Mer" kan IKKE ligge nøstet
|
||||||
|
// inni score-knappen. Løsning: denne komponenten eier en ytre
|
||||||
|
// IKKE-knapp-rad-wrapper med to søsken -- `scoreButton` (sendt inn av
|
||||||
|
// kalleren, uendret rik knapp-innhold) og "Mer"-pillen selv.
|
||||||
|
//
|
||||||
|
// Eier kun vis/skjul + selve rad-strukturen -- historikk-panelet,
|
||||||
|
// "Mål et slag" og handlingsraden forblir de ekte, uendrede komponentene
|
||||||
|
// (HoleHistoryPanel/ShotMeasurementEntry/ParticipantCompletionActions),
|
||||||
|
// sendt inn som barn. Brukes KUN i PlayerHoleCards (Score-fanen) --
|
||||||
|
// PlayerList ("Spillere og runde") beholder ParticipantCompletionActions
|
||||||
|
// synlig uten denne vekslen, siden den siden allerede er en ren
|
||||||
|
// administrasjonsvisning.
|
||||||
|
function PlayerCardMore({
|
||||||
|
scoreButton,
|
||||||
|
measureShot,
|
||||||
|
history,
|
||||||
|
actions,
|
||||||
|
}: {
|
||||||
|
/** Den eksisterende, rike score-åpne-knappen -- SØSKEN av "Mer", ikke forelder. */
|
||||||
|
scoreButton: React.ReactNode
|
||||||
|
/** "Mål et slag" -- kun scorekortførers eget kort (GPS-basert, gir ingen mening for medspillere). */
|
||||||
|
measureShot?: React.ReactNode
|
||||||
|
history?: React.ReactNode
|
||||||
|
actions: React.ReactNode
|
||||||
|
}) {
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const regionId = useId()
|
const regionId = useId()
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col border-t border-border">
|
<div className="flex flex-col">
|
||||||
|
<div className="flex items-stretch gap-2 p-3">
|
||||||
|
{scoreButton}
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setOpen((v) => !v)}
|
onClick={() => setOpen((v) => !v)}
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-controls={regionId}
|
aria-controls={regionId}
|
||||||
className="flex min-h-11 items-center justify-center gap-1.5 self-center rounded-xl px-4 py-2 text-sm font-bold text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
className={cn(
|
||||||
|
"flex min-h-11 min-w-11 shrink-0 flex-col items-center justify-center gap-0.5 rounded-2xl border border-border px-3 text-xs font-bold text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
||||||
|
open && "bg-accent text-foreground",
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{open ? "Skjul" : "Mer"}
|
<span>{open ? "Skjul" : "Mer"}</span>
|
||||||
<ChevronDown
|
<ChevronDown
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className={cn("size-4 shrink-0 transition-transform duration-200", open && "rotate-180")}
|
className={cn("size-4 shrink-0 transition-transform duration-200", open && "rotate-180")}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
</div>
|
||||||
{/* Myk høyde-animasjon via grid-rows 0fr -> 1fr -- samme prinsipp som
|
{/* Myk høyde-animasjon via grid-rows 0fr -> 1fr -- samme prinsipp som
|
||||||
"Vis banekart og hindringer" lenger oppe på skjermen. Innholdet
|
"Vis banekart og hindringer" lenger oppe på skjermen. Innholdet
|
||||||
fjernes fra a11y-treet og tab-rekkefølgen mens det er skjult. */}
|
fjernes fra a11y-treet og tab-rekkefølgen mens det er skjult. */}
|
||||||
|
|
@ -5987,7 +6017,8 @@ function PlayerCardMore({ history, actions }: { history?: React.ReactNode; actio
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="overflow-hidden">
|
<div className="overflow-hidden">
|
||||||
<div className={cn("flex flex-col gap-2 pb-2", !open && "invisible")} aria-hidden={!open}>
|
<div className={cn("flex flex-col gap-2 pb-3", !open && "invisible")} aria-hidden={!open}>
|
||||||
|
{measureShot && <div className="flex justify-end px-4">{measureShot}</div>}
|
||||||
{history && <div className="px-4">{history}</div>}
|
{history && <div className="px-4">{history}</div>}
|
||||||
{actions}
|
{actions}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -6852,6 +6883,19 @@ function PlayerHoleCards({
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
{/* Navnerad + "Mer": navnereden var tidligere ÉN stor
|
||||||
|
<button> som dekket hele kortbredden. Brukerønske
|
||||||
|
2026-08-20: flytt "Mer" INN i denne raden (kompakt
|
||||||
|
pille) og "Mål et slag" INN i "Mer"-panelet -- se
|
||||||
|
PlayerCardMore-komponenten for DOM-begrunnelsen (knapp
|
||||||
|
kan ikke ligge nøstet inni knapp, "Mer" er nå SØSKEN av
|
||||||
|
score-knappen). Historikk og "Mål et slag" er BEGGE KUN
|
||||||
|
scorekortførers eget kort -- historikk fordi panelets
|
||||||
|
tekst eksplisitt sier "Din historikk", "Mål et slag"
|
||||||
|
fordi avstandsmåling er GPS-basert fra DENNE telefonen
|
||||||
|
og gir ingen mening for en medspillers slag. */}
|
||||||
|
<PlayerCardMore
|
||||||
|
scoreButton={
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={readOnly}
|
disabled={readOnly}
|
||||||
|
|
@ -6863,7 +6907,7 @@ function PlayerHoleCards({
|
||||||
? `${player.name} har avsluttet runden, hull ${currentHole} ikke spilt`
|
? `${player.name} har avsluttet runden, hull ${currentHole} ikke spilt`
|
||||||
: `Registrer ${player.name} sin score på hull ${currentHole}${apiHole?.strokes_received ? `, mottar ${apiHole.strokes_received} slag` : ""}`
|
: `Registrer ${player.name} sin score på hull ${currentHole}${apiHole?.strokes_received ? `, mottar ${apiHole.strokes_received} slag` : ""}`
|
||||||
}
|
}
|
||||||
className="flex w-full items-center gap-3 p-4 text-left transition-colors hover:bg-accent/30 disabled:opacity-60"
|
className="flex min-w-0 flex-1 items-center gap-3 rounded-2xl bg-muted/40 p-3 text-left transition-colors hover:bg-muted disabled:opacity-60"
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
||||||
<div className="flex flex-wrap items-center gap-x-2 gap-y-1">
|
<div className="flex flex-wrap items-center gap-x-2 gap-y-1">
|
||||||
|
|
@ -6943,30 +6987,19 @@ function PlayerHoleCards({
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
{!readOnly && (
|
}
|
||||||
<div className="flex justify-end border-t border-border px-4 py-2">
|
measureShot={
|
||||||
|
player.isSelf && !readOnly ? (
|
||||||
<ShotMeasurementEntry
|
<ShotMeasurementEntry
|
||||||
roundId={roundId}
|
roundId={roundId}
|
||||||
holeNumber={currentHole}
|
holeNumber={currentHole}
|
||||||
owner={{ kind: "participant", id: player.id }}
|
owner={{ kind: "participant", id: player.id }}
|
||||||
ownBagClubs={player.isSelf ? ownBagClubs : []}
|
ownBagClubs={ownBagClubs}
|
||||||
readOnly={readOnly}
|
readOnly={readOnly}
|
||||||
variant="badge"
|
variant="badge"
|
||||||
/>
|
/>
|
||||||
</div>
|
) : undefined
|
||||||
)}
|
}
|
||||||
{/* Personlig hull-historikk (ADR-072, flyttet hit ut av
|
|
||||||
slagvinduet ADR-079, 2026-08-16) -- skjermen FØR
|
|
||||||
registrering/"Avslutt for {navn}", ikke inni selve
|
|
||||||
slagvinduet. Skjuler seg selv når banen er custom eller
|
|
||||||
spilleren ikke har historikk ennå. KUN scorekortførers
|
|
||||||
(isSelf) eget kort (2026-08-20, brukerkorrigering --
|
|
||||||
panelets tekst sier "Din historikk", som var feil for
|
|
||||||
andre spilleres kort). Tonet ned bak "Mer" sammen med
|
|
||||||
Avslutt/Send scorekort (2026-08-20, V0-eksport
|
|
||||||
`player-card-more.tsx`) -- begge var sjeldent brukte
|
|
||||||
handlinger som likevel alltid tok plass på hvert kort. */}
|
|
||||||
<PlayerCardMore
|
|
||||||
history={
|
history={
|
||||||
player.isSelf ? (
|
player.isSelf ? (
|
||||||
<HoleHistoryPanel
|
<HoleHistoryPanel
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue