Skip to content

Commit

Permalink
feat: prevent sending multiple instant meeting request
Browse files Browse the repository at this point in the history
  • Loading branch information
Udit-takkar committed Sep 30, 2024
1 parent 5c05a42 commit cb8314b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
2 changes: 1 addition & 1 deletion apps/web/public/static/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -2168,7 +2168,7 @@
"select_time": "Select Time",
"select_date": "Select Date",
"connecting_you_to_someone": "We are connecting you to someone.",
"please_do_not_close_this_tab": "Please do not close this tab",
"please_do_not_close_this_tab": "Please do not close or refresh this page",
"see_all_available_times": "See all available times",
"org_team_names_example_1": "e.g. Marketing Team",
"org_team_names_example_2": "e.g. Sales Team",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const RedirectToInstantMeetingModal = ({
) : (
<div className="text-center">
<p className="font-medium">{t("connecting_you_to_someone")}</p>
<p className="font-medium">{t("please_do_not_close_this_tab")}</p>
<p className="font-bold">{t("please_do_not_close_this_tab")}</p>
<p className="mt-2 font-medium">
{t("please_schedule_future_call", {
seconds: formatTime(timeRemaining),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type { BookerEvent } from "@calcom/features/bookings/types";
import { getFullName } from "@calcom/features/form-builder/utils";
import { useBookingSuccessRedirect } from "@calcom/lib/bookingSuccessRedirect";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import { localStorage } from "@calcom/lib/webstorage";
import { BookingStatus } from "@calcom/prisma/enums";
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
import { trpc } from "@calcom/trpc";
Expand Down Expand Up @@ -85,22 +86,63 @@ export interface IUseBookingErrors {
}
export type UseBookingsReturnType = ReturnType<typeof useBookings>;

const STORAGE_KEY = "instantBookingData";

const storeInLocalStorage = ({
eventTypeId,
expiryTime,
bookingId,
}: {
eventTypeId: number;
expiryTime: Date;
bookingId: number;
}) => {
const value = JSON.stringify({ eventTypeId, expiryTime, bookingId });
localStorage.setItem(STORAGE_KEY, value);
};

export const useBookings = ({ event, hashedLink, bookingForm, metadata, teamMemberEmail }: IUseBookings) => {
const router = useRouter();
const eventSlug = useBookerStore((state) => state.eventSlug);
const eventTypeId = useBookerStore((state) => state.eventId);
const isInstantMeeting = useBookerStore((state) => state.isInstantMeeting);

const rescheduleUid = useBookerStore((state) => state.rescheduleUid);
const bookingData = useBookerStore((state) => state.bookingData);
const timeslot = useBookerStore((state) => state.selectedTimeslot);
const { t } = useLocale();
const bookingSuccessRedirect = useBookingSuccessRedirect();
const bookerFormErrorRef = useRef<HTMLDivElement>(null);

const [instantMeetingTokenExpiryTime, setExpiryTime] = useState<Date | undefined>();
const [instantVideoMeetingUrl, setInstantVideoMeetingUrl] = useState<string | undefined>();
const duration = useBookerStore((state) => state.selectedDuration);

const isRescheduling = !!rescheduleUid && !!bookingData;

const bookingId = parseInt(getQueryParam("bookingId") || "0");
const bookingId = parseInt(getQueryParam("bookingId") ?? "0");

useEffect(() => {
if (!isInstantMeeting) return;

const storedInfo = localStorage.getItem(STORAGE_KEY);

if (storedInfo) {
const parsedInfo = JSON.parse(storedInfo);

const parsedInstantBookingInfo =
parsedInfo.eventTypeId === eventTypeId &&
isInstantMeeting &&
new Date(parsedInfo.expiryTime) > new Date()
? parsedInfo
: null;

if (parsedInstantBookingInfo) {
setExpiryTime(parsedInstantBookingInfo.expiryTime);
updateQueryParam("bookingId", parsedInstantBookingInfo.bookingId);
}
}
}, [eventTypeId, isInstantMeeting]);

const _instantBooking = trpc.viewer.bookings.getInstantBookingLocation.useQuery(
{
Expand Down Expand Up @@ -239,6 +281,14 @@ export const useBookings = ({ event, hashedLink, bookingForm, metadata, teamMemb
const createInstantBookingMutation = useMutation({
mutationFn: createInstantBooking,
onSuccess: (responseData) => {
if (eventTypeId) {
storeInLocalStorage({
eventTypeId,
expiryTime: responseData.expires,
bookingId: responseData.bookingId,
});
}

updateQueryParam("bookingId", responseData.bookingId);
setExpiryTime(responseData.expires);
},
Expand Down

0 comments on commit cb8314b

Please sign in to comment.