Feat/broadcast
Here's the MR description filled out in the same template format:
Overview
This MR implements a real-time Notification System for the EHRS frontend, enabling authenticated users to receive live in-app notifications via Server-Sent Events (SSE). It also introduces an Admin Broadcast Panel allowing administrators to send announcements and email broadcasts to volunteers registered for the active medical camp.
What does this MR do and why?
Previously, the platform lacked any centralized mechanism for administrators to push real-time updates to volunteers, and users had no way to receive live in-app notifications. This MR addresses both gaps by implementing:
- A
NotificationBellcomponent integrated into the app header for all authenticated users - Real-time SSE-based notification delivery with unread badge tracking
- An admin-facing Broadcast Center for sending in-app and email notifications
- Full i18n support and automated test coverage
The implementation prioritizes reliability and extensibility, using SSE for live delivery, TanStack Query for async state, and a design that supports future integrations like Firebase Cloud Messaging (FCM).
Changes Made
New Components Added
NotificationBell.tsxBroadcastPage.tsx
API Integrations
- Added SSE stream integration:
GET /api/v1/notifications/stream?token=<auth_token>
- Added broadcast API integration:
POST /api/v1/medical-camps/broadcast
Routing
- Added admin route:
/admin/broadcast
Localization
- Added new i18n translation keys:
common.noNewNotificationscommon.clearAllcommon.realTimeBellNotificationcommon.broadcast.centercommon.in.app.push
Testing
- Added:
NotificationBell.test.tsxBroadcastPage.test.tsx- API payload validation coverage in
api.extended.test.ts
Technical Details
Notification Bell (NotificationBell.tsx)
- Rendered in the app header via
AppLayoutfor all authenticated users - Connects to SSE endpoint with auth token on mount; closes connection on unmount
- Handles:
- Auto-reconnection and ping keep-alive events
- Connection resiliency
- Displays:
- Animated unread count badge
- Scrollable dropdown with title, message, and timestamp per notification
- Marks all notifications as read when dropdown is opened
- Supports "Clear all" functionality and outside-click-to-close behavior
- Uses
useAuthfor authentication state and token;useTranslationfor i18n
Broadcast Center (BroadcastPage.tsx)
- Admin-only access protected via
<ProtectedRoute> - Dynamic broadcast form with:
- Title field
- Message body
- Delivery channel selection (in-app push / email)
- Form validation ensures required fields and at least one delivery channel selected
- Uses
broadcastNotificationAPI function withreact-querymutation handling - Displays loading states, success toasts, and error toasts
Type of Change
-
✨ New feature (non-breaking change that adds functionality) -
🎨 UI/UX improvement -
🧪 Test update
Related Issues / References
- Supports real-time volunteer notification workflow
- Related to admin communication enhancement
- closes #348
Screenshots or Screen Recordings
| Before | After |
|---|---|
| No notification system or broadcast mechanism | Real-time notification bell in header + Admin broadcast dashboard |
How to Set Up and Validate Locally
-
Pull this branch and install dependencies:
bun install -
Configure environment variables:
# .env VITE_SERVER_URL=http://localhost:8000 -
Ensure the backend FastAPI server is running with SSE support enabled.
-
Start the frontend:
bun dev -
To validate the Notification Bell:
- Log in as any authenticated user
- Observe the bell icon in the app header
- Trigger a broadcast from the admin panel and verify the badge updates live
- Open the dropdown to mark notifications as read; test "Clear all"
-
To validate the Broadcast Center, navigate to:
http://localhost:5173/admin/broadcast- Log in as admin
- Fill in the broadcast form and select delivery channels
- Submit and verify:
- Real-time notification delivery via bell
- Email dispatch behavior
- Success/error toasts
Testing Done
-
Manual testing completed -
Unit tests added/updated
Test Cases Covered
| Scenario | Expected Result | Status |
|---|---|---|
| Auth gating on NotificationBell | Returns null when not authenticated | |
| SSE connection establishment | Connects with token in URL on mount | |
| Notification reception | Bell badge updates on SSE message | |
| Dropdown toggle | Opens/closes notification list correctly | |
| Mark as read on open | Unread count clears when dropdown opens | |
| Clear all functionality | All notifications removed from state | |
| Outside click to close | Dropdown dismisses on outside click | |
| Unmount cleanup | SSE connection closed on unmount | |
| Broadcast form validation | Prevents invalid submissions | |
| Successful broadcast mutation | Toast success + API dispatch | |
| API payload validation | Request payload matches expected schema | |
| Coverage verification | Coverage remains above 90% |
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; existing components reused where applicable -
i18n check passed — no hardcoded strings in codebase -
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 and SSE connections are properly cleaned up
Component Patterns
-
shadcn/ui components used correctly -
Tailwind classes follow utility-first approach -
Responsive design considered -
Accessibility attributes included -
Icons from lucide-react used consistently
API & Data Fetching
-
TanStack Query used for server state -
Loading and error states handled -
API types defined appropriately -
Axios interceptors handle auth tokens correctly -
Zod used for data validations
Error Handling
-
Errors caught and handled gracefully -
User-friendly error messages displayed via toasts -
Network failures handled appropriately (SSE reconnection logic)
Documentation
-
.env.exampleupdated (if applicable)
Known Limitations / Technical Debt
- Real-time notification delivery depends on backend SSE endpoint availability.
- Email delivery reliability depends on the backend mail service configuration.
- Notification state is currently session-scoped on the frontend; persistence across sessions requires backend storage support.
Additional Notes
- Backend FastAPI SSE endpoint must remain active for real-time notifications to function.
-
VITE_SERVER_URLmust be correctly configured to point to the backend instance. - The
NotificationBellis designed to be extensible — future integrations such as Firebase Cloud Messaging (FCM) can be layered on top of the existing architecture.
MR Acceptance Checklist
Evaluate this MR against the GitLab MR acceptance checklist to ensure quality, maintainability, performance, and reliability standards are met.