The /gardens page is home base: a card list of the user's gardens, creation and editing of garden metadata, and the entry point into the editor (/gardens/:id). The editor canvas itself is #9/#11 — until those land, the garden page can render a stub.
Scope
/gardens: card per garden — name, dimensions (formatted per the garden's unit_pref), notes preview. Tap/click navigates to /gardens/:id. Empty state with a "create your first garden" prompt.
Create dialog/form: name, width, height, unit preference. When imperial is selected, inputs accept ft/in and convert to cm for the API (helpers land in web/src/lib/geometry.ts via #9 — if #9 isn't merged yet, add a minimal cmFromFtIn/formatCm in web/src/lib/units.ts and let #9 consolidate).
Edit (same form, PATCH with version) and delete (confirmation dialog) from the card or a garden settings view.
React-query hooks + zod schemas for the gardens endpoints; mutations invalidate the list. Handle 409 by refetching and telling the user the garden changed elsewhere.
Mobile: cards stack single-column; forms usable on a phone.
Out of scope
The canvas/editor (#9, #11). Sharing UI and role badges (#17).
Key files & patterns
API contract from #7 (including the 409 envelope). API wrapper from #2.
Create a garden → it appears without reload; edit persists; delete asks then removes.
An imperial garden entered as 4 ft × 8 ft stores 122×244 cm and displays as ft/in.
Works at phone width; npx tsc --noEmit clean.
Part of epic #20 · Design: [DESIGN.md](https://gitea.stevedudenhoeffer.com/steve/pansy/src/branch/main/DESIGN.md)
## Context
The `/gardens` page is home base: a card list of the user's gardens, creation and editing of garden metadata, and the entry point into the editor (`/gardens/:id`). The editor canvas itself is #9/#11 — until those land, the garden page can render a stub.
## Scope
- [ ] `/gardens`: card per garden — name, dimensions (formatted per the garden's `unit_pref`), notes preview. Tap/click navigates to `/gardens/:id`. Empty state with a "create your first garden" prompt.
- [ ] Create dialog/form: name, width, height, unit preference. When imperial is selected, inputs accept ft/in and convert to cm for the API (helpers land in `web/src/lib/geometry.ts` via #9 — if #9 isn't merged yet, add a minimal `cmFromFtIn`/`formatCm` in `web/src/lib/units.ts` and let #9 consolidate).
- [ ] Edit (same form, PATCH with `version`) and delete (confirmation dialog) from the card or a garden settings view.
- [ ] React-query hooks + zod schemas for the gardens endpoints; mutations invalidate the list. Handle 409 by refetching and telling the user the garden changed elsewhere.
- [ ] Mobile: cards stack single-column; forms usable on a phone.
## Out of scope
- The canvas/editor (#9, #11). Sharing UI and role badges (#17).
## Key files & patterns
- API contract from #7 (including the 409 envelope). API wrapper from #2.
## Dependencies
Blocked by #6 (auth guard/nav) and #7 (API).
## Acceptance criteria
- Create a garden → it appears without reload; edit persists; delete asks then removes.
- An imperial garden entered as 4 ft × 8 ft stores 122×244 cm and displays as ft/in.
- Works at phone width; `npx tsc --noEmit` clean.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of epic #20 · Design: DESIGN.md
Context
The
/gardenspage is home base: a card list of the user's gardens, creation and editing of garden metadata, and the entry point into the editor (/gardens/:id). The editor canvas itself is #9/#11 — until those land, the garden page can render a stub.Scope
/gardens: card per garden — name, dimensions (formatted per the garden'sunit_pref), notes preview. Tap/click navigates to/gardens/:id. Empty state with a "create your first garden" prompt.web/src/lib/geometry.tsvia #9 — if #9 isn't merged yet, add a minimalcmFromFtIn/formatCminweb/src/lib/units.tsand let #9 consolidate).version) and delete (confirmation dialog) from the card or a garden settings view.Out of scope
Key files & patterns
Dependencies
Blocked by #6 (auth guard/nav) and #7 (API).
Acceptance criteria
npx tsc --noEmitclean.