Public Access
feat(ui): Sprint 9 — F1 onboarding tour (4-step welcome)
Hand-rolled 4-step tour (no react-joyride) anchors to existing [data-tour="<id>"] attributes. localStorage key mealplanner:onboarding-complete is the source of truth; ?reset-tour=1 clears the key and re-shows. Steps: Dashboard / Pantry / Recipes / Shopping List. Keyboard: 1-4 jump, ←/→ step, Esc dismiss. Off-route fallback renders a centered card with an 'Open <page>' CTA. A11y: role=dialog, aria-modal=true, focus captured on open and restored on close. 5 lines of code across 4 pages; 1 new component (~420 lines). No new dependencies. No backend changes. No migration. Frontend-only deploy. Tracking: Review/sprint9-verification.md (8-step browser smoke + a11y check + reset-link test).
This commit is contained in:
+60
-17
@@ -1,14 +1,40 @@
|
||||
# UI/UX Audit & Fix — Agent Handoff
|
||||
|
||||
You are taking over a 6-sprint UI/UX audit and fix cycle. All code changes are committed and build green. The user's deployment host (Tailscale `100.108.224.12`) is the only environment you should touch for verification — the local repo on this machine (`/home/peter/Projects/MealPlanner`) was the editing host; the running app lives elsewhere.
|
||||
You are taking over an 8-sprint UI/UX audit and fix cycle. **All 8 sprints' code is committed and build green.** The user's deployment host (Tailscale `100.108.224.12`) is the only environment you should touch for verification — the local repo on this machine (`/home/peter/Projects/MealPlanner`) was the editing host; the running app lives elsewhere.
|
||||
|
||||
**Date of handoff: 2026-06-04. Last updated: 2026-06-05 (Sprint 8 in progress).**
|
||||
**Date of handoff: 2026-06-05 (Sprints 7 + 8 committed `09c7525` + `efd1fc6`, awaiting user deploy).**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Active sprint: Sprint 8 — "Deny" semantics (C + Z, hard-filter escalation)
|
||||
## How to take over (fresh-agent quickstart)
|
||||
|
||||
**Status: in progress. User approved on 2026-06-05. Code not yet committed.**
|
||||
If you are a new agent continuing this work, do this **in order**:
|
||||
|
||||
1. **Read** `docs/ORIENTATION.md` (project orientation) → `docs/HANDOFF.md` (project-wide handoff) → this file (UI-audit handoff) → `Review/ui-nielsen-audit.md` (the audit itself).
|
||||
2. **Skim** the per-sprint verification docs in `Review/sprint{1..9}-verification.md`. They are the source of truth for the deploy + smoke flow.
|
||||
3. **Check the user's deployment status** — the user deploys in batches. The current pending batches (in order):
|
||||
- **Batch A:** Sprints 2-5 (one `git pull`, run `persist_aisle_backup.sql`, `alembic upgrade head`, `docker compose up -d --build backend frontend`). The 0015 cast fix is in `d78bd18`; Sprint 2's deploy was blocked on it.
|
||||
- **Batch B:** Sprint 6 (one `git pull`, `docker compose up -d --build backend frontend`, no migration).
|
||||
- **Batch C:** Sprint 7 (one `git pull`, run the SQL fix in `backend/scripts/fix_2026_06_05_to_2026_06_08.sql`, `docker compose up -d --build backend frontend`).
|
||||
- **Batch D:** Sprint 8 (one `git pull`, `alembic upgrade head` to apply 0016, `docker compose up -d --build backend frontend`).
|
||||
- **Batch E:** Sprint 9 (one `git pull`, `docker compose up -d --build frontend` — frontend-only, no migration, no backend rebuild).
|
||||
4. **Open issues** in `.agent/plan.md` (the "Phase R1-R3" section is a prior plan; the **Sprint 9 active-sprint** section is the current state) and in `.agent/context.md` (decisions + open Qs for the current sprint).
|
||||
5. **Do not** touch the pre-existing WIP files: `backend/app/api/recipes.py`, `backend/app/schemas/recipe.py`, `nginx/nginx.conf` (untouched since before this work; user's to manage).
|
||||
6. **When you commit,** use the `fix(ui):`, `feat(ui):`, `refactor(frontend):`, `docs(review):` Conventional Commit style. Force-add new files in `frontend/src/lib/` (the `.gitignore` line 17 `lib/` is a pre-existing bug that catches it).
|
||||
|
||||
**TL;DR of where things stand:**
|
||||
|
||||
- Sprints 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8: code committed and build green. Sprint 1 deployed. Sprints 2-8 awaiting user deploy.
|
||||
- The only remaining §Future items are F1 onboarding tour, F8 Spoonacular enrichment (proposal), F9 Ollama LLM matcher (proposal), and the dead `Generate Meal Plan` CTA at `Dashboard.tsx:415`. Documented in `.agent/plan.md` and `fix-ui-audit.md`; awaiting user direction.
|
||||
- Pre-existing repo issues: 1 failing test (`test_filter_blocks_by_cost` — verified pre-Sprint 8), `.gitignore` `lib/` bug, no CI. Documented.
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ Pending user deploy — Sprints 7 + 8 (committed, awaiting pull)
|
||||
|
||||
### Sprint 8 — "Deny" semantics (C + Z, hard-filter escalation)
|
||||
|
||||
**Status: COMMITTED `efd1fc6` on 2026-06-05. Build green. 21/21 planner tests pass.** Awaiting user to `git pull` + `alembic upgrade head` + rebuild.
|
||||
|
||||
**User policy decision (2026-06-05, exact words):** "Hard filter. If it is denied this week twice, it should be considered denied for good."
|
||||
|
||||
@@ -23,29 +49,43 @@ You are taking over a 6-sprint UI/UX audit and fix cycle. All code changes are c
|
||||
|
||||
**Scope (12 boxes):** see `.agent/plan.md` "Active sprint" section. Code changes are M-L: 1 migration, 2 model columns, 2 schema fields, 3 backend helpers, 2 endpoint extensions, 1 planner update, 1 email template update, 1 webui MealCard update. **No new dependencies. Migration 0016 required.**
|
||||
|
||||
**Tracking docs:** `Review/sprint8-verification.md` (deploy + smoke), `Review/ui-nielsen-audit.md` Sprint 8 status block, `fix-ui-audit.md` T2.1–T2.10, `Review/handoff-ui-audit.md` (this file), `docs/HANDOFF.md` Sprint 8 section.
|
||||
**Tracking docs:** `Review/sprint8-verification.md` (deploy + smoke), `Review/ui-nielsen-audit.md` Sprint 8 status block, `fix-ui-audit.md` T2.1–T2.10, this file, `docs/HANDOFF.md` Sprint 8 section.
|
||||
|
||||
**Thread 3 (§Future backlog) is deferred** until S8 is deployed + verified. F1 onboarding, F8/F9 proposals, dead `Generate Meal Plan` CTA at `Dashboard.tsx:415`.
|
||||
**Thread 3 (§Future backlog) is deferred** until S8 is deployed + verified. F1 onboarding, F8/F9 proposals, dead `Generate Meal Plan` CTA at `Dashboard.tsx:415`. **Sprint 9 (F1) is committed 2026-06-05; Sprint 10 (Deny Forever on Recipes) is drafted and awaits explicit "proceed".**
|
||||
|
||||
---
|
||||
### Sprint 9 — F1 Onboarding Tour (H10)
|
||||
|
||||
## ⚠️ Active sprint: Sprint 7 — Fix webui "empty meal plan" (date-semantics mismatch)
|
||||
**Status: COMMITTED on 2026-06-05. Build green. Frontend-only.** Awaiting user to `git pull` + `docker compose up -d --build frontend` (no migration, no backend rebuild).
|
||||
|
||||
**Status: in progress. User approved on 2026-06-05. Code not yet written.**
|
||||
**Root cause (one-liner):** new users land on the Dashboard with no orientation. The audit's F1 §Future item ("Onboarding hints / tour") was the natural next phase.
|
||||
|
||||
**Root cause (one-liner):** the orchestrator plans the **upcoming** Mon-Sun week (Fri 2026-06-05 → key 2026-06-08), but the frontend `isoMonday()` returns the **current** Mon-Sun (Fri 2026-06-05 → 2026-06-01). Email + DB + webui disagree by 7 days. User sees an empty page.
|
||||
**Scope (4 boxes):** 1 new `OnboardingTour.tsx` component (hand-rolled, no `react-joyride`), 5 `data-tour="<id>"` anchor attributes on existing elements, 1 mount in `App.tsx`, 1 localStorage key (`mealplanner:onboarding-complete`). **No new dependencies. No backend changes.**
|
||||
|
||||
**Scope (7 boxes):** see `.agent/plan.md` "Active sprint" section. Code changes are small (1 backend function, 1 frontend util rename, 1 new `WeekRangeNav` component, 2 call-site updates) plus 1 SQL fix script. **No migration.**
|
||||
**Tour behavior:**
|
||||
- Auto-shows on first visit to `/` (the only root route). Subsequent visits do not show.
|
||||
- 4 steps: Dashboard / Pantry / Recipes / Shopping List. Each anchors to a `[data-tour="<id>"]` element on the relevant page.
|
||||
- Keyboard: `1`–`4` jump to step, `←/→` step back/forward, `Esc` dismiss.
|
||||
- Off-route fallback: if the user is on a different page than the current step's anchor, the tooltip renders as a centered card with an "Open <page>" CTA.
|
||||
- `?reset-tour=1` in any URL clears the localStorage key + strips the param, re-showing the tour.
|
||||
- A11y: `role="dialog"`, `aria-modal="true"`, focus captured on open (primary action) and restored on close.
|
||||
|
||||
**Tracking docs:** `Review/sprint7-verification.md` (deploy + smoke), `Review/ui-nielsen-audit.md` Sprint 7 status block, `fix-ui-audit.md` S7.1–S7.6, `docs/HANDOFF.md` Sprint 7 section. All will be filled in before the user pulls.
|
||||
**Tracking docs:** `Review/sprint9-verification.md` (deploy + 8-step browser smoke + a11y check + reset-link test), `Review/ui-nielsen-audit.md` Sprint 9 status block, `fix-ui-audit.md` T3.1–T3.4, this file, `docs/HANDOFF.md` Sprint 9 section.
|
||||
|
||||
**Thread 2 + Thread 3 are deferred** (cross-week "rejected" semantics + §Future backlog) until S7 is deployed + verified.
|
||||
### Sprint 7 — Fix webui "empty meal plan" (date-semantics mismatch)
|
||||
|
||||
**Status: COMMITTED `09c7525` on 2026-06-05. Build green.** Awaiting user to `git pull` + run the SQL fix + rebuild.
|
||||
|
||||
**Root cause (one-liner):** the orchestrator plans the **upcoming** Mon-Sun week (Fri 2026-06-05 → key 2026-06-08), but the frontend `isoMonday()` returned the **current** Mon-Sun (Fri 2026-06-05 → 2026-06-01). Email + DB + webui disagree by 7 days. User sees an empty page.
|
||||
|
||||
**Scope (6 boxes):** 1 backend function, 1 frontend util rename, 1 new `WeekRangeNav` component, 2 call-site updates, 1 SQL fix script. **No migration.**
|
||||
|
||||
**Tracking docs:** `Review/sprint7-verification.md` (deploy + smoke), `Review/ui-nielsen-audit.md` Sprint 7 status block, `fix-ui-audit.md` S7.1–S7.6, this file, `docs/HANDOFF.md` Sprint 7 section.
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
Ten commits land all 14 audit findings + 6 of the §Future items:
|
||||
Twelve commits land all 14 audit findings + 6 §Future items + 2 user-driven sprints:
|
||||
|
||||
| Sprint | Commit | Scope | Build | Deploy |
|
||||
|---|---|---|---|---|
|
||||
@@ -56,12 +96,15 @@ Ten commits land all 14 audit findings + 6 of the §Future items:
|
||||
| 5 | `d78bd18` | F5 URL week selector + **CRITICAL 0015 cast fix** | ✅ green | ⚠️ not yet deployed |
|
||||
| 5 | `f740f40` | F2 keyboard shortcuts + ShortcutHelpBanner | ✅ green | ⚠️ not yet deployed |
|
||||
| 6 | `8ad4ef6` | F3 bulk pantry add + F4 plan-the-week (ShoppingList + Dashboard) | ✅ green | ⚠️ not yet deployed (backend + frontend, no migration) |
|
||||
| 7 | `09c7525` | webui "empty meal plan" date-semantics fix + new `WeekRangeNav` + SQL data fix | ✅ green | ⚠️ committed; awaiting user deploy |
|
||||
| 8 | `efd1fc6` | "Deny" semantics (C + Z, hard-filter escalation) | ✅ green | ⚠️ committed; awaiting user deploy |
|
||||
| 9 | (committed 2026-06-05) | F1 Onboarding Tour (H10) — hand-rolled, no new deps, 4-step welcome tour with `?reset-tour=1` reset | ✅ green | ⚠️ committed; awaiting user deploy (frontend-only) |
|
||||
|
||||
All work is on `main` ahead of `origin/main` (pre-existing WIP also present). All six sprints compile. **Sprint 1 is live. Sprints 2, 3, 4, 5, 6 are not yet live on `100.108.208.56:8082/`.**
|
||||
All work is on `main` ahead of `origin/main` (pre-existing WIP also present). All 9 sprints compile. **Sprint 1 is live. Sprints 2-9 are not yet live on `100.108.208.56:8082/`.**
|
||||
|
||||
**CRITICAL — Sprint 2 was effectively undeployable** because the CASE expression in `0015_normalize_pantry_aisles.py` failed with `text = boolean` on the `varchar(100) aisle` column. The bug is fixed in `d78bd18` (Sprint 5). Without that commit, `alembic upgrade head` would have failed on the deployment host, blocking Sprints 2, 3, 4 from going live. **The deployment host's DB still has the pre-0015 schema** — the migration must be run as part of the Sprints 2-5 batch deploy.
|
||||
|
||||
**Next action:** the user runs the deploy commands in `Review/sprint2-verification.md`, `Review/sprint3-verification.md`, `Review/sprint4-verification.md`, `Review/sprint5-verification.md`, and `Review/sprint6-verification.md` on the deployment host, then smoke-checks per the checklists. Sprints 2-5 are a single batch (one `git pull`, one migration, one rebuild); Sprint 6 is a separate batch (backend + frontend, no migration). After verification, any remaining items move to the §Future backlog in `fix-ui-audit.md` (F1 onboarding tour, F8 Spoonacular enrichment, F9 Ollama matcher — F3, F4, F5, F6, F7 now done across Sprints 4-6).
|
||||
**Next action:** the user runs the deploy commands in `Review/sprint2-verification.md`, `Review/sprint3-verification.md`, `Review/sprint4-verification.md`, `Review/sprint5-verification.md`, `Review/sprint6-verification.md`, `Review/sprint7-verification.md`, and `Review/sprint8-verification.md` on the deployment host, then smoke-checks per the checklists. Sprints 2-5 are a single batch (one `git pull`, one migration, one rebuild); Sprint 6 is a separate batch (backend + frontend, no migration); Sprint 7 is a separate batch (git pull + SQL fix + rebuild); Sprint 8 is a separate batch (git pull + alembic upgrade head + rebuild).
|
||||
|
||||
---
|
||||
|
||||
@@ -301,4 +344,4 @@ cd frontend && npm run build
|
||||
|
||||
Trust the build output. Trust the smoke checklist. Don't trust the deployment host's UI until the user confirms. The verification model is "I shipped, you verified, you reported, I fixed" — the agent in this role never sees the live UI directly.
|
||||
|
||||
**Last updated: 2026-06-05** — Sprints 1, 2, 3, 4, 5, 6 deployed-or-awaiting-deploy; Sprint 7 (webui empty-meal-plan fix) **committed `09c7525` awaiting user deploy**; **Sprint 8 (Deny semantics C + Z with hard-filter escalation) in progress**. See the "Active sprint" callout at the top of this file for the current state.
|
||||
**Last updated: 2026-06-05** — Sprint 1 deployed; Sprints 2-6 awaiting user deploy; **Sprint 7 (`09c7525`), Sprint 8 (`efd1fc6`), and Sprint 9 (F1 Onboarding Tour) committed on 2026-06-05, awaiting user deploy**. Sprint 10 (Deny Forever on Recipes) drafted, awaits explicit "proceed". See the "How to take over" and "Pending user deploy" sections at the top of this file.
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# Sprint 9 — F1 Onboarding Tour (H10)
|
||||
|
||||
**Status (2026-06-05):** ✅ Code complete. `npm run build` green. Awaiting user commit + deploy.
|
||||
|
||||
**Audit link:** F1 (Onboarding hints / tour) is the last §Future item with a clear UI scope. F8 (Spoonacular) and F9 (Ollama) are full backend proposals; the dead `Generate Meal Plan` CTA is a separate follow-up.
|
||||
|
||||
**Goal:** First-time visitors get a 4-step tour. Returning users never see it. The tour re-shows on demand via `?reset-tour=1`.
|
||||
|
||||
---
|
||||
|
||||
## What ships
|
||||
|
||||
### `OnboardingTour.tsx` (NEW)
|
||||
|
||||
Hand-rolled (no `react-joyride`) to keep the npm footprint flat. 4 steps:
|
||||
|
||||
1. **Dashboard** — "Your weekly meal plan"
|
||||
2. **Pantry** — "What you have in stock"
|
||||
3. **Recipes** — "Browse + filter recipes"
|
||||
4. **Shopping List** — "Plan → shop → restock"
|
||||
|
||||
Each step:
|
||||
- Anchors to a `[data-tour="<id>"]` attribute on the existing page.
|
||||
- Renders a tooltip card pinned to the anchor (top/bottom/center fallback).
|
||||
- Highlights the anchor with a primary-400 ring + soft scrim.
|
||||
- Step progress shown as 4 progress bars (top of card).
|
||||
- Skip / Back / Next (or "Got it" on the last step).
|
||||
|
||||
**Keyboard nav (when tour is visible):**
|
||||
- `1`–`4` → jump to that step
|
||||
- `←/→` → step back / forward
|
||||
- `Esc` → dismiss
|
||||
- Tab order: `Skip → Back → Next` (or `Skip → Open page → Next` when off-route)
|
||||
|
||||
**A11y:**
|
||||
- `role="dialog"`, `aria-modal="true"`, `aria-labelledby` → step title.
|
||||
- Focus is captured on open (moved to the primary action) and restored on close.
|
||||
- Tooltip + anchor ring are announced via `aria-hidden="true"` (decorative); the dialog text is the real signal.
|
||||
|
||||
**Storage:**
|
||||
- localStorage key: `mealplanner:onboarding-complete` (`"1"` once completed).
|
||||
- `?reset-tour=1` in any URL clears the key + strips the param via `navigate(..., { replace: true })` so a refresh doesn't re-clear.
|
||||
- Reading the key is wrapped in try/catch — private mode / disabled storage silently falls through.
|
||||
|
||||
### Anchor points (5 lines of code total)
|
||||
|
||||
| Page | File:line | Anchor | Notes |
|
||||
|---|---|---|---|
|
||||
| Dashboard | `pages/Dashboard.tsx:602` | `<Card data-tour="dashboard">` | The Weekly Overview grid; the most-confused first-time surface. |
|
||||
| Pantry | `pages/Pantry.tsx:185` (header) + `:208` (add form, when open) | `<div data-tour="pantry">` | Header is always present; the add-form card adds a second anchor when the form is open. |
|
||||
| Recipes | `pages/Recipes.tsx:124` (Filters button) | `<Button data-tour="recipes">` | The Filters button is the entry point most users miss. |
|
||||
| ShoppingList | `pages/ShoppingList.tsx:231` | `<div data-tour="shopping-list">` | Header; the bulk-add button only appears when items are checked. |
|
||||
|
||||
### `App.tsx` (mount)
|
||||
|
||||
- Imports `OnboardingTour` + `useOnboarding`.
|
||||
- Mounts the tour as a sibling of `<ShortcutHelpBanner />` (inside `<BrowserRouter>` so the tour can use `useLocation` / `useNavigate`).
|
||||
- The `useOnboarding()` hook is called once at the App root and the `isComplete` flag is passed down. On dismiss, the tour calls `onComplete()` which the App maps to `onboarding.reset()` — flipping the flag so re-renders don't re-show.
|
||||
|
||||
---
|
||||
|
||||
## Verify (deploy + smoke)
|
||||
|
||||
**Build:** `cd frontend && npm run build` → green (tsc 0 errors, vite 0 errors). Verified locally.
|
||||
|
||||
**Browser smoke on `http://100.108.208.56:8082/`:**
|
||||
|
||||
1. **First-visit tour.** Open an incognito window (or a new browser) and navigate to `http://100.108.208.56:8082/`. The tour auto-shows on step 1 (Dashboard) within 1 frame.
|
||||
2. **Anchor highlight.** The Weekly Overview card has a primary-400 ring around it; the rest of the page has a soft scrim.
|
||||
3. **Forward nav.** Press `→` → step 2 (Pantry) shows. If you're not on `/pantry`, the tooltip renders centered with an "Open Pantry" button.
|
||||
4. **Click "Open Pantry".** Tour stays open, navigates to `/pantry`, anchor re-renders below the header.
|
||||
5. **Keyboard jumps.** From step 2, press `3` → tour jumps to Recipes (Filters button highlighted).
|
||||
6. **Dismiss.** Press `Esc` on any step → tour disappears, localStorage key is set. Refresh the page → tour does NOT re-show.
|
||||
7. **Reset.** Navigate to `http://100.108.208.56:8082/?reset-tour=1`. The query string is stripped, localStorage key is cleared, tour shows again on step 1.
|
||||
8. **A11y.** Tab through the dialog: focus moves from Skip → Back → Next in order; Esc dismisses; screen reader announces the step title (e.g. "What you have in stock, dialog").
|
||||
|
||||
**A11y verification:**
|
||||
- VoiceOver on the dialog announces "Your weekly meal plan, dialog".
|
||||
- Arrow keys step the tour.
|
||||
- Esc dismisses.
|
||||
- Focus is restored to the previously-focused element on dismiss.
|
||||
|
||||
**Regression check:**
|
||||
- Sprint 5 keyboard shortcuts (`g d`, `g r`, `g p`, `g s`, `/`, `?`) still work.
|
||||
- Sprint 4 global error toast still fires.
|
||||
- The 3-button Sprint 8 voting row on Dashboard meal cards still works.
|
||||
- Sprint 7 `WeekRangeNav` still renders on Dashboard and ShoppingList.
|
||||
|
||||
---
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Per-page deep tutorials (the welcome tour is the only thing S9 ships).
|
||||
- Video or animated demos.
|
||||
- Tooltip-on-hover patterns.
|
||||
- A user-facing "Show tour" link in the footer (operator can use `?reset-tour=1`; a footer link is a 5-line follow-up if requested).
|
||||
- F8 Spoonacular proposal, F9 Ollama proposal, dead `Generate Meal Plan` CTA — separate.
|
||||
|
||||
---
|
||||
|
||||
## Risks & mitigations
|
||||
|
||||
- **R1: rAF polling on the anchor's `getBoundingClientRect`.** Runs while the tour is open. Cheap (one DOM read per frame). Cancelled on close. No throttling needed for a 4-step tour.
|
||||
- **R2: The auto-show on `/` only.** If the user lands on `/pantry` first (e.g. via a bookmark), the tour does NOT auto-show. The header anchor is still present so a `?reset-tour=1` would show the tour with the right anchor. Documented; not a bug.
|
||||
- **R3: `useOnboarding` flag is App-level state.** A second `<App>` mount (in tests, e.g.) would not share the flag. The tour reads localStorage on mount so the real source of truth is the storage key, not the flag.
|
||||
- **R4: Existing pre-existing WIP in `git status`.** Sprint 9 doesn't touch `backend/app/api/recipes.py`, `backend/app/schemas/recipe.py`, or `nginx/nginx.conf` — those are the user's to manage.
|
||||
|
||||
---
|
||||
|
||||
## Commit
|
||||
|
||||
One commit: `feat(ui): Sprint 9 — F1 onboarding tour (4-step welcome)`. Files:
|
||||
|
||||
- NEW `frontend/src/components/OnboardingTour.tsx` (~420 lines)
|
||||
- `frontend/src/App.tsx` (mount + flag)
|
||||
- `frontend/src/pages/Dashboard.tsx` (anchor)
|
||||
- `frontend/src/pages/Pantry.tsx` (2 anchors)
|
||||
- `frontend/src/pages/Recipes.tsx` (anchor on Filters button)
|
||||
- `frontend/src/pages/ShoppingList.tsx` (anchor on header)
|
||||
@@ -100,6 +100,14 @@ The app looks polished on the surface (Tailwind palette, clean cards, working to
|
||||
> - **No backend migration, no new dependencies.** Deploy is `git pull` + run the SQL script + `docker compose up -d --build backend frontend`.
|
||||
> - **Verification log:** `Review/sprint7-verification.md` (to be written before deploy).
|
||||
>
|
||||
> **Sprint 9 status (committed, awaiting deploy):** F1 Onboarding Tour (H10). The natural next phase from the §Future backlog (the only item with a clear UI scope; F8 Spoonacular + F9 Ollama are full backend proposals; the dead `Generate Meal Plan` CTA is a separate follow-up). User direction 2026-06-05: "Proceed with the next phase in the redesign." The Sprint 10 follow-up ("Deny Forever" on Recipes) is already drafted and awaits explicit "proceed".
|
||||
> - **T3.1** New `frontend/src/components/OnboardingTour.tsx` (~420 lines). Hand-rolled (no `react-joyride`; keeps npm footprint flat). 4 steps: Dashboard / Pantry / Recipes / Shopping List. Anchors to `[data-tour="<id>"]` attributes on existing elements. localStorage key `mealplanner:onboarding-complete`. `?reset-tour=1` re-triggers.
|
||||
> - **T3.2** Anchor points: `Dashboard.tsx:602` (Weekly Overview card), `Pantry.tsx:185, 208` (header + add-form card), `Recipes.tsx:124` (Filters button), `ShoppingList.tsx:231` (page header). 5 lines of code total.
|
||||
> - **T3.3** Tooltip = `position: fixed` `<div role="dialog" aria-modal="true">` (no portal needed). rAF loop reads anchor `getBoundingClientRect`; cancellable on close. Focus captured on open, restored on close. Keyboard: `1`–`4` jump, `←/→` step, `Esc` dismiss.
|
||||
> - **T3.4** Off-route fallback: centered card with "Open <page>" CTA so the tour still works for users who land on a non-root page first. Decorative scrim + anchor ring are `aria-hidden="true"`.
|
||||
> - **Verification log:** `Review/sprint9-verification.md`. Deploy is `git pull` + `docker compose up -d --build frontend` (frontend-only, no backend changes, no migration).
|
||||
> - **No new dependencies. No backend changes.**
|
||||
>
|
||||
> **Sprint 6 status (commit `8ad4ef6`, awaiting deploy):** Two §Future items, both with design decisions captured in the commit message.
|
||||
> - **F3** Bulk 'add checked to pantry' on ShoppingList. Backend `POST /api/pantry/bulk` accepts `{items: HomePantryCreate[]}` and returns per-item status (`added` / `updated` / `skipped`) with totals. Per-item failure model: unknown ingredient → `skipped` with reason, not a 4xx. Frontend ShoppingList gains a primary `Add N to pantry` button next to the existing Reset button; toast reports `added X, updated Y, skipped Z`; only the items that actually landed are removed from the checked Set. **Scope decision:** ShoppingList only (the checked Set was the natural substrate; Pantry would need new multi-select UI).
|
||||
> - **F4** Plan the whole week on Dashboard. Backend `POST /api/meals/{id}/fill-empty-slots` with body `{meal_types: [str, ...]}` returns `FillEmptySlotsResult { filled: [{day, meal_type, item}], failed: [{day, meal_type, reason}] }`. Iterates day 1..7 in order; skips already-occupied slots; picks a recipe (prefer un-used, fall back to any) and inserts as `pending`. Per-slot failure model — never aborts mid-batch. Frontend Dashboard gets a primary `Plan the week` button (next to the Sprint 5 week-nav control) with a dropdown: `Dinners only` / `All meals`. Toast reports partial-success precisely: `Planned 12 of 21 meal slots — 9 failed (e.g. <reason>)`.
|
||||
|
||||
Reference in New Issue
Block a user