feat(badges): Add volunteer badge system with 9 achievement levels
Overview
This MR adds a comprehensive volunteer badge system to recognize and reward volunteers for their attendance at medical camps. The system includes 9 progressive achievement levels with visual badges, progress tracking, and real-time updates.
What does this MR do and why?
Motivation: Volunteers needed a gamification system to encourage consistent attendance and recognize their contributions to medical camps. The badge system provides visual feedback and motivation through progressive achievements.
Approach:
- Implemented a complete badge UI system with React components
- Added 9 custom SVG badge designs for different achievement levels
- Integrated badge display into user profiles with real-time updates
- Created comprehensive test coverage (49 tests) for all badge components
- Added badge evaluation API integration for coordinators/admins
Trade-offs:
- Badge SVG assets increase bundle size slightly (~50KB total)
- Real-time badge updates require query invalidation after attendance marking
- Badge evaluation is manual for coordinators (could be automated in future)
Changes Made
New Components
-
src/components/badges/BadgeSection.tsx- Main collapsible badge container -
src/components/badges/BadgeGrid.tsx- Grid layout with earned/locked badges -
src/components/badges/BadgeCard.tsx- Individual badge display with progress -
src/components/badges/BadgeIcon.tsx- SVG badge icon renderer
Badge Assets (9 SVG files)
src/assets/badges/badge-1-first-step.svgsrc/assets/badges/badge-2-certified-volunteer.svgsrc/assets/badges/badge-3-consistent-volunteer.svgsrc/assets/badges/badge-4-on-a-roll.svgsrc/assets/badges/badge-5-century-contributor.svgsrc/assets/badges/badge-6-bronze-volunteer.svgsrc/assets/badges/badge-7-silver-volunteer.svgsrc/assets/badges/badge-8-gold-volunteer.svgsrc/assets/badges/badge-9-elite-volunteer.svg
API Integration
- Added 5 new badge API functions in
src/lib/api.ts:-
getMyBadges()- Fetch own badges -
getMyBadgeProgress()- Fetch own progress -
getUserBadges(userId)- Fetch user badges (coordinator/admin) -
getUserBadgeProgress(userId)- Fetch user progress -
evaluateUserBadges(userId)- Trigger badge evaluation
-
Type Definitions
- Added badge types in
src/types/api.ts:-
Badge- Earned badge structure -
BadgeResponse- API response for badges -
BadgeProgressItem- Progress tracking -
BadgeProgressResponse- API response for progress -
BadgeEvaluationResponse- Evaluation result
-
Integration Points
-
src/pages/profile/ProfilePage.tsx- Added BadgeSection to profiles -
src/pages/admin/StaffAttendancePage.tsx- Added badge query invalidation
Test Coverage
-
tests/unit/components/badges/BadgeSection.test.tsx(14 tests) -
tests/unit/components/badges/BadgeGrid.test.tsx(19 tests) -
tests/unit/components/badges/BadgeCard.test.tsx(10 tests) -
tests/unit/components/badges/BadgeIcon.test.tsx(6 tests) - Total: 49 tests, 100% statement coverage
Technical Details
Badge Progression System
First Step (1 visit) → Certified Volunteer (3) → Consistent Volunteer (5)
→ On a Roll (3 consecutive) → Bronze (6) → Century Contributor (10)
→ Silver (12) → Gold (20) → Elite (36)
Architecture Decisions
- Component Structure: Separated concerns into 4 components for reusability and testability
- State Management: Uses React Query for caching and automatic invalidation
-
Badge Icons: SVG assets loaded via Vite's
?urlimport for optimal bundling - Progress Tracking: Real-time progress bars with percentage calculations
- Permissions: Role-based evaluate button visibility (coordinator/admin only)
Data Flow
- User attends camp → Attendance marked
- Query invalidation triggers badge refetch
- BadgeSection fetches badges + progress from API
- BadgeGrid maps data to thresholdOrder for consistent display
- BadgeCard renders individual badges with locked/unlocked states
Type of Change
-
✨ New feature (non-breaking change that adds functionality) -
🎨 UI/UX improvement -
🧪 Test update
Related Issues / References
- Implements volunteer gamification feature
- Related to attendance tracking system
Screenshots or Screen Recordings
Badge Display Features
- Collapsible badge section on profile pages
- Visual distinction between earned (colored) and locked (grayscale) badges
- Progress bars showing completion percentage
- "Show more/less" toggle for locked badges
- Earned date display for unlocked badges
- Manual evaluation button for coordinators/admins
How to Set Up and Validate Locally
-
Pull this branch:
git checkout feat/volunteer-badges -
Install dependencies (if needed):
bun install -
Run development server:
bun dev -
Test badge display:
- Navigate to your profile:
http://localhost:5173/profile - Click on "Volunteer Badges" section to expand
- Verify earned badges show in color with dates
- Verify locked badges show in grayscale with progress
- Navigate to your profile:
-
Test badge evaluation (coordinator/admin only):
- Navigate to another user's profile
- Click "Evaluate" button in badge section
- Verify success toast appears
- Verify badges refresh automatically
-
Test attendance integration:
- Mark attendance at a camp
- Navigate to profile
- Verify badge progress updates
- Check if new badges are unlocked
Testing Done
-
Manual testing completed -
Unit tests added/updated
Test Cases Covered:
| Scenario | Expected Result | Status |
|---|---|---|
| Display earned badges | Shows colored badges with dates | |
| Display locked badges | Shows grayscale badges with progress | |
| Progress calculation | Correct percentage and remaining visits | |
| Expand/collapse section | Toggles badge visibility | |
| Evaluate badges (admin) | Triggers evaluation and refreshes | |
| Badge query invalidation | Updates after attendance marking | |
| Show more/less toggle | Expands/collapses locked badges | |
| Empty state | Shows default locked badges | |
| API error handling | Shows error toast | |
| Permission-based UI | Evaluate button only for coordinators |
Test Coverage:
- BadgeSection: 100% statements, 100% branches, 100% functions
- BadgeGrid: 100% statements, 92.59% branches, 100% functions
- BadgeCard: 100% statements, 100% branches, 100% functions
- BadgeIcon: 100% statements, 100% branches, 100% functions
Code Quality Checklist
Code Standards
-
Code follows project conventions (naming, structure, formatting) -
No console.log() or debugger statements left in code -
No unused imports, variables, or functions -
No duplicate code and use of existing components for reusability -
i18n check passed with no hardcoded strings in codebase for i18n support -
TypeScript types are properly defined (no anyunless justified) -
ESLint and Prettier checks pass
React Best Practices
-
Components are properly split and single-responsibility -
Hooks follow rules (no conditional hooks, proper dependencies) -
State management is appropriate (local vs global state) -
No unnecessary re-renders (memoization used where needed) -
Event handlers are properly cleaned up
Component Patterns
-
shadcn/ui components used correctly (Card, Button) -
Tailwind classes follow utility-first approach -
Responsive design considered (mobile-first with sm: breakpoints) -
Accessibility attributes included (aria-labels, roles) -
Icons from lucide-react used consistently (Award, Lock, CheckCircle, etc.)
API & Data Fetching
-
TanStack Query used for server state -
Loading and error states handled -
API types defined in src/types/api.ts -
Axios interceptors handle auth tokens correctly -
Query invalidation on attendance marking
Error Handling
-
Errors are caught and handled gracefully -
User-friendly error messages displayed -
Errors are being toasted properly (sonner) -
Network failures handled appropriately
Documentation
-
CHANGELOG.md updated -
BADGE_FEATURE_VERIFICATION.md created with complete workflow analysis -
Test documentation included
Known Limitations / Technical Debt
- Badge Evaluation: Currently manual for coordinators. Could be automated on attendance marking in future.
- Badge Assets: SVG files add ~50KB to bundle. Could optimize with sprite sheets if needed.
- Consecutive Tracking: "On a Roll" badge requires backend to track consecutive visits accurately.
- Real-time Updates: Relies on query invalidation. Could use WebSocket for instant updates.
Additional Notes
Design Decisions
- 9 Badge Levels: Balanced progression from 1 to 36 visits
- Collapsible UI: Saves space on profile pages
- Grayscale Locked Badges: Clear visual distinction between earned/locked
- Progress Bars: Motivate users to reach next milestone
- Manual Evaluation: Gives coordinators control over badge awarding
Future Enhancements
- Notification when new badge is earned
- Badge sharing on social media
- Leaderboard showing top volunteers
- Animated badge unlock transitions
- Badge details modal with achievement history
Dependencies
- No new npm packages added
- Uses existing lucide-react icons
- Leverages shadcn/ui Card and Button components
- Compatible with current TanStack Query setup
MR Acceptance Checklist
-
Code quality standards met -
Tests provide adequate coverage (100% statements) -
Documentation is complete -
No breaking changes introduced -
Performance impact is minimal -
Security considerations addressed (role-based permissions) -
Accessibility requirements met
Edited by Suma Pullaiahgari

