Puzzles redesign: a landing, solving on GameScreen with a result dialog, a home with Puzzles, and pages that use the width #450
Labels
No labels
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
spec
wayfinder:grilling
wayfinder:map
wayfinder:prototype
wayfinder:research
wayfinder:task
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amaurycoudr/chess-project#450
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem Statement
A Player who clicks Puzzles in the navigation lands straight on a board. Nothing introduces Puzzles, shows their Puzzle rating at a glance, or helps them choose what to train. The Theme picker is a plain select in a sparse aside, beside a bare board that has no move list and no player rows. A solved or failed Puzzle only changes a line of text, so the result and the rating change are easy to miss. The home page offers two doors, Local and Online, and nothing at all about Puzzles. It also leaves most of the screen empty.
The same waste shows on other pages.
PageFramepages are pinned to the left at a fixed width, and pages with little content leave most of the screen blank (see the layout audit under Further Notes).Solution
/puzzles. It introduces training:/puzzles/train. Solving moves to its own route, built onGameScreen.PageFrameis centred and uses the width, which fixes My games, the profile, the account and the History together.GameScreenlets the board grow with the window height, which also helps Local, Room and Game review. The landing andPageFramewiden to 80 rem, and each home half centres its content.The design was settled in two prototype rounds, and the owner picked home G, landing E and train screen C. All variants live on the throwaway branch
prototype/puzzles-ui-redesign; see Further Notes.User Stories
Home
Puzzles landing
Solving
Result dialog
Space
PageFramepages to spread their content across the width, so that nothing hugs one side of the page.Screens
Home
//puzzles/train./puzzles/train?theme=<theme>./puzzles./sign-up?redirect=/puzzles./room/$code./local.LandingHeading. The Puzzles door is apuzzleswidget that the route hands to the home page, as the route already hands it Room creation. The home vertical cannot import the puzzles vertical.Phone: the halves stack, Puzzles first, each at its content's height (not a full screen each).
1920 px: the halves stay full-bleed, and each half centres its content in a column of at most 36 rem, so the Puzzles shortcuts and the Play actions sit mid-half rather than against its left edge.
Puzzles landing
/puzzles/puzzles/train(Resume serves the pending Attempt)./puzzles/train?theme=<theme>./puzzles/replay/$puzzleId./puzzles/history.PageFramewidth rule from this spec (centred, same max width) and the cards' still boards.Phone: the header stacks (title and rating, then the door at full width). The families become one row of chips that scrolls sideways. The cards stack in one column, two from
sm. Recent comes after the cards.1920 px: the page widens to 80 rem, centred, and the cards run four to a row from
2xl.?family=), so Back and a reload keep it. The default is the first family.Solving
/puzzles/train(and the Replay at/puzzles/replay/$puzzleId)/puzzles./puzzles/train./puzzles/train,/puzzlesor/puzzles/history.GameScreen.Phone:
GameScreen's own reflow (the rail under the board, its move list capped).1920 px: the board grows with the window height up to 56 rem (about 830 px on a 1080 px screen, against 640 px today), and the frame widens to keep the rail beside it.
NO_PUZZLE_LEFTwith a Theme: the frame with an empty board; the status line reads "You have tried every Puzzle"; the footer offers Mixed training.NO_PUZZLE_LEFTwith no Theme: the status line reads "You have tried every Puzzle"; the footer offers the landing.NOT_REPLAYABLE(Replay route): the status line reads "You can only replay a Puzzle you tried"; the footer offers the History.Theme switcher (dialog over Solving)
/puzzles/train[?theme=], closing the dialog./puzzles.Dialog, wide (sm:max-w-3xl), its body scrolling within 60 % of the viewport height.Phone: one column of Theme buttons, two from
sm.Result dialog (over Solving)
Dialog, default width.Phone: the dialog's own
calc(100% - 2rem)width.Puzzle History
/puzzles/history/puzzles(the landing).PageFrame, now centred and wider (see Implementation Decisions). No other change to the page.Seams
puzzle.progressprocedure, through the RPC integration harness (integration test). Covers stories 3, 11 and 13 (the pending flag, per-Theme tried and solved counts, Replays not counted, every curated Theme present).@/app/router.harness, view tests with the vertical's MSW handlers). Covers stories 1, 2, 4–10, 12 and 14–37: every state listed under Screens, the switcher, the result dialog and the refusals. The API seam owns the numbers behind stories 3, 11 and 13; their rendering is still asserted here, as part of the page states.apps/e2e/tests/puzzles.spec.ts(browser). It covers the main stories end to end. First, a signed-in Player goes from the home's Puzzles half to the landing, opens a Theme card, solves the Puzzle, sees the result dialog with the rating change, and presses Next. Second, a visitor goes from the Puzzles half through sign-up and lands on the landing. The existing scenario (solve, fail, History, unrated Replay) moves onto/puzzles/trainand asserts the dialog. Stories 38 and 39 are covered by one 1920×1080 check: the solving board is at least 800 px tall, and the landing's and My games' main column is centred within 1 px.Implementation Decisions
Contracts and API
puzzle.progress→{ pending: boolean, themes: { theme, tried, solved }[] }:themesholds every curated Theme in curated order, with zeros for an untried one.triedcounts the Account's resolved Attempts on Puzzles carrying that Theme;solvedcounts the solved ones among them.pendingis whether the Account has a pending Attempt.solvedandfailedmove results and to thesolutionresult, so the Puzzle row can show it once resolved. It is not onServedPuzzle, so it never reaches the page before the Puzzle is resolved.nextkeeps serving the pending Attempt whatever Theme is asked (the service's existing rule). The switcher's "applies from the next Puzzle" line is the front's only change for it.Front
/puzzlesbecomes the landing page; solving moves to/puzzles/train, with?theme=moving with it;/puzzles/replay/$puzzleIdrenders on the same solving frame. Links to/puzzlesthat meant "train" (the History's empty state, the Replay's Next) point to/puzzles/train.GameScreen. The bespoke board-and-aside layout goes; the solving and Replay pages build onGameScreen.occupantis its rating or "hidden", and the Player's is the Puzzle rating and change.GameScreen's player-row type cannot say "Puzzle" without a Username, it gains the smallest change that lets it, insidegame/.HomePagetakes the Puzzles door as a slot from the route, as it takescreateRoomtoday. The door is apuzzleswidget that reads the account,puzzle.ratingandpuzzle.progress.puzzle.rating,puzzle.progressand the first History page (its first five rows). Every Puzzle mutation invalidatespuzzle.progressandpuzzle.ratinginonSettled(rule 7).PageFrame. It is centred (mx-auto) and widened to the landing's max width (80 rem), keeping its padding. My games, the profile, the account and the History follow with no other change.GameScreenon wide screens. The upper bound of--board-sizeatlgrises from 40 rem to 56 rem; it stays bound by the window height, as today. The frame's max width rises from 68 rem to 80 rem, so the board and the 19 rem rail still sit side by side. EveryGameScreenpage (Local, Room, Game review, solving, Replay) gets this.GLOSSARY.md(a named group of curated Themes, shown to the Player; it changes no Puzzle).Testing Decisions
apps/api/test/rpc-puzzles.integration.test.tsandrpc-puzzle-history.integration.test.ts.apps/front/src/puzzles/puzzles.test.tsx,puzzles-themes.test.tsx,puzzle-history.test.tsxandhome/home.test.tsx, through@/app/router.harnesswithpuzzles.handlers.ts.apps/e2e/tests/puzzles.spec.ts.progressfor an Account with no Attempt (all zeros), with only Replays (still zeros), and with a pending Attempt (pendingtrue, not counted).implementskill): every state above at 390, 1280 and 1920 px. Also check My games, the profile and the account after thePageFramechange, and Local, Room and Game review after theGameScreenchange, at the same three widths.Out of Scope
/games/$idnot found) andAuthNotice, which show small centred text in a whole empty page. Also a follow-up.Further Notes
Prototype. Branch
prototype/puzzles-ui-redesign(throwaway, never merged). Runpnpm dev, sign in, then:/?variant=G|H(with&as=player|visitor) for the home./puzzles?variant=D|E|F(with&data=sample|empty|pending) for the landing./puzzles/train?variant=A|B|C&state=playing|solved|failed|replay&theme=backRankMatefor the train screen.Round 1 (home A–C, landing A–C) is in the branch history. The owner's verdicts:
Layout audit, of the pages as they are on
main, not the prototypes. It was measured in the browser at 1280×800, 1920×1080 and 390×844, signed in as the demo Account. At 1280 the content area beside the 16 rem sidebar is 1023 px wide.//puzzles(today)/games,/players/$u,/account,/puzzles/historyPageFramePageFramecentred and widened/local,/room/$code,/games/$idGameScreen/games/$idnot found,AuthNotice/sign-inetc.AuthPagePageFrameNext step: this spans more than one PR (an API procedure, the landing, the solving screen, the home), so run
to-ticketson this spec, thenimplement-spec.Seam change, approved by the owner while splitting this spec into tickets: the API seam widens from the
puzzle.progressprocedure alone to thepuzzle.*procedures through the RPC integration harness. It now also covers the Puzzle's own rating added to thesolved,failedandsolutionresults (stories 19 and 32–34 for the number; their rendering stays on the front seam).mentioned in issue #451
mentioned in issue #452
mentioned in issue #453
mentioned in issue #454
mentioned in issue #455
mentioned in issue #456
mentioned in issue #457
marked this issue as related to #451
marked this issue as related to #452
marked this issue as related to #453
marked this issue as related to #454
marked this issue as related to #455
marked this issue as related to #456
marked this issue as related to #457
mentioned in merge request !557
mentioned in issue #458
mentioned in merge request !559