Files
famapp/docs/tasks/76-shadcn-tiers.md
T
ginnoir a312d4ce39
CI / checks (push) Successful in 12m55s
CI / build (push) Successful in 15m16s
fix: tighten sharing and shadcn composition
2026-06-13 05:20:01 -05:00

5.6 KiB
Raw Blame History

76 — Shadcn component implementation (Tiers 13)

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 in src/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.tsx lines 44-48, 119-123
  • Replace hand-crafted badge-success/danger/warning classes with shadcn <Badge variant="default|destructive|secondary">
  • Delete the healthBadgeClass() helper function

Task 1b — Topbar avatar → <Avatar>

  • File: src/components/topbar.tsx lines 60-75
  • Replace manual <span className="avatar"> with <Avatar><AvatarImage/><AvatarFallback/></Avatar>

Task 1c — HouseholdPill avatars → <Avatar>

  • File: src/components/sidebar.tsx lines 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-success CSS 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.tsx lines 162-180
  • File: src/modules/garden/components/container-detail.tsx lines 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.tsx line 22 → use EmptyState from ui/empty.tsx
  • File: src/modules/garden/components/container-list.tsx line 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)

  1. Zero badge-success, badge-danger, badge-warning class names remain in garden code
  2. All avatars rendered via shadcn Avatar components (verified by DOM/JSX inspection)
  3. All loading states use <Skeleton> — no animate-pulse patterns outside skeleton.tsx
  4. Garden detail pages use shadcn Tabs component (not manual buttons)
  5. Toaster rendered in app layout, delete/cancel actions show toasts
  6. EmptyState used in all garden list pages (no ad-hoc empty text paragraphs)
  7. Notification channels use shadcn Switch components
  8. pnpm lint passes with zero errors/warnings
  9. pnpm typecheck passes 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