import axios from 'axios'; import { API_CONFIG } from '../config/api'; export interface Notification { id: string; type: 'info' | 'warning' | 'success' | 'error'; titre: string; message: string; date: Date; lu: boolean; userId?: string; metadata?: { chantierId?: string; chantierNom?: string; clientId?: string; clientNom?: string; action?: string; }; } export interface NotificationStats { total: number; nonLues: number; parType: Record; tendance: { periode: string; nombre: number; }[]; } const api = axios.create({ baseURL: API_CONFIG.baseURL, timeout: API_CONFIG.timeout, headers: API_CONFIG.headers, }); // Interceptor pour ajouter le token api.interceptors.request.use((config) => { if (typeof window !== 'undefined') { const accessToken = localStorage.getItem('accessToken'); if (accessToken) { config.headers['Authorization'] = `Bearer ${accessToken}`; } } return config; }); class NotificationService { /** * Récupérer toutes les notifications */ async getNotifications(): Promise { try { const response = await api.get('/api/v1/notifications'); return response.data; } catch (error) { console.error('Erreur lors de la récupération des notifications:', error); return this.getMockNotifications(); } } /** * Récupérer les notifications non lues */ async getUnreadNotifications(): Promise { try { const response = await api.get('/api/v1/notifications/unread'); return response.data; } catch (error) { console.error('Erreur lors de la récupération des notifications non lues:', error); return this.getMockNotifications().filter(n => !n.lu); } } /** * Marquer une notification comme lue */ async markAsRead(notificationId: string): Promise { try { await api.put(`/api/v1/notifications/${notificationId}/read`); } catch (error) { console.error('Erreur lors du marquage de la notification comme lue:', error); } } /** * Marquer toutes les notifications comme lues */ async markAllAsRead(): Promise { try { await api.put('/api/v1/notifications/mark-all-read'); } catch (error) { console.error('Erreur lors du marquage de toutes les notifications comme lues:', error); } } /** * Créer une nouvelle notification */ async createNotification(notification: Omit): Promise { try { const response = await api.post('/api/v1/notifications', notification); return response.data; } catch (error) { console.error('Erreur lors de la création de la notification:', error); return { ...notification, id: Math.random().toString(36).substring(2, 11), date: new Date(), lu: false }; } } /** * Supprimer une notification */ async deleteNotification(notificationId: string): Promise { try { await api.delete(`/api/v1/notifications/${notificationId}`); } catch (error) { console.error('Erreur lors de la suppression de la notification:', error); } } /** * Récupérer les statistiques des notifications */ async getNotificationStats(): Promise { try { const response = await api.get('/api/v1/notifications/stats'); return response.data; } catch (error) { console.error('Erreur lors de la récupération des statistiques:', error); return this.getMockNotificationStats(); } } /** * Diffuser une notification à plusieurs utilisateurs */ async broadcastNotification(notification: { type: 'info' | 'warning' | 'success' | 'error'; titre: string; message: string; userIds?: string[]; roles?: string[]; }): Promise { try { await api.post('/api/v1/notifications/broadcast', notification); } catch (error) { console.error('Erreur lors de la diffusion de la notification:', error); } } /** * Notifications mockées */ private getMockNotifications(): Notification[] { return [ { id: '1', type: 'info', titre: 'Nouveau devis disponible', message: 'Le devis pour votre extension cuisine est maintenant disponible', date: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000), lu: false, metadata: { chantierId: 'chantier-1', chantierNom: 'Extension cuisine', action: 'devis_cree' } }, { id: '2', type: 'warning', titre: 'Rendez-vous prévu', message: 'Rendez-vous avec votre gestionnaire demain à 14h00', date: new Date(Date.now() - 24 * 60 * 60 * 1000), lu: false, metadata: { action: 'rendez_vous_planifie' } }, { id: '3', type: 'success', titre: 'Phase terminée', message: 'La phase "Gros œuvre" de votre chantier a été terminée', date: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), lu: true, metadata: { chantierId: 'chantier-2', chantierNom: 'Rénovation appartement', action: 'phase_terminee' } }, { id: '4', type: 'error', titre: 'Retard détecté', message: 'Le chantier "Villa moderne" accuse un retard de 3 jours', date: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000), lu: true, metadata: { chantierId: 'chantier-3', chantierNom: 'Villa moderne', action: 'retard_detecte' } }, { id: '5', type: 'info', titre: 'Nouveau client attribué', message: 'Vous avez été désigné gestionnaire pour M. Durand', date: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000), lu: true, metadata: { clientId: 'client-4', clientNom: 'M. Durand', action: 'client_attribue' } } ]; } /** * Statistiques mockées */ private getMockNotificationStats(): NotificationStats { const notifications = this.getMockNotifications(); return { total: notifications.length, nonLues: notifications.filter(n => !n.lu).length, parType: { info: notifications.filter(n => n.type === 'info').length, warning: notifications.filter(n => n.type === 'warning').length, success: notifications.filter(n => n.type === 'success').length, error: notifications.filter(n => n.type === 'error').length }, tendance: [ { periode: 'Lundi', nombre: 3 }, { periode: 'Mardi', nombre: 7 }, { periode: 'Mercredi', nombre: 2 }, { periode: 'Jeudi', nombre: 5 }, { periode: 'Vendredi', nombre: 4 }, { periode: 'Samedi', nombre: 1 }, { periode: 'Dimanche', nombre: 0 } ] }; } } export default new NotificationService();