import { defineStore } from 'pinia'; import { ref } from 'vue'; export type ToastKind = 'success' | 'error' | 'info'; export interface Toast { id: number; kind: ToastKind; message: string; timeout: number; } /** File de notifications éphémères. Aucun couplage : les vues appellent success/error/info. */ export const useToastsStore = defineStore('toasts', () => { const toasts = ref([]); let seq = 0; const timers = new Map>(); function dismiss(id: number): void { toasts.value = toasts.value.filter((t) => t.id !== id); const timer = timers.get(id); if (timer) { clearTimeout(timer); timers.delete(id); } } function push(kind: ToastKind, message: string, timeout = 4000): number { const id = ++seq; toasts.value = [...toasts.value, { id, kind, message, timeout }]; if (timeout > 0) timers.set(id, setTimeout(() => dismiss(id), timeout)); return id; } const success = (message: string): number => push('success', message); const info = (message: string): number => push('info', message); /** Normalise n'importe quelle erreur (ApiError/Error/inconnu) en message lisible. Sticky par défaut. */ function error(err: unknown, timeout = 0): number { const message = err instanceof Error ? err.message : String(err); return push('error', message, timeout); } return { toasts, push, success, info, error, dismiss }; });