fix(dashboard): UX/a11y/perf/correctness pass#1248
Merged
Conversation
Audit-driven fixes across the tenant dashboard. No backend or BuildingBlocks changes; all verified (tsc clean, eslint 22->12 warnings, build OK, Playwright 121/121). Functional bugs: - realtime-context: wire 4 subscribed-but-unregistered hub events (PresenceChanged, ChatMessagePinned/Unpinned, ChatChannelMemberRead) so live presence/pin/read-receipt updates actually arrive. - chat-search: drop a stateful /g RegExp.test() whose lastIndex drifted and mis-highlighted matches. - user-detail: key the staged-roles reset on userId (not the data array) so a background refetch can no longer wipe unsaved edits. Accessibility: - Combobox: replace invalid role="option" in a menu / role="combobox" without aria-expanded with valid menuitemradio; lift the nested interactive clear button out to a sibling. - accessible names for reaction chips, quick-react emoji, EntitySearch, collapsed sidebar nav items. - role="status"/sr-only on skeletons, role="progressbar" on upload bars, DialogTitle on the mobile nav Sheet, anchor-as-menuitem for link items, h1->h2 heading hierarchy, status rows hidden from the chat log region. - raise placeholder contrast to AA (drop sub-AA alpha multipliers). UX/correctness: - retire hardcoded text-white/bg-white/bg-black via a new --color-overlay-foreground/--color-overlay token + semantic foregrounds. - profile form: surface load errors, gate inputs while loading, seed once. - wire the previously no-op "Reduce motion" toggle through the theme provider; fix the notifications "open bell" selector. Cleanup: - remove 3 `void X` dead-import hacks + a dead effect, swap a full-page window.location reload for router navigate(), and resolve all 10 exhaustive-deps lint warnings via useMemo. Tests: update 3 identity empty-state heading-level assertions to match the corrected h2 hierarchy. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A focused UX / accessibility / performance / correctness pass over the tenant dashboard (
clients/dashboard), driven by a four-dimension audit. No backend orsrc/BuildingBlockschanges.Why
The dashboard was already mature, so this targets the things lint can't catch: silent realtime bugs, invalid ARIA, contrast gaps, and a few dead-code / footgun spots.
Highlights
Functional bugs
realtime-context.tsx(PresenceChanged,ChatMessagePinned,ChatMessageUnpinned,ChatChannelMemberRead) — live presence dots, pin/unpin, and read-receipts silently never updated. The backend broadcasts all four./gRegExp.test()in a.map()driftedlastIndexand mis-wrapped matches.roles = data ?? [], so a background refetch could wipe unsaved edits — re-keyed onuserIdwith a deterministic post-save clear.Accessibility
role="option"inside arole="menu"androle="combobox"withoutaria-expanded/controls→ validmenuitemradio; nested interactive clear button lifted to a sibling.EntitySearch(every list page), collapsed sidebar items.role="status"/sr-only on skeletons,role="progressbar"on upload bars,DialogTitleon the mobile nav Sheet, anchor-as-menuitem (asChild) for link menu items, h1→h2 heading hierarchy, chat status rows hidden from therole="log"region.UX / correctness
text-white/bg-white/bg-blackvia a new theme-independent--color-overlay-foreground/--color-overlaytoken + semantic foregrounds..reduce-motionclass + CSS); fixed the notifications "open bell" selector.Cleanup
void Xdead-import hacks + a dead effect, swapped a full-pagewindow.locationreload for routernavigate(), and resolved all 10exhaustive-depslint warnings viauseMemo.Deliberately deferred
products.tsxprimitive de-dup (render identically — churn without a defect).react-refresh/only-export-components(dev-only HMR ergonomics).Verification
tsc -bcleaneslint0 errors, 12 warnings (down from 22)vite buildsucceeds🤖 Generated with Claude Code