import * as RadioGroup from "@radix-ui/react-radio-group"; import { Trans } from "next-i18next"; import Link from "next/link"; import { useCallback, useState } from "react"; import { Controller, useFormContext } from "react-hook-form"; import { useFlagMap } from "@calcom/features/flags/context/provider"; import { classNames } from "@calcom/lib"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { BookerLayouts, defaultBookerLayoutSettings } from "@calcom/prisma/zod-utils"; import { bookerLayoutOptions, type BookerLayoutSettings } from "@calcom/prisma/zod-utils"; import useMeQuery from "@calcom/trpc/react/hooks/useMeQuery"; import { Label, CheckboxField, Button } from "@calcom/ui"; import SectionBottomActions from "./SectionBottomActions"; type BookerLayoutSelectorProps = { title?: string; description?: string; name?: string; /** * If this boolean is set, it will show the user settings if the event does not have any settings (is null). * In that case it also will NOT register itself in the form, so that way when submitting the form, the * values won't be overridden. Because as long as the event's value is null, it will fallback to the user's * settings. */ fallbackToUserSettings?: boolean; /** * isDark boolean should be passed in when the user selected 'dark mode' in the theme settings in profile/appearance. * So it's not based on the user's system settings, but on the user's preference for the booker. * This boolean is then used to show a dark version of the layout image. It's only easthetic, no functionality is attached * to this boolean. */ isDark?: boolean; isDisabled?: boolean; isOuterBorder?: boolean; }; const defaultFieldName = "metadata.bookerLayouts"; export const BookerLayoutSelector = ({ title, description, name, fallbackToUserSettings, isDark, isDisabled = false, isOuterBorder = false, }: BookerLayoutSelectorProps) => { const { control, getValues } = useFormContext(); const { t } = useLocale(); // Only fallback if event current does not have any settings, and the fallbackToUserSettings boolean is set. const shouldShowUserSettings = (fallbackToUserSettings && !getValues(name || defaultFieldName)) || false; const flags = useFlagMap(); if (flags["booker-layouts"] !== true) return null; return (

{description ? description : t("bookerlayout_description")}

( <> {!isOuterBorder && ( )} )} />
); }; type BookerLayoutFieldsProps = { settings: BookerLayoutSettings; onChange: (settings: BookerLayoutSettings) => void; showUserSettings: boolean; isDark?: boolean; isOuterBorder?: boolean; }; type BookerLayoutState = { [key in BookerLayouts]: boolean }; const BookerLayoutFields = ({ settings, onChange, showUserSettings, isDark, isOuterBorder, }: BookerLayoutFieldsProps) => { const { t } = useLocale(); const { isLoading: isUserLoading, data: user } = useMeQuery(); const [isOverridingSettings, setIsOverridingSettings] = useState(false); const disableFields = showUserSettings && !isOverridingSettings; const shownSettings = disableFields ? user?.defaultBookerLayouts : settings; const defaultLayout = shownSettings?.defaultLayout || BookerLayouts.MONTH_VIEW; // Converts the settings array into a boolean object, which can be used as form values. const toggleValues: BookerLayoutState = bookerLayoutOptions.reduce((layouts, layout) => { layouts[layout] = !shownSettings?.enabledLayouts ? defaultBookerLayoutSettings.enabledLayouts.indexOf(layout) > -1 : shownSettings.enabledLayouts.indexOf(layout) > -1; return layouts; }, {} as BookerLayoutState); const onLayoutToggleChange = useCallback( (changedLayout: BookerLayouts, checked: boolean) => { const newEnabledLayouts = Object.keys(toggleValues).filter((layout) => { if (changedLayout === layout) return checked === true; return toggleValues[layout as BookerLayouts] === true; }) as BookerLayouts[]; const isDefaultLayoutToggledOff = newEnabledLayouts.indexOf(defaultLayout) === -1; const firstEnabledLayout = newEnabledLayouts[0]; onChange({ enabledLayouts: newEnabledLayouts, // If default layout is toggled off, we set the default layout to the first enabled layout // if there's none enabled, we set it to month view. defaultLayout: isDefaultLayoutToggledOff ? firstEnabledLayout || BookerLayouts.MONTH_VIEW : defaultLayout, }); }, [defaultLayout, onChange, toggleValues] ); const onDefaultLayoutChange = useCallback( (newDefaultLayout: BookerLayouts) => { onChange({ enabledLayouts: Object.keys(toggleValues).filter( (layout) => toggleValues[layout as BookerLayouts] === true ) as BookerLayouts[], defaultLayout: newDefaultLayout, }); }, [toggleValues, onChange] ); const onOverrideSettings = () => { setIsOverridingSettings(true); // Sent default layout settings to form, otherwise it would still have 'null' as it's value. if (user?.defaultBookerLayouts) onChange(user.defaultBookerLayouts); }; return (
{bookerLayoutOptions.map((layout) => (
))}
{disableFields && (

You can manage this for all your event types in Settings {"-> "} Appearance {" "} or{" "} {" "} for this event only.

)}
); };