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:
co-authored by
Alex van Andel
parent
f84f1f5dda
commit
9c45da565e
@@ -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")}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user