From cba732fbca3a6b8479e243908ab2f2ce9ee12665 Mon Sep 17 00:00:00 2001 From: josedario87 Date: Fri, 17 Oct 2025 04:26:16 -0600 Subject: [PATCH] =?UTF-8?q?Implementar=20sistema=20de=20toast=20con=20dete?= =?UTF-8?q?cci=C3=B3n=20de=20PWA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cambios: - Crear componente Toast.vue con soporte para posiciones (top/bottom, left/center/right) - Crear composable useToast.js para manejar notificaciones - Integrar sistema de toast en App.vue - Implementar detección de PWA: * Detecta si el usuario está en modo standalone (PWA instalada) * Si puede instalar, muestra toast con botón de instalación * Si ya está instalada pero no se usa, sugiere abrir en app - Toast persistente hasta que el usuario interactúe - Soporte para tema claro/oscuro - Animaciones suaves y diseño moderno - Responsive para móviles El sistema permite mostrar toasts de tipo: success, error, warning, info, pwa con opciones de posición, duración, acciones personalizadas y modo persistente. --- frontend/src/App.vue | 75 +++++++ frontend/src/components/Toast.vue | 287 +++++++++++++++++++++++++++ frontend/src/composables/useToast.js | 64 ++++++ 3 files changed, 426 insertions(+) create mode 100644 frontend/src/components/Toast.vue create mode 100644 frontend/src/composables/useToast.js 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 + }; +}