From c14c09290e3e01691b405f86e7d8252c1513618e Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Thu, 18 Sep 2025 14:20:23 +0530 Subject: [PATCH] Fix nan prefetch in platform --- .../Booker/components/hooks/usePrefetch.ts | 56 +++++++++++++++++++ .../atoms/booker/BookerPlatformWrapper.tsx | 29 ++++------ .../atoms/booker/BookerWebWrapper.tsx | 38 +++---------- 3 files changed, 76 insertions(+), 47 deletions(-) create mode 100644 packages/features/bookings/Booker/components/hooks/usePrefetch.ts diff --git a/packages/features/bookings/Booker/components/hooks/usePrefetch.ts b/packages/features/bookings/Booker/components/hooks/usePrefetch.ts new file mode 100644 index 00000000000000..1f5cf300e72171 --- /dev/null +++ b/packages/features/bookings/Booker/components/hooks/usePrefetch.ts @@ -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) => { + 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) || + ((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, + }; +}; diff --git a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx index 59ed2baf7211e4..f58e9ba33e988e 100644 --- a/packages/platform/atoms/booker/BookerPlatformWrapper.tsx +++ b/packages/platform/atoms/booker/BookerPlatformWrapper.tsx @@ -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"; @@ -92,6 +93,7 @@ const BookerPlatformWrapperComponent = ( ); const prevStateRef = useRef(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") @@ -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(() => { @@ -223,6 +227,7 @@ const BookerPlatformWrapperComponent = ( name: prefillFormParamName, guests: defaultGuests ?? [], }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultName, defaultGuests]); const extraOptions = useMemo(() => { @@ -230,23 +235,12 @@ const BookerPlatformWrapperComponent = ( }, [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({ @@ -470,6 +464,7 @@ const BookerPlatformWrapperComponent = ( ); useEffect(() => { setSelectedDate({ date: selectedDateProp, omitUpdatingParams: true }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedDateProp]); useEffect(() => { diff --git a/packages/platform/atoms/booker/BookerWebWrapper.tsx b/packages/platform/atoms/booker/BookerWebWrapper.tsx index a1a263c625789c..5770ca9dfb9bb2 100644 --- a/packages/platform/atoms/booker/BookerWebWrapper.tsx +++ b/packages/platform/atoms/booker/BookerWebWrapper.tsx @@ -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"; @@ -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>>; @@ -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 @@ -239,6 +216,7 @@ const BookerPlatformWrapperComponent = (props: BookerWebWrapperAtomProps) => { useEffect(() => { if (hasSession) onOverlaySwitchStateChange(true); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [hasSession]); return (