Skip to content

ux: auth usability pass — 6 fixes from Nielsen heuristics + Don't Make Me Think#47

Merged
dmccoystephenson merged 6 commits into
mainfrom
ux/auth-usability-pass
Jun 7, 2026
Merged

ux: auth usability pass — 6 fixes from Nielsen heuristics + Don't Make Me Think#47
dmccoystephenson merged 6 commits into
mainfrom
ux/auth-usability-pass

Conversation

@dmccoystephenson

Copy link
Copy Markdown
Member

Summary

Usability pass over the authentication UI added in #45 (login, register, and the auth bits of the game screen). Every commit is one self-contained Nielsen / Krug fix, scoped small for easy review. Theme: feedback & error recovery — no more blocking alert()s, visible progress on submit, and the player is always told why they're looking at the login screen.

Round 1 — auth feedback & error recovery

  1. Login — failed logins show inline in a styled error box instead of a native alert() that covers the form and vanishes on dismiss (Nielsen Implement tile-by-tile army movement with Manhattan pathfinding #9).
  2. Login — the submit button disables and shows "Logging in…" during the request, giving feedback and preventing double-submits (Nielsen Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend #1, Implement Castle Capture and Win/Loss Conditions #5).
  3. Login — a neutral notice box explains why you're here ("Account created", "Your session expired") and the username is pre-filled with focus moved to the password (Nielsen Implement tile-by-tile army movement with Manhattan pathfinding #9, Krug).
  4. Register — errors (e.g. "username already taken") render inline instead of a blocking alert() (Nielsen Implement tile-by-tile army movement with Manhattan pathfinding #9).
  5. Register — the submit button shows "Creating account…", and on success the screen hands off to login with a success notice + pre-filled username instead of an alert() + empty form (Nielsen Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend #1, Krug).
  6. Game — token expiry/revocation (401) now sends the player to login with a "Your session expired" message instead of a silent kick, and voluntary logout leaves a "You have been logged out" confirmation (Nielsen Implement tile-by-tile army movement with Manhattan pathfinding #9, Implement minimal client/server game prototype with Spring Boot backend and LWJGL frontend #1).

Test plan

  • Wrong password → inline red error above the form (no popup); button returns from "Logging in…".
  • Register an existing username → inline error (no popup).
  • Register a new user → lands on login with a green "Account created — please log in" notice, username pre-filled, cursor in password.
  • Log in, then let the token be revoked (or log out from another tab) and make a move → bounced to login with "Your session expired".
  • Click Logout → login screen shows "You have been logged out".

🤖 Generated with Claude Code

BuildTools and others added 6 commits June 7, 2026 16:36
A failed login (wrong password, server down) popped a native alert() dialog
that covered the form, demanded a click to dismiss, and vanished without a
trace — leaving the player to re-find the form with no record of what went
wrong. Native alerts also look nothing like the game and read as "something
broke" rather than "here's how to fix it" (Nielsen #9: help users recognize,
diagnose, and recover from errors).

This routes both the empty-field check and the server error message into an
inline, styled error box above the form that stays visible while the player
corrects their input, and clears automatically on the next submit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…bmits

Pressing "Log In" gave no sign anything was happening: the button stayed
idle-looking while the network request ran, so on a slow connection the
player had no feedback and would click again, firing a second login (Nielsen
#1: visibility of system status). A double-submit can also race two requests.

The submit button now disables itself and switches to "Logging in…" for the
duration of the request, restoring on failure. The player sees the click
registered and cannot fire a duplicate while one is in flight (Nielsen #5:
error prevention).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a player landed on the login page they got no context: someone who just
registered, or who was bounced here by an expired session, saw only an empty
form and had to guess what happened and retype the username they'd just entered
(Nielsen #9: recognize/recover from errors; Krug: don't make me think — answer
the obvious question before it's asked).

This adds a neutral "notice" box (visually distinct from the red error box) and
reads a one-time handoff from sessionStorage on load: it shows a message like
"Account created — please log in" or "Your session expired", pre-fills the
username, and moves focus to the password field. Producers of those messages
follow in the register and game commits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The most common registration error — "username already taken" (409) — was
delivered as a native alert() that obscured the form and disappeared on
dismiss, so the player lost the message the moment they went to change their
username (Nielsen #9: help users recognize, diagnose, and recover from errors).
It also clashed visually with the game's styling.

This mirrors the login screen: the empty-field check and the server error now
render in an inline, styled error box above the form that persists while the
player edits and clears on the next submit. (The success path is handled in the
following commit.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… login

Two problems on success: the button gave no feedback while the account was
being created (Nielsen #1: visibility of system status), and on success a
native alert() said "Account created. Please log in." — then dropped the
player on an empty login form where they had to retype the username they'd
just chosen (Krug: don't make me think).

The button now disables and reads "Creating account…" during the request, and
on success the screen hands off to login via sessionStorage — showing an
"Account created — please log in" notice with the username pre-filled and the
cursor in the password field. No modal, no retyping.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a token expired or was revoked mid-game, every authenticated request's
401 handler silently called logout() and dumped the player on the login screen
with no explanation — indistinguishable from a random kick (Nielsen #9: help
users recognize and recover from errors). Voluntary logout was equally mute:
the player clicked Logout and just landed on a blank form with no confirmation
it had worked (Nielsen #1: visibility of system status).

The 401 handlers now call sessionExpired(), which leaves a "Your session
expired — please log in again" notice for the login screen to show, while
voluntary logout leaves a "You have been logged out" confirmation. sessionExpired
also skips the pointless server revoke call that logout() makes, since the token
the server just rejected is already invalid.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dmccoystephenson dmccoystephenson merged commit 5967750 into main Jun 7, 2026
2 checks passed
@dmccoystephenson dmccoystephenson deleted the ux/auth-usability-pass branch June 7, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant