Implementar sistema de toast con detección de PWA
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 27s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 27s
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.
This commit is contained in:
@@ -156,6 +156,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
<!-- Toast System -->
|
||||
<Toast position="top-center" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -168,6 +171,12 @@ import UserForm from './components/UserForm.vue';
|
||||
import RawDbViewer from './components/RawDbViewer.vue';
|
||||
import VlanForm from './components/VlanForm.vue';
|
||||
import DeviceForm from './components/DeviceForm.vue';
|
||||
import Toast from './components/Toast.vue';
|
||||
import { createToastSystem, useToast } from './composables/useToast.js';
|
||||
|
||||
// Initialize toast system
|
||||
createToastSystem();
|
||||
const { toast } = useToast();
|
||||
|
||||
const users = ref([]);
|
||||
const requests = ref([]);
|
||||
@@ -292,8 +301,74 @@ onMounted(async () => {
|
||||
await fetchRequests();
|
||||
setupSse();
|
||||
applyTheme();
|
||||
checkPWAStatus();
|
||||
});
|
||||
|
||||
// PWA Detection and Toast
|
||||
function checkPWAStatus() {
|
||||
// Don't show if already dismissed
|
||||
if (localStorage.getItem('pwa_toast_dismissed')) return;
|
||||
|
||||
// Check if running in standalone mode (PWA installed and active)
|
||||
const isStandalone = window.matchMedia('(display-mode: standalone)').matches ||
|
||||
window.navigator.standalone === true;
|
||||
|
||||
// If NOT in standalone mode, user is in browser
|
||||
if (!isStandalone) {
|
||||
// Check if PWA can be installed
|
||||
let deferredPrompt = null;
|
||||
|
||||
window.addEventListener('beforeinstallprompt', (e) => {
|
||||
e.preventDefault();
|
||||
deferredPrompt = e;
|
||||
|
||||
// Show install prompt
|
||||
setTimeout(() => {
|
||||
toast.pwa('Instala RADIUS Nucleo como aplicación para una mejor experiencia', {
|
||||
title: '📱 Instalar Aplicación',
|
||||
position: 'top-center',
|
||||
duration: 0, // Persistent
|
||||
persistent: true,
|
||||
action: {
|
||||
label: 'Instalar',
|
||||
handler: async () => {
|
||||
if (deferredPrompt) {
|
||||
deferredPrompt.prompt();
|
||||
const { outcome } = await deferredPrompt.userChoice;
|
||||
if (outcome === 'accepted') {
|
||||
localStorage.setItem('pwa_toast_dismissed', 'true');
|
||||
}
|
||||
deferredPrompt = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
});
|
||||
|
||||
// If already installed but not in standalone, prompt to open in app
|
||||
if ('getInstalledRelatedApps' in navigator) {
|
||||
navigator.getInstalledRelatedApps().then((apps) => {
|
||||
if (apps.length > 0) {
|
||||
setTimeout(() => {
|
||||
toast.pwa('Abre RADIUS Nucleo en la aplicación para una mejor experiencia', {
|
||||
title: '📱 Abrir en App',
|
||||
position: 'top-center',
|
||||
duration: 10000,
|
||||
action: {
|
||||
label: 'Entendido',
|
||||
handler: () => {
|
||||
localStorage.setItem('pwa_toast_dismissed', 'true');
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const filteredRequests = computed(() => {
|
||||
return requests.value.filter(ev => {
|
||||
if (eventFilters.type && ev.type !== eventFilters.type) return false;
|
||||
|
||||
Reference in New Issue
Block a user