# 75 — Garden dashboard, widgets, and manifest completion ## Goal Complete the garden module: full manifest registration, two dashboard widgets, search integration, quick-add polish, and a Playwright happy-path test. ## Depends on - 70–74 (all previous garden tasks) ## Scope ### Manifest completion (`src/modules/garden/manifest.tsx`) Replace the task-70 stub with the full manifest. **Entities:** ```typescript entities: [ { type: "garden.container", label: { singular: "Container", plural: "Containers" }, share: { canShare: true, defaultCapabilities: ["read"] }, search: { search: searchContainers }, resolveUrl: (id) => `/garden/containers/${id}`, loadForShare: loadContainerForShare, renderSharedView: ..., renderActivity: ..., }, { type: "garden.plant", label: { singular: "Plant", plural: "Plants" }, share: { canShare: true, defaultCapabilities: ["read"] }, search: { search: searchPlants }, resolveUrl: (id) => `/garden/plants/${id}`, loadForShare: loadPlantForShare, renderSharedView: ..., renderActivity: ..., }, ] ``` `garden.schedule` is internal (reminders only) — not registered as a shareable or searchable entity. **Quick adds** (consolidate from tasks 71–73): - `{ id: "garden.add-plant", label: "Add plant", icon: "leaf", url: "/garden/plants/new" }` - `{ id: "garden.add-container", label: "Add container", icon: "box", url: "/garden/containers/new" }` - `{ id: "garden.log-care", label: "Log plant care", icon: "droplets", url: "/garden?logCare=1" }` **Nav**: `{ href: "/garden", label: "Garden", icon: "sprout" }`. --- ### Widget 1: `garden.care-due` **Title**: "Plants needing care" | **Category**: "Garden" **Default size**: `{ w: 4, h: 4 }` | **Min size**: `{ w: 3, h: 2 }` Config schema: ```typescript z.object({ containerIds: z.union([z.literal("all"), z.array(z.string().uuid())]), daysAhead: z.number().int().min(0).max(30).default(0), }); ``` Default config: `{ containerIds: "all", daysAhead: 0 }`. `resolveConfigOptions`: returns `{ containers: [{ id, name }] }`. Render: - Empty state if nothing is due: "All plants are on schedule." - Otherwise: compact list sorted by days overdue. Each row: plant name, care type icon, urgency badge ("X days overdue" / "due today"), inline "Log care" button (calls `logCare` action + revalidates — no navigation). - Truncate at 10 rows; "View all" link to `/garden`. - Rows with `next_due_at` within `daysAhead` days show as upcoming in a lighter style below overdue rows. --- ### Widget 2: `garden.overview` **Title**: "Garden overview" | **Category**: "Garden" **Default size**: `{ w: 3, h: 2 }` | **Min size**: `{ w: 2, h: 2 }` Config schema: `z.object({})`. Render: - Stat row: total plants, total containers, overdue care count. - "Next care" line: "Next: water [Plant] in N days" / "today" / "overdue". - Link to `/garden`. --- ### Widget component (`src/modules/garden/components/plant-widget.tsx`) Server component implementing both widgets, following the pattern in `src/modules/lists/components/list-widget.tsx`. --- ### Search adapters Implement `searchContainers` and `searchPlants` using `ilike` on name fields, returning `SearchResult[]`. Both appear in the command palette. --- ### Notification body improvement (optional) If `tickReminders` in `src/modules/_core/reminders.ts` can be extended without structural changes — add a registry of entity-type resolvers and register `"garden.schedule"` to resolve to `"Time to water [plant name]"`. If it requires core changes, defer and note as known limitation. --- ### Playwright E2E test (`tests/garden.spec.ts`) Happy path: 1. Log in as the seeded user. 2. Create container "Living Room Shelf". 3. Create plant "Pothos" in that container (manual entry, no species lookup). 4. Add watering schedule: every 7 days. 5. Log care: watered. 6. Verify schedule `next_due_at` updates to ~7 days from now. 7. Confirm plant appears grouped under "Living Room Shelf" on `/garden`. 8. Add `garden.care-due` widget to the default dashboard. 9. Confirm no overdue items (just watered). ## Out of scope - Health trend charts. - Weather-based watering adjustments. - Social/community features. ## Acceptance criteria - [ ] Both widgets register and appear in the widget picker. - [ ] `garden.care-due` shows overdue plants sorted by urgency; inline log button works. - [ ] `garden.overview` shows correct counts. - [ ] Both entities appear in command palette search. - [ ] All three quick-adds appear in the `+` sheet. - [ ] Garden nav link appears in sidebar and bottom nav. - [ ] Playwright happy-path test passes.