263 lines
6.1 KiB
Markdown

# 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:**
```typescript
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:
```typescript
// 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:
```typescript
<ConfigProvider
theme={{
token: {
colorPrimary: '#3498db',
colorBgBase: '#0d1b2a',
// ... more tokens
},
}}
>
{children}
</ConfigProvider>
```
### Role-Based Navigation
AppLayout filters menu items based on user role:
```typescript
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()`:
```typescript
const screens = Grid.useBreakpoint();
const isMobile = !screens.md;
```
## Related Documentation
- [Frontend Overview](../index.md)
- [Components](../components/index.md)
- [Admin Pages](../pages/admin/index.md)
- [Public Pages](../pages/public/index.md)
- [Volunteer Pages](../pages/volunteer/index.md)
- [Theming Guide](../../development/theming.md)