feat: added customClassnames for event-setup tab (#17240)
* feat: added customClassnames for event-setup tab * Update EventTypePlatformWrapper.tsx * better classnames naming * added classNames to common types * updated classnames to use the common exported types * udpate * better classnames * better classname names * classnames -> classNames * added default styling * Update Locations.tsx * Update event-types.tsx * update * locationSelectCustomClassNames -> LocationSelectCustomClassNames * Update documentation.json * fix: better classnames * Update types.ts
This commit is contained in:
@@ -9,10 +9,18 @@ import type { UseFormGetValues, UseFormSetValue, Control, FormState } from "reac
|
||||
import type { EventLocationType } from "@calcom/app-store/locations";
|
||||
import { getEventLocationType, MeetLocationType } from "@calcom/app-store/locations";
|
||||
import { useIsPlatform } from "@calcom/atoms/monorepo";
|
||||
import type { LocationFormValues, EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
|
||||
import type {
|
||||
LocationFormValues,
|
||||
EventTypeSetupProps,
|
||||
CheckboxClassNames,
|
||||
} from "@calcom/features/eventtypes/lib/types";
|
||||
import CheckboxField from "@calcom/features/form/components/CheckboxField";
|
||||
import type { SingleValueLocationOption } from "@calcom/features/form/components/LocationSelect";
|
||||
import type {
|
||||
LocationSelectCustomClassNames,
|
||||
SingleValueLocationOption,
|
||||
} from "@calcom/features/form/components/LocationSelect";
|
||||
import LocationSelect from "@calcom/features/form/components/LocationSelect";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { WEBAPP_URL } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { Icon, Input, PhoneInput, Button, showToast } from "@calcom/ui";
|
||||
@@ -22,6 +30,24 @@ export type TLocationOptions = Pick<EventTypeSetupProps, "locationOptions">["loc
|
||||
export type TDestinationCalendar = { integration: string } | null;
|
||||
export type TPrefillLocation = { credentialId?: number; type: string };
|
||||
|
||||
type LocationInputCustomClassNames = {
|
||||
addressInput?: string;
|
||||
phoneInput?: string;
|
||||
};
|
||||
|
||||
export type LocationCustomClassNames = {
|
||||
container?: string;
|
||||
locationSelect?: LocationSelectCustomClassNames;
|
||||
removeLocationButton?: string;
|
||||
removeLocationIcon?: string;
|
||||
addLocationButton?: string;
|
||||
organizerContactInput?: {
|
||||
errorMessage?: string;
|
||||
locationInput?: LocationInputCustomClassNames;
|
||||
publicDisplayCheckbox?: CheckboxClassNames;
|
||||
};
|
||||
};
|
||||
|
||||
type LocationsProps = {
|
||||
team: { id: number } | null;
|
||||
destinationCalendar: TDestinationCalendar;
|
||||
@@ -36,6 +62,7 @@ type LocationsProps = {
|
||||
eventType: TEventTypeLocation;
|
||||
locationOptions: TLocationOptions;
|
||||
prefillLocation?: SingleValueLocationOption;
|
||||
customClassNames?: LocationCustomClassNames;
|
||||
};
|
||||
|
||||
const getLocationFromType = (type: EventLocationType["type"], locationOptions: TLocationOptions) => {
|
||||
@@ -84,6 +111,7 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
team,
|
||||
eventType,
|
||||
prefillLocation,
|
||||
customClassNames,
|
||||
...props
|
||||
}) => {
|
||||
const { t } = useLocale();
|
||||
@@ -135,8 +163,9 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
eventLocationType: EventLocationType;
|
||||
defaultValue?: string;
|
||||
index: number;
|
||||
customClassNames?: LocationInputCustomClassNames;
|
||||
}) => {
|
||||
const { eventLocationType, index, ...remainingProps } = props;
|
||||
const { eventLocationType, index, customClassNames, ...remainingProps } = props;
|
||||
if (eventLocationType?.organizerInputType === "text") {
|
||||
const { defaultValue, ...rest } = remainingProps;
|
||||
|
||||
@@ -154,7 +183,7 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
{...(disableLocationProp ? { disabled: true } : {})}
|
||||
className="my-0"
|
||||
className={classNames("my-0", customClassNames?.addressInput)}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
@@ -175,6 +204,7 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
disabled={disableLocationProp}
|
||||
placeholder={t(eventLocationType.organizerInputPlaceholder || "")}
|
||||
name={`locations[${index}].${eventLocationType.defaultValueVariable}`}
|
||||
className={customClassNames?.phoneInput}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
{...rest}
|
||||
@@ -213,8 +243,8 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
const isPlatorm = useIsPlatform();
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<ul ref={animationRef} className="space-y-2">
|
||||
<div className={classNames("w-full", customClassNames?.container)}>
|
||||
<ul ref={animationRef} className={classNames("space-y-2")}>
|
||||
{locationFields.map((field, index) => {
|
||||
const eventLocationType = getEventLocationType(field.type);
|
||||
const defaultLocation = field;
|
||||
@@ -230,7 +260,11 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
isDisabled={disableLocationProp}
|
||||
defaultValue={option}
|
||||
isSearchable={false}
|
||||
className="block min-w-0 flex-1 rounded-sm text-sm"
|
||||
className={classNames(
|
||||
"block min-w-0 flex-1 rounded-sm text-sm",
|
||||
customClassNames?.locationSelect?.selectWrapper
|
||||
)}
|
||||
customClassNames={customClassNames?.locationSelect}
|
||||
menuPlacement="auto"
|
||||
onChange={(e: SingleValueLocationOption) => {
|
||||
setShowEmptyLocationSelect(false);
|
||||
@@ -275,12 +309,18 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
{!(disableLocationProp && isChildrenManagedEventType) && (
|
||||
<button
|
||||
data-testid={`delete-locations.${index}.type`}
|
||||
className="min-h-9 block h-9 px-2"
|
||||
className={classNames("min-h-9 block h-9 px-2", customClassNames?.removeLocationButton)}
|
||||
type="button"
|
||||
onClick={() => remove(index)}
|
||||
aria-label={t("remove")}>
|
||||
<div className="h-4 w-4">
|
||||
<Icon name="x" className="border-l-1 hover:text-emphasis text-subtle h-4 w-4" />
|
||||
<Icon
|
||||
name="x"
|
||||
className={classNames(
|
||||
"border-l-1 hover:text-emphasis text-subtle h-4 w-4",
|
||||
customClassNames?.removeLocationIcon
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</button>
|
||||
)}
|
||||
@@ -302,23 +342,32 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
}
|
||||
eventLocationType={eventLocationType}
|
||||
index={index}
|
||||
customClassNames={customClassNames?.organizerContactInput?.locationInput}
|
||||
/>
|
||||
</div>
|
||||
<ErrorMessage
|
||||
errors={formState.errors?.locations?.[index]}
|
||||
name={eventLocationType.defaultValueVariable}
|
||||
className="text-error my-1 ml-6 text-sm"
|
||||
className={classNames(
|
||||
"text-error my-1 ml-6 text-sm",
|
||||
customClassNames?.organizerContactInput?.errorMessage
|
||||
)}
|
||||
as="div"
|
||||
id="location-error"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-6">
|
||||
<div
|
||||
className={classNames(
|
||||
"ml-6",
|
||||
customClassNames?.organizerContactInput?.publicDisplayCheckbox?.container
|
||||
)}>
|
||||
<CheckboxField
|
||||
name={`locations[${index}].displayLocationPublicly`}
|
||||
data-testid="display-location"
|
||||
disabled={disableLocationProp}
|
||||
defaultChecked={defaultLocation?.displayLocationPublicly}
|
||||
description={t("display_location_label")}
|
||||
className={customClassNames?.organizerContactInput?.publicDisplayCheckbox?.checkbox}
|
||||
onChange={(e) => {
|
||||
const fieldValues = getValues("locations")[index];
|
||||
updateLocationField(index, {
|
||||
@@ -344,7 +393,11 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
isDisabled={disableLocationProp}
|
||||
defaultValue={defaultValue}
|
||||
isSearchable={false}
|
||||
className="block w-full min-w-0 flex-1 rounded-sm text-sm"
|
||||
className={classNames(
|
||||
"block w-full min-w-0 flex-1 rounded-sm text-sm",
|
||||
customClassNames?.locationSelect?.selectWrapper
|
||||
)}
|
||||
customClassNames={customClassNames?.locationSelect}
|
||||
menuPlacement="auto"
|
||||
onChange={(e: SingleValueLocationOption) => {
|
||||
setShowEmptyLocationSelect(false);
|
||||
@@ -413,6 +466,7 @@ const Locations: React.FC<LocationsProps> = ({
|
||||
StartIcon="plus"
|
||||
color="minimal"
|
||||
disabled={seatsEnabled}
|
||||
className={classNames(customClassNames?.addLocationButton)}
|
||||
tooltip={seatsEnabled ? t("seats_option_doesnt_support_multi_location") : undefined}
|
||||
onClick={() => setShowEmptyLocationSelect(true)}>
|
||||
{t("add_location")}
|
||||
|
||||
@@ -5,26 +5,59 @@ import type { MultiValue } from "react-select";
|
||||
|
||||
import { useIsPlatform } from "@calcom/atoms/monorepo";
|
||||
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
|
||||
import type { LocationCustomClassNames } from "@calcom/features/eventtypes/components/Locations";
|
||||
import Locations from "@calcom/features/eventtypes/components/Locations";
|
||||
import type { EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
|
||||
import type {
|
||||
EventTypeSetupProps,
|
||||
InputClassNames,
|
||||
SelectClassNames,
|
||||
SettingsToggleClassNames,
|
||||
} from "@calcom/features/eventtypes/lib/types";
|
||||
import type { FormValues, LocationFormValues } from "@calcom/features/eventtypes/lib/types";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { md } from "@calcom/lib/markdownIt";
|
||||
import { slugify } from "@calcom/lib/slugify";
|
||||
import turndown from "@calcom/lib/turndownService";
|
||||
import { Label, Select, SettingsToggle, Skeleton, TextField, Editor, TextAreaField } from "@calcom/ui";
|
||||
|
||||
export type EventSetupTabCustomClassNames = {
|
||||
wrapper?: string;
|
||||
titleSection?: {
|
||||
container?: string;
|
||||
titleInput?: InputClassNames;
|
||||
urlInput?: InputClassNames;
|
||||
descriptionInput?: Pick<InputClassNames, "input" | "label">;
|
||||
};
|
||||
durationSection?: {
|
||||
container?: string;
|
||||
singleDurationInput?: InputClassNames;
|
||||
multipleDuration?: {
|
||||
container?: string;
|
||||
availableDurationsSelect?: SelectClassNames;
|
||||
defaultDurationSelect?: SelectClassNames;
|
||||
};
|
||||
selectDurationToggle?: SettingsToggleClassNames;
|
||||
};
|
||||
locationSection?: LocationCustomClassNames & {
|
||||
container?: string;
|
||||
label?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type EventSetupTabProps = Pick<
|
||||
EventTypeSetupProps,
|
||||
"eventType" | "locationOptions" | "team" | "teamMembers" | "destinationCalendar"
|
||||
>;
|
||||
> & {
|
||||
customClassNames?: EventSetupTabCustomClassNames;
|
||||
};
|
||||
export const EventSetupTab = (
|
||||
props: EventSetupTabProps & { urlPrefix: string; hasOrgBranding: boolean; orgId?: number }
|
||||
) => {
|
||||
const { t } = useLocale();
|
||||
const isPlatform = useIsPlatform();
|
||||
const formMethods = useFormContext<FormValues>();
|
||||
const { eventType, team, urlPrefix, hasOrgBranding, orgId } = props;
|
||||
const { eventType, team, urlPrefix, hasOrgBranding, customClassNames, orgId } = props;
|
||||
const [multipleDuration, setMultipleDuration] = useState(
|
||||
formMethods.getValues("metadata")?.multipleDuration
|
||||
);
|
||||
@@ -60,10 +93,17 @@ export const EventSetupTab = (
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="space-y-4">
|
||||
<div className="border-subtle space-y-6 rounded-lg border p-6">
|
||||
<div className={classNames("space-y-4", customClassNames?.wrapper)}>
|
||||
<div
|
||||
className={classNames(
|
||||
"border-subtle space-y-6 rounded-lg border p-6",
|
||||
customClassNames?.titleSection?.container
|
||||
)}>
|
||||
<TextField
|
||||
required
|
||||
containerClassName={classNames(customClassNames?.titleSection?.titleInput?.container)}
|
||||
labelClassName={classNames(customClassNames?.titleSection?.titleInput?.label)}
|
||||
className={classNames(customClassNames?.titleSection?.titleInput?.input)}
|
||||
label={t("title")}
|
||||
{...(isManagedEventType || isChildrenManagedEventType ? titleLockedProps : {})}
|
||||
defaultValue={eventType.title}
|
||||
@@ -77,6 +117,10 @@ export const EventSetupTab = (
|
||||
disabled: descriptionLockedProps.disabled,
|
||||
})}
|
||||
placeholder={t("quick_video_meeting")}
|
||||
className={customClassNames?.titleSection?.descriptionInput?.input}
|
||||
labelProps={{
|
||||
className: customClassNames?.titleSection?.descriptionInput?.label,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
@@ -115,6 +159,9 @@ export const EventSetupTab = (
|
||||
{...(isManagedEventType || isChildrenManagedEventType ? urlLockedProps : {})}
|
||||
defaultValue={eventType.slug}
|
||||
data-testid="event-slug"
|
||||
containerClassName={classNames(customClassNames?.titleSection?.urlInput?.container)}
|
||||
labelClassName={classNames(customClassNames?.titleSection?.urlInput?.label)}
|
||||
className={classNames(customClassNames?.titleSection?.urlInput?.input)}
|
||||
addOnLeading={
|
||||
isPlatform ? undefined : (
|
||||
<>
|
||||
@@ -133,11 +180,24 @@ export const EventSetupTab = (
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className="border-subtle rounded-lg border p-6">
|
||||
<div
|
||||
className={classNames(
|
||||
"border-subtle rounded-lg border p-6",
|
||||
customClassNames?.durationSection?.container
|
||||
)}>
|
||||
{multipleDuration ? (
|
||||
<div className="space-y-6">
|
||||
<div
|
||||
className={classNames(
|
||||
"space-y-6",
|
||||
customClassNames?.durationSection?.multipleDuration?.availableDurationsSelect?.container
|
||||
)}>
|
||||
<div>
|
||||
<Skeleton as={Label} loadingClassName="w-16">
|
||||
<Skeleton
|
||||
as={Label}
|
||||
loadingClassName="w-16"
|
||||
className={
|
||||
customClassNames?.durationSection?.multipleDuration?.availableDurationsSelect?.label
|
||||
}>
|
||||
{t("available_durations")}
|
||||
</Skeleton>
|
||||
<Select
|
||||
@@ -146,7 +206,14 @@ export const EventSetupTab = (
|
||||
name="metadata.multipleDuration"
|
||||
isSearchable={false}
|
||||
isDisabled={lengthLockedProps.disabled}
|
||||
className="h-auto !min-h-[36px] text-sm"
|
||||
className={classNames(
|
||||
"h-auto !min-h-[36px] text-sm",
|
||||
customClassNames?.durationSection?.multipleDuration?.availableDurationsSelect?.select
|
||||
)}
|
||||
innerClassNames={
|
||||
customClassNames?.durationSection?.multipleDuration?.availableDurationsSelect
|
||||
?.innerClassNames
|
||||
}
|
||||
options={multipleDurationOptions}
|
||||
value={selectedMultipleDuration}
|
||||
onChange={(options) => {
|
||||
@@ -173,8 +240,16 @@ export const EventSetupTab = (
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Skeleton as={Label} loadingClassName="w-16">
|
||||
<div
|
||||
className={
|
||||
customClassNames?.durationSection?.multipleDuration?.defaultDurationSelect?.container
|
||||
}>
|
||||
<Skeleton
|
||||
as={Label}
|
||||
loadingClassName="w-16"
|
||||
className={
|
||||
customClassNames?.durationSection?.multipleDuration?.defaultDurationSelect?.label
|
||||
}>
|
||||
{t("default_duration")}
|
||||
{shouldLockIndicator("length")}
|
||||
</Skeleton>
|
||||
@@ -182,7 +257,14 @@ export const EventSetupTab = (
|
||||
value={defaultDuration}
|
||||
isSearchable={false}
|
||||
name="length"
|
||||
className="text-sm"
|
||||
className={classNames(
|
||||
"text-sm",
|
||||
customClassNames?.durationSection?.multipleDuration?.defaultDurationSelect?.select
|
||||
)}
|
||||
innerClassNames={
|
||||
customClassNames?.durationSection?.multipleDuration?.defaultDurationSelect
|
||||
?.innerClassNames
|
||||
}
|
||||
isDisabled={lengthLockedProps.disabled}
|
||||
noOptionsMessage={() => t("default_duration_no_options")}
|
||||
options={selectedMultipleDuration}
|
||||
@@ -199,6 +281,11 @@ export const EventSetupTab = (
|
||||
<TextField
|
||||
required
|
||||
type="number"
|
||||
containerClassName={classNames(
|
||||
customClassNames?.durationSection?.singleDurationInput?.container
|
||||
)}
|
||||
labelClassName={classNames(customClassNames?.durationSection?.singleDurationInput?.label)}
|
||||
className={classNames(customClassNames?.durationSection?.singleDurationInput?.input)}
|
||||
data-testid="duration"
|
||||
{...(isManagedEventType || isChildrenManagedEventType ? lengthLockedProps : {})}
|
||||
label={t("duration")}
|
||||
@@ -215,6 +302,10 @@ export const EventSetupTab = (
|
||||
checked={multipleDuration !== undefined}
|
||||
disabled={seatsEnabled}
|
||||
tooltip={seatsEnabled ? t("seat_options_doesnt_multiple_durations") : undefined}
|
||||
labelClassName={customClassNames?.durationSection?.selectDurationToggle?.label}
|
||||
descriptionClassName={customClassNames?.durationSection?.selectDurationToggle?.description}
|
||||
switchContainerClassName={customClassNames?.durationSection?.selectDurationToggle?.container}
|
||||
childrenClassName={customClassNames?.durationSection?.selectDurationToggle?.children}
|
||||
onCheckedChange={() => {
|
||||
if (multipleDuration !== undefined) {
|
||||
setMultipleDuration(undefined);
|
||||
@@ -232,9 +323,17 @@ export const EventSetupTab = (
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="border-subtle rounded-lg border p-6">
|
||||
<div
|
||||
className={classNames(
|
||||
"border-subtle rounded-lg border p-6",
|
||||
customClassNames?.locationSection?.container
|
||||
)}>
|
||||
<div>
|
||||
<Skeleton as={Label} loadingClassName="w-16" htmlFor="locations">
|
||||
<Skeleton
|
||||
as={Label}
|
||||
loadingClassName="w-16"
|
||||
htmlFor="locations"
|
||||
className={customClassNames?.locationSection?.label}>
|
||||
{t("location")}
|
||||
{/*improve shouldLockIndicator function to also accept eventType and then conditionally render
|
||||
based on Managed Event type or not.*/}
|
||||
@@ -255,6 +354,7 @@ export const EventSetupTab = (
|
||||
control={formMethods.control as unknown as Control<LocationFormValues>}
|
||||
formState={formMethods.formState as unknown as FormState<LocationFormValues>}
|
||||
{...props}
|
||||
customClassNames={customClassNames?.locationSection}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -7,6 +7,14 @@ import { classNames } from "@calcom/lib";
|
||||
import invertLogoOnDark from "@calcom/lib/invertLogoOnDark";
|
||||
import { Select, Icon } from "@calcom/ui";
|
||||
|
||||
export type LocationSelectCustomClassNames = {
|
||||
optionIcon?: string;
|
||||
optionLabel?: string;
|
||||
optionWrapper?: string;
|
||||
groupLabel?: string;
|
||||
selectWrapper?: string;
|
||||
};
|
||||
|
||||
export type LocationOption = {
|
||||
label: string;
|
||||
value: EventLocationType["type"];
|
||||
@@ -15,39 +23,50 @@ export type LocationOption = {
|
||||
address?: string;
|
||||
credentialId?: number;
|
||||
teamName?: string;
|
||||
customClassNames?: LocationSelectCustomClassNames;
|
||||
};
|
||||
|
||||
export type SingleValueLocationOption = SingleValue<LocationOption>;
|
||||
|
||||
export type GroupOptionType = GroupBase<LocationOption>;
|
||||
|
||||
const OptionWithIcon = ({ icon, label, value }: { icon?: string; label: string; value: string }) => {
|
||||
const OptionWithIcon = ({
|
||||
icon,
|
||||
label,
|
||||
value,
|
||||
customClassNames,
|
||||
}: {
|
||||
icon?: string;
|
||||
label: string;
|
||||
value: string;
|
||||
customClassNames?: LocationSelectCustomClassNames;
|
||||
}) => {
|
||||
const isPlatform = useIsPlatform();
|
||||
|
||||
const getIconFromValue = (value: string) => {
|
||||
switch (value) {
|
||||
case "phone":
|
||||
return <Icon name="phone" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="phone" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
case "userPhone":
|
||||
return <Icon name="phone" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="phone" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
case "inPerson":
|
||||
return <Icon name="map-pin" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="map-pin" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
case "attendeeInPerson":
|
||||
return <Icon name="map-pin" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="map-pin" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
case "link":
|
||||
return <Icon name="link" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="link" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
case "somewhereElse":
|
||||
return <Icon name="map" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="map" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
default:
|
||||
return <Icon name="video" className="h-3.5 w-3.5" />;
|
||||
return <Icon name="video" className={classNames("h-3.5 w-3.5", customClassNames?.optionIcon)} />;
|
||||
}
|
||||
};
|
||||
|
||||
if (isPlatform) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={classNames("flex items-center gap-3", customClassNames?.optionWrapper)}>
|
||||
{getIconFromValue(value)}
|
||||
<span className={classNames("text-sm font-medium")}>{label}</span>
|
||||
<span className={classNames("text-sm font-medium", customClassNames?.optionLabel)}>{label}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -55,12 +74,15 @@ const OptionWithIcon = ({ icon, label, value }: { icon?: string; label: string;
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
{icon && <img src={icon} alt="cover" className={classNames("h-3.5 w-3.5", invertLogoOnDark(icon))} />}
|
||||
<span className={classNames("text-sm font-medium")}>{label}</span>
|
||||
<span className={classNames(" text-sm font-medium")}>{label}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default function LocationSelect(props: Props<LocationOption, false, GroupOptionType>) {
|
||||
export default function LocationSelect({
|
||||
customClassNames,
|
||||
...props
|
||||
}: Props<LocationOption, false, GroupOptionType> & { customClassNames?: LocationSelectCustomClassNames }) {
|
||||
const isPlatform = useIsPlatform();
|
||||
return (
|
||||
<Select<LocationOption>
|
||||
@@ -72,7 +94,12 @@ export default function LocationSelect(props: Props<LocationOption, false, Group
|
||||
return (
|
||||
<components.Option {...props}>
|
||||
<div data-testid={`location-select-item-${props.data.value}`}>
|
||||
<OptionWithIcon icon={props.data.icon} label={props.data.label} value={props.data.value} />
|
||||
<OptionWithIcon
|
||||
icon={props.data.icon}
|
||||
label={props.data.label}
|
||||
value={props.data.value}
|
||||
customClassNames={customClassNames}
|
||||
/>
|
||||
</div>
|
||||
</components.Option>
|
||||
);
|
||||
@@ -81,7 +108,12 @@ export default function LocationSelect(props: Props<LocationOption, false, Group
|
||||
return (
|
||||
<components.SingleValue {...props}>
|
||||
<div data-testid={`location-select-item-${props.data.value}`}>
|
||||
<OptionWithIcon icon={props.data.icon} label={props.data.label} value={props.data.value} />
|
||||
<OptionWithIcon
|
||||
icon={props.data.icon}
|
||||
label={props.data.label}
|
||||
value={props.data.value}
|
||||
customClassNames={customClassNames}
|
||||
/>
|
||||
</div>
|
||||
</components.SingleValue>
|
||||
);
|
||||
@@ -99,7 +131,11 @@ export default function LocationSelect(props: Props<LocationOption, false, Group
|
||||
<span>{e.label}</span>
|
||||
</div>
|
||||
)}
|
||||
formatGroupLabel={(e) => <p className="text-default text-xs font-medium">{e.label}</p>}
|
||||
formatGroupLabel={(e) => (
|
||||
<p className={classNames("text-default text-xs font-medium", customClassNames?.groupLabel)}>
|
||||
{e.label}
|
||||
</p>
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -11,6 +11,7 @@ import type { EventTeamAssignmentTabCustomClassNames } from "@calcom/features/ev
|
||||
import type { EventAvailabilityTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/availability/EventAvailabilityTab";
|
||||
import type { EventLimitsTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/limits/EventLimitsTab";
|
||||
import type { EventRecurringTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/recurring/RecurringEventController";
|
||||
import type { EventSetupTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/setup/EventSetupTab";
|
||||
import type { EventTypeSetupProps, FormValues, TabMap } from "@calcom/features/eventtypes/lib/types";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
@@ -37,6 +38,7 @@ export type PlatformTabs = keyof Omit<TabMap, "workflows" | "webhooks" | "instan
|
||||
|
||||
export type EventTypeCustomClassNames = {
|
||||
atomsWrapper?: string;
|
||||
eventSetupTab?: EventSetupTabCustomClassNames;
|
||||
eventLimitsTab?: EventLimitsTabCustomClassNames;
|
||||
eventAdvancedTab?: EventAdvancedTabCustomClassNames;
|
||||
eventAssignmentTab?: EventTeamAssignmentTabCustomClassNames;
|
||||
@@ -52,7 +54,7 @@ export type EventTypePlatformWrapperProps = {
|
||||
onDeleteSuccess?: () => void;
|
||||
onDeleteError?: (msg: string) => void;
|
||||
allowDelete: boolean;
|
||||
customClassNames?: eventTypeCustomClassNames;
|
||||
customClassNames?: EventTypeCustomClassNames;
|
||||
disableToasts?: boolean;
|
||||
};
|
||||
|
||||
@@ -156,6 +158,7 @@ const EventType = ({
|
||||
team={team}
|
||||
teamMembers={teamMembers}
|
||||
destinationCalendar={destinationCalendar}
|
||||
customClassNames={customClassNames?.eventSetupTab}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
|
||||
@@ -635,6 +635,92 @@ export default function Bookings(props: { calUsername: string; calEmail: string
|
||||
},
|
||||
},
|
||||
},
|
||||
eventSetupTab: {
|
||||
wrapper: "rounded-lg shadow-sm",
|
||||
titleSection: {
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
titleInput: {
|
||||
container: "mb-4",
|
||||
label: "text-purple-700",
|
||||
input: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
addOn: "text-purple-500",
|
||||
},
|
||||
urlInput: {
|
||||
container: "mb-4",
|
||||
label: "text-purple-700",
|
||||
input: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
addOn: "text-purple-500",
|
||||
},
|
||||
descriptionInput: {
|
||||
label: "text-purple-700",
|
||||
input: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
},
|
||||
},
|
||||
durationSection: {
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
singleDurationInput: {
|
||||
container: "mb-4",
|
||||
label: "text-purple-700",
|
||||
input: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
addOn: "text-purple-500",
|
||||
},
|
||||
multipleDuration: {
|
||||
container: "space-y-2",
|
||||
availableDurationsSelect: {
|
||||
container: "mb-4",
|
||||
label: "text-purple-700",
|
||||
select: "border border-purple-300 rounded-md text-purple-900 bg-purple-50",
|
||||
innerClassNames: {
|
||||
input: "text-purple-900",
|
||||
option: "text-purple-700 hover:bg-purple-200",
|
||||
control: "border-purple-300",
|
||||
singleValue: "text-purple-900",
|
||||
valueContainer: "bg-purple-100",
|
||||
multiValue: "bg-purple-200 rounded-md text-purple-900",
|
||||
menu: "border border-purple-200 rounded-md",
|
||||
menuList: "",
|
||||
},
|
||||
},
|
||||
defaultDurationSelect: {
|
||||
container: "mb-4",
|
||||
label: "text-purple-700",
|
||||
select: "border border-purple-300 rounded-md text-purple-900 bg-purple-50",
|
||||
},
|
||||
},
|
||||
selectDurationToggle: {
|
||||
container: "",
|
||||
label: "text-purple-700",
|
||||
description: "text-purple-500",
|
||||
children: "",
|
||||
},
|
||||
},
|
||||
locationSection: {
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
label: "text-purple-700",
|
||||
locationSelect: {
|
||||
optionIcon: "text-purple-500",
|
||||
optionLabel: "text-purple-800",
|
||||
optionWrapper: "hover:bg-purple-200 rounded-md",
|
||||
groupLabel: "text-purple-700",
|
||||
selectWrapper: "border border-purple-300 rounded-md text-purple-900 bg-purple-50",
|
||||
},
|
||||
removeLocationButton: "text-purple-500 hover:bg-purple-200 rounded-md",
|
||||
removeLocationIcon: "text-purple-500",
|
||||
addLocationButton: "text-purple-500 hover:bg-purple-200 rounded-md",
|
||||
organizerContactInput: {
|
||||
errorMessage: "text-purple-500",
|
||||
locationInput: {
|
||||
addressInput: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
phoneInput: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
},
|
||||
publicDisplayCheckbox: {
|
||||
checkbox: "border border-purple-300 text-purple-500",
|
||||
description: "text-purple-500",
|
||||
container: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
allowDelete={true}
|
||||
id={eventTypeId}
|
||||
|
||||
Reference in New Issue
Block a user