feat: added validation to limit event duration to 1440 minutes (24 ho… (#21379)
* feat: added validation to limit event duration to 1440 minutes (24 hours) * Update English locale strings in common.json * feat: introduce minimum event duration constant and update validations and fixed some suggested changes * fix: remove static error message for maximum event duration validation * fix: update minimum event duration to 1 minute and adjust validations accordingly --------- Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com> Co-authored-by: amrit <iamamrit27@gmail.com>
This commit is contained in:
6 files changed
+45
-8
No files matched your search
@@ -1,6 +1,10 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { MAX_SEATS_PER_TIME_SLOT } from "@calcom/lib/constants";
|
||||
import {
|
||||
MAX_SEATS_PER_TIME_SLOT,
|
||||
MAX_EVENT_DURATION_MINUTES,
|
||||
MIN_EVENT_DURATION_MINUTES,
|
||||
} from "@calcom/lib/constants";
|
||||
import slugify from "@calcom/lib/slugify";
|
||||
import { _EventTypeModel as EventType, _HostModel } from "@calcom/prisma/zod";
|
||||
import { customInputSchema, eventTypeBookingFields } from "@calcom/prisma/zod-utils";
|
||||
@@ -80,7 +84,7 @@ const schemaEventTypeCreateParams = z
|
||||
title: z.string(),
|
||||
slug: z.string().transform((s) => slugify(s)),
|
||||
description: z.string().optional().nullable(),
|
||||
length: z.number().int(),
|
||||
length: z.number().int().min(MIN_EVENT_DURATION_MINUTES).max(MAX_EVENT_DURATION_MINUTES),
|
||||
metadata: z.any().optional(),
|
||||
recurringEvent: recurringEventInputSchema.optional(),
|
||||
seatsPerTimeSlot: z.number().optional(),
|
||||
|
||||
@@ -3241,5 +3241,7 @@
|
||||
"meeting_start_time": "Meeting Start Time",
|
||||
"members_affected_by_disabling_delegation_credential": "Affected members",
|
||||
"no_members_affected_by_disabling_delegation_credential": "No members affected by disabling delegation credential",
|
||||
"duration_min_error": "Duration must be at least {{min}} minute(s)",
|
||||
"duration_max_error": "Duration cannot exceed {{max}} minutes (24 hours)",
|
||||
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { useState } from "react";
|
||||
import type { UseFormReturn } from "react-hook-form";
|
||||
|
||||
import { useIsPlatform } from "@calcom/atoms/hooks/useIsPlatform";
|
||||
import { MAX_EVENT_DURATION_MINUTES, MIN_EVENT_DURATION_MINUTES } from "@calcom/lib/constants";
|
||||
import type { CreateEventTypeFormValues } from "@calcom/lib/hooks/useCreateEventType";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { md } from "@calcom/lib/markdownIt";
|
||||
@@ -124,11 +125,22 @@ export default function CreateEventTypeForm({
|
||||
<TextField
|
||||
type="number"
|
||||
required
|
||||
min="10"
|
||||
min={MIN_EVENT_DURATION_MINUTES}
|
||||
max={MAX_EVENT_DURATION_MINUTES}
|
||||
placeholder="15"
|
||||
label={t("duration")}
|
||||
className="pr-4"
|
||||
{...register("length", { valueAsNumber: true })}
|
||||
{...register("length", {
|
||||
valueAsNumber: true,
|
||||
min: {
|
||||
value: MIN_EVENT_DURATION_MINUTES,
|
||||
message: t("duration_min_error", { min: MIN_EVENT_DURATION_MINUTES }),
|
||||
},
|
||||
max: {
|
||||
value: MAX_EVENT_DURATION_MINUTES,
|
||||
message: t("duration_max_error", { max: MAX_EVENT_DURATION_MINUTES }),
|
||||
},
|
||||
})}
|
||||
addOnSuffix={t("minutes")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
SettingsToggleClassNames,
|
||||
} from "@calcom/features/eventtypes/lib/types";
|
||||
import type { FormValues, LocationFormValues } from "@calcom/features/eventtypes/lib/types";
|
||||
import { MAX_EVENT_DURATION_MINUTES, MIN_EVENT_DURATION_MINUTES } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { md } from "@calcom/lib/markdownIt";
|
||||
import { slugify } from "@calcom/lib/slugify";
|
||||
@@ -337,9 +338,20 @@ export const EventSetupTab = (
|
||||
{...(isManagedEventType || isChildrenManagedEventType ? lengthLockedProps : {})}
|
||||
label={t("duration")}
|
||||
defaultValue={formMethods.getValues("length") ?? 15}
|
||||
{...formMethods.register("length")}
|
||||
{...formMethods.register("length", {
|
||||
valueAsNumber: true,
|
||||
min: {
|
||||
value: MIN_EVENT_DURATION_MINUTES,
|
||||
message: t("duration_min_error", { min: MIN_EVENT_DURATION_MINUTES }),
|
||||
},
|
||||
max: {
|
||||
value: MAX_EVENT_DURATION_MINUTES,
|
||||
message: t("duration_max_error", { max: MAX_EVENT_DURATION_MINUTES }),
|
||||
},
|
||||
})}
|
||||
addOnSuffix={<>{t("minutes")}</>}
|
||||
min={1}
|
||||
min={MIN_EVENT_DURATION_MINUTES}
|
||||
max={MAX_EVENT_DURATION_MINUTES}
|
||||
/>
|
||||
)}
|
||||
{!lengthLockedProps.disabled && (
|
||||
|
||||
@@ -61,6 +61,12 @@ export const EMBED_LIB_URL = process.env.NEXT_PUBLIC_EMBED_LIB_URL || `${WEBAPP_
|
||||
export const TRIAL_LIMIT_DAYS = 14;
|
||||
export const MAX_SEATS_PER_TIME_SLOT = 1000;
|
||||
|
||||
/** Maximum duration allowed for an event in minutes (24 hours) */
|
||||
export const MAX_EVENT_DURATION_MINUTES = 1440;
|
||||
|
||||
/** Minimum duration allowed for an event in minutes */
|
||||
export const MIN_EVENT_DURATION_MINUTES = 1;
|
||||
|
||||
export const HOSTED_CAL_FEATURES = process.env.NEXT_PUBLIC_HOSTED_CAL_FEATURES || !IS_SELF_HOSTED;
|
||||
|
||||
export const PUBLIC_QUERY_RESERVATION_INTERVAL_SECONDS =
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
import { z } from "zod";
|
||||
import * as imports from "../../zod-utils";
|
||||
import { MIN_EVENT_DURATION_MINUTES, MAX_EVENT_DURATION_MINUTES } from "@calcom/lib/constants";
|
||||
// TODO: figure out why EventTypeModel is being called even if it's not imported here, causing a circular dependency
|
||||
// import { _EventTypeModel } from "../eventtype";
|
||||
|
||||
@@ -8,7 +9,7 @@ export const createEventTypeInput = z.object({
|
||||
title: z.string().min(1),
|
||||
slug: imports.eventTypeSlug,
|
||||
description: z.string().nullish(),
|
||||
length: z.number().int(),
|
||||
length: z.number().int().min(MIN_EVENT_DURATION_MINUTES).max(MAX_EVENT_DURATION_MINUTES),
|
||||
hidden: z.boolean(),
|
||||
teamId: z.number().int().nullish(),
|
||||
schedulingType: z.nativeEnum(SchedulingType).nullish(),
|
||||
@@ -32,7 +33,7 @@ export const createEventTypeInput = z.object({
|
||||
slug: z.string(),
|
||||
title: z.string().min(1),
|
||||
description: z.string(),
|
||||
length: z.number(),
|
||||
length: z.number().int().min(MIN_EVENT_DURATION_MINUTES).max(MAX_EVENT_DURATION_MINUTES),
|
||||
teamId: z.number().nullish(),
|
||||
}).strict();
|
||||
|
||||
|
||||
Reference in new issue
Block a user