Ship a reusable SampleWidget component that renders on the main dashboard, supports collapsed/expanded toggle, and persists its state across page refreshes via localStorage.
add-sample-widget.html
docs/plans/add-sample-widget.html
Context
The dashboard currently has no reusable widget pattern. Each panel is hand-rolled, making it hard to add, remove, or reorder sections. A SampleWidget establishes the canonical widget shape — toggle state, localStorage persistence, typed props — that all future dashboard panels will follow.
This plan is also a smoke-test artifact for the plan-agent v0.8.0 optimization: it verifies the skill writes a valid verb-target.html file directly without entering harness plan mode.
Steps
SampleWidget in src/components/widgets/SampleWidget.tsx
Verify
ls src/components/widgets/SampleWidget.tsx exits 0; npm run build passes with no new type errors.SampleWidget into DashboardPage and pass required props
Verify
npm start, navigate to /dashboard, confirm the widget renders in the expected column with correct default state and no console errors.localStorage via a useLocalStorage hook
Verify
localStorage.getItem('widget-sample-expanded') returns the expected boolean string.SampleWidget covering default state, toggle behaviour, and persistence
localStorage side effect is easy to miss in a refactor; tests catch regressions before they reach production.Verify
npm test -- --testPathPattern=SampleWidget passes; coverage report shows ≥80% for the component file.Acceptance Criteria
Verification
Open a browser at http://localhost:3000/dashboard. Confirm the widget renders. Toggle it twice. Open DevTools → Application → Local Storage and confirm the key widget-sample-expanded exists with the correct value. Refresh — confirm state restores. Run npm run build && npm test in the terminal; both must exit 0 with no new failures.
Unresolved Questions
-
Should widget state use
localStorageor be synced to the user profile via API?We are adding collapsed/expanded widget state to localStorage in the SampleWidget component. Evaluate whether this should instead be persisted to the user profile via the existing /api/user/preferences endpoint. Consider: (1) behaviour when the user logs in on a new device, (2) complexity of the API route vs. a localStorage hook, (3) whether other dashboard settings already use the API. Recommend one approach with a one-paragraph rationale and identify any migration work if the API route is chosen.