Layout Architecture

WI-CARPOOL uses a flexible layout system that adapts to different user types and screen sizes, providing consistent navigation and content organization.

📱 Responsive Design

Mobile-first approach with breakpoints for all screen sizes.

🎛️ Dashboard Layouts

Specialized layouts for passenger and driver dashboards.

🧭 Consistent Navigation

Unified navigation patterns across all application areas.

🔄 State Management

Layout state persistence and responsive sidebar management.

Main Layout Components

Root Layout

The main application layout that wraps all pages with navigation and theme providers.

App Layout Structure

import { Outlet } from "react-router-dom"
import { Navbar } from "@/components/Navbar"
import { Footer } from "@/components/Footer"
import { Toaster } from "@/components/ui/sonner"
import { ThemeProvider } from "@/components/ThemeProvider"

function RootLayout() {
  return (
    <ThemeProvider defaultTheme="system" storageKey="carpool-theme">
      <div className="min-h-screen flex flex-col">
        <Navbar />
        <main className="flex-1">
          <Outlet />
        </main>
        <Footer />
        <Toaster />
      </div>
    </ThemeProvider>
  )
}

Dashboard Layout

Specialized layout for user dashboards with sidebar navigation.

Dashboard Layout Implementation

import { SidebarProvider, SidebarInset } from "@/components/ui/sidebar"
import { DashboardSidebar } from "@/components/dashboard/DashboardSidebar"
import { DashboardHeader } from "@/components/dashboard/DashboardHeader"

interface DashboardLayoutProps {
  children: React.ReactNode
  userType: "passenger" | "driver"
}

function DashboardLayout({ children, userType }: DashboardLayoutProps) {
  return (
    <SidebarProvider>
      <div className="min-h-screen flex w-full">
        <DashboardSidebar userType={userType} />
        <SidebarInset>
          <DashboardHeader />
          <div className="flex-1 space-y-4 p-4 md:p-8">
            {children}
          </div>
        </SidebarInset>
      </div>
    </SidebarProvider>
  )
}

Responsive Layout Patterns

Container Patterns

Standardized container components for consistent content width and spacing.

Container Component

import { cn } from "@/lib/utils"

interface ContainerProps {
  children: React.ReactNode
  className?: string
  size?: "sm" | "md" | "lg" | "xl" | "full"
}

function Container({ children, className, size = "lg" }: ContainerProps) {
  const sizeClasses = {
    sm: "max-w-2xl",
    md: "max-w-4xl", 
    lg: "max-w-6xl",
    xl: "max-w-7xl",
    full: "max-w-full"
  }

  return (
    <div className={cn(
      "mx-auto px-4 sm:px-6 lg:px-8",
      sizeClasses[size],
      className
    )}>
      {children}
    </div>
  )
}

Grid Layouts

Responsive grid systems for organizing content cards and lists.

Responsive Grid Component

interface GridProps {
  children: React.ReactNode
  cols?: {
    default?: number
    sm?: number
    md?: number
    lg?: number
    xl?: number
  }
  gap?: number
  className?: string
}

function Grid({ 
  children, 
  cols = { default: 1, md: 2, lg: 3 }, 
  gap = 4,
  className 
}: GridProps) {
  const gridClasses = [
    `grid`,
    `gap-${gap}`,
    cols.default && `grid-cols-${cols.default}`,
    cols.sm && `sm:grid-cols-${cols.sm}`,
    cols.md && `md:grid-cols-${cols.md}`,
    cols.lg && `lg:grid-cols-${cols.lg}`,
    cols.xl && `xl:grid-cols-${cols.xl}`,
  ].filter(Boolean).join(" ")

  return (
    <div className={cn(gridClasses, className)}>
      {children}
    </div>
  )
}

// Usage example
function RidesList({ rides }) {
  return (
    <Container>
      <Grid cols={{ default: 1, md: 2, xl: 3 }}>
        {rides.map(ride => (
          <RideCard key={ride.id} ride={ride} />
        ))}
      </Grid>
    </Container>
  )
}

Sidebar Layouts

Dashboard Sidebar

Navigation sidebar with collapsible sections and user-specific menu items.

Dashboard Sidebar Component

