Aller au contenu

Story CP-027: Notification UI (Bell, Unread Count, Offline Queuing)

Module: control-plane Slice: Slice 10b from architecture (split from CP-010) Brand context: [BOTH] Papillon HR Suite + ALTARYS ENTERPRISE HR Suite Priority: 10.1 Depends on: CP-010 Estimated complexity: S


Objective

Build the notification UI components: bell icon with unread count badge, notification dropdown, mark-as-read interactions, and offline notification queuing. These components integrate into the host shell header and consume the notification backend from CP-010.


Backend Scope

No new backend work. This story consumes the API endpoints defined in CP-010:

Method Path Response Auth
GET /api/v1/notifications Page Any authenticated
GET /api/v1/notifications/unread-count {count} Any authenticated
PATCH /api/v1/notifications/{id}/read 204 Any authenticated
PATCH /api/v1/notifications/read-all 204 Any authenticated

WebSocket subscription: /user/queue/notifications (STOMP over SockJS, configured in CP-010).


Frontend Scope

Pages & Routes

No dedicated notification page. Notifications appear in header bell icon — part of host shell.

Components

  • NotificationBell.tsx — Bell icon with unread count badge (integrates into host shell header). Connects to WebSocket for real-time updates.
  • NotificationDropdown.tsx — Dropdown panel showing recent notifications (most recent first). "Tout marquer comme lu" link at top.
  • NotificationItem.tsx — Single notification with read/unread styling. Tap → mark as read + navigate to relevant page.

UI States (ALL REQUIRED)

State Behavior French Copy
No unread Bell icon without badge
Unread Bell icon with red badge showing count
Loading Spinner in dropdown
Empty Message in dropdown "Aucune notification"
New notification Bell bounces briefly, badge count increments
Offline Queued notifications delivered on reconnect

Responsive Behavior

  • 360px (mobile): Bell in header. Dropdown takes full width. Notifications stacked vertically.
  • 1024px+ (desktop): Bell in header. Dropdown as floating panel, max-width 400px.

Interactions

  • Tap bell → dropdown with notification list (most recent first)
  • Tap notification → mark as read + navigate to relevant page
  • "Tout marquer comme lu" link at top of dropdown
  • WebSocket: new notifications appear in real-time without page refresh
  • Offline: notifications queued server-side, delivered on next WebSocket connect

Offline Queuing Behavior

When a user is offline when a notification is sent: 1. Server queues the notification (NotificationBroadcaster in CP-010) 2. On reconnect, WebSocket delivers all queued notifications 3. Bell badge updates to reflect total unread count 4. No notifications are lost

French micro-copy:

Key French Text
notifications.empty "Aucune notification"
notifications.mark_all_read "Tout marquer comme lu"

Acceptance Criteria

AC-109: Unread count
Given user has 3 unread notifications
When the bell icon renders
Then it shows a badge with "3"

AC-110: Mark as read
Given a notification is unread
When user clicks on it
Then it is marked as read and the unread count decreases

AC-111: Offline notification queuing
Given user "Aminata" is offline when a notification is sent
When Aminata comes back online
Then she receives the queued notification

OHADA & Regulatory Rules

No direct regulatory requirements for notification UI.


Standards & Conventions

  • docs/standards/react-typescript-guidelines.md — §WebSocket integration, §Header components
  • docs/standards/offline-sync-guidelines.md — §Offline queuing patterns

Testing Requirements

Unit Tests

  • NotificationBell: renders correct badge count (0, 1, 9, 99+)
  • NotificationDropdown: renders notification list sorted by date
  • NotificationItem: read vs unread styling

Integration Tests

  • Mark as read: click notification → PATCH called → badge decrements
  • Mark all as read: click "Tout marquer comme lu" → all marked → badge disappears
  • Offline queuing: disconnect → send notification → reconnect → notification appears

What QA Will Validate

  • Bell icon shows correct unread count
  • Notifications appear in real-time when online
  • Dropdown displays notifications correctly
  • "Tout marquer comme lu" works
  • Offline queuing: notifications received after reconnect

Out of Scope

  • Notification backend, templates, email delivery — CP-010
  • Notification preferences (opt out of specific types) — V2
  • Push notifications (mobile) — V2
  • Dedicated notification history page — V2

Definition of Done

  • [ ] All frontend components render correctly at 360px, 768px, 1024px
  • [ ] All 6 UI states implemented (no unread, unread, loading, empty, new notification, offline)
  • [ ] French micro-copy matches design spec exactly
  • [ ] All acceptance criteria pass manually
  • [ ] Unit tests written and passing
  • [ ] Integration tests written and passing
  • [ ] WebSocket real-time delivery verified
  • [ ] Offline queuing verified
  • [ ] No TypeScript any — all types explicit