feat: add newsletter UI implementation plan and UI spec documentation
This commit is contained in:
@@ -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.
|
||||
@@ -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.
|
||||
Reference in New Issue
Block a user