Implementation of "Notifications" Page (app/me/notifications)
Objective
Build a high-fidelity, real-time notification center that serves as the user's primary surface for staying informed about activity across the platform. The page should feel responsive and alive — notifications should arrive and update without requiring a page refresh, driven by the app's established polling logic. All read/unread state must remain in sync globally, so the sidebar badge always reflects accurate counts regardless of where the user navigates. This is not a static list — it is a living, interactive feed that respects the user's attention and time.
UI Description
Aesthetics & Design Intent
The notifications page should feel like a polished inbox — structured, calm, and easy to parse. The user should be able to triage their notifications quickly, with clear visual hierarchy separating what is new from what has already been seen. Interactions should be smooth and satisfying, with animations that reinforce state changes rather than feeling abrupt or mechanical.
Feed Layout & Grouping
- Organize all notifications into three distinct sections with clear visual separators between each group:
- New — unread notifications that have arrived since the user's last visit or last "mark all as read" action
- Earlier — previously seen notifications that are still within the active retention window
- Archived — older notifications that have been dismissed or aged out of the active feed
- Section headers should be typographically distinct — subdued but legible — so they guide the eye without competing with the notification content itself
- Empty states for each section should be handled gracefully with a brief, on-brand message rather than a blank space
Notification Interaction
- Clicking any notification item should open a
BoundlessSheet from @/components/sheet/ for immersive, full-detail reading
- The sheet must present the complete notification content and any associated metadata in a clean, readable layout
- The sheet should open with a smooth slide-in animation consistent with the app's motion language, and support keyboard dismissal (Escape key) and focus trapping for full accessibility
- Opening a notification via the sheet should automatically mark it as read and update the unread indicator in real time
"Mark All as Read" Action
- Include a prominent "Mark All as Read" button at the top of the feed, visible whenever unread notifications exist
- On activation, all unread indicators (dot badges, bold text, highlight backgrounds) should fade out smoothly using a Framer Motion transition — not disappear abruptly
- The button itself should become hidden or disabled once no unread notifications remain, with a graceful exit animation
- The action must update both the local feed state and the global
unreadCount in the session simultaneously to keep the sidebar badge in sync
Technical Details
Hooks & Data Path
Primary Hooks
- Use
useNotifications() to fetch and manage the current notification list, including read/unread status per item
- Use
useNotificationPolling() to establish the background polling interval that keeps the feed up to date without requiring manual refresh
Badge & Global State Sync
- The
unreadCount derived from the session must be synced globally to the sidebar notification badge at all times
- Implement this sync via either an
EventEmitter pattern or a shared context — the chosen approach must be consistent with how other global state is managed in the codebase
- Any action that changes read state (opening a notification, marking all as read) must immediately propagate the updated
unreadCount to the sidebar badge without requiring a full session refresh
- Avoid local-only state mutations that could cause the sidebar badge and the notification feed to fall out of sync
⚠️ Caution
This is a production environment — not a sandbox.
- Code must be performant, accessible, and clean
- No dummy data — all notification data must come from the established hooks and session; no hardcoded content or mock states
- AI-generated code will be scrutinized; poorly structured or "hallucinated" code will result in immediate issue closure
- Follow the existing design system: shadcn/ui, Tailwind, Framer Motion
Testing & Verification
Automated Tests
npm run lint # Ensure code quality
npm run build # Verify no breaking changes in routing or types
Manual Verification
Implementation of "Notifications" Page (
app/me/notifications)Objective
Build a high-fidelity, real-time notification center that serves as the user's primary surface for staying informed about activity across the platform. The page should feel responsive and alive — notifications should arrive and update without requiring a page refresh, driven by the app's established polling logic. All read/unread state must remain in sync globally, so the sidebar badge always reflects accurate counts regardless of where the user navigates. This is not a static list — it is a living, interactive feed that respects the user's attention and time.
UI Description
Aesthetics & Design Intent
The notifications page should feel like a polished inbox — structured, calm, and easy to parse. The user should be able to triage their notifications quickly, with clear visual hierarchy separating what is new from what has already been seen. Interactions should be smooth and satisfying, with animations that reinforce state changes rather than feeling abrupt or mechanical.
Feed Layout & Grouping
Notification Interaction
BoundlessSheetfrom@/components/sheet/for immersive, full-detail reading"Mark All as Read" Action
unreadCountin the session simultaneously to keep the sidebar badge in syncTechnical Details
Hooks & Data Path
Primary Hooks
useNotifications()to fetch and manage the current notification list, including read/unread status per itemuseNotificationPolling()to establish the background polling interval that keeps the feed up to date without requiring manual refreshBadge & Global State Sync
unreadCountderived from the session must be synced globally to the sidebar notification badge at all timesEventEmitterpattern or a shared context — the chosen approach must be consistent with how other global state is managed in the codebaseunreadCountto the sidebar badge without requiring a full session refreshTesting & Verification
Automated Tests
Manual Verification
useNotifications()correctly loads and renders the notification feed on page mountuseNotificationPolling()is active and new notifications appear in the feed without a manual page refreshBoundlessSheetopens with the correct full notification contentunreadCountupdates immediately after any read state change, without a full session refresh