// Progressive Web App functionality // Handles service worker registration and PWA features class PWAManager { constructor() { this.swRegistration = null; this.init(); } async init() { console.log('PWA: Initializing PWA Manager...'); if ('serviceWorker' in navigator) { try { this.swRegistration = await navigator.serviceWorker.register('/sw.js'); console.log('SW: Service Worker registered successfully'); // Listen for updates this.swRegistration.addEventListener('updatefound', () => { console.log('SW: New version available'); this.showUpdateNotification(); }); } catch (error) { console.log('SW: Service Worker registration failed:', error); } } // Setup PWA install prompt this.setupInstallPrompt(); // Setup notifications (if enabled) this.setupNotifications(); // Show manual install option after 3 seconds if no prompt appeared setTimeout(() => { if (!document.getElementById('pwa-install-btn')) { this.showManualInstallButton(); } }, 3000); } setupInstallPrompt() { let deferredPrompt; window.addEventListener('beforeinstallprompt', (e) => { console.log('PWA: beforeinstallprompt event fired'); // Prevent Chrome 67 and earlier from automatically showing the prompt e.preventDefault(); deferredPrompt = e; // Show custom install button this.showInstallButton(deferredPrompt); }); window.addEventListener('appinstalled', () => { console.log('PWA: App was installed'); this.hideInstallButton(); }); // Debug: Check if app is already installed if (this.isInstalled()) { console.log('PWA: App is already installed (standalone mode)'); } else { console.log('PWA: App is not installed, waiting for install prompt...'); } } showInstallButton(deferredPrompt) { // Create install button const installBtn = document.createElement('button'); installBtn.id = 'pwa-install-btn'; installBtn.className = 'btn btn-primary btn-sm'; installBtn.innerHTML = ' Install App'; installBtn.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 1000; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); `; installBtn.addEventListener('click', async () => { if (deferredPrompt) { deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; console.log('PWA: User response to install prompt:', outcome); deferredPrompt = null; this.hideInstallButton(); } }); document.body.appendChild(installBtn); } hideInstallButton() { const installBtn = document.getElementById('pwa-install-btn'); if (installBtn) { installBtn.remove(); } } showUpdateNotification() { // Show update available notification const notification = document.createElement('div'); notification.className = 'alert alert-info alert-dismissible'; notification.style.cssText = ` position: fixed; top: 20px; right: 20px; z-index: 1050; max-width: 300px; `; notification.innerHTML = ` Update Available!
A new version of the app is ready. `; document.body.appendChild(notification); // Handle update document.getElementById('update-btn').addEventListener('click', () => { if (this.swRegistration && this.swRegistration.waiting) { this.swRegistration.waiting.postMessage({ type: 'SKIP_WAITING' }); window.location.reload(); } }); } async setupNotifications() { // Check if notifications are supported and get permission if ('Notification' in window) { const permission = await this.requestNotificationPermission(); console.log('Notifications permission:', permission); } } async requestNotificationPermission() { if (Notification.permission === 'default') { // Only request permission when user interacts with a relevant feature // For now, just return the current status return Notification.permission; } return Notification.permission; } // Show notification (if permission granted) showNotification(title, options = {}) { if (Notification.permission === 'granted') { const notification = new Notification(title, { icon: '/icons/icon-192x192.png', badge: '/icons/icon-72x72.png', tag: 'littleshop-admin', ...options }); // Auto-close after 5 seconds setTimeout(() => { notification.close(); }, 5000); return notification; } } // Show manual install button for browsers that don't auto-prompt showManualInstallButton() { console.log('PWA: Showing manual install button'); const installBtn = document.createElement('button'); installBtn.id = 'pwa-install-btn'; installBtn.className = 'btn btn-primary btn-sm'; installBtn.innerHTML = ' Install as App'; installBtn.style.cssText = ` position: fixed; bottom: 20px; right: 20px; z-index: 1000; box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3); `; installBtn.addEventListener('click', () => { alert('To install this app:\\n\\n1. Click the browser menu (⋮)\\n2. Select "Install LittleShop Admin"\\n\\nOr look for the install icon in the address bar!'); }); document.body.appendChild(installBtn); } // Check if app is installed isInstalled() { return window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true; } } // Initialize PWA Manager const pwaManager = new PWAManager(); window.pwaManager = pwaManager; // Expose notification function globally window.showNotification = (title, options) => pwaManager.showNotification(title, options);