import {
  Sidebar,
  SidebarContent,
  SidebarGroup,
  SidebarHeader,
  SidebarMenu,
  SidebarMenuButton,
  SidebarMenuItem,
} from "@/components/ui/sidebar"
import { 
  Car, 
  Calendar, 
  CreditCard, 
  MessageSquare, 
  Settings,
  User
} from "lucide-react"

interface DashboardSidebarProps {
  userType: "passenger" | "driver"
}

export function DashboardSidebar({ userType }: DashboardSidebarProps) {
  const passengerItems = [
    { title: "Dashboard", url: "/passenger/dashboard", icon: User },
    { title: "Find Rides", url: "/passenger/find-ride", icon: Car },
    { title: "My Trips", url: "/passenger/trips", icon: Calendar },
    { title: "Messages", url: "/passenger/messages", icon: MessageSquare },
    { title: "Wallet", url: "/passenger/wallet", icon: CreditCard },
    { title: "Settings", url: "/passenger/settings", icon: Settings },
  ]

  const driverItems = [
    { title: "Dashboard", url: "/driver/dashboard", icon: User },
    { title: "Post Ride", url: "/driver/post-ride", icon: Car },
    { title: "My Rides", url: "/driver/rides", icon: Calendar },
    { title: "Messages", url: "/driver/messages", icon: MessageSquare },
    { title: "Earnings", url: "/driver/earnings", icon: CreditCard },
    { title: "Vehicle", url: "/driver/vehicle", icon: Car },
    { title: "Settings", url: "/driver/settings", icon: Settings },
  ]

  const items = userType === "passenger" ? passengerItems : driverItems

  return (
    <Sidebar variant="inset">
      <SidebarHeader>
        <div className="flex items-center gap-2 px-4 py-2">
          <Car className="h-6 w-6" />
          <span className="font-semibold">WI-CARPOOL</span>
        </div>
      </SidebarHeader>
      <SidebarContent>
        <SidebarGroup>
          <SidebarMenu>
            {items.map((item) => (
              <SidebarMenuItem key={item.title}>
                <SidebarMenuButton asChild>
                  <Link to={item.url}>
                    <item.icon />
                    <span>{item.title}</span>
                  </Link>
                </SidebarMenuButton>
              </SidebarMenuItem>
            ))}
          </SidebarMenu>
        </SidebarGroup>
      </SidebarContent>
    </Sidebar>
  )
}

Mobile Navigation

Mobile-optimized navigation with bottom tab bar.

Mobile Bottom Navigation

import { Link, useLocation } from "react-router-dom"
import { cn } from "@/lib/utils"
import {
  Home,
  Search,
  Calendar,
  MessageSquare,
  User
} from "lucide-react"

const navigationItems = [
  { name: "Home", href: "/", icon: Home },
  { name: "Search", href: "/search", icon: Search },
  { name: "Trips", href: "/trips", icon: Calendar },
  { name: "Messages", href: "/messages", icon: MessageSquare },
  { name: "Profile", href: "/profile", icon: User },
]

function MobileNavigation() {
  const location = useLocation()

  return (
    <nav className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-200 md:hidden">
      <div className="grid grid-cols-5">
        {navigationItems.map((item) => {
          const isActive = location.pathname === item.href
          
          return (
            <Link
              key={item.name}
              to={item.href}
              className={cn(
                "flex flex-col items-center py-2 px-1 text-xs",
                isActive 
                  ? "text-primary bg-primary/10" 
                  : "text-gray-600 hover:text-primary"
              )}
            >
              <item.icon className="h-5 w-5 mb-1" />
              <span>{item.name}</span>
            </Link>
          )
        })}
      </div>
    </nav>
  )
}

Page Layout Patterns

Split Layout

Two-column layout with sidebar content and main content area.

Split Layout Component

interface SplitLayoutProps {
  sidebar: React.ReactNode
  children: React.ReactNode
  sidebarWidth?: "sm" | "md" | "lg"
}

function SplitLayout({ 
  sidebar, 
  children, 
  sidebarWidth = "md" 
}: SplitLayoutProps) {
  const widthClasses = {
    sm: "w-64",
    md: "w-80", 
    lg: "w-96"
  }

  return (
    <div className="flex h-full">
      <aside className={cn(
        "hidden lg:block border-r border-gray-200 bg-gray-50",
        widthClasses[sidebarWidth]
      )}>
        {sidebar}
      </aside>
      <main className="flex-1 overflow-hidden">
        {children}
      </main>
    </div>
  )
}

