184 lines
3.5 KiB
Markdown
184 lines
3.5 KiB
Markdown
# My Activity Page
|
|
|
|
## Overview
|
|
|
|
**File Path:** `admin/src/pages/volunteer/MyActivityPage.tsx` (137 lines)
|
|
|
|
**Route:** `/volunteer/activity`
|
|
|
|
**Role Requirements:** Authenticated users
|
|
|
|
**Purpose:** Volunteer activity dashboard showing canvassing statistics and visit history.
|
|
|
|
**Key Features:**
|
|
|
|
- Statistics cards (Today's Visits, Total Doors, Total Sessions)
|
|
- Outcome breakdown with color-coded tags
|
|
- Visit history table (address, outcome, timestamp)
|
|
- Pagination (20 visits per page)
|
|
- Parallel stats + visits fetch
|
|
- Dark theme (VolunteerLayout)
|
|
|
|
---
|
|
|
|
## Features
|
|
|
|
### 1. Statistics Cards
|
|
|
|
```tsx
|
|
<Row gutter={16}>
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="Today's Visits"
|
|
value={stats.todayVisits}
|
|
prefix={<CheckCircleOutlined />}
|
|
valueStyle={{ color: '#52c41a' }}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="Total Doors"
|
|
value={stats.totalDoors}
|
|
prefix={<HomeOutlined />}
|
|
valueStyle={{ color: '#1890ff' }}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
|
|
<Col xs={24} sm={8}>
|
|
<Card>
|
|
<Statistic
|
|
title="Total Sessions"
|
|
value={stats.totalSessions}
|
|
prefix={<ClockCircleOutlined />}
|
|
valueStyle={{ color: '#722ed1' }}
|
|
/>
|
|
</Card>
|
|
</Col>
|
|
</Row>
|
|
```
|
|
|
|
### 2. Outcome Breakdown
|
|
|
|
```tsx
|
|
<Card title="Outcome Breakdown">
|
|
<Space wrap>
|
|
<Tag color="green">Strong Support: {outcomes.strongSupport}</Tag>
|
|
<Tag color="blue">Leaning Support: {outcomes.leaningSupport}</Tag>
|
|
<Tag color="yellow">Undecided: {outcomes.undecided}</Tag>
|
|
<Tag color="orange">Leaning Opposed: {outcomes.leaningOpposed}</Tag>
|
|
<Tag color="red">Opposed: {outcomes.opposed}</Tag>
|
|
<Tag color="default">No Answer: {outcomes.noAnswer}</Tag>
|
|
<Tag color="gray">Not Home: {outcomes.notHome}</Tag>
|
|
</Space>
|
|
</Card>
|
|
```
|
|
|
|
### 3. Visit History Table
|
|
|
|
```tsx
|
|
<Table
|
|
dataSource={visits}
|
|
columns={[
|
|
{
|
|
title: 'Address',
|
|
dataIndex: 'address',
|
|
key: 'address'
|
|
},
|
|
{
|
|
title: 'Outcome',
|
|
dataIndex: 'outcome',
|
|
key: 'outcome',
|
|
render: (outcome) => (
|
|
<Tag color={getOutcomeColor(outcome)}>
|
|
{outcome.replace('_', ' ')}
|
|
</Tag>
|
|
)
|
|
},
|
|
{
|
|
title: 'Notes',
|
|
dataIndex: 'notes',
|
|
key: 'notes',
|
|
ellipsis: true
|
|
},
|
|
{
|
|
title: 'Time',
|
|
dataIndex: 'createdAt',
|
|
key: 'createdAt',
|
|
render: (date) => dayjs(date).format('MMM D, h:mm A')
|
|
}
|
|
]}
|
|
pagination={{
|
|
current: page,
|
|
total: total,
|
|
pageSize: 20,
|
|
onChange: setPage
|
|
}}
|
|
/>
|
|
```
|
|
|
|
---
|
|
|
|
## API Integration
|
|
|
|
### Endpoints
|
|
|
|
#### 1. Get Stats
|
|
```http
|
|
GET /api/map/canvass/my-stats
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"todayVisits": 23,
|
|
"totalDoors": 187,
|
|
"totalSessions": 12,
|
|
"outcomes": {
|
|
"strongSupport": 45,
|
|
"leaningSupport": 32,
|
|
"undecided": 28,
|
|
"leaningOpposed": 15,
|
|
"opposed": 12,
|
|
"noAnswer": 38,
|
|
"notHome": 17
|
|
}
|
|
}
|
|
```
|
|
|
|
#### 2. Get Visit History
|
|
```http
|
|
GET /api/map/canvass/my-visits?page=1&limit=20
|
|
Authorization: Bearer {token}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"visits": [
|
|
{
|
|
"id": "cm1visit123",
|
|
"address": "123 Main St",
|
|
"outcome": "strong_support",
|
|
"notes": "Very enthusiastic, requested yard sign",
|
|
"createdAt": "2025-02-12T14:30:00.000Z"
|
|
}
|
|
],
|
|
"total": 187,
|
|
"page": 1
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- [Volunteer Map Page](./volunteer-map-page.md)
|
|
- [My Routes Page](./my-routes-page.md)
|
|
- [Canvass Dashboard](../admin/canvass-dashboard-page.md)
|