From 0876a9db2dd36ff20ef04d2904b0eec14bfa7f81 Mon Sep 17 00:00:00 2001 From: tiennm99 Date: Tue, 1 Sep 2026 17:16:53 +0700 Subject: [PATCH] feat(ui): username flow rework Defer username prompt to first Play click, make username editable in header chip, generate random Player-xxxxxx name on skip or deep-link, update tests accordingly. --- src/app/components/RegionPicker.js | 41 +++++++++++---- src/app/components/UsernameModal.js | 39 +++++++++++--- src/app/page.js | 79 ++++++++++++++++++++++------- src/lib/username.js | 17 +++++++ tests/e2e/helpers.js | 14 +++++ tests/e2e/username.spec.js | 60 +++++++++++++++++----- tests/username.test.js | 19 +++++++ 7 files changed, 220 insertions(+), 49 deletions(-) create mode 100644 tests/username.test.js diff --git a/src/app/components/RegionPicker.js b/src/app/components/RegionPicker.js index 1def547..4d0a473 100644 --- a/src/app/components/RegionPicker.js +++ b/src/app/components/RegionPicker.js @@ -44,13 +44,23 @@ function unavailableLabel(code) { * @param {string} props.code Region code. * @param {string} props.label Text to show. * @param {boolean} props.emphasis True to style as the primary action. + * @param {Function} props.onPlayClick Pre-navigation hook; returning true + * cancels the navigation (the caller resumes it itself). */ -function PlayRow({ code, label, emphasis }) { +function PlayRow({ code, label, emphasis, onPlayClick }) { const { panos } = coverageOf(code); + const href = `/game?region=${code}`; return ( { + // Modified clicks (new tab, new window) keep native behavior: the + // deep-linked game page can name the player itself, so hijacking the + // gesture would cost more than the prompt is worth. + if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) return; + if (onPlayClick && onPlayClick(href)) e.preventDefault(); + }} className={`group flex min-h-14 items-center justify-between gap-3 rounded-xl border p-4 shadow-xs transition-all duration-150 hover:border-brand/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background ${ emphasis ? 'city-card-accent border-border bg-card' : 'border-border/60 bg-card/60' }`} @@ -60,13 +70,21 @@ function PlayRow({ code, label, emphasis }) { {label} {isThin(code) && ( - + few streets )} - {count(panos)} + + {count(panos)} spots + Play