feat: implement pwa push notifications
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import prisma from "@/lib/prisma"
|
||||
import { revalidatePath } from "next/cache"
|
||||
import { headers } from "next/headers"
|
||||
import { sendNotification } from "@/lib/notifications"
|
||||
import { sendPlanNotification } from "@/lib/notifications"
|
||||
import { getDictionary } from "@/get-dictionary"
|
||||
|
||||
export async function createBooking(planId: string, date: Date, name: string, type: "SITTER" | "OWNER_HOME" = "SITTER", lang: string = "en") {
|
||||
@@ -34,7 +34,7 @@ export async function createBooking(planId: string, date: Date, name: string, ty
|
||||
}
|
||||
})
|
||||
|
||||
if (plan?.webhookUrl && plan.notifyAll) {
|
||||
if (plan?.notifyAll) {
|
||||
const host = (await headers()).get("host")
|
||||
const protocol = host?.includes("localhost") ? "http" : "https"
|
||||
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
|
||||
@@ -44,7 +44,7 @@ export async function createBooking(planId: string, date: Date, name: string, ty
|
||||
? dict.notifications.ownerHome.replace("{date}", dateStr).replace("{url}", planUrl)
|
||||
: dict.notifications.newBooking.replace("{name}", name).replace("{date}", dateStr).replace("{url}", planUrl)
|
||||
|
||||
await sendNotification(plan.webhookUrl, message)
|
||||
await sendPlanNotification(planId, message, plan.webhookUrl)
|
||||
}
|
||||
|
||||
revalidatePath(`/${lang}/dashboard/${planId}`)
|
||||
@@ -64,7 +64,7 @@ export async function deleteBooking(bookingId: number, planId: string, lang: str
|
||||
where: { id: bookingId }
|
||||
})
|
||||
|
||||
if (booking.plan.webhookUrl) {
|
||||
if (booking.plan.notifyAll) {
|
||||
const host = (await headers()).get("host")
|
||||
const protocol = host?.includes("localhost") ? "http" : "https"
|
||||
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
|
||||
@@ -77,7 +77,7 @@ export async function deleteBooking(bookingId: number, planId: string, lang: str
|
||||
.replace("{url}", planUrl)
|
||||
.replace("{message}", messageDisplay)
|
||||
|
||||
await sendNotification(booking.plan.webhookUrl, message)
|
||||
await sendPlanNotification(planId, message, booking.plan.webhookUrl)
|
||||
}
|
||||
|
||||
revalidatePath(`/${lang}/dashboard/${planId}`)
|
||||
@@ -98,7 +98,7 @@ export async function completeBooking(bookingId: number, planId: string, lang: s
|
||||
data: { completedAt: new Date() }
|
||||
})
|
||||
|
||||
if (booking.plan.webhookUrl) {
|
||||
if (booking.plan.notifyAll) {
|
||||
const host = (await headers()).get("host")
|
||||
const protocol = host?.includes("localhost") ? "http" : "https"
|
||||
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
|
||||
@@ -109,7 +109,7 @@ export async function completeBooking(bookingId: number, planId: string, lang: s
|
||||
.replace("{date}", dateStr)
|
||||
.replace("{url}", planUrl)
|
||||
|
||||
await sendNotification(booking.plan.webhookUrl, message)
|
||||
await sendPlanNotification(planId, message, booking.plan.webhookUrl)
|
||||
}
|
||||
|
||||
revalidatePath(`/${lang}/dashboard/${planId}`)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import prisma from "@/lib/prisma"
|
||||
import { revalidatePath } from "next/cache"
|
||||
import { headers } from "next/headers"
|
||||
import { sendNotification } from "@/lib/notifications"
|
||||
import { sendPlanNotification } from "@/lib/notifications"
|
||||
import { getDictionary } from "@/get-dictionary"
|
||||
|
||||
export async function updatePlan(
|
||||
@@ -34,14 +34,15 @@ export async function updatePlan(
|
||||
}
|
||||
})
|
||||
|
||||
if (data.instructions && plan.webhookUrl && plan.notifyAll) {
|
||||
if (data.instructions && plan.notifyAll) {
|
||||
const host = (await headers()).get("host")
|
||||
const protocol = host?.includes("localhost") ? "http" : "https"
|
||||
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
|
||||
|
||||
await sendNotification(
|
||||
plan.webhookUrl,
|
||||
dict.notifications.instructionsUpdated.replace("{url}", planUrl)
|
||||
await sendPlanNotification(
|
||||
planId,
|
||||
dict.notifications.instructionsUpdated.replace("{url}", planUrl),
|
||||
plan.webhookUrl
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
45
app/actions/subscription.ts
Normal file
45
app/actions/subscription.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
"use server";
|
||||
|
||||
import prisma from "@/lib/prisma";
|
||||
|
||||
export async function subscribeUser(planId: string, subscription: any) {
|
||||
if (!subscription || !subscription.endpoint || !subscription.keys) {
|
||||
throw new Error("Invalid subscription object");
|
||||
}
|
||||
|
||||
const { endpoint, keys: { p256dh, auth } } = subscription;
|
||||
|
||||
// Use upsert to handle updates gracefully
|
||||
// If endpoint exists, update the planId. A device follows the last plan logged into (or explicitly subscribed to).
|
||||
|
||||
// Check existence first to decide logic (or just upsert)
|
||||
// Actually, if we want to allow multiple plans per device, we need a different model.
|
||||
// For now, simple model: One device -> One Plan.
|
||||
|
||||
await prisma.pushSubscription.upsert({
|
||||
where: { endpoint },
|
||||
create: {
|
||||
planId,
|
||||
endpoint,
|
||||
p256dh,
|
||||
auth,
|
||||
},
|
||||
update: {
|
||||
planId,
|
||||
p256dh,
|
||||
auth,
|
||||
}
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function unsubscribeUser(endpoint: string) {
|
||||
if (!endpoint) return;
|
||||
|
||||
await prisma.pushSubscription.deleteMany({
|
||||
where: { endpoint },
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
Reference in New Issue
Block a user