Skip to content

refactor(pente): extract turn bar, rules panel, game-over drawer from pente.js - #47

Merged
brooksRoley merged 1 commit into
mainfrom
claude/youthful-davinci-0psjh6
Sep 15, 2026
Merged

brooksRoley merged 1 commit into
mainfrom
claude/youthful-davinci-0psjh6

Conversation

@brooksRoley

Copy link
Copy Markdown
Owner

Summary

  • src/pages/posts/pente.js (1249 lines) was the last of the three large-file refactor candidates the ledger has tracked since 2026-08-15 (siblings basketball-platform.jsx and nba.tsx were already split up in PR refactor(basketball-platform): extract 1206-line page into five components #36 and refactor(nba): extract explorer config and canvas drawing from nba.tsx #40). This PR does the same for Pente, following the same pattern: pull out provably pure / cleanly parameterizable presentational chunks, leave all game-state logic (move handling, bot effects, matchmaking, capture rules) in the page component untouched.
  • New files: src/lib/pente/boardDisplay.js (cell/style class helpers + the static MODE_PRESETS/MODE_RULES tables — pure, zero behavior change), src/components/pente/TurnStatusBar.jsx (turn dot + score/captures row), src/components/pente/RulesPanel.jsx (collapsible rules blurb), src/components/pente/GameOverDrawer.jsx (post-game banner, move analysis list, consulting CTA).
  • pente.js drops from 1249 → 1006 lines (19%). Content was moved verbatim — diffed programmatically against the original text rather than retyped — so rendered output and game behavior are unchanged.

Livelihood stream

  • Games

This is the site's flagship game (/posts/pente), with a documented roadmap to paid tiers (tip jar → premium puzzles → competitive tier). A 1249-line single component is the same risk class that caused the Hardwood incident (PR #43, reverted same-day) — harder to safely hotfix under time pressure, harder to review, harder to test in isolation. Shrinking the flagship page to a shell plus four focused, independently reviewable components reduces that risk without touching player-facing behavior.

Files changed

  • src/lib/pente/boardDisplay.js (new)
  • src/components/pente/TurnStatusBar.jsx (new)
  • src/components/pente/RulesPanel.jsx (new)
  • src/components/pente/GameOverDrawer.jsx (new)
  • src/pages/posts/pente.js (modified — imports the four extractions, all extracted JSX replaced with component calls)

Test steps

  1. yarn dev, open /posts/pente
  2. Default mode is "vs Bot" — click a board cell as Black; confirm the stone appears, the turn indicator flips to the bot, and the bot (White) responds after its "thinking" delay
  3. Click "Rules" — confirm the rules panel opens with mode-specific copy; click again to close
  4. Play a full game to a win (five-in-a-row or five captured pairs) — confirm the game-over drawer renders the winner banner, "Play Again"/"Analyze" buttons, and the consulting CTA
  5. Switch mode presets (vs 3 Bots, 2v2 Bots, Local) — confirm the mode tabs and score/capture row track the active players correctly

Verification actually run this session (pasted output, not asserted):

  • yarn lintDone in 16.79s (no errors, --max-warnings 0)
  • npx tsc --noEmit → clean, no errors
  • yarn testTest Files 73 passed (73) / Tests 834 passed (834) — matches the pre-PR baseline exactly, no regressions
  • yarn build → succeeds, /posts/pente present in the static route manifest
  • Live yarn dev + headless-Chromium pass on /posts/pente: turn indicator rendered ("Black's turn"), a click placed a Black stone, the Rules panel opened and showed "Capture:" copy, and after the click the bot (White) placed a stone in response — confirming TurnStatusBar, RulesPanel, and the untouched game loop all still work end-to-end. (The only console errors captured were sandbox-network artifacts — blocked Google Fonts/accounts requests — not application errors.)

Agent checklist

  • yarn build passes locally
  • yarn test passes (834/834, no regressions to game logic)
  • No TODO, placeholder, or stub code
  • No secrets, API keys, or .env values committed
  • New pages include og:title, og:description, og:image, twitter:card — n/a, no new page, /posts/pente's existing <Head> is untouched
  • PreText, Reveal, TiltCard used for any new UI text/cards — n/a, extracted components reuse existing markup verbatim, no new UI text
  • Lighthouse scores not regressed — not independently re-run this session; no new render-blocking assets or layout changes introduced, CI will enforce
  • README updated — n/a, no new routes or top-level components requiring README changes

Learn

Large stateful React components can be shrunk safely without a full rewrite by asking "what here is a pure function of props, with no direct access to setState or refs?" and extracting exactly that — nothing more. Every extraction in this PR (TurnStatusBar, RulesPanel, GameOverDrawer) takes only derived values and callbacks as props; none of them touch useState/useRef directly. That constraint is what keeps a refactor of an untested, 1200-line game component provably behavior-preserving instead of a leap of faith.

🤖 Generated with Claude Code

https://claude.ai/code/session_016Lfm8TKaQqN3pRXLxF3b1g


Generated by Claude Code

…rd-display helpers

Splits src/pages/posts/pente.js (1249 lines) the same way PR #36/#40 did
for basketball-platform.jsx and nba.tsx: pull out provably pure /
cleanly parameterizable presentational chunks, leave all game-state
logic (move handling, bot effects, matchmaking, capture rules) in the
page component untouched.

- src/lib/pente/boardDisplay.js — cellClass/captureClass/hoverClass,
  MODE_PRESETS, MODE_RULES, and the two button-class helpers. Pure
  functions/constants, zero behavior change.
- src/components/pente/TurnStatusBar.jsx — turn dot + score/captures row.
- src/components/pente/RulesPanel.jsx — the collapsible rules blurb.
- src/components/pente/GameOverDrawer.jsx — post-game banner, analysis
  list, and consulting CTA for local (non-multiplayer) games.

pente.js drops from 1249 to 1006 lines. Content was moved verbatim
(diffed programmatically against the original, not retyped) so
rendered output and game behavior are unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Lfm8TKaQqN3pRXLxF3b1g
@vercel

vercel Bot commented Sep 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
zero-next Ready Ready Preview Sep 12, 2026 3:56pm UTC

@brooksRoley
brooksRoley merged commit d2a9fa3 into main Sep 15, 2026
4 checks passed
@brooksRoley
brooksRoley deleted the claude/youthful-davinci-0psjh6 branch September 15, 2026 02:56
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.

2 participants