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:
- Dashboard - Overview and quick actions
- Influence - Campaign management, responses, email queue
- Map - Locations, cuts, shifts, canvassing
- Content - Landing pages, email templates
- Media - Video library, public gallery, jobs
- Services - Integrations (Listmonk, Pangolin, MkDocs, etc.)
- 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 (
#0d1b2abackground) - 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:
- Dashboard - Overview and stats
- Assignments - Assigned shifts
- Activity - Visit history
- 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;