diff --git a/apps/web/components/eventtype/EventLimitsTab.tsx b/apps/web/components/eventtype/EventLimitsTab.tsx index 8b9a147d33..0431dbf57a 100644 --- a/apps/web/components/eventtype/EventLimitsTab.tsx +++ b/apps/web/components/eventtype/EventLimitsTab.tsx @@ -1,23 +1,29 @@ import { useAutoAnimate } from "@formkit/auto-animate/react"; import * as RadioGroup from "@radix-ui/react-radio-group"; import { EventTypeSetupInfered, FormValues } from "pages/event-types/[type]"; -import { useState } from "react"; -import { useFormContext, Controller, useWatch } from "react-hook-form"; +import { useMemo, useRef, useState } from "react"; +import { Controller, useFormContext, useWatch } from "react-hook-form"; import { classNames } from "@calcom/lib"; +import convertToNewDurationType, { DurationType } from "@calcom/lib/convertToNewDurationType"; +import findDurationType from "@calcom/lib/findDurationType"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { PeriodType } from "@calcom/prisma/client"; import type { BookingLimit } from "@calcom/types/Calendar"; import { Icon } from "@calcom/ui"; import { Button } from "@calcom/ui/components"; -import { Label, Input, MinutesField } from "@calcom/ui/components/form"; +import { Input, InputField, Label } from "@calcom/ui/components/form"; import { Select, SettingsToggle } from "@calcom/ui/v2"; import DateRangePicker from "@calcom/ui/v2/core/form/date-range-picker/DateRangePicker"; -export const EventLimitsTab = (props: Pick) => { +export const EventLimitsTab = ({ eventType }: Pick) => { const { t } = useLocale(); const formMethods = useFormContext(); - const { eventType } = props; + const minimumBookingNoticeType = useRef(findDurationType(eventType.minimumBookingNotice)); + const prevBookingNoticeType = useRef(minimumBookingNoticeType.current); + + const minimumBookingNoticeInDurationTypeFormValue = formMethods.watch("minimumBookingNoticeInDurationType"); + const PERIOD_TYPES = [ { type: "ROLLING" as const, @@ -47,6 +53,57 @@ export const EventLimitsTab = (props: Pick) defaultValue: periodType?.type, }); + const onMinimumNoticeDurationTypeChange = useMemo( + () => (durationType?: DurationType) => { + if (typeof durationType === "undefined") return; + + // Store current selected type in ref to use in previous run for comparrison. + minimumBookingNoticeType.current = durationType; + + // Uses the previous selected type and converts the value to the new type. + // Eg day was selected before, user selects hours now, so we multiple * 24 and round up. + const minimumBookingNoticeInDurationType = convertToNewDurationType( + prevBookingNoticeType.current, + durationType, + Number(minimumBookingNoticeInDurationTypeFormValue) + ); + + // Uses the round up value in the new type to calculate the value in minutes. + // We should NOT use minimumBookingNoticeInDurationTypeFormValue here, since that + // would break in the case that the user enters 90 minutes, changes the type to + // hours (that will show 2 hours), but the value in minutes would then remain 90, + // which is something else than the user things they save. + const minimumBookingNoticeInMinutes = convertToNewDurationType( + durationType, + "minutes", + Number(minimumBookingNoticeInDurationType) + ); + + // Updates both form values as well as stores the current type as previous type in ref. + formMethods.setValue("minimumBookingNotice", minimumBookingNoticeInMinutes); + formMethods.setValue("minimumBookingNoticeInDurationType", minimumBookingNoticeInDurationType); + prevBookingNoticeType.current = durationType; + }, + [formMethods, minimumBookingNoticeInDurationTypeFormValue] + ); + + /** + * When the user inputs a new value for minimumBookingNoticeInDurationType, + * we calculate the value in minutes, and update this hidden field as well. + */ + const onMinimumNoticeChange = useMemo( + () => (duration: string) => { + const minimumBookingNoticeInMinutes = convertToNewDurationType( + minimumBookingNoticeType.current, + "minutes", + Number(duration) + ); + + formMethods.setValue("minimumBookingNotice", minimumBookingNoticeInMinutes); + }, + [formMethods] + ); + return (
@@ -116,13 +173,54 @@ export const EventLimitsTab = (props: Pick)
-
- + { + const durationTypeOptions = [ + { + label: t("minutes"), + value: "minutes", + }, + { + label: t("hours"), + value: "hours", + }, + { + label: t("days"), + value: "days", + }, + ]; + + return ( + <> +
+ ) => + onMinimumNoticeChange(event.target.value), + })} + /> + +
+