From 86918b03cffb8c31e1b81da4691ce99f731efbb5 Mon Sep 17 00:00:00 2001 From: Lauris Skraucis Date: Fri, 16 May 2025 14:32:06 +0200 Subject: [PATCH] fix: booker atom seated events reservation (#21339) * fix: reserving first seated booking slot * fix: input type in useReserveSlot * fix: handleReserveSlot submit bookingUid to api * null -> undefined * dont touch web app --- .../slots/slots-2024-04-15/services/slots.service.ts | 4 +++- .../bookings/Booker/components/AvailableTimeSlots.tsx | 4 +++- packages/platform/atoms/hooks/useReserveSlot.ts | 6 +++--- packages/platform/atoms/hooks/useSlots.ts | 3 +++ packages/platform/examples/base/src/pages/booking.tsx | 3 --- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts b/apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts index e97ab48e1b..d62c12b0e3 100644 --- a/apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts +++ b/apps/api/v2/src/modules/slots/slots-2024-04-15/services/slots.service.ts @@ -21,7 +21,9 @@ export class SlotsService_2024_04_15 { let shouldReserveSlot = true; if (eventType.seatsPerTimeSlot) { - const bookingWithAttendees = await this.slotsRepo.getBookingWithAttendees(input.bookingUid); + const bookingWithAttendees = input.bookingUid + ? await this.slotsRepo.getBookingWithAttendees(input.bookingUid) + : undefined; const bookingAttendeesLength = bookingWithAttendees?.attendees?.length; if (bookingAttendeesLength) { const seatsLeft = eventType.seatsPerTimeSlot - bookingAttendeesLength; diff --git a/packages/features/bookings/Booker/components/AvailableTimeSlots.tsx b/packages/features/bookings/Booker/components/AvailableTimeSlots.tsx index ec05deb42e..a1c5b6efc9 100644 --- a/packages/features/bookings/Booker/components/AvailableTimeSlots.tsx +++ b/packages/features/bookings/Booker/components/AvailableTimeSlots.tsx @@ -136,7 +136,8 @@ export const AvailableTimeSlots = ({ schedule?.invalidate(); } setTentativeSelectedTimeslots([]); - setSelectedTimeslot(time); + // note(Lauris): setting setSeatedEventData before setSelectedTimeslot so that in useSlots we have seated event data available + // and only then we invoke handleReserveSlot that is triggered by the changes in setSelectedTimeslot. if (seatsPerTimeSlot) { setSeatedEventData({ seatsPerTimeSlot, @@ -145,6 +146,7 @@ export const AvailableTimeSlots = ({ showAvailableSeatsCount, }); } + setSelectedTimeslot(time); const isTimeSlotAvailable = !unavailableTimeSlots.includes(time); if (skipConfirmStep && isTimeSlotAvailable) { onSubmit(time); diff --git a/packages/platform/atoms/hooks/useReserveSlot.ts b/packages/platform/atoms/hooks/useReserveSlot.ts index 07d9a0bc0e..11af761bae 100644 --- a/packages/platform/atoms/hooks/useReserveSlot.ts +++ b/packages/platform/atoms/hooks/useReserveSlot.ts @@ -5,7 +5,7 @@ import type { ApiResponse, ApiErrorResponse, ApiSuccessResponse, - ReserveSlotInput, + ReserveSlotInput_2024_04_15, } from "@calcom/platform-types"; import http from "../lib/http"; @@ -24,8 +24,8 @@ export const useReserveSlot = ( }, } ) => { - const reserveSlot = useMutation, unknown, ReserveSlotInput>({ - mutationFn: (props: ReserveSlotInput) => { + const reserveSlot = useMutation, unknown, ReserveSlotInput_2024_04_15>({ + mutationFn: (props: ReserveSlotInput_2024_04_15) => { return http.post>("/slots/reserve", props).then((res) => { if (res.data.status === SUCCESS_STATUS) { return res.data; diff --git a/packages/platform/atoms/hooks/useSlots.ts b/packages/platform/atoms/hooks/useSlots.ts index a4b24bdd04..477801e1dd 100644 --- a/packages/platform/atoms/hooks/useSlots.ts +++ b/packages/platform/atoms/hooks/useSlots.ts @@ -52,6 +52,8 @@ export const useSlots = ( onError: onReserveSlotError, }); + const seatedEventData = useBookerStore((state) => state.seatedEventData); + const removeSelectedSlot = useDeleteSelectedSlot({ onSuccess: onDeleteSlotSuccess, onError: onDeleteSlotError, @@ -78,6 +80,7 @@ export const useSlots = ( .add(selectedDuration || event.data.length, "minutes") .format(), _isDryRun: isBookingDryRun, + bookingUid: seatedEventData.bookingUid || undefined, }); } }; diff --git a/packages/platform/examples/base/src/pages/booking.tsx b/packages/platform/examples/base/src/pages/booking.tsx index 33a2fb8041..6ba70fb216 100644 --- a/packages/platform/examples/base/src/pages/booking.tsx +++ b/packages/platform/examples/base/src/pages/booking.tsx @@ -132,9 +132,6 @@ export default function Bookings(props: { calUsername: string; calEmail: string : { username: props.calUsername })} hostsLimit={3} allowUpdatingUrlParams={true} - handleSlotReservation={(timeslot) => { - console.log("Selected timeslot:", timeslot); - }} /> )}