[P6] Multi-board sidebar + switcher + first-run flow #2
Reference in New Issue
Block a user
Delete Branch "wt/redesign-boards"
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?
Phase 6 of the ultra-todo Trello-style redesign
Closes [P6] in the parent task graph.
What's in this PR
src/components/Sidebar.jsx+Sidebar.css: 240px dark Trello sidebar (#1d2125) with boards list, hover⋯menu (Rename / Delete with confirm), inline rename input, mobile overlay with backdrop, first-run variant showing "+ Create your first board".src/components/BoardListItem: small subcomponent embedded in Sidebar.jsx for clarity. Renders as a<button>witharia-currentfor keyboard nav.src/components/TopBar.jsx+TopBar.css: shows active board name + mobile-only hamburger. Backgroundrgba(255,255,255,.15)over the board gradient.src/components/AppShell.jsx+AppShell.css: composes Sidebar + TopBar + content slot. Owns mobile-breakpoint detection viawindow.matchMedia. Pass-through for state + callbacks (decoupled fromuseBoardStore).src/components/EmptyState.jsx+EmptyState.css: centered welcome (first-run) and "select or create a board" (no-board) variants.src/App.jsx: holds multi-board state inuseLocalStorage('ultra-todo-v2-state', ...)matching the spike data-model spec. ProvidesaddBoard/renameBoard/deleteBoard/setActiveBoardto AppShell. State lives in App.jsx locally — P2'suseBoardStorewill replace this in P7 integration overlay.src/App.css: removed.app { max-width: 500px; margin: 0 auto; }per spike.Test framework setup (mirrors P2)
jest.config.cjs(jsdom + babel-jest + CSS stub mapper)babel.config.cjs(@babel/preset-env + preset-react automatic runtime)jest.setup.cjs(loads@testing-library/jest-dom+ jsdommatchMediapolyfill)__mocks__/styleMock.js(so JSX canimport './Foo.css')npm testscript in package.jsonTests
25 tests across 3 files, all passing:
src/components/Sidebar.test.jsxsrc/components/TopBar.test.jsxsrc/components/AppShell.test.jsxTDD: every test was written first, watched fail (
Sidebarnot found), then implementation made them pass. Mobile responsive paths tested viashowHamburgerprop andisMobileOpenoverlay toggle.Pitfalls addressed (from the task body)
Board(P3/P5)nullif none<button>(free keyboard nav, ARIA-correct)Acceptance
npm testpasses (25/25)npm run buildsucceedslocalStorage.clear())Known merge collisions to resolve in P7
src/App.css: P3 also strips themax-width: 500px. Same change, identical line removal — git auto-resolves.src/App.jsx: P3 will render<Board />conditionally inside the legacy shell. Mine replaces the body with<AppShell />. P7 picks whichever works with the unifieduseBoardStoreand the final layout (probably: App.jsx callsuseBoardStore(), hands state to AppShell, AppShell renders<Board />as children).package.jsonand resolves.package-lock.json: large diff (8198 lines), all fromnpm install. Acceptable for first PR.Manual smoke procedure
- src/App.jsx: replaces flat-todo UI with multi-board state held in useLocalStorage('ultra-todo-v2-state') matching the spike spec ({ schemaVersion: 2, activeBoardId, boards, boardOrder, ... }). Provides addBoard / renameBoard / deleteBoard / setActiveBoard callbacks to AppShell. deleteBoard falls back to first remaining board or null when active is deleted. Local state lives in App.jsx (not a separate store file) to avoid colliding with P2's useBoardStore module. P7 integration overlay swaps this for the real hook. - src/App.css: removes .app max-width: 500px + margin: 0 auto (per spike). Same change P3 will make; P7 merge resolves.Pull request closed