Ny-runde-veiviser: legg utslag direkte i gjesteskjemaet
Brukertilbakemelding: valg av utslag for en nyopprettet gjest var lite intuitivt -- måtte inn i det ferdigopprettede gjestekortets "Rediger"- visning for i det hele tatt å se hvilket utslag som ble valgt. addGuest() valgte allerede utslag automatisk (kjønnsbasert), men helt stille -- selve GuestForm hadde aldri et synlig Utslag-felt. Lagt til et kontrollert teeId-felt direkte i gjesteskjemaet, samme NativeSelect-mønster og kjønn->utslag-resynk-logikk som PlayerCards tilsvarende felt allerede hadde -- inkludert i "Fyll inn automatisk"- knappen for kjente gjester (samme feilklasse, ikke tidligere rettet der). Scratch-verifisert: kjønnsbytte i skjemaet oppdaterer utslag-valget umiddelbart, og det ferdige spillerkortet viser riktig utslag med det samme uten å måtte åpne redigering. Se CHANGELOG.md punkt 47.
This commit is contained in:
parent
43482d9ba9
commit
ad3c47bfa3
2 changed files with 39 additions and 5 deletions
|
|
@ -6,6 +6,7 @@ import { cn } from "@/lib/utils"
|
|||
import { ChevronDown, Search, Sparkles, UserPlus, X } from "lucide-react"
|
||||
import { useEffect, useMemo, useRef, useState } from "react"
|
||||
import { Avatar, Field, NativeSelect, Pill, TextInput, ToggleButton, useDebouncedValue } from "./primitives"
|
||||
import type { Tee } from "@/lib/ny-runde/types"
|
||||
import { useWizard } from "./wizard-context"
|
||||
|
||||
const GENDERS: { value: Gender; label: string }[] = [
|
||||
|
|
@ -272,6 +273,7 @@ function AddPlayerPanel({
|
|||
const [gender, setGender] = useState<Gender>("mann")
|
||||
const [hcp, setHcp] = useState("")
|
||||
const [stat, setStat] = useState<StatLevel>(defaultStat)
|
||||
const [teeId, setTeeId] = useState<string | undefined>(() => compatibleTees(course, "mann")[0]?.id)
|
||||
const firstRef = useRef<HTMLInputElement>(null)
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -330,7 +332,7 @@ function AddPlayerPanel({
|
|||
isGuest: true,
|
||||
email: email.trim() || undefined,
|
||||
hcp: hcp.trim() === "" ? null : Number.parseFloat(hcp.replace(",", ".")),
|
||||
teeId: compatibleTees(course, gender)[0]?.id,
|
||||
teeId,
|
||||
statLevel: stat,
|
||||
})
|
||||
}
|
||||
|
|
@ -400,6 +402,7 @@ function AddPlayerPanel({
|
|||
</div>
|
||||
) : (
|
||||
<GuestForm
|
||||
course={course}
|
||||
first={first}
|
||||
setFirst={setFirst}
|
||||
last={last}
|
||||
|
|
@ -412,6 +415,8 @@ function AddPlayerPanel({
|
|||
setHcp={setHcp}
|
||||
stat={stat}
|
||||
setStat={setStat}
|
||||
teeId={teeId}
|
||||
setTeeId={setTeeId}
|
||||
firstRef={firstRef}
|
||||
onBackToSearch={() => setMode("search")}
|
||||
onSubmit={addGuest}
|
||||
|
|
@ -422,6 +427,7 @@ function AddPlayerPanel({
|
|||
}
|
||||
|
||||
function GuestForm({
|
||||
course,
|
||||
first,
|
||||
setFirst,
|
||||
last,
|
||||
|
|
@ -434,10 +440,13 @@ function GuestForm({
|
|||
setHcp,
|
||||
stat,
|
||||
setStat,
|
||||
teeId,
|
||||
setTeeId,
|
||||
firstRef,
|
||||
onBackToSearch,
|
||||
onSubmit,
|
||||
}: {
|
||||
course?: Course
|
||||
first: string
|
||||
setFirst: (v: string) => void
|
||||
last: string
|
||||
|
|
@ -450,10 +459,13 @@ function GuestForm({
|
|||
setHcp: (v: string) => void
|
||||
stat: StatLevel
|
||||
setStat: (v: StatLevel) => void
|
||||
teeId: string | undefined
|
||||
setTeeId: (v: string | undefined) => void
|
||||
firstRef: React.RefObject<HTMLInputElement | null>
|
||||
onBackToSearch: () => void
|
||||
onSubmit: () => void
|
||||
}) {
|
||||
const tees = compatibleTees(course, gender)
|
||||
// kjent-gjest-oppslag på e-post (scoped til DENNE brukeren server-side)
|
||||
const debouncedEmail = useDebouncedValue(email, 350)
|
||||
const [match, setMatch] = useState<KnownGuest | null>(null)
|
||||
|
|
@ -508,8 +520,12 @@ function GuestForm({
|
|||
onClick={() => {
|
||||
setFirst(match.firstName)
|
||||
setLast(match.lastName)
|
||||
if (match.gender === "m") setGender("mann")
|
||||
else if (match.gender === "f") setGender("kvinne")
|
||||
const matchedGender = match.gender === "m" ? "mann" : match.gender === "f" ? "kvinne" : null
|
||||
if (matchedGender) {
|
||||
const stillOk = compatibleTees(course, matchedGender).some((t) => t.id === teeId)
|
||||
setGender(matchedGender)
|
||||
if (!stillOk) setTeeId(compatibleTees(course, matchedGender)[0]?.id)
|
||||
}
|
||||
if (match.hcp != null) setHcp(String(match.hcp))
|
||||
}}
|
||||
className="mt-1 text-[13px] font-semibold text-[var(--nr-accent)] underline-offset-2 hover:underline"
|
||||
|
|
@ -521,7 +537,25 @@ function GuestForm({
|
|||
) : null}
|
||||
|
||||
<Field label="Kjønn">
|
||||
<GenderChoice value={gender} onChange={setGender} />
|
||||
<GenderChoice
|
||||
value={gender}
|
||||
onChange={(g) => {
|
||||
const stillOk = compatibleTees(course, g).some((t) => t.id === teeId)
|
||||
setGender(g)
|
||||
if (!stillOk) setTeeId(compatibleTees(course, g)[0]?.id)
|
||||
}}
|
||||
/>
|
||||
</Field>
|
||||
|
||||
<Field label="Utslag" htmlFor="g-tee">
|
||||
<NativeSelect id="g-tee" value={teeId ?? ""} onChange={(e) => setTeeId(e.target.value || undefined)}>
|
||||
<option value="">Velg utslag</option>
|
||||
{tees.map((t: Tee) => (
|
||||
<option key={t.id} value={t.id}>
|
||||
{t.name}
|
||||
</option>
|
||||
))}
|
||||
</NativeSelect>
|
||||
</Field>
|
||||
|
||||
<Field label="HCP" optional htmlFor="g-hcp">
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue