Files
cat-sitting-planner/app/actions/booking.ts

128 lines
4.1 KiB
TypeScript

"use server"
import prisma from "@/lib/prisma"
import { revalidatePath } from "next/cache"
import { headers } from "next/headers"
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") {
const dict = await getDictionary(lang as any)
// Simple check to ensure no double booking on server side
const existing = await prisma.booking.findFirst({
where: {
planId,
date: date,
}
})
if (existing) {
throw new Error("Day is already booked")
}
const plan = await prisma.plan.findUnique({
where: { id: planId }
})
await prisma.booking.create({
data: {
planId,
date,
sitterName: name,
type
}
})
if (plan?.notifyAll) {
const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
const dateStr = date.toLocaleDateString(lang)
const message = type === "OWNER_HOME"
? dict.notifications.ownerHome.replace("{date}", dateStr).replace("{url}", planUrl)
: dict.notifications.newBooking.replace("{name}", name).replace("{date}", dateStr).replace("{url}", planUrl)
await sendPlanNotification(planId, message, plan.webhookUrl)
}
revalidatePath(`/${lang}/dashboard/${planId}`)
}
export async function deleteBooking(bookingId: number, planId: string, lang: string = "en", reason?: string) {
const dict = await getDictionary(lang as any)
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
include: { plan: true }
})
if (!booking) return
await prisma.booking.delete({
where: { id: bookingId }
})
if (booking.plan.notifyAll) {
const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
const dateStr = booking.date.toLocaleDateString(lang)
const messageDisplay = reason ? `\nMessage: ${reason}` : ""
const message = dict.notifications.cancellation
.replace("{name}", booking.sitterName || "Someone")
.replace("{date}", dateStr)
.replace("{url}", planUrl)
.replace("{message}", messageDisplay)
await sendPlanNotification(planId, message, booking.plan.webhookUrl)
}
revalidatePath(`/${lang}/dashboard/${planId}`)
}
export async function completeBooking(bookingId: number, planId: string, lang: string = "en", message?: string, imageUrl?: string) {
const dict = await getDictionary(lang as any)
const booking = await prisma.booking.findUnique({
where: { id: bookingId },
include: { plan: true }
})
if (!booking) return
await prisma.booking.update({
where: { id: bookingId },
data: {
completedAt: new Date(),
completionMessage: message,
completionImage: imageUrl
}
})
if (booking.plan.notifyAll) {
const host = (await headers()).get("host")
const protocol = host?.includes("localhost") ? "http" : "https"
const planUrl = `${protocol}://${host}/${lang}/dashboard/${planId}`
const dateStr = booking.date.toLocaleDateString(lang)
let notificationMessage = dict.notifications.completed
.replace("{name}", booking.sitterName || "Someone")
.replace("{date}", dateStr)
.replace("{url}", planUrl)
if (message) {
notificationMessage += `\n"${message}"`
}
// We need to pass the full URL for the image
const fullImageUrl = imageUrl ? `${protocol}://${host}${imageUrl}` : undefined
await sendPlanNotification(planId, notificationMessage, booking.plan.webhookUrl, fullImageUrl)
}
revalidatePath(`/${lang}/dashboard/${planId}`)
}