diff --git a/docs/superpowers/plans/2026-05-17-newsletter-ui.md b/docs/superpowers/plans/2026-05-17-newsletter-ui.md new file mode 100644 index 0000000..27c7a69 --- /dev/null +++ b/docs/superpowers/plans/2026-05-17-newsletter-ui.md @@ -0,0 +1,70 @@ +# Newsletter UI Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Replace the rough web views with a functional two-pane newsletter browser that defaults to the latest issue and can switch to all issues. + +**Architecture:** Keep the current Express/server-rendered UI. Add focused SQLite read methods to `CatalogDatabase`, render reusable layout/navigation/table helpers in `src/web/views.ts`, and wire new routes in `src/web/app.ts` for dashboard, newsletter browser, all links, sponsors, dead links, and runs. Use query parameters for selected newsletter, issue scope, link search, and category filters. + +**Tech Stack:** TypeScript, Express, Node `node:sqlite`, server-rendered HTML/CSS, Vitest. + +--- + +### Task 1: Database Read Models + +**Files:** + +- Modify: `src/database/store.ts` +- Test: `tests/web.test.ts` + +- [ ] Write failing tests that a fixture database can return newsletter summaries with issue/link/sponsor counts. +- [ ] Write failing tests that selected newsletter links default to the latest issue and can include all issues. +- [ ] Add `newsletterSummaries()`, `newsletterById()`, `newsletterLinks()`, `categoriesForNewsletter()`, and `allLinks()` read methods. +- [ ] Run `npm test -- tests/web.test.ts`. + +### Task 2: Two-Pane Newsletter Page + +**Files:** + +- Modify: `src/web/views.ts` +- Modify: `src/web/app.ts` +- Test: `tests/web.test.ts` + +- [ ] Write failing tests that `/newsletters` renders a two-pane layout, newsletter search input, selected state, latest/all issue controls, category filter, and external link attributes. +- [ ] Implement reusable page layout with dark default styling, light mode toggle, global nav, responsive two-pane layout, and empty states. +- [ ] Implement `/newsletters` with query params: `newsletter`, `scope`, `q`, `category`. +- [ ] Run `npm test -- tests/web.test.ts`. + +### Task 3: Global Views and Smoke + +**Files:** + +- Modify: `src/web/app.ts` +- Modify: `src/web/views.ts` +- Modify: `scripts/smoke.mjs` +- Test: `tests/web.test.ts` + +- [ ] Write failing tests that dashboard, all links, sponsored links, dead links, and runs use the new layout. +- [ ] Update `/`, `/links`, `/sponsors`, `/dead-links`, and `/runs` to use the shared layout and table helpers. +- [ ] Keep `nlc serve --help` in smoke validation. +- [ ] Run `npm test -- tests/web.test.ts`. + +### Task 4: Docs and Verification + +**Files:** + +- Add: `notes/UI Spec.md` +- Modify: `README.md` + +- [ ] Track the approved UI spec. +- [ ] Document `nlc serve` and the newsletter browser behavior. +- [ ] Run `npm run lint`. +- [ ] Run `npm run format:check`. +- [ ] Run `npm run typecheck`. +- [ ] Run `npm test`. +- [ ] Run `npm run build`. +- [ ] Run `npm run smoke`. + +## Self-Review + +The plan covers the approved UI spec: two-pane layout, newsletter navigation, latest issue default, all-issues option, global navigation, search/filter controls, dark default, light option, mobile-friendly responsive behavior, and safe external links. It avoids a frontend build stack and keeps the first implementation functional. diff --git a/notes/UI Spec.md b/notes/UI Spec.md new file mode 100644 index 0000000..351f65c --- /dev/null +++ b/notes/UI Spec.md @@ -0,0 +1,88 @@ +# Newsletter Link Catalog UI Spec + +## Goal + +Create a clean, functional web UI for browsing the SQLite-backed newsletter catalog. The UI should feel like a focused database browser: fast to scan, easy to filter, and useful before visual polish. + +## Layout + +Use a two-pane catalog layout. + +### Left Pane: Newsletter Navigation + +- Narrow column on desktop. +- Contains a newsletter search field at the top. +- Shows a scrollable list of newsletters below the search. +- Each newsletter item should show: + - Newsletter name. + - Optional short description or source email when available. + - Compact counts such as issues, links, and sponsored links. +- The currently selected newsletter should have a clear selected state. + +### Right Pane: Newsletter Detail + +- Shows details for the selected newsletter. +- Defaults to the most recent issue only to reduce cognitive load. +- Header should show: + - Newsletter name. + - Optional description/source email. + - Latest issue date. + - Counts for the displayed issue. +- Links should be displayed in a scannable table or grouped list. +- Link rows should include: + - Title. + - Category. + - Description. + - URL. + - Also In, when available. +- Links should be clickable and open in a new tab using `target="_blank"` and `rel="noopener noreferrer"`. + +## Issue Scope Controls + +The right pane defaults to **Latest Issue**. + +Provide a clear control to switch to **All Issues** for the selected newsletter. In All Issues mode: + +- Show links from every issue for the selected newsletter. +- Include issue date on each row. +- Keep the same search/filter controls. +- Make it easy to return to Latest Issue mode. + +## Global Navigation + +Provide lightweight navigation for: + +- Dashboard. +- Newsletters. +- All Links. +- Sponsored Links. +- Dead Links. +- Runs. + +The Newsletter view should be the primary working screen. + +## Search and Filters + +- Newsletter search filters the left pane immediately. +- Link search filters the right pane within the selected newsletter and current issue scope. +- Category filtering should be available in the right pane. +- Date filtering is only needed in All Issues mode. +- Empty states should explain what is missing: + - No newsletters imported yet. + - No links for the selected newsletter. + - No matches for the current search/filter. + +## Theme and Responsiveness + +- Dark mode should be the default visual direction. +- Respect system preference where practical. +- Provide a light mode option. +- Mobile layout should collapse the left pane into a drawer, dropdown, or stacked selector. +- The UI should remain usable on small screens without horizontal scrolling for core actions. + +## Visual Style + +- Clean, restrained, and operational. +- Avoid marketing-style hero sections. +- Prioritize readable tables/lists, clear selected states, and compact metadata. +- UI polish can remain minimal for the first implementation, but spacing, contrast, and text wrapping should be professional.