# Tier 2: Skeleton loading states, settings Tabs navigation, toast notifications via sonner, form FieldGroup audit, manual separators → ## Goal Standardize loading UX, navigation, and toast patterns across the app using shadcn components. Audit form field consistency. Replace hand-crafted separator borders with the shadcn Separator component. --- ### Task 2a: Skeleton loading states **Files affected:** 1. `src/app/d/[slug]/page.tsx` line ~120 — inline `` with animate-pulse divs (3 lines). Convert to `` components. 2. `src/modules/garden/components/plant-detail.tsx` line 55 — `uploadingImage` state during image upload, no visual feedback other than button text. Add a skeleton overlay or shimmer on the gallery card area. 3. `src/modules/garden/components/container-detail.tsx` line 30 — same pattern: `uploadingImage` state without skeleton. 4. Any garden page with loading states that use animate-pulse instead of Skeleton. **Changes:** 1. **d/[slug]/page.tsx:** Replace inline fallback divs: ```tsx }> ``` 2. **plant-detail.tsx / container-detail.tsx:** When `uploadingImage` is true, wrap the image area with a Skeleton overlay (absolute positioned, full-width). Or add a shimmer effect using the existing skeleton component. --- ### Task 2b: Settings Tabs navigation → `` **File:** `src/app/settings/page.tsx` + `src/components/settings-section.tsx` - **Current state:** Uses a sidebar nav (vertical list with URL hash sync). This is fine for desktop but doesn't use ``. - **What needs to change:** The **garden detail pages** that have manual tab buttons need to use shadcn Tabs, NOT the settings page. The tier says "settings Tabs navigation" — checking the context: plant-detail.tsx line 164 and container-detail.tsx line 139 both have hand-crafted tab buttons with border-bottom active state. These should become `` + `` + `` + ``. **Changes:** 1. **plant-detail.tsx (lines 162-180):** Replace manual tab buttons: ```tsx import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; setTab(v as Tab)} className="mt-4"> Info Gallery Care {/* existing info section */} {/* existing gallery section */} {/* existing care section */} ; ``` 2. **container-detail.tsx (lines 138-155):** Same pattern — info/gallery tabs: ```tsx setTab(v as Tab)} className="mt-4"> Info Gallery {/* ... */} {/* ... */} ``` --- ### Task 2c: Toast notifications via sonner **Files affected:** Need to find all manual error/success messages and convert to toast calls. 1. **`src/app/layout.tsx`:** Add `` component to the app layout root so toasts are globally available. 2. **Places that need toast conversion (search for inline `setError` / success messages):** - `src/modules/garden/components/plant-detail.tsx` — delete confirmation success/error → `toast.success()` / `toast.error()` - `src/modules/garden/components/container-detail.tsx` — same pattern - `src/modules/garden/components/care-schedule-editor.tsx` line 192 (`calendarSuccess`) and error states → toast - `src/components/share-button.tsx` — "Share link created" dialog could be a toast instead (or keep as dialog but add toast on copy) **Changes:** ```tsx // In any component that needs toasts: import { toast } from "sonner"; // On success: toast.success("Event added to calendar"); // On error: toast.error("Failed to create share link"); // In layout.tsx (client component or client wrapper): import { Toaster } from "@/components/ui/sonner"; return ; ``` **Acceptance for 2c:** - `` is present in the app shell layout - All delete confirmations show toasts on success/error - The share dialog can remain as-is (it's a distinct UX), but copy action adds toast confirmation --- ### Task 2d: Form FieldGroup audit **Scope:** Audit all form field components across the app. Check for consistency in label-input-error patterns. **Files to audit:** - `src/modules/garden/components/container-form.tsx` — garden container form fields - `src/modules/garden/components/plant-form.tsx` — garden plant form fields - `src/app/settings/household/*` — household edit forms - Any other server/action-driven forms **Audit checklist:** 1. Do all form inputs have `