diff --git a/admin/src/components/volunteer/dashboard/ActionCampaignCard.tsx b/admin/src/components/volunteer/dashboard/ActionCampaignCard.tsx index 345b3e92..60ff18b7 100644 --- a/admin/src/components/volunteer/dashboard/ActionCampaignCard.tsx +++ b/admin/src/components/volunteer/dashboard/ActionCampaignCard.tsx @@ -1,4 +1,4 @@ -import { Card, Progress, Typography, Space, Tag, Alert } from 'antd'; +import { Card, Progress, Typography, Tag, Alert } from 'antd'; import { TrophyOutlined } from '@ant-design/icons'; import type { DashboardActionCampaign } from './types'; @@ -17,61 +17,65 @@ export default function ActionCampaignCard({ campaign }: ActionCampaignCardProps return ( - - Your Goal - + + + Your Goal + } - styles={{ body: { padding: 20 } }} > - -
- - {campaign.title} - - {campaign.description && ( - - {campaign.description} - - )} -
+ + {campaign.title} + + {campaign.description && ( + + {campaign.description} + + )} -
-
- - Progress: {campaign.completedSteps} of {campaign.totalSteps} complete - - {campaign.rewardEarned && Reward Earned!} -
- -
+
+ + {campaign.completedSteps} of {campaign.totalSteps} complete + + {campaign.rewardEarned && Reward Earned!} +
+ - {campaign.rewardEarned && campaign.rewardText && ( - - )} + {campaign.rewardEarned && campaign.rewardText && ( + + )} - {!campaign.rewardEarned && campaign.rewardText && ( - - Reward: {campaign.rewardText} - - )} + {!campaign.rewardEarned && campaign.rewardText && ( + + + {campaign.rewardText} + + )} - {nextStep && !campaign.rewardEarned && ( - - Next: {nextStep.label} + {nextStep && !campaign.rewardEarned && ( +
+ + Next:{' '} + {nextStep.label} - )} - +
+ )}
); } diff --git a/admin/src/components/volunteer/dashboard/ActionStepsList.tsx b/admin/src/components/volunteer/dashboard/ActionStepsList.tsx index 7dac8482..98731738 100644 --- a/admin/src/components/volunteer/dashboard/ActionStepsList.tsx +++ b/admin/src/components/volunteer/dashboard/ActionStepsList.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Card, List, Button, Typography, Tag, Space, App } from 'antd'; +import { Card, Button, Typography, Tag, Space, App } from 'antd'; import { VideoCameraOutlined, MailOutlined, @@ -10,8 +10,6 @@ import { LinkOutlined, CheckSquareOutlined, CheckCircleFilled, - RightOutlined, - UnorderedListOutlined, } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import { api } from '@/lib/api'; @@ -100,88 +98,101 @@ export default function ActionStepsList({ campaign, onRefresh }: ActionStepsList return ( - - Actions - - } - extra={ - - {campaign.completedSteps} of {campaign.totalSteps} + + {campaign.completedSteps} of {campaign.totalSteps} Actions } - styles={{ body: { padding: 0 } }} > - { - const isSelfReport = step.kind === 'CUSTOM' || step.kind === 'VISIT_LINK'; - const canNavigate = resolveStepLink(step) !== null; - return ( - }>Completed - ) : isSelfReport ? ( - - {canNavigate && ( - - )} - - - ) : ( + {sortedSteps.map((step, i) => { + const isSelfReport = step.kind === 'CUSTOM' || step.kind === 'VISIT_LINK'; + const canNavigate = resolveStepLink(step) !== null; + + return ( +
0 ? '1px solid rgba(255,255,255,0.04)' : undefined, + opacity: step.completed ? 0.55 : 1, + gap: 12, + }} + > +
+
+ {step.completed ? : KIND_ICONS[step.kind]} +
+
+ + {KIND_LABELS[step.kind]} + + + {step.label} + +
+
+ +
+ {step.completed ? ( + Done + ) : isSelfReport ? ( + + {canNavigate && ( + + )} - ), - ]} - > - - {step.completed ? : KIND_ICONS[step.kind]} -
- } - title={ - - - {KIND_LABELS[step.kind]}: - {' '} - {step.label} - - } - /> - - ); - }} - /> + + ) : ( + + )} +
+ + ); + })}
); } diff --git a/admin/src/components/volunteer/dashboard/ActivityCard.tsx b/admin/src/components/volunteer/dashboard/ActivityCard.tsx index 172762b5..3cc9d4c3 100644 --- a/admin/src/components/volunteer/dashboard/ActivityCard.tsx +++ b/admin/src/components/volunteer/dashboard/ActivityCard.tsx @@ -1,4 +1,4 @@ -import { Card, Row, Col, Statistic, Space } from 'antd'; +import { Card, Typography } from 'antd'; import { TrophyOutlined, StarFilled } from '@ant-design/icons'; import type { DashboardPoints } from './types'; @@ -9,32 +9,36 @@ interface ActivityCardProps { export default function ActivityCard({ points }: ActivityCardProps) { return ( - - My Activity - + Activity + } + extra={ + + {points.total} pts + } - styles={{ body: { padding: 20 } }} > - - - } - valueStyle={{ fontSize: 32, fontWeight: 600 }} - /> - - - } - valueStyle={{ fontSize: 32, fontWeight: 600 }} - /> - - +
+ + + {points.total} + +
+ + points earned + + {points.achievementCount > 0 && ( +
+ + + {points.achievementCount} achievement{points.achievementCount !== 1 ? 's' : ''} + +
+ )}
); } diff --git a/admin/src/components/volunteer/dashboard/MyEventsCard.tsx b/admin/src/components/volunteer/dashboard/MyEventsCard.tsx index 8d4f5c7b..1ad110e9 100644 --- a/admin/src/components/volunteer/dashboard/MyEventsCard.tsx +++ b/admin/src/components/volunteer/dashboard/MyEventsCard.tsx @@ -1,4 +1,4 @@ -import { Card, List, Button, Typography, Space, Empty, Tag } from 'antd'; +import { Card, Button, Typography, Empty, Tag } from 'antd'; import { CalendarOutlined, TagOutlined } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import dayjs from 'dayjs'; @@ -13,13 +13,16 @@ export default function MyEventsCard({ events }: MyEventsCardProps) { return ( - - My Events - + + + My Events + } - styles={{ body: { padding: 0 } }} > {events.length === 0 ? (
@@ -29,39 +32,43 @@ export default function MyEventsCard({ events }: MyEventsCardProps) { />
) : ( - ( - navigate(`/event/${event.eventSlug}`)} - > - Details - , - ]} + events.map((event, i) => ( +
0 ? '1px solid rgba(255,255,255,0.04)' : undefined, + gap: 12, + }} + > +
+ + {event.eventTitle} + +
+ + {dayjs(event.eventDate).format('MMM D, YYYY')} + + {event.tierName && ( + } color="blue" style={{ margin: 0, fontSize: 11, lineHeight: '18px', padding: '0 6px' }}> + {event.tierName} + + )} +
+
+ +
+ )) )}
); diff --git a/admin/src/components/volunteer/dashboard/ResourcesGrid.tsx b/admin/src/components/volunteer/dashboard/ResourcesGrid.tsx index 5ebb0427..65662493 100644 --- a/admin/src/components/volunteer/dashboard/ResourcesGrid.tsx +++ b/admin/src/components/volunteer/dashboard/ResourcesGrid.tsx @@ -1,11 +1,10 @@ -import { Card, Row, Col, Button, Typography, Empty, Space } from 'antd'; +import { Card, Row, Col, Button, Typography, Empty } from 'antd'; import { FileTextOutlined, VideoCameraOutlined, PictureOutlined, DownloadOutlined, EyeOutlined, - FolderOpenOutlined, } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import { mediaApi } from '@/lib/media-api'; @@ -16,15 +15,9 @@ interface ResourcesGridProps { } const KIND_ICONS = { - document: , - video: , - photo: , -}; - -const KIND_LABELS = { - document: 'Document', - video: 'Video', - photo: 'Photo', + document: , + video: , + photo: , }; function resolveDownloadUrl(downloadPath: string): string { @@ -58,13 +51,13 @@ export default function ResourcesGrid({ resources }: ResourcesGridProps) { return ( - - Resources - + Tools & Resources } - styles={{ body: { padding: 20 } }} > {resources.length === 0 ? ( @@ -75,15 +68,15 @@ export default function ResourcesGrid({ resources }: ResourcesGridProps) {
- - {resource.title} - - - {KIND_LABELS[resource.kind]} - - +
+ + {resource.title} + + +
))} diff --git a/admin/src/components/volunteer/dashboard/TakeActionCard.tsx b/admin/src/components/volunteer/dashboard/TakeActionCard.tsx index a2a0cdbb..c86abe22 100644 --- a/admin/src/components/volunteer/dashboard/TakeActionCard.tsx +++ b/admin/src/components/volunteer/dashboard/TakeActionCard.tsx @@ -1,5 +1,5 @@ -import { Card, Button, Typography, Space } from 'antd'; -import { FireOutlined, CalendarOutlined, EnvironmentOutlined, RightOutlined } from '@ant-design/icons'; +import { Button, Typography } from 'antd'; +import { CalendarOutlined, EnvironmentOutlined, RightOutlined } from '@ant-design/icons'; import { useNavigate } from 'react-router-dom'; import dayjs from 'dayjs'; import type { DashboardFeaturedEvent } from './types'; @@ -11,55 +11,52 @@ interface TakeActionCardProps { export default function TakeActionCard({ event }: TakeActionCardProps) { const navigate = useNavigate(); - const handleClick = () => { - navigate(`/event/${event.slug}`); - }; - return ( - - - Take Action - - } - styles={{ body: { padding: 0 } }} - style={{ overflow: 'hidden' }} +
- {event.coverImageUrl && ( -
- )} -
- +
+ + Take Action + +
+
+ {event.title} - - - {dayjs(event.date).format('MMM D, YYYY')} at {event.startTime} +
+ + + {dayjs(event.date).format('ddd, MMM D, YYYY')} at {event.startTime} {event.venueName && ( - - {event.venueName} + + + {event.venueName} )} - +
- +
); } diff --git a/admin/src/components/volunteer/dashboard/TrainingList.tsx b/admin/src/components/volunteer/dashboard/TrainingList.tsx index cca44e6a..1b86ec0e 100644 --- a/admin/src/components/volunteer/dashboard/TrainingList.tsx +++ b/admin/src/components/volunteer/dashboard/TrainingList.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; -import { Card, List, Button, Typography, Tag, Space, Empty, App } from 'antd'; -import { ReadOutlined, CalendarOutlined, ClockCircleOutlined, EnvironmentOutlined, CheckOutlined } from '@ant-design/icons'; +import { Card, Button, Typography, Tag, Empty, App } from 'antd'; +import { ReadOutlined, CheckOutlined } from '@ant-design/icons'; import dayjs from 'dayjs'; import { api } from '@/lib/api'; import type { DashboardTraining } from './types'; @@ -27,66 +27,79 @@ export default function TrainingList({ trainings, onRefresh }: TrainingListProps } }; + const upcoming = trainings.filter((t) => new Date(t.date) >= new Date()); + return ( - - Upcoming Trainings - + + + Volunteer Training + + } + extra={ + upcoming.length > 0 ? ( + + {upcoming.length} Upcoming + + ) : null } - styles={{ body: { padding: 0 } }} > {trainings.length === 0 ? (
) : ( - { - const full = training.maxVolunteers > 0 && training.currentVolunteers >= training.maxVolunteers; - return ( - }>Signed up - ) : ( - - ), - ]} - > - - - {dayjs(training.date).format('MMM D, YYYY')} - - - {training.startTime} – {training.endTime} - - {training.location && ( - - {training.location} - - )} - - } - /> - - ); - }} - /> + trainings.map((training, i) => { + const full = training.maxVolunteers > 0 && training.currentVolunteers >= training.maxVolunteers; + return ( +
0 ? '1px solid rgba(255,255,255,0.04)' : undefined, + gap: 12, + }} + > +
+
+ + {training.location ? 'In Person' : 'Virtual'} + + + {dayjs(training.date).format('ddd, MMM D')} · {training.startTime} - {training.endTime} + +
+ + {training.title} + +
+
+ {training.isSignedUp ? ( + } style={{ margin: 0 }}>Signed up + ) : ( + + )} +
+
+ ); + }) )}
);