Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions packages/features/bookings/Booker/components/hooks/usePrefetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import dayjs from "@calcom/dayjs";
import type { BookerState } from "@calcom/features/bookings/Booker/types";
import { BookerLayouts } from "@calcom/prisma/zod-utils";

interface UsePrefetchParams {
date: string;
month: string | null;
bookerLayout: {
layout: string;
extraDays: number;
columnViewExtraDays: { current: number };
};
bookerState: BookerState;
}

export const usePrefetch = ({ date, month, bookerLayout, bookerState }: UsePrefetchParams) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should use useMemo here, so that the references to prefetchNextMonth,
monthCount change only when date, month, bookerLayout, bookerState change

const dateMonth = dayjs(date).month();
const monthAfterAdding1Month = dayjs(date).add(1, "month").month();
const monthAfterAddingExtraDays = dayjs(date).add(bookerLayout.extraDays, "day").month();
const monthAfterAddingExtraDaysColumnView = dayjs(date)
.add(bookerLayout.columnViewExtraDays.current, "day")
.month();

const isValidDate = dayjs(date).isValid();
const twoWeeksAfter = dayjs(month).startOf("month").add(2, "week");
const isSameMonth = dayjs().isSame(dayjs(month), "month");
const isAfter2Weeks = dayjs().isAfter(twoWeeksAfter);

const prefetchNextMonth =
(bookerLayout.layout === BookerLayouts.WEEK_VIEW &&
!!bookerLayout.extraDays &&
!isNaN(dateMonth) &&
!isNaN(monthAfterAddingExtraDays) &&
dateMonth !== monthAfterAddingExtraDays) ||
(bookerLayout.layout === BookerLayouts.COLUMN_VIEW &&
!isNaN(dateMonth) &&
!isNaN(monthAfterAddingExtraDaysColumnView) &&
dateMonth !== monthAfterAddingExtraDaysColumnView) ||
Comment on lines +32 to +38
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added these NaN checks as well because the root cause is that date string itself could be invalid causing the issue with all other derived variables from it.

I will be adding unit tests for it in a followup and then this could be simplified when needed, ideally we return early when such a situation arise instead of having NaN checks everywhere

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

((bookerLayout.layout === BookerLayouts.MONTH_VIEW || bookerLayout.layout === "mobile") &&
(!isValidDate || isSameMonth) &&
isAfter2Weeks);

const monthCount =
((bookerLayout.layout !== BookerLayouts.WEEK_VIEW && bookerState === "selecting_time") ||
bookerLayout.layout === BookerLayouts.COLUMN_VIEW) &&
!isNaN(monthAfterAdding1Month) &&
!isNaN(monthAfterAddingExtraDaysColumnView) &&
monthAfterAdding1Month !== monthAfterAddingExtraDaysColumnView
? 2
: undefined;