Card Layout

Card-based layout for organizing related content sections.

Card Layout Example

function ProfilePage() {
  return (
    <Container>
      <div className="space-y-6">
        <div className="flex items-center justify-between">
          <h1 className="text-3xl font-bold">Profile</h1>
          <Button>Edit Profile</Button>
        </div>
        
        <Grid cols={{ default: 1, lg: 3 }} gap={6}>
          <div className="lg:col-span-2 space-y-6">
            <Card>
              <CardHeader>
                <CardTitle>Personal Information</CardTitle>
              </CardHeader>
              <CardContent>
                <!-- Personal info form -->
              </CardContent>
            </Card>
            
            <Card>
              <CardHeader>
                <CardTitle>Preferences</CardTitle>
              </CardHeader>
              <CardContent>
                <!-- Preferences form -->
              </CardContent>
            </Card>
          </div>
          
          <div className="space-y-6">
            <Card>
              <CardHeader>
                <CardTitle>Profile Picture</CardTitle>
              </CardHeader>
              <CardContent>
                <!-- Profile picture upload -->
              </CardContent>
            </Card>
            
            <Card>
              <CardHeader>
                <CardTitle>Quick Stats</CardTitle>
              </CardHeader>
              <CardContent>
                <!-- Stats display -->
              </CardContent>
            </Card>
          </div>
        </Grid>
      </div>
    </Container>
  )
}

Layout Utilities

Layout Context

Context for managing layout state across components.

Layout Context Implementation

import { createContext, useContext, useState } from "react"

interface LayoutContextType {
  isSidebarOpen: boolean
  toggleSidebar: () => void
  isMobile: boolean
  setIsMobile: (mobile: boolean) => void
}

const LayoutContext = createContext<LayoutContextType | undefined>(undefined)

export function LayoutProvider({ children }: { children: React.ReactNode }) {
  const [isSidebarOpen, setIsSidebarOpen] = useState(true)
  const [isMobile, setIsMobile] = useState(false)

  const toggleSidebar = () => setIsSidebarOpen(!isSidebarOpen)

  return (
    <LayoutContext.Provider value={{
      isSidebarOpen,
      toggleSidebar,
      isMobile,
      setIsMobile
    }}>
      {children}
    </LayoutContext.Provider>
  )
}

export function useLayout() {
  const context = useContext(LayoutContext)
  if (!context) {
    throw new Error("useLayout must be used within a LayoutProvider")
  }
  return context
}

Responsive Hooks

Custom hooks for responsive layout management.

Responsive Layout Hooks

import { useState, useEffect } from "react"

export function useBreakpoint() {
  const [breakpoint, setBreakpoint] = useState("lg")

  useEffect(() => {
    const updateBreakpoint = () => {
      const width = window.innerWidth
      if (width < 640) setBreakpoint("sm")
      else if (width < 768) setBreakpoint("md")
      else if (width < 1024) setBreakpoint("lg")
      else if (width < 1280) setBreakpoint("xl")
      else setBreakpoint("2xl")
    }

    updateBreakpoint()
    window.addEventListener("resize", updateBreakpoint)
    return () => window.removeEventListener("resize", updateBreakpoint)
  }, [])

  return breakpoint
}

export function useViewport() {
  const [viewport, setViewport] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  })

  useEffect(() => {
    const updateViewport = () => {
      setViewport({
        width: window.innerWidth,
        height: window.innerHeight
      })
    }

    window.addEventListener("resize", updateViewport)
    return () => window.removeEventListener("resize", updateViewport)
  }, [])

  return viewport
}

Best Practices

Performance

  • Use CSS Grid and Flexbox for layout instead of JavaScript calculations
  • Implement virtual scrolling for long lists
  • Lazy load off-screen content
  • Optimize layout shifts with consistent dimensions

Accessibility

  • Use semantic HTML elements for proper structure
  • Implement skip links for keyboard navigation
  • Ensure focus management in complex layouts
  • Provide alternative navigation methods

Responsive Design

  • Follow mobile-first design principles
  • Use relative units for flexible layouts
  • Test across different screen sizes and orientations
  • Implement progressive enhancement