Gadfly on #107:
- ClearBed reported a failure twice — ConfirmModal's inline Alert AND
useClearObject's own onError toast. Dropped the toast from useClearObject
(its only caller is that modal now), so the failure shows once, inline in
the dialog where the action is.
- LeaveGarden's onConfirm silently resolved (closing the dialog as if it
worked) if me.data was missing, relying on confirmDisabled to prevent it.
Throw instead, so a drift in that guard surfaces an error rather than a
fake success.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01H3zbym8Doka2d7D48maSgZ
Three tidy-ups from the audit's deferred list:
- Extracted a ConfirmModal primitive (message + Cancel/Confirm, owning the
busy lock + inline error) and folded the five hand-rolled confirm dialogs
onto it: DeleteGarden, LeaveGarden, DeletePlant, DeleteSeedLot, ClearBed.
Each is now just its message + mutation + labels. Bonus: ClearBed now
shows a failure inline instead of swallowing it. (CopyGarden stays on
Modal — it has a name field, not a plain confirm.)
- Removed components/PageStub.tsx — dead scaffolding, imported nowhere.
- The garden editor was squeezed into the max-w-5xl reading measure the
other pages use; the canvas routes (editor + public garden) now go
edge-to-edge on desktop, and the top bar matches so the brand aligns with
the editor's left edge. Mobile was already full-width, so it's unchanged.
Verified live: the Delete-garden confirm renders/cancels; the desktop editor
now uses the full viewport width. tsc + vitest + build green.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01H3zbym8Doka2d7D48maSgZ