Skip to content

Key Reusuable Components and Code Patterns

phawatboom edited this page Sep 23, 2025 · 1 revision

🎨 Core UI Components

1. Button Component (/components/Button/)

  • Highly flexible with multiple variants using class-variance-authority
  • Polymorphic: Works as both <button> and <Link> based on href prop
  • Variants: primary, outline, secondary, ghost
  • Sizes: sm, md, lg
  • Colors: cream, abyss, algae, grass
  • Usage: Perfect for CTAs, navigation, forms

2. PayloadImage Component (/components/PayloadImage/)

  • Smart image optimization with automatic size selection
  • Built-in placeholders and error handling
  • CMS integration with Payload Media types
  • Responsive image loading with custom loader
  • Usage: All image displays throughout the site

3. RichText Component (/components/RichText/)

  • Payload CMS integration for rich text content
  • Prose styling with Tailwind typography
  • Usage: Blog posts, descriptions, CMS content

4. GradeBadge Component (GradeBadge.tsx)

  • Domain-specific for river grading system
  • Color-coded difficulty levels (Grade 1-6)
  • Usage: River difficulty indicators

5. Skeleton Component (skeleton.tsx)

  • Loading states with animation
  • Consistent styling across the app
  • Usage: Content loading placeholders

πŸ—ΊοΈ Map Components (/components/Map/)

Map & MapWrapper

  • Leaflet integration with React
  • Multi-marker support with popups
  • Auto-fitting bounds for multiple coordinates
  • Mobile-responsive map interactions
  • Usage: River locations, event venues

πŸƒ Card System (/components/TripsCard/)

Modular card architecture with separate concerns:

  • TripsCard.tsx - Main container
  • TripsCardContent.tsx - Text content
  • TripsCardImage.tsx - Image display
  • TripsCardDate.tsx - Date formatting
  • TripsCardLocation.tsx - Location display
  • TripsCardButtons.tsx - Action buttons

This pattern is perfect for replication across other content types!

πŸ› οΈ Utility Functions (/lib/utils/)

1. cn() Function (cn.ts)

// Combines clsx and tailwind-merge for optimal class handling
cn('base-class', condition && 'conditional-class', className)

2. Date Utilities

  • formatDate() - Single date formatting (NZ locale)
  • formatDateRange() - Smart date range formatting
  • Timezone aware (Pacific/Auckland)

3. Content Processing

  • getPlainText() - Extracts text from rich content
  • Payload CMS integration helpers

πŸ“Š Data Layer Patterns

Query Functions (/queries/)

  • Consistent API for data fetching
  • TypeScript typed responses
  • Error handling built-in
  • Reusable patterns for different content types

Example pattern:

export async function getContent(options?: QueryOptions) {
  const { docs: content } = await payload.find({
    collection: 'content',
    ...options
  })
  return { content }
}

🎯 Page Architecture Patterns

Consistent Page Structure:

  1. Page Component (page.tsx) - Data fetching
  2. Page Component (_components/PageName.tsx) - UI logic
  3. Sub-components - Specific sections

Layout Components (_components/layout/)

  • Header/Navbar - Global navigation
  • Footer - Site-wide footer
  • Consistent spacing and responsive design

🎨 Design System

Color Palette (from styles.css):

--abyss: oklch(27.35% 0.017 189.89);    /* Dark blue */
--grass: oklch(66.38% 0.088 132.22);    /* Green */
--cream: oklch(94.49% 0.013 97.45);     /* Light cream */
--water: oklch(79.98% 0.038 187.93);    /* Light blue */
--algae: oklch(74.26% 0.113 127.26);    /* Light green */
--seafoam: oklch(89.92% 0.0193 162.89); /* Very light blue */

Typography System:

  • Heading: Rubik Mono One (monospace)
  • Body: Rubik (sans-serif)
  • Handwritten: Caveat (cursive)
  • Display: Unbounded (sans-serif)

πŸ”„ Most Reusable Patterns

  1. Button Component - Use everywhere for consistency
  2. Card Architecture - Apply TripsCard pattern to other content
  3. PayloadImage - All image handling
  4. cn() utility - Every component for class management
  5. Date formatters - All date displays
  6. Query pattern - All data fetching
  7. Page structure - Consistent across all routes

πŸ’‘ Recommendations for New Pages

When creating new pages, leverage these existing patterns:

  • Copy the TripsCard modular approach for other card types
  • Use Button component for all interactive elements
  • Follow the page β†’ _components structure
  • Utilize existing utilities (cn, date formatters, etc.)
  • Maintain color palette consistency
  • Use PayloadImage for all media display

Clone this wiki locally