6.1 KiB

Frontend Layouts

Layout components provide consistent page structure and navigation across different sections of the Changemaker Lite application. Each layout serves a specific user context with appropriate theming and navigation.

Layout Components

AppLayout

Admin sidebar layout for authenticated admin users.

Location: admin/src/components/AppLayout.tsx

Features:

  • Collapsible sidebar navigation
  • Role-based menu items (SUPER_ADMIN, INFLUENCE_ADMIN, MAP_ADMIN)
  • User dropdown menu with logout
  • Breadcrumb navigation
  • Mobile responsive drawer
  • Light theme

Route Context: /app/*

Used By:

  • Dashboard
  • User management
  • Campaign management
  • Location management
  • Settings pages
  • All admin features

Navigation Sections:

  1. Dashboard - Overview and quick actions
  2. Influence - Campaign management, responses, email queue
  3. Map - Locations, cuts, shifts, canvassing
  4. Content - Landing pages, email templates
  5. Media - Video library, public gallery, jobs
  6. Services - Integrations (Listmonk, Pangolin, MkDocs, etc.)
  7. System - Users, settings, observability

Sidebar Behavior:

  • Default collapsed state for better content space
  • Expand on hover (desktop)
  • Drawer for mobile devices
  • Persistent state in localStorage
  • Active menu item highlighting

PublicLayout

Dark theme layout for public-facing pages.

Location: admin/src/components/PublicLayout.tsx

Features:

  • Dark blue/teal color scheme (#0d1b2a background)
  • Header with logo and navigation links
  • Footer with contact/about links
  • Full-width content area
  • Responsive grid breakpoints
  • No authentication required

Route Context: /campaigns, /map, /shifts, /p/:slug, /media

Used By:

  • Public campaign listing
  • Campaign detail pages
  • Response wall
  • Public map view
  • Public shift signup
  • Landing pages
  • Public media gallery

Theme Colors:

colorBgBase: '#0d1b2a'       // Dark navy background
colorBgContainer: '#1b2838'  // Container background
colorPrimary: '#3498db'      // Bright blue
colorLink: '#3498db'         // Link color
colorText: '#e0e0e0'         // Light text

Header Navigation:

  • Home link
  • Campaigns
  • Map
  • Shifts
  • Media Gallery
  • Login button (when not authenticated)

VolunteerLayout

Top navigation layout for volunteer portal.

Location: admin/src/components/VolunteerLayout.tsx

Features:

  • Horizontal navigation bar
  • Mobile hamburger menu
  • User status display (name, role)
  • Active route highlighting
  • Dark theme (consistent with public)
  • Logout button

Route Context: /volunteer/*

Used By:

  • Volunteer dashboard
  • Shift assignments
  • Canvass map (linked from assignments)
  • Activity history
  • Route history

Navigation Items:

  1. Dashboard - Overview and stats
  2. Assignments - Assigned shifts
  3. Activity - Visit history
  4. Routes - Walking route history

Mobile Behavior:

  • Hamburger menu for small screens
  • Drawer navigation
  • Full-width content
  • Touch-friendly controls

MediaPublicLayout

Minimal layout for public media gallery.

Location: admin/src/components/MediaPublicLayout.tsx

Features:

  • Clean header with branding
  • Full-width content area
  • Dark theme consistency
  • No footer clutter
  • Focus on media content

Route Context: /media, /media/:id

Used By:

  • Public media gallery page
  • Video viewer page

Layout Selection Pattern

Layouts are selected based on route context:

// Admin routes use AppLayout
<Route path="/app" element={<AppLayout />}>
  <Route path="dashboard" element={<DashboardPage />} />
  <Route path="users" element={<UsersPage />} />
  // ... more admin routes
</Route>

// Public routes use PublicLayout
<Route element={<PublicLayout />}>
  <Route path="/campaigns" element={<CampaignsListPage />} />
  <Route path="/campaigns/:id" element={<CampaignPage />} />
  <Route path="/map" element={<MapPage />} />
</Route>

// Volunteer routes use VolunteerLayout
<Route path="/volunteer" element={<VolunteerLayout />}>
  <Route path="dashboard" element={<VolunteerDashboardPage />} />
  <Route path="assignments" element={<VolunteerShiftsPage />} />
</Route>

// Some pages are full-screen (no layout)
<Route path="/volunteer/canvass/:cutId" element={<VolunteerMapPage />} />
<Route path="/app/pages/:id/edit" element={<PageEditorPage />} />

Full-Screen Pages

Some pages render without any layout wrapper:

  • VolunteerMapPage - Full-screen canvass map with GPS
  • PageEditorPage - GrapesJS editor (desktop-only)
  • EmailTemplateEditorPage - Email template editor

These pages handle their own navigation and controls.

Layout Customization

Theme Overrides

Layouts use Ant Design ConfigProvider for theming:

<ConfigProvider
  theme={{
    token: {
      colorPrimary: '#3498db',
      colorBgBase: '#0d1b2a',
      // ... more tokens
    },
  }}
>
  {children}
</ConfigProvider>

Role-Based Navigation

AppLayout filters menu items based on user role:

const menuItems = [
  { key: 'dashboard', label: 'Dashboard', icon: <DashboardOutlined /> },

  // Influence section - only for SUPER_ADMIN, INFLUENCE_ADMIN
  user.role === 'SUPER_ADMIN' || user.role === 'INFLUENCE_ADMIN' ? {
    key: 'influence',
    label: 'Influence',
    children: [...]
  } : null,

  // Map section - only for SUPER_ADMIN, MAP_ADMIN
  user.role === 'SUPER_ADMIN' || user.role === 'MAP_ADMIN' ? {
    key: 'map',
    label: 'Map',
    children: [...]
  } : null,
].filter(Boolean);

Responsive Breakpoints

Layouts use Ant Design grid breakpoints:

  • xs - < 576px (mobile)
  • sm - ≥ 576px (tablet)
  • md - ≥ 768px (small desktop)
  • lg - ≥ 992px (desktop)
  • xl - ≥ 1200px (large desktop)
  • xxl - ≥ 1600px (extra large)

Access via Grid.useBreakpoint():

const screens = Grid.useBreakpoint();
const isMobile = !screens.md;