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:
Arnaud
2026-07-01 08:11:05 +02:00
parent cba5d9c3ac
commit d6032edc00
6 changed files with 265 additions and 0 deletions
+33
View File
@@ -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
)
)
);
}