// Custom service worker for push notifications // This will be merged with Workbox generated SW import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching' import { clientsClaim, skipWaiting } from 'workbox-core' // Precache and route static assets precacheAndRoute(self.__WB_MANIFEST) cleanupOutdatedCaches() // Take control of all pages immediately skipWaiting() clientsClaim() // Push notification event handler self.addEventListener('push', (event) => { console.log('Push event received:', event) let notificationData = { title: 'New Announcement', body: 'You have a new admin announcement', icon: '/pwa-192x192.png', badge: '/pwa-192x192.png', data: { url: '/', timestamp: Date.now() }, tag: 'admin-announcement', requireInteraction: true, actions: [ { action: 'view', title: 'View', icon: '/pwa-192x192.png' }, { action: 'dismiss', title: 'Dismiss' } ] } // Parse push data if available if (event.data) { try { const pushData = event.data.json() notificationData = { ...notificationData, ...pushData } } catch (error) { console.warn('Failed to parse push data:', error) // Use default notification data } } event.waitUntil( self.registration.showNotification(notificationData.title, notificationData) ) }) // Notification click handler self.addEventListener('notificationclick', (event) => { console.log('Notification clicked:', event) event.notification.close() const action = event.action const notificationData = event.notification.data || {} if (action === 'dismiss') { return // Just close the notification } // Default action or 'view' action - open the app const urlToOpen = notificationData.url || '/' event.waitUntil( clients.matchAll({ type: 'window', includeUncontrolled: true }) .then((clientList) => { // Try to find an existing window with the app for (const client of clientList) { if (client.url.includes(self.location.origin) && 'focus' in client) { client.focus() // Navigate to the notification URL if different if (client.url !== urlToOpen) { client.navigate(urlToOpen) } return } } // If no existing window, open a new one if (clients.openWindow) { return clients.openWindow(urlToOpen) } }) ) }) // Background sync for offline notification queue (future enhancement) self.addEventListener('sync', (event) => { if (event.tag === 'notification-queue') { event.waitUntil( // Process any queued notifications when back online console.log('Background sync: notification-queue') ) } }) // Message handler for communication with main app self.addEventListener('message', (event) => { console.log('Service worker received message:', event.data) if (event.data && event.data.type === 'SHOW_NOTIFICATION') { const { title, body, data } = event.data.payload self.registration.showNotification(title, { body, icon: '/pwa-192x192.png', badge: '/pwa-192x192.png', data, tag: 'manual-notification', requireInteraction: false }) } })