feat: Improving Booking Visibility at Month-End (#22770)
* remove first weeks and add last * fix added last week * prefetch availability of next month * don't switch month * On hover show month * only show new UI in monthly view * show month tooldtip only when needed * show month on first day of month * remove isFirstDayOfNextMonth * fix prefetching next month * fix datePicker tests * preventMonthSwitching in monthly view * add tests * code clean up * code clean up * code clena up for ooo days * push first day of month * remove bg color for the month badge * fix text colour * remove not needed * use object param * revert: use object param * use object param * fix DatePicker tests --------- Co-authored-by: CarinaWolli <wollencarina@gmail.com> Co-authored-by: Sean Brydon <sean@cal.com> Co-authored-by: Eunjae Lee <hey@eunjae.dev>
This commit is contained in:
co-authored by
CarinaWolli
Sean Brydon
Eunjae Lee
parent
63df3d9c14
commit
7fef683abf
@@ -74,7 +74,10 @@ export const DatePicker = ({
|
||||
scrollToTimeSlots?: () => void;
|
||||
}) => {
|
||||
const { i18n } = useLocale();
|
||||
const [month, selectedDate] = useBookerStore((state) => [state.month, state.selectedDate], shallow);
|
||||
const [month, selectedDate, layout] = useBookerStore(
|
||||
(state) => [state.month, state.selectedDate, state.layout],
|
||||
shallow
|
||||
);
|
||||
|
||||
const [setSelectedDate, setMonth, setDayCount] = useBookerStore(
|
||||
(state) => [state.setSelectedDate, state.setMonth, state.setDayCount],
|
||||
@@ -83,7 +86,7 @@ export const DatePicker = ({
|
||||
|
||||
const onMonthChange = (date: Dayjs) => {
|
||||
setMonth(date.format("YYYY-MM"));
|
||||
setSelectedDate(date.format("YYYY-MM-DD"));
|
||||
setSelectedDate({ date: date.format("YYYY-MM-DD") });
|
||||
setDayCount(null); // Whenever the month is changed, we nullify getting X days
|
||||
};
|
||||
|
||||
@@ -98,6 +101,9 @@ export const DatePicker = ({
|
||||
});
|
||||
moveToNextMonthOnNoAvailability();
|
||||
|
||||
// Determine if this is a compact sidebar view based on layout
|
||||
const isCompact = layout !== "month_view";
|
||||
|
||||
const periodData: PeriodData = {
|
||||
...{
|
||||
periodType: "UNLIMITED",
|
||||
@@ -126,7 +132,11 @@ export const DatePicker = ({
|
||||
className={classNames?.datePickerContainer}
|
||||
isLoading={isLoading}
|
||||
onChange={(date: Dayjs | null, omitUpdatingParams?: boolean) => {
|
||||
setSelectedDate(date === null ? date : date.format("YYYY-MM-DD"), omitUpdatingParams);
|
||||
setSelectedDate({
|
||||
date: date === null ? date : date.format("YYYY-MM-DD"),
|
||||
omitUpdatingParams,
|
||||
preventMonthSwitching: !isCompact, // Prevent month switching when in monthly view
|
||||
});
|
||||
}}
|
||||
onMonthChange={onMonthChange}
|
||||
includedDates={nonEmptyScheduleDays}
|
||||
@@ -137,6 +147,7 @@ export const DatePicker = ({
|
||||
slots={slots}
|
||||
scrollToTimeSlots={scrollToTimeSlots}
|
||||
periodData={periodData}
|
||||
isCompact={isCompact}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -130,7 +130,7 @@ export function Header({
|
||||
<Button
|
||||
className="capitalize ltr:ml-2 rtl:mr-2"
|
||||
color="secondary"
|
||||
onClick={() => setSelectedDate(today.format("YYYY-MM-DD"))}>
|
||||
onClick={() => setSelectedDate({ date: today.format("YYYY-MM-DD") })}>
|
||||
{t("today")}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -83,7 +83,11 @@ export type BookerStore = {
|
||||
* Date selected by user (exact day). Format is YYYY-MM-DD.
|
||||
*/
|
||||
selectedDate: string | null;
|
||||
setSelectedDate: (date: string | null, omitUpdatingParams?: boolean) => void;
|
||||
setSelectedDate: (params: {
|
||||
date: string | null;
|
||||
omitUpdatingParams?: boolean;
|
||||
preventMonthSwitching?: boolean;
|
||||
}) => void;
|
||||
addToSelectedDate: (days: number) => void;
|
||||
/**
|
||||
* Multiple Selected Dates and Times
|
||||
@@ -192,7 +196,7 @@ export const useBookerStore = createWithEqualityFn<BookerStore>((set, get) => ({
|
||||
return set({ layout });
|
||||
},
|
||||
selectedDate: getQueryParam("date") || null,
|
||||
setSelectedDate: (selectedDate: string | null, omitUpdatingParams = false) => {
|
||||
setSelectedDate: ({ date: selectedDate, omitUpdatingParams = false, preventMonthSwitching = false }) => {
|
||||
// unset selected date
|
||||
if (!selectedDate) {
|
||||
removeQueryParam("date");
|
||||
@@ -207,7 +211,8 @@ export const useBookerStore = createWithEqualityFn<BookerStore>((set, get) => ({
|
||||
}
|
||||
|
||||
// Setting month make sure small calendar in fullscreen layouts also updates.
|
||||
if (newSelection.month() !== currentSelection.month()) {
|
||||
// preventMonthSwitching is true in monthly view
|
||||
if (!preventMonthSwitching && newSelection.month() !== currentSelection.month()) {
|
||||
set({ month: newSelection.format("YYYY-MM") });
|
||||
if (!omitUpdatingParams && (!get().isPlatform || get().allowUpdatingUrlParams)) {
|
||||
updateQueryParam("month", newSelection.format("YYYY-MM"));
|
||||
@@ -264,7 +269,7 @@ export const useBookerStore = createWithEqualityFn<BookerStore>((set, get) => ({
|
||||
if (!get().isPlatform || get().allowUpdatingUrlParams) {
|
||||
updateQueryParam("month", month ?? "");
|
||||
}
|
||||
get().setSelectedDate(null);
|
||||
get().setSelectedDate({ date: null });
|
||||
},
|
||||
dayCount: BOOKER_NUMBER_OF_DAYS_TO_LOAD > 0 ? BOOKER_NUMBER_OF_DAYS_TO_LOAD : null,
|
||||
setDayCount: (dayCount: number | null) => {
|
||||
|
||||
@@ -14,6 +14,7 @@ import type { PeriodData } from "@calcom/types/Event";
|
||||
import classNames from "@calcom/ui/classNames";
|
||||
import { Button } from "@calcom/ui/components/button";
|
||||
import { SkeletonText } from "@calcom/ui/components/skeleton";
|
||||
import { Tooltip } from "@calcom/ui/components/tooltip";
|
||||
|
||||
import NoAvailabilityDialog from "./NoAvailabilityDialog";
|
||||
|
||||
@@ -56,6 +57,8 @@ export type DatePickerProps = {
|
||||
}[]
|
||||
>;
|
||||
periodData?: PeriodData;
|
||||
// Whether this is a compact sidebar view or main monthly view
|
||||
isCompact?: boolean;
|
||||
};
|
||||
|
||||
const Day = ({
|
||||
@@ -65,6 +68,8 @@ const Day = ({
|
||||
away,
|
||||
emoji,
|
||||
customClassName,
|
||||
showMonthTooltip,
|
||||
isFirstDayOfNextMonth,
|
||||
...props
|
||||
}: JSX.IntrinsicElements["button"] & {
|
||||
active: boolean;
|
||||
@@ -75,12 +80,14 @@ const Day = ({
|
||||
dayContainer?: string;
|
||||
dayActive?: string;
|
||||
};
|
||||
showMonthTooltip?: boolean;
|
||||
isFirstDayOfNextMonth?: boolean;
|
||||
}) => {
|
||||
const { t } = useLocale();
|
||||
const enabledDateButtonEmbedStyles = useEmbedStyles("enabledDateButton");
|
||||
const disabledDateButtonEmbedStyles = useEmbedStyles("disabledDateButton");
|
||||
|
||||
return (
|
||||
const buttonContent = (
|
||||
<button
|
||||
type="button"
|
||||
style={disabled ? { ...disabledDateButtonEmbedStyles } : { ...enabledDateButtonEmbedStyles }}
|
||||
@@ -113,6 +120,33 @@ const Day = ({
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
||||
const content = showMonthTooltip ? (
|
||||
<Tooltip content={date.format("MMMM")}>{buttonContent}</Tooltip>
|
||||
) : (
|
||||
buttonContent
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isFirstDayOfNextMonth && (
|
||||
<div
|
||||
className={classNames(
|
||||
"absolute top-0 z-10 mx-auto w-fit rounded-full font-semibold uppercase tracking-wide",
|
||||
active ? "text-white" : "text-default",
|
||||
disabled && "bg-emphasis"
|
||||
)}
|
||||
style={{
|
||||
fontSize: "10px",
|
||||
lineHeight: "13px",
|
||||
padding: disabled ? "0 3px" : "3px 3px 3px 4px",
|
||||
}}>
|
||||
{date.format("MMM")}
|
||||
</div>
|
||||
)}
|
||||
{content}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const Days = ({
|
||||
@@ -129,6 +163,7 @@ const Days = ({
|
||||
customClassName,
|
||||
isBookingInPast,
|
||||
periodData,
|
||||
isCompact,
|
||||
...props
|
||||
}: Omit<DatePickerProps, "locale" | "className" | "weekStart"> & {
|
||||
DayComponent?: React.FC<React.ComponentProps<typeof Day>>;
|
||||
@@ -143,20 +178,48 @@ const Days = ({
|
||||
scrollToTimeSlots?: () => void;
|
||||
isBookingInPast: boolean;
|
||||
periodData: PeriodData;
|
||||
isCompact?: boolean;
|
||||
}) => {
|
||||
// Create placeholder elements for empty days in first week
|
||||
const weekdayOfFirst = browsingDate.date(1).day();
|
||||
|
||||
const includedDates = getAvailableDatesInMonth({
|
||||
browsingDate: browsingDate.toDate(),
|
||||
minDate,
|
||||
includedDates: props.includedDates,
|
||||
});
|
||||
|
||||
const days: (Dayjs | null)[] = Array((weekdayOfFirst - weekStart + 7) % 7).fill(null);
|
||||
for (let day = 1, dayCount = daysInMonth(browsingDate); day <= dayCount; day++) {
|
||||
const date = browsingDate.set("date", day);
|
||||
days.push(date);
|
||||
const today = dayjs();
|
||||
const firstDayOfMonth = browsingDate.startOf("month");
|
||||
const isSecondWeekOver = today.isAfter(firstDayOfMonth.add(2, "week"));
|
||||
let days: (Dayjs | null)[] = [];
|
||||
|
||||
const getPadding = (day: number) => (browsingDate.set("date", day).day() - weekStart + 7) % 7;
|
||||
const totalDays = daysInMonth(browsingDate);
|
||||
|
||||
// Only apply end-of-month logic for main monthly view (not compact sidebar)
|
||||
if (isSecondWeekOver && !isCompact) {
|
||||
const startDay = 8;
|
||||
const pad = getPadding(startDay);
|
||||
days = Array(pad).fill(null);
|
||||
|
||||
for (let day = startDay; day <= totalDays; day++) {
|
||||
days.push(browsingDate.set("date", day));
|
||||
}
|
||||
|
||||
const remainingInRow = days.length % 7;
|
||||
const extraDays = (remainingInRow > 0 ? 7 - remainingInRow : 0) + 7;
|
||||
const nextMonth = browsingDate.add(1, "month");
|
||||
|
||||
// Add days starting from day 1 of next month
|
||||
for (let i = 0; i < extraDays; i++) {
|
||||
days.push(nextMonth.set("date", 1 + i));
|
||||
}
|
||||
} else {
|
||||
// Traditional calendar grid logic for compact sidebar or early in month
|
||||
const pad = getPadding(1);
|
||||
days = Array(pad).fill(null);
|
||||
|
||||
for (let day = 1; day <= totalDays; day++) {
|
||||
days.push(browsingDate.set("date", day));
|
||||
}
|
||||
}
|
||||
|
||||
const [selectedDatesAndTimes] = useBookerStore((state) => [state.selectedDatesAndTimes], shallow);
|
||||
@@ -188,20 +251,29 @@ const Days = ({
|
||||
|
||||
const daysToRenderForTheMonth = days.map((day) => {
|
||||
if (!day) return { day: null, disabled: true };
|
||||
|
||||
const dateKey = yyyymmdd(day);
|
||||
const oooInfo = slots && slots?.[dateKey] ? slots?.[dateKey]?.find((slot) => slot.away) : null;
|
||||
const daySlots = slots?.[dateKey] || [];
|
||||
const oooInfo = daySlots.find((slot) => slot.away) || null;
|
||||
|
||||
const isNextMonth = day.month() !== browsingDate.month();
|
||||
const isFirstDayOfNextMonth = isSecondWeekOver && !isCompact && isNextMonth && day.date() === 1;
|
||||
|
||||
const included = includedDates?.includes(dateKey);
|
||||
const excluded = excludedDates.includes(dateKey);
|
||||
|
||||
const isOOOAllDay = !!(slots && slots[dateKey] && slots[dateKey].every((slot) => slot.away));
|
||||
const hasAvailableSlots = daySlots.some((slot) => !slot.away);
|
||||
const isOOOAllDay = daySlots.length > 0 && daySlots.every((slot) => slot.away);
|
||||
const away = isOOOAllDay;
|
||||
const disabled = away ? !oooInfo?.toUser : !included || excluded;
|
||||
|
||||
const disabled = away ? !oooInfo?.toUser : isNextMonth ? !hasAvailableSlots : !included || excluded;
|
||||
|
||||
return {
|
||||
day: day,
|
||||
day,
|
||||
disabled,
|
||||
away,
|
||||
emoji: oooInfo?.emoji,
|
||||
isFirstDayOfNextMonth,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -239,7 +311,7 @@ const Days = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{daysToRenderForTheMonth.map(({ day, disabled, away, emoji }, idx) => (
|
||||
{daysToRenderForTheMonth.map(({ day, disabled, away, emoji, isFirstDayOfNextMonth }, idx) => (
|
||||
<div key={day === null ? `e-${idx}` : `day-${day.format()}`} className="relative w-full pt-[100%]">
|
||||
{day === null ? (
|
||||
<div key={`e-${idx}`} />
|
||||
@@ -265,6 +337,8 @@ const Days = ({
|
||||
active={isActive(day)}
|
||||
away={away}
|
||||
emoji={emoji}
|
||||
showMonthTooltip={isSecondWeekOver && !isCompact}
|
||||
isFirstDayOfNextMonth={isFirstDayOfNextMonth}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -297,6 +371,7 @@ const DatePicker = ({
|
||||
periodDays: null,
|
||||
periodType: "UNLIMITED",
|
||||
},
|
||||
isCompact,
|
||||
...passThroughProps
|
||||
}: DatePickerProps &
|
||||
Partial<React.ComponentProps<typeof Days>> & {
|
||||
@@ -406,6 +481,7 @@ const DatePicker = ({
|
||||
includedDates={includedDates}
|
||||
isBookingInPast={isBookingInPast}
|
||||
periodData={periodData}
|
||||
isCompact={isCompact}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { TooltipProvider } from "@radix-ui/react-tooltip";
|
||||
import { render } from "@testing-library/react";
|
||||
import React from "react";
|
||||
import { vi } from "vitest";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { PeriodType } from "@calcom/prisma/enums";
|
||||
@@ -13,18 +16,20 @@ describe("Tests for DatePicker Component", () => {
|
||||
test("Should render correctly with default date", async () => {
|
||||
const testDate = dayjs("2024-02-20");
|
||||
const { getByTestId } = render(
|
||||
<DatePicker
|
||||
onChange={noop}
|
||||
browsingDate={testDate}
|
||||
locale="en"
|
||||
periodData={{
|
||||
periodType: PeriodType.UNLIMITED,
|
||||
periodDays: null,
|
||||
periodCountCalendarDays: false,
|
||||
periodStartDate: null,
|
||||
periodEndDate: null,
|
||||
}}
|
||||
/>
|
||||
<TooltipProvider>
|
||||
<DatePicker
|
||||
onChange={noop}
|
||||
browsingDate={testDate}
|
||||
locale="en"
|
||||
periodData={{
|
||||
periodType: PeriodType.UNLIMITED,
|
||||
periodDays: null,
|
||||
periodCountCalendarDays: false,
|
||||
periodStartDate: null,
|
||||
periodEndDate: null,
|
||||
}}
|
||||
/>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const selectedMonthLabel = getByTestId("selected-month-label");
|
||||
@@ -35,7 +40,9 @@ describe("Tests for DatePicker Component", () => {
|
||||
const testDate = dayjs("2024-02-20");
|
||||
const minDate = dayjs("2025-02-10");
|
||||
const { getByTestId } = render(
|
||||
<DatePicker onChange={noop} browsingDate={testDate} minDate={minDate.toDate()} locale="en" />
|
||||
<TooltipProvider>
|
||||
<DatePicker onChange={noop} browsingDate={testDate} minDate={minDate.toDate()} locale="en" />
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const selectedMonthLabel = getByTestId("selected-month-label");
|
||||
@@ -46,10 +53,141 @@ describe("Tests for DatePicker Component", () => {
|
||||
const testDate = dayjs("2025-03-20");
|
||||
const minDate = dayjs("2025-02-10");
|
||||
const { getByTestId } = render(
|
||||
<DatePicker onChange={noop} browsingDate={testDate} minDate={minDate} locale="en" />
|
||||
<TooltipProvider>
|
||||
<DatePicker onChange={noop} browsingDate={testDate} minDate={minDate.toDate()} locale="en" />
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const selectedMonthLabel = getByTestId("selected-month-label");
|
||||
await expect(selectedMonthLabel).toHaveAttribute("dateTime", testDate.format("YYYY-MM"));
|
||||
});
|
||||
|
||||
describe("End-of-Month UI Improvements", () => {
|
||||
const createMockSlots = (dates: string[]) => {
|
||||
const slots: Record<string, { time: string; userIds?: number[] }[]> = {};
|
||||
dates.forEach((date) => {
|
||||
slots[date] = [{ time: `${date}T10:00:00` }];
|
||||
});
|
||||
return slots;
|
||||
};
|
||||
|
||||
test("Should show traditional calendar view before second week of month", async () => {
|
||||
// Set test date to early in month (January 10th, 2024)
|
||||
const earlyMonthDate = dayjs("2024-01-10");
|
||||
|
||||
// Mock current date to also be early in month so isSecondWeekOver is false
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(earlyMonthDate.toDate());
|
||||
|
||||
const slots = createMockSlots([
|
||||
"2024-01-15", // Available date in current month
|
||||
"2024-01-20",
|
||||
]);
|
||||
|
||||
const { getAllByTestId } = render(
|
||||
<TooltipProvider>
|
||||
<DatePicker
|
||||
onChange={noop}
|
||||
browsingDate={earlyMonthDate}
|
||||
locale="en"
|
||||
slots={slots}
|
||||
isCompact={false}
|
||||
periodData={{
|
||||
periodType: PeriodType.UNLIMITED,
|
||||
periodDays: null,
|
||||
periodCountCalendarDays: false,
|
||||
periodStartDate: null,
|
||||
periodEndDate: null,
|
||||
}}
|
||||
/>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const dayElements = getAllByTestId("day");
|
||||
|
||||
// Should show full month starting from day 1
|
||||
const firstAvailableDay = dayElements.find((day) => day.textContent && day.textContent.trim() !== "");
|
||||
expect(firstAvailableDay?.textContent).toBe("1");
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
test("Should show end-of-month view after second week (monthly view)", async () => {
|
||||
// Mock current date to ensure we're after second week
|
||||
const mockDate = dayjs("2024-01-20");
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(mockDate.toDate());
|
||||
|
||||
const lateMonthDate = dayjs("2024-01-20");
|
||||
|
||||
const slots = createMockSlots([
|
||||
"2024-01-25", // Available in current month
|
||||
"2024-02-01", // Available in next month
|
||||
"2024-02-05",
|
||||
]);
|
||||
|
||||
const { getAllByTestId, queryByText } = render(
|
||||
<TooltipProvider>
|
||||
<DatePicker
|
||||
onChange={noop}
|
||||
browsingDate={lateMonthDate}
|
||||
locale="en"
|
||||
slots={slots}
|
||||
isCompact={false}
|
||||
periodData={{
|
||||
periodType: PeriodType.UNLIMITED,
|
||||
periodDays: null,
|
||||
periodCountCalendarDays: false,
|
||||
periodStartDate: null,
|
||||
periodEndDate: null,
|
||||
}}
|
||||
/>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const dayElements = getAllByTestId("day");
|
||||
|
||||
const firstAvailableDay = dayElements.find((day) => day.textContent && day.textContent.trim() !== "");
|
||||
|
||||
// Should show days from day 8 onwards of current month (the main change in end-of-month view)
|
||||
expect(firstAvailableDay?.textContent).toBe("8");
|
||||
|
||||
// Should show next month days (February days when browsing January)
|
||||
// In end-of-month view, the first day of next month gets a month label
|
||||
const febLabel = queryByText("Feb");
|
||||
expect(febLabel).toBeTruthy();
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
test("Should show traditional view when compact=true (not monthly view) even after second week", async () => {
|
||||
const lateMonthDate = dayjs("2024-01-20");
|
||||
const slots = createMockSlots(["2024-01-25", "2024-02-01"]);
|
||||
|
||||
const { getAllByTestId } = render(
|
||||
<TooltipProvider>
|
||||
<DatePicker
|
||||
onChange={noop}
|
||||
browsingDate={lateMonthDate}
|
||||
locale="en"
|
||||
slots={slots}
|
||||
isCompact={true} // This should force traditional view
|
||||
periodData={{
|
||||
periodType: PeriodType.UNLIMITED,
|
||||
periodDays: null,
|
||||
periodCountCalendarDays: false,
|
||||
periodStartDate: null,
|
||||
periodEndDate: null,
|
||||
}}
|
||||
/>
|
||||
</TooltipProvider>
|
||||
);
|
||||
|
||||
const dayElements = getAllByTestId("day");
|
||||
|
||||
// Should show day 1 even in compact mode after second week
|
||||
const firstDayOfMonth = dayElements.find((day) => day.textContent === "1");
|
||||
expect(firstDayOfMonth).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -359,11 +359,11 @@ const EmailEmbed = ({
|
||||
<DatePicker
|
||||
isLoading={schedule.isPending}
|
||||
onChange={(date: Dayjs | null) => {
|
||||
setSelectedDate(date === null ? date : date.format("YYYY-MM-DD"));
|
||||
setSelectedDate({ date: date === null ? date : date.format("YYYY-MM-DD") });
|
||||
}}
|
||||
onMonthChange={(date: Dayjs) => {
|
||||
setMonth(date.format("YYYY-MM"));
|
||||
setSelectedDate(date.format("YYYY-MM-DD"));
|
||||
setSelectedDate({ date: date.format("YYYY-MM-DD") });
|
||||
}}
|
||||
includedDates={nonEmptyScheduleDays}
|
||||
locale={i18n.language}
|
||||
|
||||
@@ -206,7 +206,10 @@ export const BookerPlatformWrapper = (
|
||||
!!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());
|
||||
dayjs(date).month() !== dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month()) ||
|
||||
(bookerLayout.layout === BookerLayouts.MONTH_VIEW &&
|
||||
(!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") ||
|
||||
@@ -413,7 +416,7 @@ export const BookerPlatformWrapper = (
|
||||
[props.selectedDate]
|
||||
);
|
||||
useEffect(() => {
|
||||
setSelectedDate(selectedDateProp, true);
|
||||
setSelectedDate({ date: selectedDateProp, omitUpdatingParams: true });
|
||||
}, [selectedDateProp]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -421,7 +424,7 @@ export const BookerPlatformWrapper = (
|
||||
return () => {
|
||||
slots.handleRemoveSlot();
|
||||
setBookerState("loading");
|
||||
setSelectedDate(null);
|
||||
setSelectedDate({ date: null });
|
||||
setSelectedTimeslot(null);
|
||||
setSelectedDuration(null);
|
||||
setOrg(null);
|
||||
|
||||
@@ -77,6 +77,7 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => {
|
||||
|
||||
const [bookerState, _] = useBookerStore((state) => [state.state, state.setState], shallow);
|
||||
const [dayCount] = useBookerStore((state) => [state.dayCount, state.setDayCount], shallow);
|
||||
const [month] = useBookerStore((state) => [state.month, state.setMonth], shallow);
|
||||
|
||||
const { data: session } = useSession();
|
||||
const routerQuery = useRouterQuery();
|
||||
@@ -126,7 +127,10 @@ export const BookerWebWrapper = (props: BookerWebWrapperAtomProps) => {
|
||||
!!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());
|
||||
dayjs(date).month() !== dayjs(date).add(bookerLayout.columnViewExtraDays.current, "day").month()) ||
|
||||
(bookerLayout.layout === BookerLayouts.MONTH_VIEW &&
|
||||
(!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") ||
|
||||
|
||||
Reference in New Issue
Block a user