- Next.js 16 App Router project with Tailwind CSS - Plant disease knowledge base (93 diseases, 25 plants) - Image upload with client+server preprocessing - ML inference pipeline with mock/demo fallback - Responsive results page with disease cards and treatment - Full test suite (285 passing tests)
6.0 KiB
6.0 KiB
06. Responsive UI, Homepage, Navigation, Loading States, and Error Handling
meta: id: hyper-specific-plant-disease-id-06 feature: hyper-specific-plant-disease-id priority: P2 depends_on: [hyper-specific-plant-disease-id-01, hyper-specific-plant-disease-id-05] tags: [frontend, ui, ux, polish]
objective:
- Build the public-facing pages (homepage, browse plants, about), global navigation, consistent loading skeletons, error boundaries, and responsive layout so the app feels polished and production-ready.
deliverables:
app/page.tsx— homepage hero with upload CTA, feature highlights, sample disease cardsapp/browse/page.tsx— browse/search all plants with disease countsapp/browse/[plantId]/page.tsx— single plant detail page with its disease listapp/about/page.tsx— about page explaining methodology and disclaimercomponents/Navbar.tsx— responsive global navigation with search barcomponents/Footer.tsx— site footer with links and disclaimercomponents/LoadingSkeleton.tsx— reusable skeleton component for loading statescomponents/ErrorBoundary.tsx— React error boundary with fallback UIcomponents/EmptyState.tsx— reusable empty state with illustration and CTAapp/layout.tsx— root layout with Navbar, Footer, metadata, and font loadinglib/constants.ts— site-wide constants (app name, tagline, social links)
steps:
- Build
components/Navbar.tsx:- Sticky top bar with app name/logo, navigation links (Home, Browse Plants, About).
- Mobile hamburger menu with slide-out drawer.
- Search input that navigates to
/browse?search=...on submit. - Active link highlighting.
- Build
components/Footer.tsx:- Three-column layout: about blurb, quick links, disclaimer (beta, not a professional diagnosis).
- "Made by gardeners, for gardeners" tagline.
- Build
app/page.tsx(Homepage):- Hero section: large headline ("Snap. Identify. Treat."), subtitle, prominent image upload component (from task 03) centered.
- How-it-works section: 3-step illustration (Upload → AI Analysis → Treatment Plan).
- Featured plants / common diseases section — carousel of 6-8 popular plant cards linking to
/browse/.... - Trust signals: "Trained on 50K+ images", "Covers 20+ plants", "Open source".
- Build
app/browse/page.tsx:- Grid of plant cards (image + name + disease count).
- Search input at top filters plants client-side by name.
- Category filter chips: "All", "Vegetables", "Herbs", "Houseplants", "Flowers".
- Click a card → navigates to
/browse/{plantId}.
- Build
app/browse/[plantId]/page.tsx:- Plant hero: common name, scientific name, family, care summary.
- Disease list: each disease is a card linking to... (todo: disease detail page could be a future enhancement; for now show expandable info inline or redirect to the identification flow).
- "Identify a disease on this plant" button → triggers upload flow targeting this plant for narrowed identification.
- Build
app/about/page.tsx:- Mission statement, how the model works (plain language), data sources, limitations disclaimer.
- Open-source credits and contribution guide.
- FAQ accordion.
- Build
components/LoadingSkeleton.tsx:- Configurable skeleton:
variant(card, text, image, circle) andcount(repeat). - Pulse animation using Tailwind
animate-pulse. - Export presets:
ResultsSkeleton,PlantCardSkeleton,UploadSkeleton.
- Configurable skeleton:
- Build
components/ErrorBoundary.tsx:- Class-based React error boundary with
componentDidCatch. - Fallback UI: friendly message ("Something went wrong!"), error detail (dev mode), "Try again" button, "Go home" link.
- Class-based React error boundary with
- Build
components/EmptyState.tsx:- Illustration (emoji or SVG), message, optional CTA button.
- Used in browse page when search returns no results.
- Update
app/layout.tsx:- Import and wrap Navbar + Footer.
- Set metadata (title template, description, Open Graph).
- Load Inter font via Next.js font optimization.
- Wrap children in
ErrorBoundary.
- Add responsive breakpoints and test on 375px, 768px, 1024px, 1440px.
- Add smooth scroll behavior and transition utilities.
tests:
- Integration: Homepage loads with hero, upload component, and featured plants.
- Integration: Browse page renders plant grid and search filters work.
- Integration: Plant detail page shows disease list.
- Integration: Mobile hamburger menu opens and closes.
- Integration: Error boundary catches thrown errors and shows fallback.
- Integration: Search in navbar navigates to browse page with query param.
- Visual: All pages render without layout shift at 375px and 1280px.
acceptance_criteria:
- Homepage, browse, plant detail, and about pages all render without errors.
- Navigation is accessible via keyboard and screen reader.
- Loading skeletons appear while pages/data are loading.
- Error boundary catches runtime errors with helpful fallback.
- Empty state shown when search or filter yields no results.
- Mobile navigation hamburger menu works on touch devices.
- All pages pass basic Lighthouse audit (no layout shift, proper heading hierarchy).
validation:
curl http://localhost:3000/ # → 200, homepage renders
curl http://localhost:3000/browse # → 200, plant grid renders
curl http://localhost:3000/browse/tomato # → 200, tomato detail
curl http://localhost:3000/about # → 200, about page
# Open in browser at 375px → hamburger menu visible and functional
# Run Lighthouse → Performance ≥90, Accessibility ≥90, SEO ≥90
notes:
- Use Next.js
<Image>component with remote patterns configured for any external plant photos. - All static pages are server-rendered (no
'use client'unless interactivity requires it). - The homepage should feel warm and approachable — use plant emoji / botanical illustrations as visual elements.
- Keep the beta disclaimer visible in footer to manage expectations (AI is not a substitute for professional diagnosis).