* init * updated typing, english localization text, used existing calculatePeriodLimits and isTimeViolatingFutureLimit to determine if go to next month button should be disabled * improving copy * semantic dialog heading tag, proper EN localization, * reverting * force local to origin * Translations by LLM * intit tests * moving NoAvailability to its own file. * refactor overlay component to encpsulate logic in hooks * improved tests * remove unintended change * fix: period data type import. Providing default periodData values * fix: type errors on event object * fix: updates case in type import * removing translations * remove unnecessary import * remove unnecessary import * improving mocks for booker and logger * moving tests to __tests__ folder --------- Co-authored-by: Tushar Bhatt <95581504+TusharBhatt1@users.noreply.github.com>
105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import { useState } from "react";
|
|
|
|
import type { Dayjs } from "@calcom/dayjs";
|
|
import dayjs from "@calcom/dayjs";
|
|
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
|
import { calculatePeriodLimits, isTimeViolatingFutureLimit } from "@calcom/lib/isOutOfBounds";
|
|
import type { PeriodData } from "@calcom/types/Event";
|
|
import { Button } from "@calcom/ui/components/button";
|
|
import { Dialog, DialogContent, DialogFooter, DialogClose } from "@calcom/ui/components/dialog";
|
|
|
|
// Determines if the next month will pass the booking limits for 'ROLLING' and 'RANGE' period types
|
|
const useNoFutureAvailability = (browsingDate: Dayjs, periodData: PeriodData) => {
|
|
const { periodDays, periodType, periodCountCalendarDays, periodEndDate, periodStartDate } = periodData;
|
|
const periodLimits = calculatePeriodLimits({
|
|
periodType,
|
|
periodDays,
|
|
periodCountCalendarDays,
|
|
periodStartDate,
|
|
periodEndDate,
|
|
allDatesWithBookabilityStatusInBookerTz: null, // Temporary workaround
|
|
_skipRollingWindowCheck: true,
|
|
eventUtcOffset: 0,
|
|
bookerUtcOffset: 0,
|
|
});
|
|
// Check if limit is before start of next month
|
|
const isOutOfBoundsByPeriod = isTimeViolatingFutureLimit({
|
|
time: browsingDate.add(1, "month").startOf("month").toDate(),
|
|
periodLimits,
|
|
});
|
|
return isOutOfBoundsByPeriod;
|
|
};
|
|
|
|
// Creates message to use in dialog explaining lack of availability based on period type
|
|
const useDescription = (noFutureAvailability: boolean, p: PeriodData) => {
|
|
const { t } = useLocale();
|
|
|
|
if (!noFutureAvailability) return "";
|
|
|
|
if (p.periodType === "ROLLING") {
|
|
const daysDescription = p.periodCountCalendarDays ? t("calendar_days") : t("business_days");
|
|
return t("no_availability_rolling", { days: `${p.periodDays} ${daysDescription}` });
|
|
}
|
|
|
|
if (p.periodType === "RANGE") {
|
|
return t("no_availability_range", { date: dayjs(p.periodEndDate).format("MMMM D YYYY") });
|
|
}
|
|
|
|
return "";
|
|
};
|
|
|
|
// This component is used to show a dialog when there is no availability in the selected month.
|
|
const NoAvailabilityDialog = ({
|
|
month,
|
|
nextMonthButton,
|
|
browsingDate,
|
|
periodData,
|
|
}: {
|
|
month: string | null;
|
|
nextMonthButton: () => void;
|
|
browsingDate: Dayjs;
|
|
periodData: PeriodData;
|
|
}) => {
|
|
const { t } = useLocale();
|
|
const [isOpenDialog, setIsOpenDialog] = useState(true);
|
|
const noFutureAvailability = useNoFutureAvailability(browsingDate, periodData);
|
|
const description = useDescription(noFutureAvailability, periodData);
|
|
|
|
const closeDialog = () => {
|
|
setIsOpenDialog(false);
|
|
};
|
|
return (
|
|
<Dialog
|
|
open={isOpenDialog}
|
|
onOpenChange={(open) => {
|
|
setIsOpenDialog(open);
|
|
}}>
|
|
<DialogContent
|
|
title={t("no_availability_in_month", { month: month })}
|
|
type="creation"
|
|
description={description}
|
|
preventCloseOnOutsideClick={false}>
|
|
<DialogFooter>
|
|
<DialogClose
|
|
color={noFutureAvailability ? "primary" : "secondary"}
|
|
onClick={closeDialog}
|
|
data-testid="close_dialog_button">
|
|
{t("close")}
|
|
</DialogClose>
|
|
{!noFutureAvailability && (
|
|
<Button
|
|
color="primary"
|
|
onClick={nextMonthButton}
|
|
data-testid="view_next_month"
|
|
EndIcon="arrow-right">
|
|
{t("view_next_month")}
|
|
</Button>
|
|
)}
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
};
|
|
|
|
export default NoAvailabilityDialog;
|