fix: Slot reservation in new booker (#9769)
## What does this PR do? Bring back the slot reservation sistem to the new booker ## Type of change <!-- Please delete bullets that are not relevant. --> - Bug fix (non-breaking change which fixes an issue) ## How should this be tested? <!-- Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration --> ### Seated event - [x] Open the new booker in an event with seats - [x] Select an available slot - [x] Open the same event and date in other browser, the seat should be already reserved. - [x] In the first browser come back to the slots views or close the booking form - [x] In the second browser reload the booking page, the reserved slot should be realeased. ### No seated event - [x] Open the new booker - [x] Select an available slot - [x] Open the same event and date in other browser, the seat should be disabled ## Mandatory Tasks - [x] Make sure you have self-reviewed the code. A decent size PR without self-review might be rejected.
This commit is contained in:
@@ -4,7 +4,6 @@ import dayjs from "@calcom/dayjs";
|
||||
import { AvailableTimes, AvailableTimesSkeleton } from "@calcom/features/bookings";
|
||||
import { useSlotsForMultipleDates } from "@calcom/features/schedules/lib/use-schedule/useSlotsForDate";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { trpc } from "@calcom/trpc";
|
||||
|
||||
import { useBookerStore } from "../store";
|
||||
import { useEvent, useScheduleForEvent } from "../utils/event";
|
||||
@@ -23,9 +22,7 @@ type AvailableTimeSlotsProps = {
|
||||
* in columns next to each other.
|
||||
*/
|
||||
export const AvailableTimeSlots = ({ extraDays, limitHeight, seatsPerTimeslot }: AvailableTimeSlotsProps) => {
|
||||
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation();
|
||||
const selectedDate = useBookerStore((state) => state.selectedDate);
|
||||
const duration = useBookerStore((state) => state.selectedDuration);
|
||||
const setSelectedTimeslot = useBookerStore((state) => state.setSelectedTimeslot);
|
||||
const event = useEvent();
|
||||
const date = selectedDate || dayjs().format("YYYY-MM-DD");
|
||||
@@ -34,14 +31,6 @@ export const AvailableTimeSlots = ({ extraDays, limitHeight, seatsPerTimeslot }:
|
||||
setSelectedTimeslot(time);
|
||||
|
||||
if (!event.data) return;
|
||||
reserveSlotMutation.mutate({
|
||||
slotUtcStartDate: time,
|
||||
eventTypeId: event.data.id,
|
||||
slotUtcEndDate: dayjs(time)
|
||||
.utc()
|
||||
.add(duration || event.data.length, "minutes")
|
||||
.format(),
|
||||
});
|
||||
};
|
||||
|
||||
const schedule = useScheduleForEvent({
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { UseMutationResult } from "@tanstack/react-query";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import type { TFunction } from "next-i18next";
|
||||
import { useRouter } from "next/router";
|
||||
import { useMemo, useRef } from "react";
|
||||
import { useEffect, useMemo, useRef } from "react";
|
||||
import type { FieldError } from "react-hook-form";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { z } from "zod";
|
||||
@@ -23,8 +23,10 @@ import getBookingResponsesSchema, {
|
||||
getBookingResponsesPartialSchema,
|
||||
} from "@calcom/features/bookings/lib/getBookingResponsesSchema";
|
||||
import { bookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
|
||||
import { MINUTES_TO_BOOK } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { HttpError } from "@calcom/lib/http-error";
|
||||
import { trpc } from "@calcom/trpc";
|
||||
import { Form, Button, Alert, EmptyScreen } from "@calcom/ui";
|
||||
import { Calendar } from "@calcom/ui/components/icon";
|
||||
|
||||
@@ -38,6 +40,12 @@ type BookEventFormProps = {
|
||||
};
|
||||
|
||||
export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
|
||||
const reserveSlotMutation = trpc.viewer.public.slots.reserveSlot.useMutation({
|
||||
trpc: { context: { skipBatch: true } },
|
||||
});
|
||||
const releaseSlotMutation = trpc.viewer.public.slots.removeSelectedSlotMark.useMutation({
|
||||
trpc: { context: { skipBatch: true } },
|
||||
});
|
||||
const router = useRouter();
|
||||
const { t, i18n } = useLocale();
|
||||
const { timezone } = useTimePreferences();
|
||||
@@ -55,6 +63,30 @@ export const BookEventForm = ({ onCancel }: BookEventFormProps) => {
|
||||
const event = useEvent();
|
||||
const eventType = event.data;
|
||||
|
||||
const reserveSlot = () => {
|
||||
if (eventType) {
|
||||
reserveSlotMutation.mutate({
|
||||
slotUtcStartDate: dayjs(timeslot).utc().format(),
|
||||
eventTypeId: eventType.id,
|
||||
slotUtcEndDate: dayjs(timeslot)
|
||||
.utc()
|
||||
.add(duration || eventType.length, "minutes")
|
||||
.format(),
|
||||
});
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
reserveSlot();
|
||||
const interval = setInterval(reserveSlot, parseInt(MINUTES_TO_BOOK) * 60 * 1000 - 2000);
|
||||
return () => {
|
||||
if (eventType) {
|
||||
releaseSlotMutation.mutate();
|
||||
clearInterval(interval);
|
||||
}
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [eventType]);
|
||||
|
||||
const defaultValues = useMemo(() => {
|
||||
if (Object.keys(formValues).length) return formValues;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user