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:
Efraín Rochín
2023-06-27 16:34:15 -07:00
committed by GitHub
parent 467cacb8da
commit 04ed36cfcf
2 changed files with 33 additions and 12 deletions
@@ -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;