Merge branch 'main' into feat-add-social-links-on-public-page
commit
a20a86b8c7
|
@ -5,6 +5,7 @@ import type { Dayjs } from "@calcom/dayjs";
|
||||||
import dayjs from "@calcom/dayjs";
|
import dayjs from "@calcom/dayjs";
|
||||||
import { useEmbedStyles } from "@calcom/embed-core/embed-iframe";
|
import { useEmbedStyles } from "@calcom/embed-core/embed-iframe";
|
||||||
import { useBookerStore } from "@calcom/features/bookings/Booker/store";
|
import { useBookerStore } from "@calcom/features/bookings/Booker/store";
|
||||||
|
import { getAvailableDatesInMonth } from "@calcom/features/calendars/lib/getAvailableDatesInMonth";
|
||||||
import classNames from "@calcom/lib/classNames";
|
import classNames from "@calcom/lib/classNames";
|
||||||
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
||||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||||
|
@ -23,9 +24,9 @@ export type DatePickerProps = {
|
||||||
/** which date or dates are currently selected (not tracked from here) */
|
/** which date or dates are currently selected (not tracked from here) */
|
||||||
selected?: Dayjs | Dayjs[] | null;
|
selected?: Dayjs | Dayjs[] | null;
|
||||||
/** defaults to current date. */
|
/** defaults to current date. */
|
||||||
minDate?: Dayjs;
|
minDate?: Date;
|
||||||
/** Furthest date selectable in the future, default = UNLIMITED */
|
/** Furthest date selectable in the future, default = UNLIMITED */
|
||||||
maxDate?: Dayjs;
|
maxDate?: Date;
|
||||||
/** locale, any IETF language tag, e.g. "hu-HU" - defaults to Browser settings */
|
/** locale, any IETF language tag, e.g. "hu-HU" - defaults to Browser settings */
|
||||||
locale: string;
|
locale: string;
|
||||||
/** Defaults to [], which dates are not bookable. Array of valid dates like: ["2022-04-23", "2022-04-24"] */
|
/** Defaults to [], which dates are not bookable. Array of valid dates like: ["2022-04-23", "2022-04-24"] */
|
||||||
|
@ -102,7 +103,7 @@ const NoAvailabilityOverlay = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const Days = ({
|
const Days = ({
|
||||||
minDate = dayjs.utc(),
|
minDate,
|
||||||
excludedDates = [],
|
excludedDates = [],
|
||||||
browsingDate,
|
browsingDate,
|
||||||
weekStart,
|
weekStart,
|
||||||
|
@ -121,30 +122,12 @@ const Days = ({
|
||||||
}) => {
|
}) => {
|
||||||
// Create placeholder elements for empty days in first week
|
// Create placeholder elements for empty days in first week
|
||||||
const weekdayOfFirst = browsingDate.date(1).day();
|
const weekdayOfFirst = browsingDate.date(1).day();
|
||||||
const currentDate = minDate.utcOffset(browsingDate.utcOffset());
|
|
||||||
const availableDates = (includedDates: string[] | undefined) => {
|
|
||||||
const dates = [];
|
|
||||||
const lastDateOfMonth = browsingDate.date(daysInMonth(browsingDate));
|
|
||||||
for (
|
|
||||||
let date = currentDate;
|
|
||||||
date.isBefore(lastDateOfMonth) || date.isSame(lastDateOfMonth, "day");
|
|
||||||
date = date.add(1, "day")
|
|
||||||
) {
|
|
||||||
// even if availableDates is given, filter out the passed included dates
|
|
||||||
if (includedDates && !includedDates.includes(yyyymmdd(date))) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
dates.push(yyyymmdd(date));
|
|
||||||
}
|
|
||||||
return dates;
|
|
||||||
};
|
|
||||||
|
|
||||||
const utcBrowsingDateWithOffset = browsingDate.utc().add(browsingDate.utcOffset(), "minute");
|
const includedDates = getAvailableDatesInMonth({
|
||||||
const utcCurrentDateWithOffset = currentDate.utc().add(browsingDate.utcOffset(), "minute");
|
browsingDate: browsingDate.toDate(),
|
||||||
|
minDate,
|
||||||
const includedDates = utcCurrentDateWithOffset.isSame(utcBrowsingDateWithOffset, "month")
|
includedDates: props.includedDates,
|
||||||
? availableDates(props.includedDates)
|
});
|
||||||
: props.includedDates;
|
|
||||||
|
|
||||||
const days: (Dayjs | null)[] = Array((weekdayOfFirst - weekStart + 7) % 7).fill(null);
|
const days: (Dayjs | null)[] = Array((weekdayOfFirst - weekStart + 7) % 7).fill(null);
|
||||||
for (let day = 1, dayCount = daysInMonth(browsingDate); day <= dayCount; day++) {
|
for (let day = 1, dayCount = daysInMonth(browsingDate); day <= dayCount; day++) {
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { describe, expect, test } from "vitest";
|
||||||
|
|
||||||
|
import { getAvailableDatesInMonth } from "@calcom/features/calendars/lib/getAvailableDatesInMonth";
|
||||||
|
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
||||||
|
|
||||||
|
describe("Test Suite: Date Picker", () => {
|
||||||
|
describe("Calculates the available dates left in the month", () => {
|
||||||
|
// *) Use right amount of days in given month. (28, 30, 31)
|
||||||
|
test("it returns the right amount of days in a given month", () => {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const nextMonthDate = new Date(Date.UTC(currentDate.getFullYear(), currentDate.getMonth() + 1));
|
||||||
|
|
||||||
|
const result = getAvailableDatesInMonth({
|
||||||
|
browsingDate: nextMonthDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toHaveLength(daysInMonth(nextMonthDate));
|
||||||
|
});
|
||||||
|
// *) Dates in the past are not available.
|
||||||
|
test("it doesn't return dates that already passed", () => {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const result = getAvailableDatesInMonth({
|
||||||
|
browsingDate: currentDate,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toHaveLength(daysInMonth(currentDate) - currentDate.getDate() + 1);
|
||||||
|
});
|
||||||
|
// *) Intersect with included dates.
|
||||||
|
test("it intersects with given included dates", () => {
|
||||||
|
const currentDate = new Date();
|
||||||
|
const result = getAvailableDatesInMonth({
|
||||||
|
browsingDate: currentDate,
|
||||||
|
includedDates: [yyyymmdd(currentDate)],
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { daysInMonth, yyyymmdd } from "@calcom/lib/date-fns";
|
||||||
|
|
||||||
|
// calculate the available dates in the month:
|
||||||
|
// *) Intersect with included dates.
|
||||||
|
// *) Dates in the past are not available.
|
||||||
|
// *) Use right amount of days in given month. (28, 30, 31)
|
||||||
|
export function getAvailableDatesInMonth({
|
||||||
|
browsingDate, // pass as UTC
|
||||||
|
minDate = new Date(),
|
||||||
|
includedDates,
|
||||||
|
}: {
|
||||||
|
browsingDate: Date;
|
||||||
|
minDate?: Date;
|
||||||
|
includedDates?: string[];
|
||||||
|
}) {
|
||||||
|
const dates = [];
|
||||||
|
const lastDateOfMonth = new Date(
|
||||||
|
Date.UTC(browsingDate.getFullYear(), browsingDate.getMonth(), daysInMonth(browsingDate))
|
||||||
|
);
|
||||||
|
for (
|
||||||
|
let date = browsingDate > minDate ? browsingDate : minDate;
|
||||||
|
date <= lastDateOfMonth;
|
||||||
|
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate() + 1))
|
||||||
|
) {
|
||||||
|
// intersect included dates
|
||||||
|
if (includedDates && !includedDates.includes(yyyymmdd(date))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dates.push(yyyymmdd(date));
|
||||||
|
}
|
||||||
|
return dates;
|
||||||
|
}
|
Loading…
Reference in New Issue