Plant catalog UI: /plants page + PlantPicker (#13) #32

Merged
steve merged 2 commits from phase-4-plants-ui into main 2026-07-19 02:18:12 +00:00
2 Commits
Author SHA1 Message Date
steveandClaude Opus 4.8 62b78b4168 Address Gadfly review on #13: real bugs + dedupe page/picker
Build image / build-and-push (push) Successful in 8s
Correctness:
- PlantFormModal: validate days-to-maturity with Number() so "1.5" is rejected
  rather than silently truncated to 1 (parseInt). Accurate "at least 1 <unit>"
  spacing message; spacing input min now matches validation. Drop the icon
  maxLength that could split a multi-codepoint emoji (server caps at 32 bytes).
- PlantPicker: namespace row keys (recent- / all-) so a plant shown in both the
  Recent and All sections no longer collides on a duplicate React key.

Dedupe (the review's dominant, multi-model theme) — also sets up #15's reuse:
- lib/plants.ts: shared CategoryFilter type + filterPlants() helper.
- components/plants/CategoryChips.tsx and PlantIcon.tsx: extracted the chip row
  and the color-mix icon tile, now used by both the /plants page and PlantPicker
  (and PlantCard for the tile).

Skipped (cosmetic/cross-file, low agreement): conflictPlant→generic helper,
PlantCard vs GardenCard button-class dup, form component length, and localStorage
user-scoping (recent custom-plant ids don't resolve cross-user anyway).

tsc --noEmit clean; 20/20 vitest; production build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi
2026-07-18 22:16:45 -04:00
steveandClaude Opus 4.8 74d3e3704a Add plant catalog UI: /plants page + PlantPicker (#13)
Build image / build-and-push (push) Successful in 8s
Gadfly review (reusable) / review (pull_request) Successful in 7m21s
Adversarial Review (Gadfly) / review (pull_request) Successful in 7m21s
- web/src/lib/plants.ts: zod-validated Plant schema + react-query hooks
  (list/create/update/delete) over the #12 endpoints, with the category enum,
  labels, isBuiltin helper, and a 409 conflict extractor.
- /plants page: searchable, category-chip-filtered grid of PlantCard; built-ins
  badged and offer only Duplicate; own plants add Edit/Delete. A local
  metric/imperial spacing toggle (no per-user unit pref exists server-side).
- PlantFormModal: create/edit/duplicate a custom plant (name, category, spacing,
  color, emoji icon, days-to-maturity, notes), unit-aware spacing, 409 rebase.
- DeletePlantModal: confirm + surface the server's PLANT_IN_USE refusal inline.
- editor/PlantPicker.tsx: reusable search-first chooser with recently-used
  (localStorage) and category filter, bottom-sheet on mobile / panel on desktop,
  onSelect callback. Demoed via the /plants "Try the picker" button until #15
  consumes it.
- units.ts: small-scale spacing helpers (cm/inches) + tests.

tsc --noEmit clean; 20/20 vitest; production build green.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01JdQpdYYsTgtkJBxbcpAszi
2026-07-18 21:55:12 -04:00