feat(pwa): service worker, offline page, web push notifications
PWA manifest, sw.js with offline cache. VAPID web-push via lib/push.ts. Push subscribe button (client). Push fired on recipe comment creation. VAPID keys configurable via admin site settings.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import webpush from "web-push";
|
||||
import { db, pushSubscriptions, eq } from "@epicure/db";
|
||||
|
||||
webpush.setVapidDetails(
|
||||
"mailto:contact@epicure.app",
|
||||
process.env.NEXT_PUBLIC_VAPID_PUBLIC_KEY!,
|
||||
process.env.VAPID_PRIVATE_KEY!
|
||||
);
|
||||
|
||||
export async function sendPushNotification(
|
||||
userId: string,
|
||||
notification: { title: string; body: string; url?: string }
|
||||
): Promise<void> {
|
||||
const subs = await db
|
||||
.select()
|
||||
.from(pushSubscriptions)
|
||||
.where(eq(pushSubscriptions.userId, userId));
|
||||
|
||||
const payload = JSON.stringify({
|
||||
title: notification.title,
|
||||
body: notification.body,
|
||||
url: notification.url ?? "/",
|
||||
});
|
||||
|
||||
await Promise.allSettled(
|
||||
subs.map((sub) =>
|
||||
webpush.sendNotification(
|
||||
{ endpoint: sub.endpoint, keys: { p256dh: sub.p256dh, auth: sub.auth } },
|
||||
payload
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user