feat: add range of dates for availability over-ride (#10462)

* feat: add range of dates for availability over-ride

* chore: changed range select to multiple select

---------

Co-authored-by: Alex van Andel <me@alexvanandel.com>
This commit is contained in:
Pradumn Kumar
2023-08-12 07:22:44 +00:00
committed by GitHub
co-authored by Alex van Andel
parent f84f1f5dda
commit 9c45da565e
3 changed files with 62 additions and 22 deletions
+1 -1
View File
@@ -74,7 +74,7 @@ const DateOverride = ({ workingHours }: { workingHours: WorkingHours[] }) => {
<DateOverrideInputDialog
workingHours={workingHours}
excludedDates={excludedDates}
onChange={(ranges) => append({ ranges })}
onChange={(ranges) => ranges.forEach((range) => append({ ranges: [range] }))}
Trigger={
<Button color="secondary" StartIcon={Plus} data-testid="add-override">
{t("add_an_override")}
+8 -3
View File
@@ -19,8 +19,8 @@ export type DatePickerProps = {
onChange: (date: Dayjs) => void;
/** Fires when the month is changed. */
onMonthChange?: (date: Dayjs) => void;
/** which date is currently selected (not tracked from here) */
selected?: Dayjs | null;
/** which date or dates are currently selected (not tracked from here) */
selected?: Dayjs | Dayjs[] | null;
/** defaults to current date. */
minDate?: Dayjs;
/** Furthest date selectable in the future, default = UNLIMITED */
@@ -147,11 +147,16 @@ const Days = ({
const [selectedDatesAndTimes] = useBookerStore((state) => [state.selectedDatesAndTimes], shallow);
const isActive = (day: dayjs.Dayjs) => {
// for selecting a range of dates
if (Array.isArray(selected)) {
return Array.isArray(selected) && selected?.some((e) => yyyymmdd(e) === yyyymmdd(day));
}
if (selected && yyyymmdd(selected) === yyyymmdd(day)) {
return true;
}
// for multiple dates select
// for selecting multiple dates for an event
if (
eventSlug &&
selectedDatesAndTimes &&
@@ -4,6 +4,7 @@ import { useForm } from "react-hook-form";
import type { Dayjs } from "@calcom/dayjs";
import dayjs from "@calcom/dayjs";
import { classNames } from "@calcom/lib";
import { yyyymmdd } from "@calcom/lib/date-fns";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
import type { WorkingHours } from "@calcom/types/schedule";
@@ -48,10 +49,26 @@ const DateOverrideForm = ({
value[0].end.getUTCMinutes() === 0
);
const [date, setDate] = useState<Dayjs | null>(value ? dayjs.utc(value[0].start) : null);
const [selectedDates, setSelectedDates] = useState<Dayjs[]>(value ? [dayjs.utc(value[0].start)] : []);
const onDateChange = (newDate: Dayjs) => {
// If clicking on a selected date unselect it
if (selectedDates.some((date) => yyyymmdd(date) === yyyymmdd(newDate))) {
setSelectedDates(selectedDates.filter((date) => yyyymmdd(date) !== yyyymmdd(newDate)));
return;
}
// If it's not editing we can allow multiple select
if (!value) {
setSelectedDates((prev) => [...prev, newDate]);
return;
}
setSelectedDates([newDate]);
};
const defaultRanges = (workingHours || []).reduce((dayRanges: TimeRange[], workingHour) => {
if (date && workingHour.days.includes(date.day())) {
if (selectedDates[0] && workingHour.days.includes(selectedDates[0].day())) {
dayRanges.push({
start: dayjs.utc().startOf("day").add(workingHour.startTime, "minute").toDate(),
end: dayjs.utc().startOf("day").add(workingHour.endTime, "minute").toDate(),
@@ -91,31 +108,49 @@ const DateOverrideForm = ({
<Form
form={form}
handleSubmit={(values) => {
if (!date) return;
if (selectedDates.length === 0) return;
const datesInRanges: TimeRange[] = [];
if (!datesUnavailable) {
selectedDates.map((date) => {
values.range.map((item) => {
datesInRanges.push({
start: date
.hour(item.start.getUTCHours())
.minute(item.start.getUTCMinutes())
.utc(true)
.toDate(),
end: date.hour(item.end.getUTCHours()).minute(item.end.getUTCMinutes()).utc(true).toDate(),
});
});
});
}
onChange(
(datesUnavailable
? [
{
datesUnavailable
? selectedDates.map((date) => {
return {
start: date.utc(true).startOf("day").toDate(),
end: date.utc(true).startOf("day").add(1, "day").toDate(),
},
]
: values.range
).map((item) => ({
start: date.hour(item.start.getUTCHours()).minute(item.start.getUTCMinutes()).utc(true).toDate(),
end: date.hour(item.end.getUTCHours()).minute(item.end.getUTCMinutes()).utc(true).toDate(),
}))
};
})
: datesInRanges
);
onClose();
}}
className="p-6 sm:flex sm:p-0">
<div className={classNames(date && "sm:border-subtle w-full sm:border-r sm:pr-6", "sm:p-4 md:p-8")}>
<div
className={classNames(
selectedDates[0] && "sm:border-subtle w-full sm:border-r sm:pr-6",
"sm:p-4 md:p-8"
)}>
<DialogHeader title={t("date_overrides_dialog_title")} />
<DatePicker
excludedDates={excludedDates}
weekStart={0}
selected={date}
onChange={(day) => setDate(day)}
selected={selectedDates}
onChange={(day) => onDateChange(day)}
onMonthChange={(newMonth) => {
setBrowsingDate(newMonth);
}}
@@ -123,7 +158,7 @@ const DateOverrideForm = ({
locale={isLocaleReady ? i18n.language : "en"}
/>
</div>
{date && (
{selectedDates[0] && (
<div className="relative mt-8 flex w-full flex-col sm:mt-0 sm:p-4 md:p-8">
<div className="mb-4 flex-grow space-y-4">
<p className="text-medium text-emphasis text-sm">{t("date_overrides_dialog_which_hours")}</p>
@@ -148,7 +183,7 @@ const DateOverrideForm = ({
className="ml-2"
color="primary"
type="submit"
disabled={!date}
disabled={selectedDates.length === 0}
data-testid="add-override-submit-btn">
{value ? t("date_overrides_update_btn") : t("date_overrides_add_btn")}
</Button>