0aecf5b41c
Remove influencer-specific features (campaigns, TikTok, gifts, shadow ledger, contracts, briefings) and consolidate into a clean ERP foundation with core bookkeeping, invoicing, receipts, tax reporting, and calendar functionality. Reorganize database migrations into a clean numbered sequence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
94 lines
2.2 KiB
JavaScript
94 lines
2.2 KiB
JavaScript
/**
|
|
* Service Worker for Push Notifications
|
|
* Handles incoming push notifications and notification click events
|
|
*/
|
|
|
|
// Handle push events
|
|
self.addEventListener('push', (event) => {
|
|
if (!event.data) {
|
|
console.log('Push event received but no data')
|
|
return
|
|
}
|
|
|
|
let payload
|
|
try {
|
|
payload = event.data.json()
|
|
} catch (e) {
|
|
console.error('Error parsing push data:', e)
|
|
return
|
|
}
|
|
|
|
const { title, body, icon, badge, tag, data, actions } = payload
|
|
|
|
const options = {
|
|
body: body || '',
|
|
icon: icon || '/icons/icon-192.png',
|
|
badge: badge || '/icons/badge-72.png',
|
|
tag: tag,
|
|
data: data || {},
|
|
actions: actions || [],
|
|
vibrate: [200, 100, 200],
|
|
requireInteraction: false,
|
|
}
|
|
|
|
event.waitUntil(
|
|
self.registration.showNotification(title || 'Ekonomi', options)
|
|
)
|
|
})
|
|
|
|
// Handle notification clicks
|
|
self.addEventListener('notificationclick', (event) => {
|
|
event.notification.close()
|
|
|
|
const action = event.action
|
|
const data = event.notification.data
|
|
|
|
// Determine URL to open
|
|
let url = '/'
|
|
|
|
if (action === 'view' && data?.url) {
|
|
url = data.url
|
|
} else if (action === 'dismiss') {
|
|
// Just close the notification
|
|
return
|
|
} else if (data?.url) {
|
|
// Default click goes to the data URL
|
|
url = data.url
|
|
}
|
|
|
|
event.waitUntil(
|
|
// Try to focus existing window, otherwise open new one
|
|
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((windowClients) => {
|
|
// Check if there's already a window we can focus
|
|
for (const client of windowClients) {
|
|
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
|
client.focus()
|
|
if ('navigate' in client) {
|
|
client.navigate(url)
|
|
}
|
|
return
|
|
}
|
|
}
|
|
// Otherwise open a new window
|
|
if (clients.openWindow) {
|
|
return clients.openWindow(url)
|
|
}
|
|
})
|
|
)
|
|
})
|
|
|
|
// Handle notification close (for analytics if needed)
|
|
self.addEventListener('notificationclose', (event) => {
|
|
console.log('Notification closed:', event.notification.tag)
|
|
})
|
|
|
|
// Service worker activation
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(clients.claim())
|
|
})
|
|
|
|
// Service worker install
|
|
self.addEventListener('install', (event) => {
|
|
self.skipWaiting()
|
|
})
|