import { NotificationType } from '../entities/notification.entity'; /** * Ou mene une notification. * * Une notification n'est pas un message : c'est un pointeur vers quelque chose * qui a change. Le lien est donc derive du type et des metadonnees, ici et nulle * part ailleurs — l'interface se contente de suivre. * * Les liens etaient jusqu'ici ecrits a la main a chaque appel, et deux d'entre * eux visaient des routes qui n'existent pas : `/bookings/{id}` (la vraie route * est `/dashboard/bookings/{id}`) et `/dashboard/admin/organizations` (l'espace * d'administration a depuis son propre segment `/admin`). Les regrouper permet * de les eprouver contre les routes reelles, en une seule fois. * * Les liens sont **relatifs et sans prefixe de langue** : le frontend est * localise (`/fr`, `/en`) et ajoute le sien. */ export function notificationTarget( type: NotificationType, metadata: Record | undefined ): string | null { const bookingId = asId(metadata?.bookingId); switch (type) { // Toutes les notifications de reservation menent au dossier concerne. case NotificationType.BOOKING_CREATED: case NotificationType.BOOKING_UPDATED: case NotificationType.BOOKING_CONFIRMED: case NotificationType.BOOKING_CANCELLED: case NotificationType.CSV_BOOKING_ACCEPTED: case NotificationType.CSV_BOOKING_REJECTED: case NotificationType.CSV_BOOKING_REQUEST_SENT: case NotificationType.DOCUMENT_UPLOADED: return bookingId ? `/dashboard/bookings/${bookingId}` : '/dashboard/bookings'; case NotificationType.RATE_QUOTE_EXPIRING: return '/dashboard/search-advanced'; case NotificationType.USER_INVITED: return '/dashboard/settings/users'; case NotificationType.ORGANIZATION_UPDATE: return '/dashboard/settings/organization'; // Une annonce ne pointe vers rien : la ligne ne doit pas se presenter comme // cliquable pour n'aboutir nulle part. case NotificationType.SYSTEM_ANNOUNCEMENT: return null; } } /** Un identifiant utilisable dans une URL, ou rien. */ function asId(value: unknown): string | null { if (typeof value !== 'string') return null; const trimmed = value.trim(); // Les metadonnees sont du JSON libre : refuser ce qui sortirait du segment. return trimmed && /^[A-Za-z0-9_-]{1,64}$/.test(trimmed) ? trimmed : null; }