5.6 KiB
76 — Shadcn component implementation (Tiers 1–3)
Goal
Implement the three shadcn component adoption tiers that replace ad-hoc UI patterns across the app with shadcn/ui primitives. This is the execution phase — components are already installed (see 2026-06-13-shadcn-component-install.md).
| Tier | Name | Tasks | Files touched |
|---|---|---|---|
| 1 | Garden badges → Badge, topbar avatar → Avatar, + fallback, semantic token | 5 sub-tasks | topbar.tsx, sidebar.tsx, plant-detail.tsx, push-opt-in.tsx, care-schedule-editor.tsx, plant-widget.tsx |
| 2 | Skeleton loading, Tabs nav, Sonner toasts, FieldGroup audit, Separator | 5 sub-tasks | d/[slug]/page.tsx, plant-detail.tsx, container-detail.tsx, layout.tsx, notify-channel-toggles.tsx |
| 3 | Garden empty-state, Switch for notify channels | 2 sub-tasks | plant-list.tsx, container-list.tsx, notify-channel-toggles.tsx |
Depends on
2026-06-13-shadcn-component-install.md— components are already insrc/components/ui/- The shadcn migration map at
2026-06-13-shadcn-migration.md
Scope by tier
Tier 1 (detailed brief: docs/tasks/1a-badges-avatars.md)
Task 1a — Garden health badges → <Badge>
- File:
src/modules/garden/components/plant-detail.tsxlines 44-48, 119-123 - Replace hand-crafted
badge-success/danger/warningclasses with shadcn<Badge variant="default|destructive|secondary"> - Delete the
healthBadgeClass()helper function
Task 1b — Topbar avatar → <Avatar>
- File:
src/components/topbar.tsxlines 60-75 - Replace manual
<span className="avatar">with<Avatar><AvatarImage/><AvatarFallback/></Avatar>
Task 1c — HouseholdPill avatars → <Avatar>
- File:
src/components/sidebar.tsxlines 106-120 - Replace inner span elements with Avatar components (keep avatarColor hash for fallback background)
Task 1d — Generic AvatarFallbackWithName component
- New file:
src/components/avatar-fallback.tsx - Thin wrapper that handles the Image/Fallback pattern with name/initial logic
- Imported by both topbar.tsx and sidebar.tsx to remove duplication
Task 1e — share-green → semantic token
- Files: push-opt-in.tsx (line ~104), care-schedule-editor.tsx (line ~185), plant-widget.tsx urgencyLabel, plus any other green-600/green-500 in garden components
- Add
--c-successCSS variable to the global theme - Replace all hardcoded green-600 references with
var(--c-success)
Tier 2 (detailed brief: docs/tasks/1b-skeleton-tabs-toasts.md)
Task 2a — Skeleton loading states
- d/[slug]/page.tsx inline animate-pulse →
<Skeleton>components - plant-detail.tsx & container-detail.tsx uploadingImage → skeleton overlay
- Any other animate-pulse patterns outside skeleton.tsx itself
Task 2b — Settings/garden Tabs navigation → <Tabs>
- File:
src/modules/garden/components/plant-detail.tsxlines 162-180 - File:
src/modules/garden/components/container-detail.tsxlines 138-155 - Replace manual button-based tabs with shadcn Tabs/TabsList/TabsTrigger/TabsContent
Task 2c — Toast notifications via sonner
- Add
<Toaster>to app layout (src/app/layout.tsx) - Convert delete confirmations, calendar schedule success/error, and share-link actions to
toast.success()/toast.error()calls
Task 2d — Form FieldGroup audit
- Audit: container-form.tsx, plant-form.tsx, household edit forms
- Check consistency of Label + Input + error pattern
- Fix any non-shadcn form fields found
Task 2e — Manual separators → <Separator>
- Remove border-bottom on garden detail tab bars, replace with shadcn Separator (usually alongside the Tabs component)
Tier 3 (detailed brief: docs/tasks/1c-emptystate-switch.md)
Task 3a — Garden empty-state component
- File:
src/modules/garden/components/plant-list.tsxline 22 → use EmptyState from ui/empty.tsx - File:
src/modules/garden/components/container-list.tsxline 39 → use EmptyState - Use appropriate icons (Sprout for plants, Container for containers)
Task 3b — Notify channel toggles → <Switch>
- File:
src/components/notify-channel-toggles.tsx - Replace native
<input type="checkbox">with shadcn<Switch>component - Keep server action integration (setNotifChannel)
- Disabled state for ntfy when unconfigured
Acceptance criteria (all tiers)
- Zero
badge-success,badge-danger,badge-warningclass names remain in garden code - All avatars rendered via shadcn Avatar components (verified by DOM/JSX inspection)
- All loading states use
<Skeleton>— no animate-pulse patterns outside skeleton.tsx - Garden detail pages use shadcn Tabs component (not manual buttons)
- Toaster rendered in app layout, delete/cancel actions show toasts
- EmptyState used in all garden list pages (no ad-hoc empty text paragraphs)
- Notification channels use shadcn Switch components
pnpm lintpasses with zero errors/warningspnpm typecheckpasses with zero errors
Execution order
Execute tiers sequentially: 1 → 2 → 3. Each tier builds on the previous one's patterns and fixes foundational issues before adding polish.
Detailed task briefs are in:
- Tier 1:
docs/tasks/1a-badges-avatars.md - Tier 2:
docs/tasks/1b-skeleton-tabs-toasts.md - Tier 3:
docs/tasks/1c-emptystate-switch.md