You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ManageHub has no PWA setup — members cannot install it to their home screen and receive no push notifications when the tab is closed. A PWA manifest and service worker turn the web app into an installable, push-capable experience.
Context
frontend/app/layout.tsx — root layout for adding manifest link and SW registration
frontend/public/ — location for manifest.json and sw.js
Depends on BE-50 for the push subscription endpoints and VAPID public key
Next.js 15 App Router — use next/metadata for manifest linking
Shown once after login if Notification.permission === 'default'
"Enable Notifications" button calls Notification.requestPermission(), then fetches VAPID public key from GET /notifications/push/vapid-public-key, subscribes via PushManager.subscribe(), and posts the subscription to POST /notifications/push/subscribe
"Not now" dismisses and stores push_dismissed = true in localStorage (do not show again for 7 days)
Add the banner to frontend/components/dashboard/DashboardLayout.tsx
Handle the case where the browser does not support push notifications gracefully (feature detection, no error thrown)
Overview
ManageHub has no PWA setup — members cannot install it to their home screen and receive no push notifications when the tab is closed. A PWA manifest and service worker turn the web app into an installable, push-capable experience.
Context
frontend/app/layout.tsx— root layout for adding manifest link and SW registrationfrontend/public/— location formanifest.jsonandsw.jsnext/metadatafor manifest linkingTasks
frontend/public/manifest.json:name,short_name,start_url,display: "standalone",theme_color,background_colorfrontend/public/icons/frontend/app/layout.tsxclient component vianavigator.serviceWorker.register('/sw.js')frontend/public/sw.js— handlespushevents and showsself.registration.showNotification(title, { body, icon, data: { url } }); clicking the notification navigates todata.urlfrontend/components/notifications/PushPermissionBanner.tsx:Notification.permission === 'default'Notification.requestPermission(), then fetches VAPID public key fromGET /notifications/push/vapid-public-key, subscribes viaPushManager.subscribe(), and posts the subscription toPOST /notifications/push/subscribepush_dismissed = truein localStorage (do not show again for 7 days)frontend/components/dashboard/DashboardLayout.tsxFiles to Modify / Create
frontend/public/manifest.jsonfrontend/public/sw.jsfrontend/public/icons/icon-192.png,icon-512.pngfrontend/components/notifications/PushPermissionBanner.tsxfrontend/app/layout.tsxfrontend/components/dashboard/DashboardLayout.tsx