import { LocationMarkerIcon } from "@heroicons/react/solid"; import { zodResolver } from "@hookform/resolvers/zod"; import { isValidPhoneNumber } from "libphonenumber-js"; import dynamic from "next/dynamic"; import { useEffect } from "react"; import { Controller, useForm, useWatch } from "react-hook-form"; import { z } from "zod"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { Button } from "@calcom/ui"; import { Dialog, DialogContent } from "@calcom/ui/Dialog"; import { Form } from "@calcom/ui/form/fields"; import { QueryCell } from "@lib/QueryCell"; import { linkValueToString } from "@lib/linkValueToString"; import { LocationType } from "@lib/location"; import { LocationOptionsToString } from "@lib/locationOptions"; import { inferQueryOutput, trpc } from "@lib/trpc"; import CheckboxField from "@components/ui/form/CheckboxField"; import type PhoneInputType from "@components/ui/form/PhoneInput"; import Select from "@components/ui/form/Select"; const PhoneInput = dynamic( () => import("@components/ui/form/PhoneInput") ) as unknown as typeof PhoneInputType; type BookingItem = inferQueryOutput<"viewer.bookings">["bookings"][number]; type OptionTypeBase = { label: string; value: LocationType; disabled?: boolean; }; type LocationFormValues = { locationType: LocationType; locationAddress?: string; locationLink?: string; locationPhoneNumber?: string; displayLocationPublicly?: boolean; }; interface ISetLocationDialog { saveLocation: (newLocationType: LocationType, details: { [key: string]: string }) => void; selection?: OptionTypeBase; booking?: BookingItem; defaultValues?: { type: LocationType; address?: string | undefined; link?: string | undefined; hostPhoneNumber?: string | undefined; displayLocationPublicly?: boolean | undefined; }[]; setShowLocationModal: React.Dispatch>; isOpenDialog: boolean; setSelectedLocation?: (param: OptionTypeBase | undefined) => void; } export const EditLocationDialog = (props: ISetLocationDialog) => { const { saveLocation, selection, booking, setShowLocationModal, isOpenDialog, defaultValues, setSelectedLocation, } = props; const { t } = useLocale(); const locationsQuery = trpc.useQuery(["viewer.locationOptions"]); useEffect(() => { if (selection) { locationFormMethods.setValue("locationType", selection?.value); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [selection]); const locationFormSchema = z.object({ locationType: z.string(), locationAddress: z.string().optional(), locationLink: z.string().url().optional(), displayLocationPublicly: z.boolean().optional(), locationPhoneNumber: z .string() .refine((val) => isValidPhoneNumber(val)) .optional(), }); const locationFormMethods = useForm({ mode: "onSubmit", resolver: zodResolver(locationFormSchema), }); const selectedLocation = useWatch({ control: locationFormMethods.control, name: "locationType", }); const LocationOptions = selectedLocation === LocationType.InPerson ? ( <>
location.type === LocationType.InPerson )?.address : undefined } />
{!booking && (
( location.type === LocationType.InPerson) ?.displayLocationPublicly : undefined } description={t("display_location_label")} onChange={(e) => locationFormMethods.setValue("displayLocationPublicly", e.target.checked) } informationIconText={t("display_location_info_badge")}> )} />
)}
) : selectedLocation === LocationType.Link ? (
location.type === LocationType.Link )?.link : undefined } /> {locationFormMethods.formState.errors.locationLink && (

{t("url_start_with_https")}

)}
{!booking && (
( location.type === LocationType.Link) ?.displayLocationPublicly : undefined } onChange={(e) => locationFormMethods.setValue("displayLocationPublicly", e.target.checked)} informationIconText={t("display_location_info_badge")}> )} />
)}
) : selectedLocation === LocationType.UserPhone ? (
control={locationFormMethods.control} name="locationPhoneNumber" required id="locationPhoneNumber" placeholder={t("host_phone_number")} defaultValue={ defaultValues ? defaultValues.find( (location: { type: LocationType }) => location.type === LocationType.UserPhone )?.hostPhoneNumber : undefined } /> {locationFormMethods.formState.errors.locationPhoneNumber && (

Invalid input

)}
) : (

{LocationOptionsToString(selectedLocation, t)}

); return (
{!booking && (

{t("this_input_will_shown_booking_this_event")}

)}
{booking && ( <>

{t("current_location")}:

{linkValueToString(booking.location, t)}

)}
{ const { locationType: newLocation, displayLocationPublicly } = values; let details = {}; if (newLocation === LocationType.InPerson) { details = { address: values.locationAddress, displayLocationPublicly, }; } if (newLocation === LocationType.Link) { details = { link: values.locationLink, displayLocationPublicly }; } if (newLocation === LocationType.UserPhone) { details = { hostPhoneNumber: values.locationPhoneNumber }; } saveLocation(newLocation, details); setShowLocationModal(false); setSelectedLocation?.(undefined); locationFormMethods.unregister([ "locationType", "locationLink", "locationAddress", "locationPhoneNumber", ]); }}> { if (!locationOptions.length) return null; return ( (