From 199e82875baa5620db68f1b5bbe2839ccaf457ae Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 01:36:35 +0200 Subject: [PATCH 01/26] Initial concept for sending booking notifications to KM --- .../(app)/booking/create/+page.server.ts | 57 ++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 5696b30fc..aa9f60dae 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -5,6 +5,13 @@ import { redirect } from "$lib/utils/redirect"; import * as m from "$paraglide/messages"; import { bookingSchema } from "../schema"; import dayjs from "dayjs"; +import { + type Bookable, + type BookingRequest, + PrismaClient, +} from "@prisma/client"; +import sendNotification from "$lib/utils/notifications"; +import { NotificationType } from "$lib/utils/notifications/types"; export const load = async ({ locals }) => { const { prisma } = locals; @@ -26,6 +33,49 @@ export const load = async ({ locals }) => { return { bookables, bookingRequests, form }; }; +type BookingRequestWithBookables = BookingRequest & { + bookables: Bookable[]; +}; + +const sendNotificationToKM = async ( + bookingRequest: BookingRequestWithBookables, + prisma: PrismaClient, +) => { + console.log("notifications: finding kallarmastare"); + const kallarMastare = await prisma.member.findFirstOrThrow({ + where: { + mandates: { + some: { + positionId: "dsek.km.mastare", // Placeholder, don't know the actual id yet... + endDate: { + gte: new Date(), + }, + }, + }, + }, + }); + + const booker = await prisma.member.findUniqueOrThrow({ + where: { + id: bookingRequest.bookerId ?? undefined, + }, + }); + + const bookablesString = bookingRequest.bookables + .map((bookable) => bookable.name) + .join(", "); // Should be nameEn, perhaps? + + console.log("notifications: sending notification to km"); + await sendNotification({ + title: `Booking request: ${bookingRequest.event}`, + message: `${booker.firstName} ${booker.lastName} wants to book '${bookablesString}' from ${dayjs(bookingRequest.start).format("DD/MM HH:mm")} to ${dayjs(bookingRequest.end).format("DD/MM HH:mm")}.`, + type: NotificationType.BOOKING_REQUEST, + link: "/booking/admin", + memberIds: [kallarMastare.id], + }); + console.log("notifications: notification sent"); +}; + export const actions = { default: async (event) => { const { request, locals } = event; @@ -35,7 +85,7 @@ export const actions = { if (!form.valid) return fail(400, { form }); const { start, end, name, bookables } = form.data; - await prisma.bookingRequest.create({ + const createdRequest = await prisma.bookingRequest.create({ data: { bookerId: user?.memberId, start: new Date(start), @@ -48,8 +98,13 @@ export const actions = { }, status: "PENDING", }, + include: { + bookables: true, + }, }); + await sendNotificationToKM(createdRequest, prisma); + throw redirect( `/booking`, { From c0204adc98da8c47440515d134911409895cfb19 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 14:32:05 +0200 Subject: [PATCH 02/26] Removed unnecessary type --- src/routes/(app)/booking/create/+page.server.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index aa9f60dae..6b9f03a5d 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -33,12 +33,8 @@ export const load = async ({ locals }) => { return { bookables, bookingRequests, form }; }; -type BookingRequestWithBookables = BookingRequest & { - bookables: Bookable[]; -}; - const sendNotificationToKM = async ( - bookingRequest: BookingRequestWithBookables, + bookingRequest: BookingRequest & { bookables: Bookable[] }, prisma: PrismaClient, ) => { console.log("notifications: finding kallarmastare"); From dbfb5cea8aed7a9d3c23c7758f0059e25ebd15a9 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 14:36:24 +0200 Subject: [PATCH 03/26] Improved notification message --- src/routes/(app)/booking/create/+page.server.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 6b9f03a5d..33579c08f 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -58,13 +58,13 @@ const sendNotificationToKM = async ( }); const bookablesString = bookingRequest.bookables - .map((bookable) => bookable.name) - .join(", "); // Should be nameEn, perhaps? + .map((bookable) => bookable.name) // Should be nameEn, perhaps? + .join(", "); console.log("notifications: sending notification to km"); await sendNotification({ - title: `Booking request: ${bookingRequest.event}`, - message: `${booker.firstName} ${booker.lastName} wants to book '${bookablesString}' from ${dayjs(bookingRequest.start).format("DD/MM HH:mm")} to ${dayjs(bookingRequest.end).format("DD/MM HH:mm")}.`, + title: `New booking request: ${bookingRequest.event}`, + message: `${booker.firstName} ${booker.lastName} wants to book '${bookablesString}' from ${dayjs(bookingRequest.start).format("DD/MM HH:mm")} until ${dayjs(bookingRequest.end).format("DD/MM HH:mm")}.`, type: NotificationType.BOOKING_REQUEST, link: "/booking/admin", memberIds: [kallarMastare.id], From cdf17cf1122657975df107967a445b6f7cab796b Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 18:31:10 +0200 Subject: [PATCH 04/26] Fixed incorrect time when editing booking requests --- src/routes/(app)/booking/[id]/edit/+page.server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(app)/booking/[id]/edit/+page.server.ts b/src/routes/(app)/booking/[id]/edit/+page.server.ts index 2927a5114..467724316 100644 --- a/src/routes/(app)/booking/[id]/edit/+page.server.ts +++ b/src/routes/(app)/booking/[id]/edit/+page.server.ts @@ -24,10 +24,10 @@ export const load = async ({ locals, params }) => { const initialData = { name: bookingRequest.event ?? undefined, start: bookingRequest.start - ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:MM") + ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:mm") : undefined, end: bookingRequest.end - ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:MM") + ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:mm") : undefined, bookables: bookingRequest.bookables?.map((bookable) => bookable.id), }; From 4655e6f9d88794af3daa67109f18fccbeb360b56 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 20:08:14 +0200 Subject: [PATCH 05/26] Added new page for accepting/denying booking requests and linked notifications there --- .../booking/admin/BookingInspector.svelte | 167 ++++++++++++++++++ .../(app)/booking/admin/[id]/+page.server.ts | 148 ++++++++++++++++ .../(app)/booking/admin/[id]/+page.svelte | 25 +++ .../(app)/booking/create/+page.server.ts | 2 +- 4 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 src/routes/(app)/booking/admin/BookingInspector.svelte create mode 100644 src/routes/(app)/booking/admin/[id]/+page.server.ts create mode 100644 src/routes/(app)/booking/admin/[id]/+page.svelte diff --git a/src/routes/(app)/booking/admin/BookingInspector.svelte b/src/routes/(app)/booking/admin/BookingInspector.svelte new file mode 100644 index 000000000..559b42f89 --- /dev/null +++ b/src/routes/(app)/booking/admin/BookingInspector.svelte @@ -0,0 +1,167 @@ + + +
+
+ +
+ {#if bookingRequest.status === "ACCEPTED"} +
+ {m.booking_accepted()} +
+ {:else if bookingRequest.status === "DENIED"} +
+ {m.booking_denied()} +
+ {:else if bookingRequest.status === "PENDING"} +
+ {m.booking_pending()} +
+ {/if} + + {#if conflict} +
+
+ {m.booking_conflict()} +
+
+ {/if} +
+
+
0} + > + {m.booking_booking()} + {#each data.bookables as bookable} + + {/each} +
+ + + + + + + +
+ + + +
+
diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts new file mode 100644 index 000000000..6ef240881 --- /dev/null +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -0,0 +1,148 @@ +import * as m from "$paraglide/messages"; +import { error } from "@sveltejs/kit"; +import dayjs from "dayjs"; +import { superValidate } from "sveltekit-superforms/server"; +import { zod } from "sveltekit-superforms/adapters"; +import { bookingSchema } from "../../schema"; +import { authorize } from "$lib/utils/authorization"; +import apiNames from "$lib/utils/apiNames"; +import type { Actions } from "./$types"; +import sendNotification from "$lib/utils/notifications"; +import { NotificationType } from "$lib/utils/notifications/types"; + +export const load = async ({ locals, params }) => { + const { prisma, user } = locals; + authorize(apiNames.BOOKINGS.UPDATE, user); + const bookables = await prisma.bookable.findMany(); + + const allBookingRequests = await prisma.bookingRequest.findMany({ + include: { + bookables: true, + }, + }); + + const allBookingRequestsWeekly = await prisma.bookingRequest.findMany({ + where: { + end: { + gte: dayjs().subtract(1, "week").toDate(), + }, + }, + orderBy: [{ start: "asc" }, { end: "asc" }, { status: "asc" }], + include: { + bookables: true, + booker: true, + }, + }); + + const bookingRequest = await prisma.bookingRequest.findUnique({ + where: { + id: params.id, + }, + include: { + bookables: true, + }, + }); + + if (!bookingRequest) { + throw error(404, m.booking_errors_notFound()); + } + + const initialData = { + name: bookingRequest.event ?? undefined, + start: bookingRequest.start + ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:mm") + : undefined, + end: bookingRequest.end + ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:mm") + : undefined, + bookables: bookingRequest.bookables?.map((bookable) => bookable.id), + }; + const form = await superValidate(initialData, zod(bookingSchema)); + + return { + bookables, + form, + booking: bookingRequest, + allBookingRequests, + bookingRequests: allBookingRequestsWeekly, + }; +}; + +export const actions: Actions = { + accept: async (event) => { + const { request, locals } = event; + const { prisma, user } = locals; + const formData = await request.formData(); + const id = formData.get("id"); + + if (id && typeof id === "string") { + await prisma.bookingRequest.update({ + where: { + id, + }, + data: { + status: "ACCEPTED", + }, + }); + + const request = await prisma.bookingRequest.findFirst({ + where: { + id, + }, + select: { + bookerId: true, + event: true, + }, + }); + + if (request && request.bookerId != null && user && user.memberId) { + sendNotification({ + title: "Booking request accepted", + message: `Your booking request for ${request.event} has been accepted`, + type: NotificationType.BOOKING_REQUEST, + link: `/booking`, + memberIds: [request.bookerId], + fromMemberId: user.memberId, + }); + } + } + }, + reject: async (event) => { + const { request, locals } = event; + const { prisma, user } = locals; + const formData = await request.formData(); + const id = formData.get("id"); + + if (id && typeof id === "string") { + await prisma.bookingRequest.update({ + where: { + id, + }, + data: { + status: "DENIED", + }, + }); + + const request = await prisma.bookingRequest.findFirst({ + where: { + id, + }, + select: { + bookerId: true, + event: true, + }, + }); + + if (request && request.bookerId != null && user && user.memberId) { + sendNotification({ + title: "Booking request denied", + message: `Your booking request for ${request.event} has been denied`, + type: NotificationType.BOOKING_REQUEST, + link: `/booking`, + memberIds: [request.bookerId], + fromMemberId: user.memberId, + }); + } + } + }, +}; diff --git a/src/routes/(app)/booking/admin/[id]/+page.svelte b/src/routes/(app)/booking/admin/[id]/+page.svelte new file mode 100644 index 000000000..d304e7db3 --- /dev/null +++ b/src/routes/(app)/booking/admin/[id]/+page.svelte @@ -0,0 +1,25 @@ + + + + +{#if !isAdmin} + +{/if} + + + + diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 33579c08f..65f7eb69b 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -66,7 +66,7 @@ const sendNotificationToKM = async ( title: `New booking request: ${bookingRequest.event}`, message: `${booker.firstName} ${booker.lastName} wants to book '${bookablesString}' from ${dayjs(bookingRequest.start).format("DD/MM HH:mm")} until ${dayjs(bookingRequest.end).format("DD/MM HH:mm")}.`, type: NotificationType.BOOKING_REQUEST, - link: "/booking/admin", + link: `/booking/admin/${bookingRequest.id}`, memberIds: [kallarMastare.id], }); console.log("notifications: notification sent"); From 2883d5f3bea40b0b1d7d3524f346835b03d2ea6d Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 20:30:32 +0200 Subject: [PATCH 06/26] Refactored identical code for accepting/rejecting booking requests to sharedActions.ts --- .../(app)/booking/admin/+page.server.ts | 74 +---------------- .../(app)/booking/admin/[id]/+page.server.ts | 83 +------------------ .../(app)/booking/admin/sharedActions.ts | 83 +++++++++++++++++++ 3 files changed, 88 insertions(+), 152 deletions(-) create mode 100644 src/routes/(app)/booking/admin/sharedActions.ts diff --git a/src/routes/(app)/booking/admin/+page.server.ts b/src/routes/(app)/booking/admin/+page.server.ts index 1885ea050..07a9bb2ec 100644 --- a/src/routes/(app)/booking/admin/+page.server.ts +++ b/src/routes/(app)/booking/admin/+page.server.ts @@ -1,9 +1,8 @@ import apiNames from "$lib/utils/apiNames"; import { authorize } from "$lib/utils/authorization"; -import sendNotification from "$lib/utils/notifications"; -import { NotificationType } from "$lib/utils/notifications/types"; import dayjs from "dayjs"; -import type { Actions, PageServerLoad } from "./$types"; +import type { PageServerLoad } from "./$types"; +import { actions } from "./sharedActions"; export const load: PageServerLoad = async ({ locals }) => { const { prisma, user } = locals; @@ -24,71 +23,4 @@ export const load: PageServerLoad = async ({ locals }) => { return { bookingRequests }; }; -export const actions: Actions = { - accept: async (event) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { id }, - data: { - status: "ACCEPTED", - }, - }); - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request accepted", - message: `Your booking request for ${request.event} has been accepted`, - type: NotificationType.BOOKING_REQUEST, - link: "/booking", - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } - } - }, - reject: async (event) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { id }, - data: { - status: "DENIED", - }, - }); - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request denied", - message: `Your booking request for ${request.event} has been denied`, - type: NotificationType.BOOKING_REQUEST, - link: "/booking", - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } - } - }, -}; +export { actions }; diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index 6ef240881..b83eddb4a 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -6,9 +6,7 @@ import { zod } from "sveltekit-superforms/adapters"; import { bookingSchema } from "../../schema"; import { authorize } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; -import type { Actions } from "./$types"; -import sendNotification from "$lib/utils/notifications"; -import { NotificationType } from "$lib/utils/notifications/types"; +import { actions } from "../sharedActions"; export const load = async ({ locals, params }) => { const { prisma, user } = locals; @@ -68,81 +66,4 @@ export const load = async ({ locals, params }) => { }; }; -export const actions: Actions = { - accept: async (event) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); - - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { - id, - }, - data: { - status: "ACCEPTED", - }, - }); - - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); - - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request accepted", - message: `Your booking request for ${request.event} has been accepted`, - type: NotificationType.BOOKING_REQUEST, - link: `/booking`, - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } - } - }, - reject: async (event) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); - - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { - id, - }, - data: { - status: "DENIED", - }, - }); - - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); - - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request denied", - message: `Your booking request for ${request.event} has been denied`, - type: NotificationType.BOOKING_REQUEST, - link: `/booking`, - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } - } - }, -}; +export { actions }; diff --git a/src/routes/(app)/booking/admin/sharedActions.ts b/src/routes/(app)/booking/admin/sharedActions.ts new file mode 100644 index 000000000..2c8e8a39e --- /dev/null +++ b/src/routes/(app)/booking/admin/sharedActions.ts @@ -0,0 +1,83 @@ +import sendNotification from "$lib/utils/notifications"; +import { NotificationType } from "$lib/utils/notifications/types"; +import type { RequestEvent } from "@sveltejs/kit"; +import type { Actions } from "./$types"; + +export const actions: Actions = { + accept: async (event: RequestEvent) => { + const { request, locals } = event; + const { prisma, user } = locals; + const formData = await request.formData(); + const id = formData.get("id"); + + if (id && typeof id === "string") { + await prisma.bookingRequest.update({ + where: { + id, + }, + data: { + status: "ACCEPTED", + }, + }); + + const request = await prisma.bookingRequest.findFirst({ + where: { + id, + }, + select: { + bookerId: true, + event: true, + }, + }); + + if (request && request.bookerId != null && user && user.memberId) { + sendNotification({ + title: "Booking request accepted", + message: `Your booking request for ${request.event} has been accepted`, + type: NotificationType.BOOKING_REQUEST, + link: `/booking`, + memberIds: [request.bookerId], + fromMemberId: user.memberId, + }); + } + } + }, + reject: async (event: RequestEvent) => { + const { request, locals } = event; + const { prisma, user } = locals; + const formData = await request.formData(); + const id = formData.get("id"); + + if (id && typeof id === "string") { + await prisma.bookingRequest.update({ + where: { + id, + }, + data: { + status: "DENIED", + }, + }); + + const request = await prisma.bookingRequest.findFirst({ + where: { + id, + }, + select: { + bookerId: true, + event: true, + }, + }); + + if (request && request.bookerId != null && user && user.memberId) { + sendNotification({ + title: "Booking request denied", + message: `Your booking request for ${request.event} has been denied`, + type: NotificationType.BOOKING_REQUEST, + link: `/booking`, + memberIds: [request.bookerId], + fromMemberId: user.memberId, + }); + } + } + }, +}; From b286838251ac8e69bf3915def93303f169ad23da Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 20:38:13 +0200 Subject: [PATCH 07/26] Refactored code for handling accept/reject actions into one function --- .../(app)/booking/admin/sharedActions.ts | 110 +++++++----------- 1 file changed, 40 insertions(+), 70 deletions(-) diff --git a/src/routes/(app)/booking/admin/sharedActions.ts b/src/routes/(app)/booking/admin/sharedActions.ts index 2c8e8a39e..cd260b15b 100644 --- a/src/routes/(app)/booking/admin/sharedActions.ts +++ b/src/routes/(app)/booking/admin/sharedActions.ts @@ -5,79 +5,49 @@ import type { Actions } from "./$types"; export const actions: Actions = { accept: async (event: RequestEvent) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); - - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { - id, - }, - data: { - status: "ACCEPTED", - }, - }); - - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); - - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request accepted", - message: `Your booking request for ${request.event} has been accepted`, - type: NotificationType.BOOKING_REQUEST, - link: `/booking`, - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } - } + await performAction(event, true) }, reject: async (event: RequestEvent) => { - const { request, locals } = event; - const { prisma, user } = locals; - const formData = await request.formData(); - const id = formData.get("id"); + await performAction(event, false) + }, +}; - if (id && typeof id === "string") { - await prisma.bookingRequest.update({ - where: { - id, - }, - data: { - status: "DENIED", - }, - }); +async function performAction(event: RequestEvent, accepted: boolean) { + const { request, locals } = event; + const { prisma, user } = locals; + const formData = await request.formData(); + const id = formData.get("id"); + const status = accepted ? "ACCEPTED" : "DENIED" - const request = await prisma.bookingRequest.findFirst({ - where: { - id, - }, - select: { - bookerId: true, - event: true, - }, - }); + if (id && typeof id === "string") { + await prisma.bookingRequest.update({ + where: { + id, + }, + data: { + status, + }, + }); + + const request = await prisma.bookingRequest.findFirst({ + where: { + id, + }, + select: { + bookerId: true, + event: true, + }, + }); - if (request && request.bookerId != null && user && user.memberId) { - sendNotification({ - title: "Booking request denied", - message: `Your booking request for ${request.event} has been denied`, - type: NotificationType.BOOKING_REQUEST, - link: `/booking`, - memberIds: [request.bookerId], - fromMemberId: user.memberId, - }); - } + if (request && request.bookerId != null && user && user.memberId) { + sendNotification({ + title: `Booking request ${status.toLowerCase()}`, + message: `Your booking request for ${request.event} has been ${status.toLowerCase()}`, + type: NotificationType.BOOKING_REQUEST, + link: `/booking`, + memberIds: [request.bookerId], + fromMemberId: user.memberId, + }); } - }, -}; + } +} From 4cf859a3ef398e0602e8ff70b450368409eaa38e Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 20:55:07 +0200 Subject: [PATCH 08/26] Refactored code for getting weekly booking requests --- src/routes/(app)/booking/admin/+page.server.ts | 17 +++-------------- .../(app)/booking/admin/[id]/+page.server.ts | 17 ++--------------- .../admin/{sharedActions.ts => sharedUtils.ts} | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 29 deletions(-) rename src/routes/(app)/booking/admin/{sharedActions.ts => sharedUtils.ts} (77%) diff --git a/src/routes/(app)/booking/admin/+page.server.ts b/src/routes/(app)/booking/admin/+page.server.ts index 07a9bb2ec..c3d14291c 100644 --- a/src/routes/(app)/booking/admin/+page.server.ts +++ b/src/routes/(app)/booking/admin/+page.server.ts @@ -1,25 +1,14 @@ import apiNames from "$lib/utils/apiNames"; import { authorize } from "$lib/utils/authorization"; -import dayjs from "dayjs"; import type { PageServerLoad } from "./$types"; -import { actions } from "./sharedActions"; +import { actions, getAllBookingRequestsWeekly } from "./sharedUtils"; export const load: PageServerLoad = async ({ locals }) => { const { prisma, user } = locals; authorize(apiNames.BOOKINGS.UPDATE, user); - const bookingRequests = await prisma.bookingRequest.findMany({ - where: { - start: { - gte: dayjs().subtract(1, "week").toDate(), - }, - }, - orderBy: [{ start: "asc" }, { end: "asc" }, { status: "asc" }], - include: { - bookables: true, - booker: true, - }, - }); + const bookingRequests = await getAllBookingRequestsWeekly(prisma) + return { bookingRequests }; }; diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index b83eddb4a..e57c07918 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -6,7 +6,7 @@ import { zod } from "sveltekit-superforms/adapters"; import { bookingSchema } from "../../schema"; import { authorize } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; -import { actions } from "../sharedActions"; +import { actions, getAllBookingRequestsWeekly } from "../sharedUtils"; export const load = async ({ locals, params }) => { const { prisma, user } = locals; @@ -19,19 +19,6 @@ export const load = async ({ locals, params }) => { }, }); - const allBookingRequestsWeekly = await prisma.bookingRequest.findMany({ - where: { - end: { - gte: dayjs().subtract(1, "week").toDate(), - }, - }, - orderBy: [{ start: "asc" }, { end: "asc" }, { status: "asc" }], - include: { - bookables: true, - booker: true, - }, - }); - const bookingRequest = await prisma.bookingRequest.findUnique({ where: { id: params.id, @@ -62,7 +49,7 @@ export const load = async ({ locals, params }) => { form, booking: bookingRequest, allBookingRequests, - bookingRequests: allBookingRequestsWeekly, + bookingRequests: await getAllBookingRequestsWeekly(prisma), }; }; diff --git a/src/routes/(app)/booking/admin/sharedActions.ts b/src/routes/(app)/booking/admin/sharedUtils.ts similarity index 77% rename from src/routes/(app)/booking/admin/sharedActions.ts rename to src/routes/(app)/booking/admin/sharedUtils.ts index cd260b15b..b2381e49f 100644 --- a/src/routes/(app)/booking/admin/sharedActions.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -2,6 +2,8 @@ import sendNotification from "$lib/utils/notifications"; import { NotificationType } from "$lib/utils/notifications/types"; import type { RequestEvent } from "@sveltejs/kit"; import type { Actions } from "./$types"; +import dayjs from "dayjs"; +import { PrismaClient } from "@prisma/client"; export const actions: Actions = { accept: async (event: RequestEvent) => { @@ -12,6 +14,21 @@ export const actions: Actions = { }, }; +export async function getAllBookingRequestsWeekly(prisma: PrismaClient) { + return await prisma.bookingRequest.findMany({ + where: { + start: { + gte: dayjs().subtract(1, "week").toDate(), + }, + }, + orderBy: [{ start: "asc" }, { end: "asc" }, { status: "asc" }], + include: { + bookables: true, + booker: true, + }, + }); +} + async function performAction(event: RequestEvent, accepted: boolean) { const { request, locals } = event; const { prisma, user } = locals; From 460a432119162917483111bd8dcdb589208e3027 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 21:35:31 +0200 Subject: [PATCH 09/26] Changed StatusComponent.svelte to support two different modes --- .../booking/admin/BookingInspector.svelte | 66 ++----------------- .../booking/admin/StatusComponent.svelte | 3 +- src/routes/(app)/booking/admin/sharedUtils.ts | 3 +- 3 files changed, 10 insertions(+), 62 deletions(-) diff --git a/src/routes/(app)/booking/admin/BookingInspector.svelte b/src/routes/(app)/booking/admin/BookingInspector.svelte index 559b42f89..18e67b527 100644 --- a/src/routes/(app)/booking/admin/BookingInspector.svelte +++ b/src/routes/(app)/booking/admin/BookingInspector.svelte @@ -4,7 +4,7 @@ import * as m from "$paraglide/messages"; import type { Bookable, BookingRequest } from "@prisma/client"; import { superForm } from "$lib/utils/client/superForms"; - import dayjs from "dayjs"; + import StatusComponent from "./StatusComponent.svelte"; type BookingRequestWithBookables = BookingRequest & { bookables: Bookable[] }; export let data: { @@ -15,31 +15,7 @@ }; $: bookingRequest = data.booking; - $: otherBookings = data.allBookingRequests.filter( - (booking) => - booking.id !== bookingRequest.id && booking.status !== "DENIED", - ); - $: conflict = otherBookings.find( - (otherBooking) => - dayjs(otherBooking.start).isBefore(bookingRequest.end) && - dayjs(otherBooking.end).isAfter(bookingRequest.start) && - otherBooking.bookables.some((otherBookable) => - bookingRequest.bookables - .map((bookable) => bookable.id) - .includes(otherBookable.id), - ), - ); - $: conflictingBookables = conflict?.bookables - .filter((booking) => - bookingRequest.bookables - .map((bookable) => bookable.id) - .includes(booking.id), - ) - .map((bookable) => bookable.name) - .join(", "); - $: conflictError = - bookingRequest.status !== "DENIED" && conflict?.status === "ACCEPTED"; - $: conflictWarning = conflict && !conflictError; + const { form, errors, enhance } = superForm(data.form); @@ -51,39 +27,11 @@ {m.booking_goBack()} -
- {#if bookingRequest.status === "ACCEPTED"} -
- {m.booking_accepted()} -
- {:else if bookingRequest.status === "DENIED"} -
- {m.booking_denied()} -
- {:else if bookingRequest.status === "PENDING"} -
- {m.booking_pending()} -
- {/if} - - {#if conflict} -
-
- {m.booking_conflict()} -
-
- {/if} -
+
br.id !== bookingRequest.id && br.status !== "DENIED", ); @@ -29,7 +30,7 @@ $: conflictWarning = conflict && !conflictError; -
+
{#if bookingRequest.status === "ACCEPTED"}
{m.booking_accepted()} diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/admin/sharedUtils.ts index b2381e49f..80122042a 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -3,7 +3,6 @@ import { NotificationType } from "$lib/utils/notifications/types"; import type { RequestEvent } from "@sveltejs/kit"; import type { Actions } from "./$types"; import dayjs from "dayjs"; -import { PrismaClient } from "@prisma/client"; export const actions: Actions = { accept: async (event: RequestEvent) => { @@ -14,7 +13,7 @@ export const actions: Actions = { }, }; -export async function getAllBookingRequestsWeekly(prisma: PrismaClient) { +export async function getAllBookingRequestsWeekly(prisma) { return await prisma.bookingRequest.findMany({ where: { start: { From fb609c5b080107225d3fc6d3338ce2a238c7ed8b Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 23:05:42 +0200 Subject: [PATCH 10/26] Formatting fix and added link to inspect page from /booking/admin --- src/routes/(app)/booking/admin/+page.server.ts | 2 +- src/routes/(app)/booking/admin/+page.svelte | 11 +++++++++-- src/routes/(app)/booking/admin/StatusComponent.svelte | 8 ++++++-- src/routes/(app)/booking/admin/sharedUtils.ts | 6 +++--- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/routes/(app)/booking/admin/+page.server.ts b/src/routes/(app)/booking/admin/+page.server.ts index c3d14291c..ee3df00cc 100644 --- a/src/routes/(app)/booking/admin/+page.server.ts +++ b/src/routes/(app)/booking/admin/+page.server.ts @@ -7,7 +7,7 @@ export const load: PageServerLoad = async ({ locals }) => { const { prisma, user } = locals; authorize(apiNames.BOOKINGS.UPDATE, user); - const bookingRequests = await getAllBookingRequestsWeekly(prisma) + const bookingRequests = await getAllBookingRequestsWeekly(prisma); return { bookingRequests }; }; diff --git a/src/routes/(app)/booking/admin/+page.svelte b/src/routes/(app)/booking/admin/+page.svelte index 950028d34..a348bb5ce 100644 --- a/src/routes/(app)/booking/admin/+page.svelte +++ b/src/routes/(app)/booking/admin/+page.svelte @@ -41,7 +41,7 @@ - {#each data.bookingRequests as bookingRequest (bookingRequest.id)} + {#each data.bookingRequests as bookingRequest, index (bookingRequest.id)} {#each bookingRequest.bookables.map((a) => a.name) as bookable} @@ -50,7 +50,14 @@ {dayjs(bookingRequest.start).format("YYYY-MM-DD HH:MM")} {dayjs(bookingRequest.end).format("YYYY-MM-DD HH:MM")} - {bookingRequest.event} + + + {bookingRequest.event} + +
{#if bookingRequest.booker} diff --git a/src/routes/(app)/booking/admin/StatusComponent.svelte b/src/routes/(app)/booking/admin/StatusComponent.svelte index 744f924d9..a727fb0a4 100644 --- a/src/routes/(app)/booking/admin/StatusComponent.svelte +++ b/src/routes/(app)/booking/admin/StatusComponent.svelte @@ -6,7 +6,7 @@ type T = BookingRequest & { bookables: Bookable[] }; export let bookingRequest: T; export let bookingRequests: T[]; - export let mode: "list" | "inspect" = "list" + export let mode: "list" | "inspect" = "list"; $: otherBookingRequests = bookingRequests.filter( (br) => br.id !== bookingRequest.id && br.status !== "DENIED", ); @@ -30,7 +30,11 @@ $: conflictWarning = conflict && !conflictError; -
+
{#if bookingRequest.status === "ACCEPTED"}
{m.booking_accepted()} diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/admin/sharedUtils.ts index 80122042a..5f151c182 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -6,10 +6,10 @@ import dayjs from "dayjs"; export const actions: Actions = { accept: async (event: RequestEvent) => { - await performAction(event, true) + await performAction(event, true); }, reject: async (event: RequestEvent) => { - await performAction(event, false) + await performAction(event, false); }, }; @@ -33,7 +33,7 @@ async function performAction(event: RequestEvent, accepted: boolean) { const { prisma, user } = locals; const formData = await request.formData(); const id = formData.get("id"); - const status = accepted ? "ACCEPTED" : "DENIED" + const status = accepted ? "ACCEPTED" : "DENIED"; if (id && typeof id === "string") { await prisma.bookingRequest.update({ From 7eb27b891d748819339bf5fa876b56cbf41ddeea Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 23:06:55 +0200 Subject: [PATCH 11/26] Fixed incorrect date format on /booking/admin --- src/routes/(app)/booking/admin/+page.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(app)/booking/admin/+page.svelte b/src/routes/(app)/booking/admin/+page.svelte index a348bb5ce..0c78b99aa 100644 --- a/src/routes/(app)/booking/admin/+page.svelte +++ b/src/routes/(app)/booking/admin/+page.svelte @@ -48,8 +48,8 @@

{bookable}

{/each} - {dayjs(bookingRequest.start).format("YYYY-MM-DD HH:MM")} - {dayjs(bookingRequest.end).format("YYYY-MM-DD HH:MM")} + {dayjs(bookingRequest.start).format("YYYY-MM-DD HH:mm")} + {dayjs(bookingRequest.end).format("YYYY-MM-DD HH:mm")} Date: Thu, 17 Oct 2024 23:40:53 +0200 Subject: [PATCH 12/26] Refactored identical code for getting bookingRequest and form into sharedUtils.ts --- .../(app)/booking/[id]/edit/+page.server.ts | 28 +++--------- .../(app)/booking/admin/[id]/+page.server.ts | 39 ++++------------- src/routes/(app)/booking/admin/sharedUtils.ts | 43 +++++++++++++++++-- 3 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/routes/(app)/booking/[id]/edit/+page.server.ts b/src/routes/(app)/booking/[id]/edit/+page.server.ts index 467724316..3a5c0893e 100644 --- a/src/routes/(app)/booking/[id]/edit/+page.server.ts +++ b/src/routes/(app)/booking/[id]/edit/+page.server.ts @@ -5,33 +5,17 @@ import { redirect } from "$lib/utils/redirect"; import * as m from "$paraglide/messages"; import { isAuthorized } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; -import { error } from "@sveltejs/kit"; -import dayjs from "dayjs"; +import { + getBookingRequestOrThrow, + getSuperValidatedForm, +} from "../../admin/sharedUtils"; export const load = async ({ locals, params }) => { const { prisma } = locals; const bookables = await prisma.bookable.findMany(); - const bookingRequest = await prisma.bookingRequest.findUnique({ - where: { id: params.id }, - include: { bookables: true }, - }); - - if (!bookingRequest) { - throw error(404, m.booking_errors_notFound()); - } - - const initialData = { - name: bookingRequest.event ?? undefined, - start: bookingRequest.start - ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:mm") - : undefined, - end: bookingRequest.end - ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:mm") - : undefined, - bookables: bookingRequest.bookables?.map((bookable) => bookable.id), - }; - const form = await superValidate(initialData, zod(bookingSchema)); + const bookingRequest = await getBookingRequestOrThrow(prisma, params.id); + const form = await getSuperValidatedForm(bookingRequest); return { bookables, form, booking: bookingRequest }; }; diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index e57c07918..8ec104a57 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -1,12 +1,11 @@ -import * as m from "$paraglide/messages"; -import { error } from "@sveltejs/kit"; -import dayjs from "dayjs"; -import { superValidate } from "sveltekit-superforms/server"; -import { zod } from "sveltekit-superforms/adapters"; -import { bookingSchema } from "../../schema"; import { authorize } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; -import { actions, getAllBookingRequestsWeekly } from "../sharedUtils"; +import { + actions, + getAllBookingRequestsWeekly, + getBookingRequestOrThrow, + getSuperValidatedForm, +} from "../sharedUtils"; export const load = async ({ locals, params }) => { const { prisma, user } = locals; @@ -19,30 +18,8 @@ export const load = async ({ locals, params }) => { }, }); - const bookingRequest = await prisma.bookingRequest.findUnique({ - where: { - id: params.id, - }, - include: { - bookables: true, - }, - }); - - if (!bookingRequest) { - throw error(404, m.booking_errors_notFound()); - } - - const initialData = { - name: bookingRequest.event ?? undefined, - start: bookingRequest.start - ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:mm") - : undefined, - end: bookingRequest.end - ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:mm") - : undefined, - bookables: bookingRequest.bookables?.map((bookable) => bookable.id), - }; - const form = await superValidate(initialData, zod(bookingSchema)); + const bookingRequest = await getBookingRequestOrThrow(prisma, params.id); + const form = await getSuperValidatedForm(bookingRequest); return { bookables, diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/admin/sharedUtils.ts index 5f151c182..023bb993b 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -1,8 +1,13 @@ import sendNotification from "$lib/utils/notifications"; import { NotificationType } from "$lib/utils/notifications/types"; -import type { RequestEvent } from "@sveltejs/kit"; +import { error, type RequestEvent } from "@sveltejs/kit"; import type { Actions } from "./$types"; import dayjs from "dayjs"; +import type { Bookable, BookingRequest, PrismaClient } from "@prisma/client"; +import { superValidate } from "sveltekit-superforms/server"; +import { zod } from "sveltekit-superforms/adapters"; +import { bookingSchema } from "../schema"; +import * as m from "$paraglide/messages"; export const actions: Actions = { accept: async (event: RequestEvent) => { @@ -13,8 +18,8 @@ export const actions: Actions = { }, }; -export async function getAllBookingRequestsWeekly(prisma) { - return await prisma.bookingRequest.findMany({ +export async function getAllBookingRequestsWeekly(prisma: PrismaClient) { + return prisma.bookingRequest.findMany({ where: { start: { gte: dayjs().subtract(1, "week").toDate(), @@ -28,6 +33,38 @@ export async function getAllBookingRequestsWeekly(prisma) { }); } +export async function getBookingRequestOrThrow( + prisma: PrismaClient, + id: string, +) { + const bookingRequest = await prisma.bookingRequest.findUnique({ + where: { id }, + include: { bookables: true }, + }); + + if (!bookingRequest) { + throw error(404, m.booking_errors_notFound()); + } + + return bookingRequest; +} + +export async function getSuperValidatedForm( + bookingRequest: BookingRequest & { bookables: Bookable[] }, +) { + const initialData = { + name: bookingRequest.event ?? undefined, + start: bookingRequest.start + ? dayjs(bookingRequest.start).format("YYYY-MM-DDTHH:mm") + : undefined, + end: bookingRequest.end + ? dayjs(bookingRequest.end).format("YYYY-MM-DDTHH:mm") + : undefined, + bookables: bookingRequest.bookables?.map((bookable) => bookable.id), + }; + return await superValidate(initialData, zod(bookingSchema)); +} + async function performAction(event: RequestEvent, accepted: boolean) { const { request, locals } = event; const { prisma, user } = locals; From 14f1bec471ecfc3911d8620e1cbe30047e9437c7 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 23:42:20 +0200 Subject: [PATCH 13/26] Removed old, unnecessary code --- src/routes/(app)/booking/admin/[id]/+page.svelte | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/routes/(app)/booking/admin/[id]/+page.svelte b/src/routes/(app)/booking/admin/[id]/+page.svelte index d304e7db3..d4c347612 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.svelte +++ b/src/routes/(app)/booking/admin/[id]/+page.svelte @@ -1,25 +1,14 @@ -{#if !isAdmin} - -{/if} - From 03712c834e73b0c40d31da42188db3d162f2c3b2 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 23:51:56 +0200 Subject: [PATCH 14/26] Fixed invalid bookingRequest id error --- src/routes/(app)/booking/admin/sharedUtils.ts | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/admin/sharedUtils.ts index 023bb993b..75dfb0ed7 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -37,16 +37,14 @@ export async function getBookingRequestOrThrow( prisma: PrismaClient, id: string, ) { - const bookingRequest = await prisma.bookingRequest.findUnique({ - where: { id }, - include: { bookables: true }, - }); - - if (!bookingRequest) { - throw error(404, m.booking_errors_notFound()); - } - - return bookingRequest; + return prisma.bookingRequest + .findUniqueOrThrow({ + where: { id }, + include: { bookables: true }, + }) + .catch((e) => { + throw error(404, m.booking_errors_notFound()); + }); } export async function getSuperValidatedForm( From f6488f8caec3e34dfc6a4d990212ecd943baa9f9 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Thu, 17 Oct 2024 23:52:39 +0200 Subject: [PATCH 15/26] Removed unused parameter --- src/routes/(app)/booking/admin/sharedUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/admin/sharedUtils.ts index 75dfb0ed7..8f983d6a8 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/admin/sharedUtils.ts @@ -42,7 +42,7 @@ export async function getBookingRequestOrThrow( where: { id }, include: { bookables: true }, }) - .catch((e) => { + .catch(() => { throw error(404, m.booking_errors_notFound()); }); } From 21aa913ba5839586b7fa4df785c94f5f67c5096f Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 00:00:57 +0200 Subject: [PATCH 16/26] Removed old testing code --- src/routes/(app)/booking/create/+page.server.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 65f7eb69b..67106f643 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -37,7 +37,6 @@ const sendNotificationToKM = async ( bookingRequest: BookingRequest & { bookables: Bookable[] }, prisma: PrismaClient, ) => { - console.log("notifications: finding kallarmastare"); const kallarMastare = await prisma.member.findFirstOrThrow({ where: { mandates: { @@ -61,7 +60,6 @@ const sendNotificationToKM = async ( .map((bookable) => bookable.name) // Should be nameEn, perhaps? .join(", "); - console.log("notifications: sending notification to km"); await sendNotification({ title: `New booking request: ${bookingRequest.event}`, message: `${booker.firstName} ${booker.lastName} wants to book '${bookablesString}' from ${dayjs(bookingRequest.start).format("DD/MM HH:mm")} until ${dayjs(bookingRequest.end).format("DD/MM HH:mm")}.`, @@ -69,7 +67,6 @@ const sendNotificationToKM = async ( link: `/booking/admin/${bookingRequest.id}`, memberIds: [kallarMastare.id], }); - console.log("notifications: notification sent"); }; export const actions = { From 78fcb8b7ab0c5d82a297749b6b11da637925acce Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 00:03:26 +0200 Subject: [PATCH 17/26] Added error handling for KM notifications --- src/routes/(app)/booking/create/+page.server.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 67106f643..d870117d8 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -96,7 +96,9 @@ export const actions = { }, }); - await sendNotificationToKM(createdRequest, prisma); + await sendNotificationToKM(createdRequest, prisma).catch((e) => { + console.log("Failed sending notifications to KM: ", e); + }); throw redirect( `/booking`, From 201e03a78377bfeef5caf7209742d4bdbf045f2e Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 00:18:15 +0200 Subject: [PATCH 18/26] Removed unused variable --- src/routes/(app)/booking/admin/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(app)/booking/admin/+page.svelte b/src/routes/(app)/booking/admin/+page.svelte index 0c78b99aa..205111d61 100644 --- a/src/routes/(app)/booking/admin/+page.svelte +++ b/src/routes/(app)/booking/admin/+page.svelte @@ -41,7 +41,7 @@ - {#each data.bookingRequests as bookingRequest, index (bookingRequest.id)} + {#each data.bookingRequests as bookingRequest (bookingRequest.id)} {#each bookingRequest.bookables.map((a) => a.name) as bookable} From 6162e2328723b22ea34efbebd47dc7a4ca4667fa Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 00:18:34 +0200 Subject: [PATCH 19/26] Moved sharedUtils.ts --- src/routes/(app)/booking/[id]/edit/+page.server.ts | 2 +- src/routes/(app)/booking/admin/+page.server.ts | 2 +- src/routes/(app)/booking/admin/[id]/+page.server.ts | 2 +- src/routes/(app)/booking/{admin => }/sharedUtils.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename src/routes/(app)/booking/{admin => }/sharedUtils.ts (98%) diff --git a/src/routes/(app)/booking/[id]/edit/+page.server.ts b/src/routes/(app)/booking/[id]/edit/+page.server.ts index 3a5c0893e..ebf9079a1 100644 --- a/src/routes/(app)/booking/[id]/edit/+page.server.ts +++ b/src/routes/(app)/booking/[id]/edit/+page.server.ts @@ -8,7 +8,7 @@ import apiNames from "$lib/utils/apiNames"; import { getBookingRequestOrThrow, getSuperValidatedForm, -} from "../../admin/sharedUtils"; +} from "../../sharedUtils"; export const load = async ({ locals, params }) => { const { prisma } = locals; diff --git a/src/routes/(app)/booking/admin/+page.server.ts b/src/routes/(app)/booking/admin/+page.server.ts index ee3df00cc..b944b034c 100644 --- a/src/routes/(app)/booking/admin/+page.server.ts +++ b/src/routes/(app)/booking/admin/+page.server.ts @@ -1,7 +1,7 @@ import apiNames from "$lib/utils/apiNames"; import { authorize } from "$lib/utils/authorization"; import type { PageServerLoad } from "./$types"; -import { actions, getAllBookingRequestsWeekly } from "./sharedUtils"; +import { actions, getAllBookingRequestsWeekly } from "../sharedUtils"; export const load: PageServerLoad = async ({ locals }) => { const { prisma, user } = locals; diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index 8ec104a57..111b31e03 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -5,7 +5,7 @@ import { getAllBookingRequestsWeekly, getBookingRequestOrThrow, getSuperValidatedForm, -} from "../sharedUtils"; +} from "../../sharedUtils"; export const load = async ({ locals, params }) => { const { prisma, user } = locals; diff --git a/src/routes/(app)/booking/admin/sharedUtils.ts b/src/routes/(app)/booking/sharedUtils.ts similarity index 98% rename from src/routes/(app)/booking/admin/sharedUtils.ts rename to src/routes/(app)/booking/sharedUtils.ts index 8f983d6a8..a1f993870 100644 --- a/src/routes/(app)/booking/admin/sharedUtils.ts +++ b/src/routes/(app)/booking/sharedUtils.ts @@ -6,7 +6,7 @@ import dayjs from "dayjs"; import type { Bookable, BookingRequest, PrismaClient } from "@prisma/client"; import { superValidate } from "sveltekit-superforms/server"; import { zod } from "sveltekit-superforms/adapters"; -import { bookingSchema } from "../schema"; +import { bookingSchema } from "./schema"; import * as m from "$paraglide/messages"; export const actions: Actions = { From 6ed10d4b02f762afa6e9bfadbef568bf3ed2f424 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 00:43:47 +0200 Subject: [PATCH 20/26] Edited import --- src/routes/(app)/booking/create/+page.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index d870117d8..778e7cb66 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -8,7 +8,7 @@ import dayjs from "dayjs"; import { type Bookable, type BookingRequest, - PrismaClient, + type PrismaClient, } from "@prisma/client"; import sendNotification from "$lib/utils/notifications"; import { NotificationType } from "$lib/utils/notifications/types"; From 54b932aecc6eb7e8b746ff12d96facc7fca1aa21 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Fri, 18 Oct 2024 17:25:16 +0200 Subject: [PATCH 21/26] Added TODO --- src/routes/(app)/booking/create/+page.server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 778e7cb66..103869f2c 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -41,7 +41,7 @@ const sendNotificationToKM = async ( where: { mandates: { some: { - positionId: "dsek.km.mastare", // Placeholder, don't know the actual id yet... + positionId: "dsek.km.mastare", // TODO: Change to actual id... endDate: { gte: new Date(), }, @@ -57,7 +57,7 @@ const sendNotificationToKM = async ( }); const bookablesString = bookingRequest.bookables - .map((bookable) => bookable.name) // Should be nameEn, perhaps? + .map((bookable) => bookable.name) // TODO: Change to nameEn (dev db has faked values) .join(", "); await sendNotification({ From 4fede284e82def3f8f56ff181a21d87b2a4840d1 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Mon, 21 Oct 2024 08:54:08 +0200 Subject: [PATCH 22/26] Changed the booking inspector to match the updated booking editor --- src/routes/(app)/booking/admin/BookingInspector.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/(app)/booking/admin/BookingInspector.svelte b/src/routes/(app)/booking/admin/BookingInspector.svelte index 18e67b527..2180feb1a 100644 --- a/src/routes/(app)/booking/admin/BookingInspector.svelte +++ b/src/routes/(app)/booking/admin/BookingInspector.svelte @@ -34,13 +34,12 @@ />
0} > {m.booking_booking()} {#each data.bookables as bookable} -
From 5afbecded08491aecbb977a399b20611cef2b0a5 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Mon, 21 Oct 2024 10:05:00 +0200 Subject: [PATCH 23/26] Update to booking inspector: * Added review mode and functionality to BookingEditor.svelte * Removed old BookingInspector.svelte * Renamed instances of "inspect" to "review" * Added translations message for admin/[id] page title * Moved StatusComponent.svelte to reflect its new usage --- src/routes/(app)/booking/+page.svelte | 2 +- src/routes/(app)/booking/BookingEditor.svelte | 73 +++++++++-- .../{admin => }/StatusComponent.svelte | 4 +- src/routes/(app)/booking/admin/+page.svelte | 2 +- .../booking/admin/BookingInspector.svelte | 115 ------------------ .../(app)/booking/admin/[id]/+page.svelte | 7 +- src/translations/en.json | 3 +- src/translations/sv.json | 5 +- 8 files changed, 76 insertions(+), 135 deletions(-) rename src/routes/(app)/booking/{admin => }/StatusComponent.svelte (95%) delete mode 100644 src/routes/(app)/booking/admin/BookingInspector.svelte diff --git a/src/routes/(app)/booking/+page.svelte b/src/routes/(app)/booking/+page.svelte index 0c188c977..5ba7160ff 100644 --- a/src/routes/(app)/booking/+page.svelte +++ b/src/routes/(app)/booking/+page.svelte @@ -4,7 +4,7 @@ import { isAuthorized } from "$lib/utils/authorization"; import { page } from "$app/stores"; import apiNames from "$lib/utils/apiNames"; - import StatusComponent from "./admin/StatusComponent.svelte"; + import StatusComponent from "./StatusComponent.svelte"; import dayjs from "dayjs"; import ConfirmDialog from "$lib/components/ConfirmDialog.svelte"; import BookingCalendar from "./BookingCalendar.svelte"; diff --git a/src/routes/(app)/booking/BookingEditor.svelte b/src/routes/(app)/booking/BookingEditor.svelte index bf8bd1db2..fa50fd8ae 100644 --- a/src/routes/(app)/booking/BookingEditor.svelte +++ b/src/routes/(app)/booking/BookingEditor.svelte @@ -3,15 +3,21 @@ import type { BookingSchema } from "./schema"; import { superForm } from "$lib/utils/client/superForms"; import * as m from "$paraglide/messages"; - import type { Bookable } from "@prisma/client"; + import type { Bookable, BookingRequest } from "@prisma/client"; + import StatusComponent from "./StatusComponent.svelte"; + type BookingRequestWithBookables = BookingRequest & { bookables: Bookable[] }; export let data: { form: SuperValidated>; bookables: Bookable[]; + booking?: BookingRequestWithBookables; + allBookingRequests?: BookingRequestWithBookables[]; }; + $: bookingRequest = data.booking; + const { form, errors, enhance, constraints } = superForm(data.form); - export let mode: "create" | "edit" = "create"; + export let mode: "create" | "edit" | "review" = "create"; let start = $form.start; let end = $form.end; @@ -60,6 +66,23 @@
+ {#if mode === "review"} +
+ + {#if bookingRequest && data.allBookingRequests} + + {/if} +
+ {/if}
0} @@ -73,6 +96,7 @@ name="bookables" value={bookable.id} bind:group={$form.bookables} + disabled={mode === "review"} /> {bookable.name} @@ -89,6 +113,7 @@ bind:value={start} on:change={handleStartChange} {...$constraints.start} + disabled={mode === "review"} /> @@ -103,6 +128,7 @@ bind:value={end} on:change={handleEndChange} {...$constraints.end} + disabled={mode === "review"} /> @@ -114,15 +140,42 @@ class="input input-bordered w-full" bind:value={$form.name} {...$constraints.name} + disabled={mode === "review"} /> -
- {m.booking_goBack()} - {#if mode === "edit"} - - {:else if mode === "create"} - - {/if} -
+ {#if mode === "review" && bookingRequest} +
+ + + +
+ {/if} + + {#if mode !== "review"} +
+ {m.booking_goBack()} + {#if mode === "edit"} + + {:else if mode === "create"} + + {/if} +
+ {/if} diff --git a/src/routes/(app)/booking/admin/StatusComponent.svelte b/src/routes/(app)/booking/StatusComponent.svelte similarity index 95% rename from src/routes/(app)/booking/admin/StatusComponent.svelte rename to src/routes/(app)/booking/StatusComponent.svelte index a727fb0a4..a90509500 100644 --- a/src/routes/(app)/booking/admin/StatusComponent.svelte +++ b/src/routes/(app)/booking/StatusComponent.svelte @@ -6,7 +6,7 @@ type T = BookingRequest & { bookables: Bookable[] }; export let bookingRequest: T; export let bookingRequests: T[]; - export let mode: "list" | "inspect" = "list"; + export let mode: "list" | "review" = "list"; $: otherBookingRequests = bookingRequests.filter( (br) => br.id !== bookingRequest.id && br.status !== "DENIED", ); @@ -33,7 +33,7 @@
{#if bookingRequest.status === "ACCEPTED"}
diff --git a/src/routes/(app)/booking/admin/+page.svelte b/src/routes/(app)/booking/admin/+page.svelte index 205111d61..87521d645 100644 --- a/src/routes/(app)/booking/admin/+page.svelte +++ b/src/routes/(app)/booking/admin/+page.svelte @@ -1,6 +1,6 @@ - -
- -
0} - > - {m.booking_booking()} - {#each data.bookables as bookable} - - {/each} -
- - - - - - - -
- - - -
-
diff --git a/src/routes/(app)/booking/admin/[id]/+page.svelte b/src/routes/(app)/booking/admin/[id]/+page.svelte index d4c347612..d2e250fef 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.svelte +++ b/src/routes/(app)/booking/admin/[id]/+page.svelte @@ -1,14 +1,15 @@ - + - + diff --git a/src/translations/en.json b/src/translations/en.json index d389b28e9..9afe3f220 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -755,5 +755,6 @@ "nollning_wikia_literature": "Student literature", "nollning_wikia_literature_body": "Facebook groupo where a lot of second-hand course literature is being sold by older students, it's a private group but everyone is allowed to join, just ask a phadder to approve you.", "members_errors_tooLargePicture": "Profile picture too big, max size is {size}.", - "nollning_events_ticketCTA": "Ticket/Register" + "nollning_events_ticketCTA": "Ticket/Register", + "booking_reviewBooking": "Review booking" } diff --git a/src/translations/sv.json b/src/translations/sv.json index 445cbd350..234d00c9c 100644 --- a/src/translations/sv.json +++ b/src/translations/sv.json @@ -30,8 +30,8 @@ "access": "Åtkomst", "doors": "Dörrar", "emailAliases": "Mejlaliaser", - "alerts": "Globala meddelanden", "linkShortener": "Länkförkortare", + "alerts": "Globala meddelanden", "adminSettings": "Admininställningar", "files": "Filer", "phadderGroups": "Phaddergrupper", @@ -751,5 +751,6 @@ "nollning_wikia_literature": "Studentlitteratur", "nollning_wikia_literature_body": "Facebookgrupp där mycket kurslitteratur säljs av äldre studenter, det är en privat grupp men alla får gå med, be en phadder godkänna dig.", "members_errors_tooLargePicture": "Profilbild är för stor, den får max vara {size}.", - "nollning_events_ticketCTA": "Biljett/Anmälan" + "nollning_events_ticketCTA": "Biljett/Anmälan", + "booking_reviewBooking": "Granska bokning" } From c8d13ec5bada9a2c0ac7e08b7885718f779105b9 Mon Sep 17 00:00:00 2001 From: Simon Mechler Date: Tue, 22 Oct 2024 17:58:09 +0200 Subject: [PATCH 24/26] Changed notification bookable names to nameEn --- src/routes/(app)/booking/create/+page.server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 103869f2c..4ad642770 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -41,7 +41,7 @@ const sendNotificationToKM = async ( where: { mandates: { some: { - positionId: "dsek.km.mastare", // TODO: Change to actual id... + positionId: "dsek.km.mastare", endDate: { gte: new Date(), }, @@ -57,7 +57,7 @@ const sendNotificationToKM = async ( }); const bookablesString = bookingRequest.bookables - .map((bookable) => bookable.name) // TODO: Change to nameEn (dev db has faked values) + .map((bookable) => bookable.nameEn) .join(", "); await sendNotification({ From 396d626857dc6ccc46442eed0e22ae3aeb31c9ef Mon Sep 17 00:00:00 2001 From: Simon Mechler <170467894+Fiery-132@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:03:34 +0200 Subject: [PATCH 25/26] Fixed the calendar on review booking page so it does not display *all* bookings --- src/routes/(app)/booking/admin/[id]/+page.server.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index 111b31e03..f5b357e1e 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -1,5 +1,6 @@ import { authorize } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; +import dayjs from "dayjs"; import { actions, getAllBookingRequestsWeekly, @@ -13,6 +14,12 @@ export const load = async ({ locals, params }) => { const bookables = await prisma.bookable.findMany(); const allBookingRequests = await prisma.bookingRequest.findMany({ + where: { + start: { + gte: dayjs().subtract(1, "week").toDate(), + }, + }, + orderBy: [{ start: "asc" }, { end: "asc" }, { status: "asc" }], include: { bookables: true, }, From 61756e8c798c76439bc8c3c2013cf6cd5e645cb4 Mon Sep 17 00:00:00 2001 From: Daniel Adu-Gyan <26229521+danieladugyan@users.noreply.github.com> Date: Sat, 9 Nov 2024 20:27:21 +0100 Subject: [PATCH 26/26] General refactoring --- src/routes/(app)/booking/+page.svelte | 1 + src/routes/(app)/booking/BookingEditor.svelte | 2 +- src/routes/(app)/booking/StatusComponent.svelte | 11 +++++------ src/routes/(app)/booking/[id]/edit/+page.server.ts | 5 +---- src/routes/(app)/booking/admin/+page.server.ts | 4 ++-- src/routes/(app)/booking/admin/+page.svelte | 1 + src/routes/(app)/booking/admin/[id]/+page.server.ts | 6 +++--- src/routes/(app)/booking/create/+page.server.ts | 13 +++++-------- .../(app)/booking/{sharedUtils.ts => utils.ts} | 2 +- 9 files changed, 20 insertions(+), 25 deletions(-) rename src/routes/(app)/booking/{sharedUtils.ts => utils.ts} (97%) diff --git a/src/routes/(app)/booking/+page.svelte b/src/routes/(app)/booking/+page.svelte index 5ba7160ff..480145e3a 100644 --- a/src/routes/(app)/booking/+page.svelte +++ b/src/routes/(app)/booking/+page.svelte @@ -60,6 +60,7 @@ diff --git a/src/routes/(app)/booking/BookingEditor.svelte b/src/routes/(app)/booking/BookingEditor.svelte index fa50fd8ae..b554b9879 100644 --- a/src/routes/(app)/booking/BookingEditor.svelte +++ b/src/routes/(app)/booking/BookingEditor.svelte @@ -78,7 +78,7 @@ {/if}
diff --git a/src/routes/(app)/booking/StatusComponent.svelte b/src/routes/(app)/booking/StatusComponent.svelte index a90509500..92a8c7b35 100644 --- a/src/routes/(app)/booking/StatusComponent.svelte +++ b/src/routes/(app)/booking/StatusComponent.svelte @@ -2,11 +2,14 @@ import type { Bookable, BookingRequest } from "@prisma/client"; import dayjs from "dayjs"; import * as m from "$paraglide/messages"; + import { twMerge } from "tailwind-merge"; type T = BookingRequest & { bookables: Bookable[] }; export let bookingRequest: T; export let bookingRequests: T[]; - export let mode: "list" | "review" = "list"; + let clazz: string | undefined = undefined; + export { clazz as class }; + $: otherBookingRequests = bookingRequests.filter( (br) => br.id !== bookingRequest.id && br.status !== "DENIED", ); @@ -30,11 +33,7 @@ $: conflictWarning = conflict && !conflictError; -
+
{#if bookingRequest.status === "ACCEPTED"}
{m.booking_accepted()} diff --git a/src/routes/(app)/booking/[id]/edit/+page.server.ts b/src/routes/(app)/booking/[id]/edit/+page.server.ts index ebf9079a1..3bf3c8c34 100644 --- a/src/routes/(app)/booking/[id]/edit/+page.server.ts +++ b/src/routes/(app)/booking/[id]/edit/+page.server.ts @@ -5,10 +5,7 @@ import { redirect } from "$lib/utils/redirect"; import * as m from "$paraglide/messages"; import { isAuthorized } from "$lib/utils/authorization"; import apiNames from "$lib/utils/apiNames"; -import { - getBookingRequestOrThrow, - getSuperValidatedForm, -} from "../../sharedUtils"; +import { getBookingRequestOrThrow, getSuperValidatedForm } from "../../utils"; export const load = async ({ locals, params }) => { const { prisma } = locals; diff --git a/src/routes/(app)/booking/admin/+page.server.ts b/src/routes/(app)/booking/admin/+page.server.ts index b944b034c..5e76f66e4 100644 --- a/src/routes/(app)/booking/admin/+page.server.ts +++ b/src/routes/(app)/booking/admin/+page.server.ts @@ -1,13 +1,13 @@ import apiNames from "$lib/utils/apiNames"; import { authorize } from "$lib/utils/authorization"; import type { PageServerLoad } from "./$types"; -import { actions, getAllBookingRequestsWeekly } from "../sharedUtils"; +import { actions, getUpcomingBookingRequests } from "../utils"; export const load: PageServerLoad = async ({ locals }) => { const { prisma, user } = locals; authorize(apiNames.BOOKINGS.UPDATE, user); - const bookingRequests = await getAllBookingRequestsWeekly(prisma); + const bookingRequests = await getUpcomingBookingRequests(prisma); return { bookingRequests }; }; diff --git a/src/routes/(app)/booking/admin/+page.svelte b/src/routes/(app)/booking/admin/+page.svelte index 87521d645..f0f9c3f1f 100644 --- a/src/routes/(app)/booking/admin/+page.svelte +++ b/src/routes/(app)/booking/admin/+page.svelte @@ -77,6 +77,7 @@ diff --git a/src/routes/(app)/booking/admin/[id]/+page.server.ts b/src/routes/(app)/booking/admin/[id]/+page.server.ts index f5b357e1e..c97031161 100644 --- a/src/routes/(app)/booking/admin/[id]/+page.server.ts +++ b/src/routes/(app)/booking/admin/[id]/+page.server.ts @@ -3,10 +3,10 @@ import apiNames from "$lib/utils/apiNames"; import dayjs from "dayjs"; import { actions, - getAllBookingRequestsWeekly, + getUpcomingBookingRequests, getBookingRequestOrThrow, getSuperValidatedForm, -} from "../../sharedUtils"; +} from "../../utils"; export const load = async ({ locals, params }) => { const { prisma, user } = locals; @@ -33,7 +33,7 @@ export const load = async ({ locals, params }) => { form, booking: bookingRequest, allBookingRequests, - bookingRequests: await getAllBookingRequestsWeekly(prisma), + bookingRequests: await getUpcomingBookingRequests(prisma), }; }; diff --git a/src/routes/(app)/booking/create/+page.server.ts b/src/routes/(app)/booking/create/+page.server.ts index 4ad642770..c7b8814e2 100644 --- a/src/routes/(app)/booking/create/+page.server.ts +++ b/src/routes/(app)/booking/create/+page.server.ts @@ -42,19 +42,18 @@ const sendNotificationToKM = async ( mandates: { some: { positionId: "dsek.km.mastare", - endDate: { - gte: new Date(), - }, + startDate: { lte: new Date() }, + endDate: { gte: new Date() }, }, }, }, }); - const booker = await prisma.member.findUniqueOrThrow({ + const booker = (await prisma.member.findUnique({ where: { id: bookingRequest.bookerId ?? undefined, }, - }); + })) ?? { firstName: "Unknown", lastName: "" }; const bookablesString = bookingRequest.bookables .map((bookable) => bookable.nameEn) @@ -91,9 +90,7 @@ export const actions = { }, status: "PENDING", }, - include: { - bookables: true, - }, + include: { bookables: true }, }); await sendNotificationToKM(createdRequest, prisma).catch((e) => { diff --git a/src/routes/(app)/booking/sharedUtils.ts b/src/routes/(app)/booking/utils.ts similarity index 97% rename from src/routes/(app)/booking/sharedUtils.ts rename to src/routes/(app)/booking/utils.ts index a1f993870..2f9a2dfa3 100644 --- a/src/routes/(app)/booking/sharedUtils.ts +++ b/src/routes/(app)/booking/utils.ts @@ -18,7 +18,7 @@ export const actions: Actions = { }, }; -export async function getAllBookingRequestsWeekly(prisma: PrismaClient) { +export async function getUpcomingBookingRequests(prisma: PrismaClient) { return prisma.bookingRequest.findMany({ where: { start: {