Compare commits

...

6 Commits

Author SHA1 Message Date
Peer Richelsen 18b378469a
Merge branch 'main' into fix/location-improvements 2023-10-31 19:45:15 +00:00
Peer Richelsen 424f549355
Merge branch 'main' into fix/location-improvements 2023-10-31 19:37:51 +00:00
Udit Takkar a48c4a8a51 fix: use 18n 2023-10-31 18:42:21 +05:30
Udit Takkar 1792d8c172 fix: link input 2023-10-31 12:00:14 +05:30
Udit Takkar cfe2b7f624 chore: add placeholder 2023-10-30 20:50:17 +05:30
Udit Takkar 23f5e0393b fix: improve error message 2023-10-30 20:48:07 +05:30
3 changed files with 73 additions and 39 deletions

View File

@ -30,8 +30,7 @@ import {
Button, Button,
showToast, showToast,
} from "@calcom/ui"; } from "@calcom/ui";
import { Plus, X, Check } from "@calcom/ui/components/icon"; import { Plus, X, Check, CornerDownRight } from "@calcom/ui/components/icon";
import { CornerDownRight } from "@calcom/ui/components/icon";
import CheckboxField from "@components/ui/form/CheckboxField"; import CheckboxField from "@components/ui/form/CheckboxField";
import type { SingleValueLocationOption } from "@components/ui/form/LocationSelect"; import type { SingleValueLocationOption } from "@components/ui/form/LocationSelect";
@ -200,9 +199,9 @@ export const EventSetupTab = (
defaultValue={defaultValue} defaultValue={defaultValue}
render={({ field: { onChange, value } }) => { render={({ field: { onChange, value } }) => {
return ( return (
<>
<Input <Input
name={`locations[${index}].${eventLocationType.defaultValueVariable}`} name={`locations[${index}].${eventLocationType.defaultValueVariable}`}
placeholder={t(eventLocationType.organizerInputPlaceholder || "")}
type="text" type="text"
required required
onChange={onChange} onChange={onChange}
@ -210,13 +209,6 @@ export const EventSetupTab = (
className="my-0" className="my-0"
{...rest} {...rest}
/> />
<ErrorMessage
errors={formMethods.formState.errors.locations?.[index]}
name={eventLocationType.defaultValueVariable}
className="text-error my-1 text-sm"
as="div"
/>
</>
); );
}} }}
/> />
@ -231,21 +223,14 @@ export const EventSetupTab = (
defaultValue={defaultValue} defaultValue={defaultValue}
render={({ field: { onChange, value } }) => { render={({ field: { onChange, value } }) => {
return ( return (
<>
<PhoneInput <PhoneInput
required required
placeholder={t(eventLocationType.organizerInputPlaceholder || "")}
name={`locations[${index}].${eventLocationType.defaultValueVariable}`} name={`locations[${index}].${eventLocationType.defaultValueVariable}`}
value={value} value={value}
onChange={onChange} onChange={onChange}
{...rest} {...rest}
/> />
<ErrorMessage
errors={formMethods.formState.errors.locations?.[index]}
name={eventLocationType.defaultValueVariable}
className="text-error my-1 text-sm"
as="div"
/>
</>
); );
}} }}
/> />
@ -320,11 +305,11 @@ export const EventSetupTab = (
{eventLocationType?.organizerInputType && ( {eventLocationType?.organizerInputType && (
<div className="mt-2 space-y-2"> <div className="mt-2 space-y-2">
<div className="w-full">
<div className="flex gap-2"> <div className="flex gap-2">
<div className="flex items-center justify-center"> <div className="flex items-center justify-center">
<CornerDownRight className="h-4 w-4" /> <CornerDownRight className="h-4 w-4" />
</div> </div>
<div className="w-full">
<LocationInput <LocationInput
defaultValue={ defaultValue={
defaultLocation defaultLocation
@ -335,6 +320,12 @@ export const EventSetupTab = (
index={index} index={index}
/> />
</div> </div>
<ErrorMessage
errors={formMethods.formState.errors.locations?.[index]}
name={eventLocationType.defaultValueVariable}
className="text-error my-1 ml-6 text-sm"
as="div"
/>
</div> </div>
<div className="ml-6"> <div className="ml-6">
<CheckboxField <CheckboxField

View File

@ -8,6 +8,7 @@ import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { z } from "zod"; import { z } from "zod";
import { getEventLocationType } from "@calcom/app-store/locations";
import { validateCustomEventName } from "@calcom/core/event"; import { validateCustomEventName } from "@calcom/core/event";
import type { EventLocationType } from "@calcom/core/location"; import type { EventLocationType } from "@calcom/core/location";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession"; import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
@ -321,6 +322,47 @@ const EventTypePage = (props: EventTypeSetupProps) => {
teamName: z.string().optional(), teamName: z.string().optional(),
}) })
.passthrough() .passthrough()
.superRefine((val, ctx) => {
if (val?.link) {
const link = val.link;
const eventLocationType = getEventLocationType(val.type);
if (
eventLocationType &&
!eventLocationType.default &&
eventLocationType.linkType === "static" &&
eventLocationType.urlRegExp
) {
const valid = z
.string()
.regex(new RegExp(eventLocationType.urlRegExp))
.safeParse(link).success;
if (!valid) {
const sampleUrl = eventLocationType.organizerInputPlaceholder;
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: [eventLocationType?.defaultValueVariable ?? "link"],
message: t("invalid_url_error_message", {
label: eventLocationType.label,
sampleUrl: sampleUrl ?? "https://cal.com",
}),
});
}
return;
}
const valid = z.string().url().optional().safeParse(link).success;
if (!valid) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: [eventLocationType?.defaultValueVariable ?? "link"],
message: `Invalid URL`,
});
}
}
return;
})
) )
.optional(), .optional(),
}) })

View File

@ -1222,6 +1222,7 @@
"organizer_name_variable": "Organizer name", "organizer_name_variable": "Organizer name",
"app_upgrade_description": "In order to use this feature, you need to upgrade to a Pro account.", "app_upgrade_description": "In order to use this feature, you need to upgrade to a Pro account.",
"invalid_number": "Invalid phone number", "invalid_number": "Invalid phone number",
"invalid_url_error_message": "Invalid URL for {{label}}. Sample URL: {{sampleUrl}}",
"navigate": "Navigate", "navigate": "Navigate",
"open": "Open", "open": "Open",
"close": "Close", "close": "Close",