Skip to content

feat(portal): show/hide password toggle on login and setup (bd-2668) - #204

Merged
hatafatif merged 1 commit into
mainfrom
bd-2668-to-main
Aug 13, 2026
Merged

feat(portal): show/hide password toggle on login and setup (bd-2668)#204
hatafatif merged 1 commit into
mainfrom
bd-2668-to-main

Conversation

@hatafatif

Copy link
Copy Markdown
Collaborator

Cherry-pick of 3592bbf from develop (merged there as #203) onto main.

Why a cherry-pick and not develop → main: develop is 48 commits ahead of main — a full promotion would ship the Android OTA pipeline, conversation-state recovery, the bd-2540 Gamma strip, and Railway build changes to prod alongside this. Operator chose to isolate the toggle. The 47 other commits stay queued on develop for a separate, deliberate release.

What ships

Eye toggle on PortalLogin and PortalSetup; aria-label on the pre-existing reset-screen toggle (it was icon-only, announced as just "button"). 4 files, all under portal/src/portal/pages/. No bot code, no DB, no env vars, no Meta assets.

Setup gets ONE toggle driving both fields — the failure it fixes is "these two don't match and I can't see why", which needs both visible at once.

Verified on THIS base, not just develop

Since main is 48 commits behind, the commit was re-verified after the cherry-pick rather than assumed:

  • Cherry-pick applied with zero conflicts
  • Confirmed main's PortalLogin carries the bd-2569 session gate, so the test's useAuth mock is faithful here too
  • Portal vitest: 18 files / 94 tests green (94 vs develop's 97 — main lacks 3 tests from unmerged commits, expected)
  • tsc --noEmit: clean · vite build: clean

Tests are red-first (6 failed / 1 passed against develop before the fix) and assert on the input's type attribute — what actually masks characters — not on which icon renders. The toggle being type=button is pinned, so peeking can't submit the login form.

Blast radius

Login and account-setup are the two screens every NIETE teacher passes through. The change is additive — no auth logic, submit path, or API calls touched. Deploys via Railway auto-deploy from main.

Not covered: how it renders on a real phone — worth a post-deploy look.

Closes: bd-2668

🤖 Generated with Claude Code

The login and setup screens were the two places a teacher typed a password
completely blind. Setup is the worse of the two: an 8-character-plus-a-digit
password, typed twice, with "Passwords do not match" as the only feedback —
and it cannot tell you which of the two you fat-fingered. On a phone keyboard
that is a dead end.

PortalPasswordResetVerify already had this toggle, so the pattern is copied
from there rather than invented: the input type flips between 'password' and
'text', the button sits absolutely inside a relative wrapper, and the field
gets pr-10 so a long password does not run under the icon.

Setup gets ONE toggle driving both fields, matching the reset screen. The
failure being fixed is "these two do not match and I cannot see why", which
needs both visible at once; a per-field toggle makes that comparison harder,
not easier.

Also gives the pre-existing reset-screen toggle an aria-label — it was an
icon-only button with no accessible name, so a screen reader announced it as
just "button". Same three-line pattern, and shipping two inconsistent copies
of it was the worse option.

Tests assert on the input's type attribute, which is what actually determines
whether characters are masked; asserting on which icon renders would pass even
if the wiring were broken. Also pinned: the toggle is type=button, so peeking
at your password does not submit the form.

Tests: 7 new (red-first against develop: 6 failed, 1 passed), portal suite
18 files / 97 tests green, tsc clean, vite build clean. Root Jest is at its
pre-existing 33-suite baseline (needs bot/ deps, installed separately in CI).

Closes: bd-2668
@hatafatif
hatafatif merged commit 5516ca7 into main Aug 13, 2026
1 check passed
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