diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 63a7601..3fb8f8f 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -156,6 +156,9 @@ + + + + + diff --git a/frontend/src/composables/useToast.js b/frontend/src/composables/useToast.js new file mode 100644 index 0000000..2ce7785 --- /dev/null +++ b/frontend/src/composables/useToast.js @@ -0,0 +1,64 @@ +import { ref, provide, inject } from 'vue'; + +const toasts = ref([]); +let toastId = 0; + +export function createToastSystem() { + const removeToast = (id) => { + const index = toasts.value.findIndex(t => t.id === id); + if (index !== -1) { + toasts.value.splice(index, 1); + } + }; + + const addToast = (options) => { + const id = ++toastId; + const toast = { + id, + message: options.message || '', + title: options.title || '', + type: options.type || 'info', + position: options.position || 'top-right', + duration: options.duration ?? 5000, + persistent: options.persistent || false, + action: options.action || null + }; + + toasts.value.push(toast); + + if (!toast.persistent && toast.duration > 0) { + setTimeout(() => removeToast(id), toast.duration); + } + + return id; + }; + + provide('toasts', toasts); + provide('removeToast', removeToast); + provide('addToast', addToast); + + return { + toasts, + addToast, + removeToast + }; +} + +export function useToast() { + const addToast = inject('addToast'); + const removeToast = inject('removeToast'); + + const toast = { + success: (message, options = {}) => addToast({ message, type: 'success', ...options }), + error: (message, options = {}) => addToast({ message, type: 'error', ...options }), + warning: (message, options = {}) => addToast({ message, type: 'warning', ...options }), + info: (message, options = {}) => addToast({ message, type: 'info', ...options }), + pwa: (message, options = {}) => addToast({ message, type: 'pwa', ...options }), + custom: (options) => addToast(options) + }; + + return { + toast, + removeToast + }; +}