UI Overhaul Integration#97
Open
b006n97 wants to merge 12 commits into
Open
Conversation
Return the 50 most recent games per variant instead of 30, matching the redesigned Games page which surfaces more history. Symmetric change across both variant services; no other behavior affected.
Introduces the platform layer the rest of the UI overhaul sits on, with no feature redesigns yet: - theme/tokens.ts: single source of truth for accent ramps (red/blue/green), per-scheme neutrals, medal/placement colors, and timing. - theme/index.ts: createAppTheme(accent) builds a colorSchemes (light/dark) theme, exposing accent + neutrals as CSS vars (--mui-palette-*). - theme/AccentContext.tsx: runtime accent switch (localStorage-persisted), orthogonal to MUI's color-scheme mode. - theme/utils.ts: additive sx presets (gradientTitle, eyebrowLabel) plus restyled existing helpers; export names/types unchanged so current components keep compiling. - index.tsx: InitColorSchemeScript to avoid a flash of the wrong theme. - index.html: load the Manrope font used by the theme typography. - App.tsx: swap ThemeProvider(createAppTheme()) for <AccentProvider> only; routing is left untouched here and migrated in later PRs. - DESIGN.md: design-system reference. Fixed the tokens.ts docstring drift (was "two accent variants"; there are three: red/blue/green). Typechecks independently (tsc --noEmit clean) with the still-un-migrated components consuming the new theme.
Reusable presentational primitives consumed by the Home, Leaderboard, and Statistics redesigns in later PRs. Depend only on React + MUI (theme values resolve at runtime via CSS vars); additive with no importers yet, so this lands clean and keeps the feature PRs small.
Replace the 469-line monolithic common/NavBar.tsx with a focused module: - navbar/index.tsx: composition + shared AppBar shell - DesktopNav.tsx / MobileDrawer.tsx: the two responsive layouts - LogoIcon.tsx, navStyles.ts (shared sx + easing), navActive.ts (active-route helpers) WithNav.tsx now imports @/common/navbar. Behavior is preserved (same links, auth gating, active highlighting); styling is updated to the new theme. Depends only on the design-system foundation.
New Hero.tsx (full-bleed hero with gradient title over a left-anchored scrim and hero.webp artwork) and a restructured Home.tsx using the shared IconBadge and SectionHeader atoms. Depends on the design-system foundation and shared atoms; no routing or data changes.
- StatisticsSummary.tsx: new stat-tile summary built on the StatCard atom. - PlacementDistributionBar.tsx: new 1st-4th distribution bar using the shared placement colors from theme tokens. - PlacementHistoryGraph.tsx: reworked placement history chart. - placementConstants.ts: shared ORDINALS / PLACEMENTS constants. - Statistics.tsx: slimmed to compose the above; DisplayStatistics export kept backward-compatible so the (still-legacy) Leaderboard keeps compiling. Depends on the design-system foundation and shared atoms.
Collapse the four prop-driven per-board routes into a single /leaderboard page that reads ?variant=&type= via useSearchParams and lets the user switch boards in-page. Legacy URLs (/leaderboard/jp, .../casual, /leaderboard/hk, ...) now redirect with the intended board carried in the query string, so existing links/bookmarks still land on the right selection. App.tsx changes are scoped to the leaderboard routes; games/create routing is migrated in later PRs.
- Shared AuthLayout.tsx + BrandHeader.tsx wrap Login / Register / password-reset flows in a consistent branded shell. - Login, Register, RequestPasswordReset, PasswordReset restyled onto the layout. - Settings.tsx gains an accent picker (red/blue/green) driven by useAccent, with dragon-tile SVG swatches per accent. Depends on the design-system foundation (theme + AccentContext).
Restyle the resources/guides page onto the new design system (section headers, cards, typography). Content and routing unchanged.
Unrelated micro-changes batched to keep the feature PRs pure:
- admin/{AdminChombo,AdminPlayers,AdminSeason}: drop unused imports.
- common/{AuthContext,LoadingFallback,Unauthorized}: small cleanups/restyle.
- App.scss: global-style tweaks.
- bump @types/react 18.3.11 -> 18.3.31 (types-only).
No behavior or routing changes.
Merge the separate LiveGames and GameLogs views into a single /games page:
- Games.tsx composes LiveGamesSection + GameLogsSection under shared
GameSectionHeader.
- LiveGames.tsx / GameLogs.tsx refactored to export those sections and share
GameSummaryCard -> GameSummaryBody, with placement.ts (new) as the shared
place-color/label source and Utils.formatRelativeTime for "5m ago" stamps.
- App.tsx: /games/current/{jp,hk} collapse to /games/current; /games now
renders Games. (Record-game /games/create routing is migrated in the next PR.)
placement.ts is added here as an additive shared helper; the record-game flow
picks it up in the following PR. Record-game code is untouched and still
compiles against the existing constants.
Rework game entry (CreateGame, Game, and the legacy jp/hk game screens) onto a
stepped UI with clearer per-round requirements, and consolidate create routing:
- StepSection / RoundRequirements / TransactionTypeSelector (replacing
TransactionTypeButtonList) / PlayerScoreCard drive the new entry flow;
Footer, PlayerButtonRow, PointsInput, DropdownInput, TableDisplay restyled.
- App.tsx: /games/create/{jp,hk}[/casual] collapse to a single query-param
/games/create page; legacy URLs redirect carrying variant/type.
BEHAVIORAL CHANGES (intentional, confirmed):
- constants.ts default hand: JP_UNDEFINED_HAND {han:-2,fu:10} -> {han:1,fu:30};
HK_UNDEFINED_HAND (-1) renamed/retuned to HK_DEFAULT_HAND (3). Entry now
starts from a valid minimum hand instead of a sentinel.
- assignRoundAction centralizes role-exclusivity (a player can't be winner and
loser at once) across every assignment path.
- getUnmet{Japanese,HongKong}RoundRequirements add soft, non-throwing
validation so the UI can gate Submit; the throwing validators remain the
submit-time safety net.
TESTING GAP: assignRoundAction / isValidHand / getUnmet*RoundRequirements are
pure and unit-testable, but the frontend has no test runner configured. Cover
via a follow-up (add vitest to frontend) or manual QA of deal-in / self-draw /
pao / nagashi / deck-out entry in both variants before release.
Closed
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.
Overview
Full UI overhaul of the MJC website: a new design-token system with light/dark
color schemes and a runtime accent switcher, a decomposed navigation module,
consolidated routing, and a redesign of every feature surface (home, leaderboard,
statistics, games, record-game, auth/account, resources).
78 files, +6,389 / −2,352, 12 commits. No backend/DB schema changes of
substance — this is a frontend overhaul plus one small backend page-size tweak.
How to review
This branch is the one-cutover merge of a 12-PR reviewed stack. Review the
small, ordered slices below (bottom-up); this PR is the single atomic merge to
main. Do not merge until all 12 are approved.Changes by area
theme/tokens.ts,theme/index.ts,AccentContext.tsx,animations.ts,theme/utils.ts,DESIGN.md): single source of truth forcolors/typography/timing; MUI
colorSchemeslight + dark exposed as CSS vars;runtime accent (red/blue/green) persisted in localStorage; Manrope font;
InitColorSchemeScriptto prevent theme flash.NavBar.tsx→ focusedcommon/navbar/module(DesktopNav, MobileDrawer, LogoIcon, navStyles, navActive).
Register/reset, Account settings, Resources — all restyled onto the system,
with shared atoms and game/common primitives.
Behavioral changes (intentional — please scrutinize)
take: 30 → 50: live-games queries now return 50 rows/variant.JP_UNDEFINED_HAND {han:-2,fu:10}→{han:1,fu:30};HK_UNDEFINED_HAND (-1)→HK_DEFAULT_HAND (3). Entry starts from a validminimum hand instead of a sentinel.
assignRoundAction: centralizes role-exclusivity (a player can't bewinner and loser simultaneously) across every assignment path.
getUnmet{Japanese,HongKong}RoundRequirements: non-throwingchecks that gate the Submit button; the existing throwing validators remain the
submit-time safety net.
Routing changes
/leaderboard/{jp,hk}[/casual]→ single/leaderboard?variant=&type=; legacyURLs 301-redirect carrying the selection.
/games/current/{jp,hk}→/games/current;/gamesnow renders the mergedGames page.
/games/create/{jp,hk}[/casual]→ single/games/create?variant=&type=; legacyURLs redirect.
Deliberately NOT included (accidental cruft dropped from the original branch)
Root
package-lock.json(orphaned framer-motion, imported nowhere),backend/package-lock.jsonname-line churn, aschema.prismawhitespace-onlyedit, and comment noise in dead
game/new/*. Also cleaned up: the now-unusedTransactionTypeButtonList.tsx(replaced byTransactionTypeSelector).Testing
tsc --noEmitand fullnpm run buildpass on this branch (each of the 12slices also typechecks independently).
frontend has no test runner. Before merge, either add vitest to cover
assignRoundAction/isValidHand/getUnmet*RoundRequirements, or manuallyQA game entry in both variants:
self-hosting for privacy/offline/CSP.