return {
prefetchNextMonth,
monthCount,
};
};
29 changes: 12 additions & 17 deletions packages/platform/atoms/booker/BookerPlatformWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { useBookerLayout } from "@calcom/features/bookings/Booker/components/hooks/useBookerLayout";
import { useBookingForm } from "@calcom/features/bookings/Booker/components/hooks/useBookingForm";
import { useLocalSet } from "@calcom/features/bookings/Booker/components/hooks/useLocalSet";
import { usePrefetch } from "@calcom/features/bookings/Booker/components/hooks/usePrefetch";
import { useInitializeBookerStore } from "@calcom/features/bookings/Booker/store";
import { useTimePreferences } from "@calcom/features/bookings/lib";
import { useTimesForSchedule } from "@calcom/features/schedules/lib/use-schedule/useTimesForSchedule";
Expand Down Expand Up @@ -92,6 +93,7 @@ const BookerPlatformWrapperComponent = (
);
const prevStateRef = useRef<BookerStoreValues | null>(null);
const bookerStoreContext = useContext(BookerStoreContext);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const getStateValues = useCallback((state: any): BookerStoreValues => {
return Object.fromEntries(
Object.entries(state).filter(([_, value]) => typeof value !== "function")
Expand Down Expand Up @@ -147,10 +149,12 @@ const BookerPlatformWrapperComponent = (

useEffect(() => {
setSelectedDuration(props.duration ?? null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.duration]);

useEffect(() => {
setOrg(props.entity?.orgSlug ?? null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.entity?.orgSlug]);

const isDynamic = useMemo(() => {
Expand Down Expand Up @@ -223,30 +227,20 @@ const BookerPlatformWrapperComponent = (
name: prefillFormParamName,
guests: defaultGuests ?? [],
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [defaultName, defaultGuests]);

const extraOptions = useMemo(() => {
return restFormValues;
}, [restFormValues]);
const date = dayjs(selectedDate).format("YYYY-MM-DD");

const prefetchNextMonth =
(bookerLayout.layout === BookerLayouts.WEEK_VIEW &&
!!bookerLayout.extraDays &&
dayjs(date).month() !== dayjs(date).add(bookerLayout.extraDays, "day").month()) ||
(bookerLayout.layout === BookerLayouts.COLUMN_VIEW &&
dayjs(date).month() !== dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month()) ||
((bookerLayout.layout === BookerLayouts.MONTH_VIEW || bookerLayout.layout === "mobile") &&
(!dayjs(date).isValid() || dayjs().isSame(dayjs(month), "month")) &&
dayjs().isAfter(dayjs(month).startOf("month").add(2, "week")));

const monthCount =
((bookerLayout.layout !== BookerLayouts.WEEK_VIEW && bookerState === "selecting_time") ||
bookerLayout.layout === BookerLayouts.COLUMN_VIEW) &&
dayjs(date).add(1, "month").month() !==
dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month()
? 2
: undefined;
const { prefetchNextMonth, monthCount } = usePrefetch({
date,
month,
bookerLayout,
bookerState,
});
const { timezone } = useTimePreferences();

const [calculatedStartTime, calculatedEndTime] = useTimesForSchedule({
Expand Down Expand Up @@ -470,6 +464,7 @@ const BookerPlatformWrapperComponent = (
);
useEffect(() => {
setSelectedDate({ date: selectedDateProp, omitUpdatingParams: true });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedDateProp]);

useEffect(() => {
Expand Down
38 changes: 8 additions & 30 deletions packages/platform/atoms/booker/BookerWebWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useBookerLayout } from "@calcom/features/bookings/Booker/components/hoo
import { useBookingForm } from "@calcom/features/bookings/Booker/components/hooks/useBookingForm";
import { useBookings } from "@calcom/features/bookings/Booker/components/hooks/useBookings";
import { useCalendars } from "@calcom/features/bookings/Booker/components/hooks/useCalendars";
import { usePrefetch } from "@calcom/features/bookings/Booker/components/hooks/usePrefetch";
import { useSlots } from "@calcom/features/bookings/Booker/components/hooks/useSlots";
import { useVerifyCode } from "@calcom/features/bookings/Booker/components/hooks/useVerifyCode";
import { useVerifyEmail } from "@calcom/features/bookings/Booker/components/hooks/useVerifyEmail";
Expand All @@ -31,7 +32,6 @@ import type { getPublicEvent } from "@calcom/features/eventtypes/lib/getPublicEv
import { DEFAULT_LIGHT_BRAND_COLOR, DEFAULT_DARK_BRAND_COLOR, WEBAPP_URL } from "@calcom/lib/constants";
import { useRouterQuery } from "@calcom/lib/hooks/useRouterQuery";
import { localStorage } from "@calcom/lib/webstorage";
import { BookerLayouts } from "@calcom/prisma/zod-utils";

export type BookerWebWrapperAtomProps = BookerProps & {
eventData?: NonNullable<Awaited<ReturnType<typeof getPublicEvent>>>;
Expand Down Expand Up @@ -139,35 +139,12 @@ const BookerPlatformWrapperComponent = (props: BookerWebWrapperAtomProps) => {

const isEmbed = useIsEmbed();

const _month = dayjs(date).month();
const _monthAfterAdding1Month = dayjs(date).add(1, "month").month();
const _monthAfterAddingExtraDays = dayjs(date).add(bookerLayout.extraDays, "day").month();
const _monthAfterAddingExtraDaysColumnView = dayjs(date)
.add(bookerLayout.columnViewExtraDays.current, "day")
.month();

const _isValidDate = dayjs(date).isValid();
const _2WeeksAfter = dayjs(month).startOf("month").add(2, "week");
const _isSameMonth = dayjs().isSame(dayjs(month), "month");
const _isAfter2Weeks = dayjs().isAfter(_2WeeksAfter);

const prefetchNextMonth =
(bookerLayout.layout === BookerLayouts.WEEK_VIEW &&
!!bookerLayout.extraDays &&
_month !== _monthAfterAddingExtraDays) ||
(bookerLayout.layout === BookerLayouts.COLUMN_VIEW && _month !== _monthAfterAddingExtraDaysColumnView) ||
((bookerLayout.layout === BookerLayouts.MONTH_VIEW || bookerLayout.layout === "mobile") &&
(!_isValidDate || _isSameMonth) &&
_isAfter2Weeks);

const monthCount =
((bookerLayout.layout !== BookerLayouts.WEEK_VIEW && bookerState === "selecting_time") ||
bookerLayout.layout === BookerLayouts.COLUMN_VIEW) &&
!isNaN(_monthAfterAdding1Month) &&
!isNaN(_monthAfterAddingExtraDaysColumnView) &&
_monthAfterAdding1Month !== _monthAfterAddingExtraDaysColumnView
? 2
: undefined;
const { prefetchNextMonth, monthCount } = usePrefetch({
date,
month,
bookerLayout,
bookerState,
});
/**
* Prioritize dateSchedule load
* Component will render but use data already fetched from here, and no duplicate requests will be made
Expand Down Expand Up @@ -239,6 +216,7 @@ const BookerPlatformWrapperComponent = (props: BookerWebWrapperAtomProps) => {

useEffect(() => {
if (hasSession) onOverlaySwitchStateChange(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasSession]);

return (
Expand Down
Loading