326 lines
10 KiB
Markdown
326 lines
10 KiB
Markdown
# Améliorations du Système de Notifications
|
|
|
|
## 📋 Résumé
|
|
|
|
Ce document décrit les améliorations apportées au système de notifications de Xpeditis pour offrir une meilleure expérience utilisateur avec navigation contextuelle et vue détaillée.
|
|
|
|
## ✨ Nouvelles Fonctionnalités
|
|
|
|
### 1. **Redirection Contextuelle** 🔗
|
|
|
|
**Avant:**
|
|
- Cliquer sur une notification marquait seulement comme lue
|
|
- Pas de navigation vers le contenu lié
|
|
|
|
**Après:**
|
|
- Clic sur une notification redirige automatiquement vers le service/page lié via `actionUrl`
|
|
- Navigation intelligente basée sur le type de notification :
|
|
- Booking créé → `/bookings/{bookingId}`
|
|
- Booking confirmé → `/bookings/{bookingId}`
|
|
- Document uploadé → `/bookings/{bookingId}`
|
|
- CSV Booking → `/bookings/{bookingId}`
|
|
|
|
**Fichiers modifiés:**
|
|
- `apps/frontend/src/components/NotificationDropdown.tsx` (ligne 63-73)
|
|
|
|
```typescript
|
|
const handleNotificationClick = (notification: NotificationResponse) => {
|
|
if (!notification.read) {
|
|
markAsReadMutation.mutate(notification.id);
|
|
}
|
|
setIsOpen(false);
|
|
|
|
// Navigate to actionUrl if available
|
|
if (notification.actionUrl) {
|
|
window.location.href = notification.actionUrl;
|
|
}
|
|
};
|
|
```
|
|
|
|
### 2. **Panneau Latéral Détaillé** 📱
|
|
|
|
**Nouveau composant:** `NotificationPanel.tsx`
|
|
|
|
Un panneau latéral (sidebar) qui s'ouvre depuis la droite pour afficher toutes les notifications avec :
|
|
|
|
- **Filtres avancés** : All / Unread / Read
|
|
- **Pagination** : Navigation entre les pages de notifications
|
|
- **Actions individuelles** :
|
|
- Cliquer pour voir les détails et naviguer
|
|
- Supprimer une notification (icône poubelle au survol)
|
|
- Marquer comme lu automatiquement
|
|
- **Affichage enrichi** :
|
|
- Icônes par type de notification (📦, ✅, ❌, 📄, etc.)
|
|
- Badges de priorité (LOW, MEDIUM, HIGH, URGENT)
|
|
- Code couleur par priorité (bleu, jaune, orange, rouge)
|
|
- Timestamp relatif ("2h ago", "Just now", etc.)
|
|
- Métadonnées complètes
|
|
- **Bouton "Mark all as read"** pour les notifications non lues
|
|
- **Animation d'ouverture** fluide (slide-in from right)
|
|
|
|
**Caractéristiques techniques:**
|
|
- Responsive (max-width: 2xl)
|
|
- Overlay backdrop semi-transparent
|
|
- Pagination avec contrôles Previous/Next
|
|
- Query invalidation automatique pour refresh en temps réel
|
|
- Gestion d'erreurs avec confirmations
|
|
- Optimistic UI updates
|
|
|
|
**Fichier créé:**
|
|
- `apps/frontend/src/components/NotificationPanel.tsx` (348 lignes)
|
|
|
|
### 3. **Page Complète des Notifications** 📄
|
|
|
|
**Nouvelle route:** `/dashboard/notifications`
|
|
|
|
Page dédiée pour la gestion complète des notifications avec :
|
|
|
|
- **Header avec statistiques** :
|
|
- Nombre total de notifications
|
|
- Compteur de non lues
|
|
- Bouton "Mark all as read" global
|
|
- **Barre de filtres** :
|
|
- All / Unread / Read
|
|
- Affichage du nombre de non lues sur le filtre
|
|
- **Liste des notifications** :
|
|
- Affichage complet et détaillé
|
|
- Bordure de couleur à gauche selon la priorité
|
|
- Badge "NEW" pour les non lues
|
|
- Métadonnées complètes (type, priorité, timestamp)
|
|
- Bouton de suppression au survol
|
|
- Lien "View details" pour les notifications avec action
|
|
- **Pagination avancée** :
|
|
- Boutons Previous/Next
|
|
- Numéros de pages cliquables (jusqu'à 5 pages visibles)
|
|
- Affichage du total de notifications
|
|
- **États vides personnalisés** :
|
|
- Message pour "No notifications"
|
|
- Message spécial pour "You're all caught up!" (unread filter)
|
|
- **Loading states** avec spinner animé
|
|
|
|
**Fichier créé:**
|
|
- `apps/frontend/app/dashboard/notifications/page.tsx` (406 lignes)
|
|
|
|
### 4. **Intégration dans le Dropdown** 🔄
|
|
|
|
**Modifications:**
|
|
- Le bouton "View all notifications" ouvre désormais le panneau latéral au lieu de rediriger
|
|
- État `isPanelOpen` pour gérer l'ouverture du panneau
|
|
- Import du composant `NotificationPanel`
|
|
|
|
**Fichier modifié:**
|
|
- `apps/frontend/src/components/NotificationDropdown.tsx`
|
|
|
|
### 5. **Types TypeScript Améliorés** 📝
|
|
|
|
**Avant:**
|
|
```typescript
|
|
export type NotificationType = 'INFO' | 'WARNING' | 'ERROR' | 'SUCCESS';
|
|
|
|
export interface NotificationResponse {
|
|
id: string;
|
|
userId: string;
|
|
type: NotificationType;
|
|
title: string;
|
|
message: string;
|
|
read: boolean;
|
|
createdAt: string;
|
|
}
|
|
```
|
|
|
|
**Après:**
|
|
```typescript
|
|
export type NotificationType =
|
|
| 'booking_created'
|
|
| 'booking_updated'
|
|
| 'booking_cancelled'
|
|
| 'booking_confirmed'
|
|
| 'rate_quote_expiring'
|
|
| 'document_uploaded'
|
|
| 'system_announcement'
|
|
| 'user_invited'
|
|
| 'organization_update'
|
|
| 'csv_booking_accepted'
|
|
| 'csv_booking_rejected'
|
|
| 'csv_booking_request_sent';
|
|
|
|
export type NotificationPriority = 'low' | 'medium' | 'high' | 'urgent';
|
|
|
|
export interface NotificationResponse {
|
|
id: string;
|
|
type: NotificationType | string;
|
|
priority?: NotificationPriority;
|
|
title: string;
|
|
message: string;
|
|
metadata?: Record<string, any>;
|
|
read: boolean;
|
|
readAt?: string;
|
|
actionUrl?: string;
|
|
createdAt: string;
|
|
}
|
|
```
|
|
|
|
**Fichier modifié:**
|
|
- `apps/frontend/src/types/api.ts` (lignes 274-301)
|
|
|
|
### 6. **Corrections API** 🔧
|
|
|
|
**Problèmes corrigés:**
|
|
1. **Query parameter** : `isRead` → `read` (pour correspondre au backend)
|
|
2. **HTTP method** : `PATCH` → `POST` pour `/notifications/read-all`
|
|
|
|
**Fichier modifié:**
|
|
- `apps/frontend/src/lib/api/notifications.ts`
|
|
|
|
## 🎨 Design & UX
|
|
|
|
### Icônes par Type de Notification
|
|
|
|
| Type | Icône | Description |
|
|
|------|-------|-------------|
|
|
| `booking_created` | 📦 | Nouvelle réservation |
|
|
| `booking_updated` | 🔄 | Mise à jour de réservation |
|
|
| `booking_cancelled` | ❌ | Annulation |
|
|
| `booking_confirmed` | ✅ | Confirmation |
|
|
| `csv_booking_accepted` | ✅ | Acceptation CSV |
|
|
| `csv_booking_rejected` | ❌ | Rejet CSV |
|
|
| `csv_booking_request_sent` | 📧 | Demande envoyée |
|
|
| `rate_quote_expiring` | ⏰ | Devis expirant |
|
|
| `document_uploaded` | 📄 | Document uploadé |
|
|
| `system_announcement` | 📢 | Annonce système |
|
|
| `user_invited` | 👤 | Utilisateur invité |
|
|
| `organization_update` | 🏢 | Mise à jour organisation |
|
|
|
|
### Code Couleur par Priorité
|
|
|
|
- 🔴 **URGENT** : Rouge (border-red-500, bg-red-50)
|
|
- 🟠 **HIGH** : Orange (border-orange-500, bg-orange-50)
|
|
- 🟡 **MEDIUM** : Jaune (border-yellow-500, bg-yellow-50)
|
|
- 🔵 **LOW** : Bleu (border-blue-500, bg-blue-50)
|
|
|
|
### Format de Timestamp
|
|
|
|
- **< 1 min** : "Just now"
|
|
- **< 60 min** : "15m ago"
|
|
- **< 24h** : "3h ago"
|
|
- **< 7 jours** : "2d ago"
|
|
- **> 7 jours** : "Dec 15" ou "Dec 15, 2024"
|
|
|
|
## 📁 Structure des Fichiers
|
|
|
|
```
|
|
apps/frontend/
|
|
├── app/
|
|
│ └── dashboard/
|
|
│ └── notifications/
|
|
│ └── page.tsx # 🆕 Page complète
|
|
├── src/
|
|
│ ├── components/
|
|
│ │ ├── NotificationDropdown.tsx # ✏️ Modifié
|
|
│ │ └── NotificationPanel.tsx # 🆕 Nouveau panneau
|
|
│ ├── lib/
|
|
│ │ └── api/
|
|
│ │ └── notifications.ts # ✏️ Corrigé
|
|
│ └── types/
|
|
│ └── api.ts # ✏️ Types améliorés
|
|
```
|
|
|
|
## 🔄 Flux Utilisateur
|
|
|
|
### Scénario 1 : Clic sur notification dans le dropdown
|
|
1. Utilisateur clique sur la cloche 🔔
|
|
2. Dropdown s'ouvre avec les 10 dernières notifications non lues
|
|
3. Utilisateur clique sur une notification
|
|
4. ✅ Notification marquée comme lue
|
|
5. 🔗 Redirection vers la page du booking/document
|
|
6. Dropdown se ferme
|
|
|
|
### Scénario 2 : Ouverture du panneau latéral
|
|
1. Utilisateur clique sur la cloche 🔔
|
|
2. Dropdown s'ouvre
|
|
3. Utilisateur clique sur "View all notifications"
|
|
4. Dropdown se ferme
|
|
5. 📱 Panneau latéral s'ouvre (animation slide-in)
|
|
6. Affichage de toutes les notifications avec filtres et pagination
|
|
7. Utilisateur peut filtrer (All/Unread/Read)
|
|
8. Clic sur notification → redirection + panneau se ferme
|
|
9. Clic sur "X" ou backdrop → panneau se ferme
|
|
|
|
### Scénario 3 : Page complète
|
|
1. Utilisateur navigue vers `/dashboard/notifications`
|
|
2. Affichage de toutes les notifications avec pagination complète
|
|
3. Statistiques en header
|
|
4. Filtres + "Mark all as read"
|
|
5. Clic sur notification → redirection
|
|
|
|
## 🧪 Tests Recommandés
|
|
|
|
### Tests Fonctionnels
|
|
- [ ] Clic sur notification redirige vers la bonne page
|
|
- [ ] actionUrl null ne provoque pas d'erreur
|
|
- [ ] "Mark as read" fonctionne correctement
|
|
- [ ] "Mark all as read" marque toutes les notifications
|
|
- [ ] Suppression d'une notification
|
|
- [ ] Filtres (All/Unread/Read) fonctionnent
|
|
- [ ] Pagination (Previous/Next)
|
|
- [ ] Ouverture/Fermeture du panneau latéral
|
|
- [ ] Clic sur backdrop ferme le panneau
|
|
- [ ] Animation d'ouverture du panneau
|
|
|
|
### Tests d'Intégration
|
|
- [ ] Invalidation des queries après actions
|
|
- [ ] Refetch automatique toutes les 30s
|
|
- [ ] Synchronisation entre dropdown et panneau
|
|
- [ ] Navigation entre pages
|
|
- [ ] États de chargement
|
|
|
|
### Tests Visuels
|
|
- [ ] Responsive design (mobile, tablet, desktop)
|
|
- [ ] Icônes affichées correctement
|
|
- [ ] Code couleur par priorité
|
|
- [ ] Badges et indicateurs
|
|
- [ ] Animations fluides
|
|
|
|
## 🚀 Prochaines Améliorations Possibles
|
|
|
|
1. **WebSocket en temps réel** : Mise à jour automatique sans polling
|
|
2. **Notifications groupées** : Regrouper les notifications similaires
|
|
3. **Préférences utilisateur** : Activer/désactiver certains types
|
|
4. **Notifications push** : Notifications navigateur
|
|
5. **Recherche/Tri** : Rechercher dans les notifications
|
|
6. **Archivage** : Archiver les anciennes notifications
|
|
7. **Exportation** : Exporter en CSV/PDF
|
|
8. **Statistiques** : Dashboard des notifications
|
|
|
|
## 📝 Notes Techniques
|
|
|
|
### Backend (déjà existant)
|
|
- ✅ Entity avec `actionUrl` défini
|
|
- ✅ Service avec méthodes helper pour chaque type
|
|
- ✅ Controller avec tous les endpoints
|
|
- ✅ WebSocket Gateway pour temps réel
|
|
|
|
### Frontend (amélioré)
|
|
- ✅ Composants réactifs avec TanStack Query
|
|
- ✅ Types TypeScript complets
|
|
- ✅ API client corrigé
|
|
- ✅ Navigation contextuelle
|
|
- ✅ UI/UX professionnelle
|
|
|
|
## 🎯 Objectifs Atteints
|
|
|
|
- ✅ Redirection vers le service lié au clic
|
|
- ✅ Panneau latéral avec toutes les notifications
|
|
- ✅ Vue détaillée complète
|
|
- ✅ Filtres et pagination
|
|
- ✅ Actions (delete, mark as read)
|
|
- ✅ Design professionnel et responsive
|
|
- ✅ Types TypeScript complets
|
|
- ✅ API client corrigé
|
|
|
|
---
|
|
|
|
**Date de création** : 16 décembre 2024
|
|
**Version** : 1.0.0
|
|
**Auteur** : Claude Code
|