mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 09:28:47 +02:00
Add budget module and push notifications for transactions
All checks were successful
Deploy to VPS / deploy (push) Successful in 34s
All checks were successful
Deploy to VPS / deploy (push) Successful in 34s
Budget: recurring items CRUD, yearly/monthly projections with no-double-count logic, and full UI (overview, monthly detail, recurring items manager). Push notifications: Web Push via VAPID keys, triggered on transaction creation from n8n. Includes service worker handlers, frontend subscription flow, and a test button on the Dashboard (temporary). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,6 +27,9 @@ self.addEventListener('fetch', (event) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only handle http(s) requests — skip chrome-extension:// etc.
|
||||
if (!url.protocol.startsWith('http')) return;
|
||||
|
||||
// Cache-first for static assets
|
||||
if (url.pathname.startsWith('/assets/')) {
|
||||
event.respondWith(
|
||||
@@ -50,3 +53,46 @@ self.addEventListener('fetch', (event) => {
|
||||
// Default: network with cache fallback
|
||||
event.respondWith(fetch(request).catch(() => caches.match(request)));
|
||||
});
|
||||
|
||||
// --- Push Notifications ---
|
||||
|
||||
self.addEventListener('push', (event) => {
|
||||
if (!event.data) return;
|
||||
|
||||
let data;
|
||||
try {
|
||||
data = event.data.json();
|
||||
} catch {
|
||||
// Fallback for plain-text pushes (e.g. browser test pushes)
|
||||
data = { title: 'WealthySmart', body: event.data.text() };
|
||||
}
|
||||
|
||||
const options = {
|
||||
body: data.body,
|
||||
icon: '/icons/icon-192.png',
|
||||
badge: '/icons/icon-192.png',
|
||||
data: { url: data.url || '/' },
|
||||
vibrate: [200, 100, 200],
|
||||
tag: 'transaction',
|
||||
renotify: true,
|
||||
};
|
||||
|
||||
event.waitUntil(self.registration.showNotification(data.title, options));
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', (event) => {
|
||||
event.notification.close();
|
||||
|
||||
const url = event.notification.data?.url || '/';
|
||||
event.waitUntil(
|
||||
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((windowClients) => {
|
||||
for (const client of windowClients) {
|
||||
if (client.url.includes(self.location.origin) && 'focus' in client) {
|
||||
client.navigate(url);
|
||||
return client.focus();
|
||||
}
|
||||
}
|
||||
return clients.openWindow(url);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user