v0.9 Phase 4: TownManager drawer + retire modal CRUD#67
Merged
Conversation
Replaces CreateTownModal, EditTownModal, and the Phase 2 sidebar
bridge stubs (window.prompt switcher, Edit/+New buttons, hemisphere
toggle) with a single right-side TownManager drawer mounted at the
App layout level. Drawer is a bottom sheet at <=720px.
Honors locked Decision 1: the inline edit form has no game <select>;
gameId is shown as a read-only badge and never appears in the patch
object passed to updateTown. Honors Decision 5 by removing playerName
from the Town type, store, CSV export, and tests.
Auto-opens in forceCreate mode when towns.length === 0, replacing
the previous CreateTownModal required={noTowns} pattern. Resolves
the v0.8.1 greyed-out-buttons stopgap because the drawer now mounts
above the router and is unaffected by overflow/z-index on category
tabs.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Owner
Author
|
@claude Testing comment 1. |
Owner
Author
|
@codex[agent] Testing comment 2. |
|
To use Codex here, create a Codex account and connect to github. |
Contributor
No action needed here; lint/test/build are green on my side. Latest commit on branch remains the existing TownManager change. |
This was referenced May 4, 2026
Merged
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.
Summary
Phase 4 of the v0.9.0-beta plan (
docs/v0.9-plan.md§ Phase 4). ReplacesCreateTownModal,EditTownModal, and the Phase 2 sidebar bridge stubs with a single right-side TownManager drawer mounted at the App layout level.Added
TownManager(src/components/TownManager.tsx) — 420px right-side drawer (bottom sheet at ≤720px). View / activate / inline-edit / delete towns; sticky+ New townform in the footer. Mounts inApp.tsxabove the router so it overlays every route.useUIStore(src/lib/uiStore.ts) — small non-persisted Zustand store:townManagerOpen,townManagerForceCreate,openTownManager(forceCreate?),closeTownManager().towns.length === 0(replacesCreateTownModal'srequired={noTowns}flow). Scrim, Esc, and the close button are all suppressed in this state.GAME_LISTexport insrc/lib/types.ts— ordered array used by the new-town form's game selector.src/index.css(drawer, list, edit/new forms, segmented hemisphere control, bottom-sheet variant).Retired
src/components/modals/CreateTownModal.tsx— replaced by the drawer's New Town form.src/components/modals/EditTownModal.tsx— replaced by the drawer's inline row edit.src/components/shared/TownNameFields.tsx— no remaining consumers.window.prompttown switcher, the inlineEdit/+ Newbuttons, and the inline NH/SH segmented hemisphere toggle. The singleSwitch town ›button now opens the drawer; hemisphere is shown read-only in the sidebar and edited inside the drawer.Decisions
<select>. Game is rendered as a read-only badge with the hint "Game can't be changed after creation."handleSavebuilds a patch of{ name, hemisphere }only —gameIdnever appears. The v0.9.2 design's<select>(lines 104–106 ofaddons.jsx) was deliberately dropped per the plan's override.playerNameremoved fromTown,useAppStore.createTown/updateTown,downloadCSV/buildCSV, andstore.test.ts. No migration callback — Zustand persist silently drops unknown fields on the next write.useUIStorerather than insideuseAppStore, so it isn't persisted to localStorage across reloads.requiredplumbing.updateTownnow takes aTownPatch({ name?, hemisphere? }). Anullhemisphere from the form (non-ACNH games) is ignored so a stored hemisphere never gets clobbered if the game flag changes in the future.Test plan
npm run build— passes (zero TypeScript errors).npm test— 59 tests pass (2 files).npm run lint— clean.lint-staged(eslint + prettier) — clean.🤖 Generated with Claude Code