import { defineStore } from "pinia"; // Global toast instance - will be set during app initialization let toastInstance = null; export const useNotificationStore = defineStore("notifications", { state: () => ({ // Configuration for PrimeVue Toast defaultLife: 4000, position: "top-right", }), getters: { // Helper to check if toast is available isToastAvailable: () => !!toastInstance, }, actions: { // Set the toast instance (called from main component) setToastInstance(toast) { toastInstance = toast; }, // Core method to show notifications using PrimeVue Toast addNotification(notification) { if (!toastInstance) { console.warn( "Toast instance not available. Make sure to call setToastInstance first.", ); return; } const toastMessage = { severity: this.mapTypesToSeverity(notification.type || "info"), summary: notification.title || this.getDefaultTitle(notification.type || "info"), detail: notification.message || "", life: notification.persistent ? 0 : (notification.duration ?? this.defaultLife), group: notification.group || "main", }; toastInstance.add(toastMessage); }, // Convenience methods for different types of notifications addSuccess(message, title = "Success", options = {}) { this.addNotification({ type: "success", title, message, ...options, }); }, addError(message, title = "Error", options = {}) { this.addNotification({ type: "error", title, message, duration: options.duration ?? 6000, // Errors stay longer by default ...options, }); }, addWarning(message, title = "Warning", options = {}) { this.addNotification({ type: "warn", title, message, ...options, }); }, addInfo(message, title = "Info", options = {}) { this.addNotification({ type: "info", title, message, ...options, }); }, // Show API operation notifications showApiSuccess(operation, message = null) { const defaultMessages = { create: "Item created successfully", update: "Item updated successfully", delete: "Item deleted successfully", fetch: "Data loaded successfully", }; this.addSuccess( message || defaultMessages[operation] || "Operation completed successfully", ); }, showApiError(operation, error, message = null) { const defaultMessages = { create: "Failed to create item", update: "Failed to update item", delete: "Failed to delete item", fetch: "Failed to load data", }; let errorMessage = message; if (!errorMessage) { if (typeof error === "string") { errorMessage = error; } else if (error?.response?.data?.message) { errorMessage = error.response.data.message; } else if (error?.message) { errorMessage = error.message; } else { errorMessage = defaultMessages[operation] || "Operation failed"; } } this.addError(errorMessage); }, // Configuration methods setPosition(position) { this.position = position; }, setDefaultLife(life) { this.defaultLife = life; }, // Clear all notifications clearAll() { if (toastInstance) { toastInstance.removeAllGroups(); } }, // Utility method for handling async operations with notifications async withNotifications(operation, asyncFunction, options = {}) { const { loadingMessage = "Processing...", successMessage = null, errorMessage = null, showLoading = true, } = options; try { if (showLoading) { this.addInfo(loadingMessage, "Loading", { persistent: true }); } const result = await asyncFunction(); if (successMessage !== false) { this.showApiSuccess(operation, successMessage); } return result; } catch (error) { this.showApiError(operation, error, errorMessage); throw error; } }, // Helper methods mapTypesToSeverity(type) { const mapping = { success: "success", error: "error", warn: "warn", warning: "warn", info: "info", }; return mapping[type] || "info"; }, getDefaultTitle(type) { const titles = { success: "Success", error: "Error", warn: "Warning", warning: "Warning", info: "Information", }; return titles[type] || "Notification"; }, }, });