feat: added customClassnames for event-recurring tab (#17551)
* added classNames to common types * Update types.ts * feat: added custom classnames to event-recurring tab * Update EventTypePlatformWrapper.tsx * customClassnames -> customClassNames * added example classnames for demo * fixed classnames
This commit is contained in:
@@ -1,12 +1,20 @@
|
||||
import type { EventRecurringWebWrapperProps } from "@calcom/atoms/event-types/wrappers/EventRecurringWebWrapper";
|
||||
import getPaymentAppData from "@calcom/lib/getPaymentAppData";
|
||||
|
||||
import type { RecurringEventControllerProps } from "./RecurringEventController";
|
||||
import RecurringEventController from "./RecurringEventController";
|
||||
|
||||
export const EventRecurringTab = ({ eventType }: EventRecurringWebWrapperProps) => {
|
||||
export type EventRecurringTabProps = Omit<RecurringEventControllerProps, "paymentEnabled">;
|
||||
|
||||
export const EventRecurringTab = ({ eventType, customClassNames }: EventRecurringTabProps) => {
|
||||
const paymentAppData = getPaymentAppData(eventType);
|
||||
|
||||
const requirePayment = paymentAppData.price > 0;
|
||||
|
||||
return <RecurringEventController paymentEnabled={requirePayment} eventType={eventType} />;
|
||||
return (
|
||||
<RecurringEventController
|
||||
paymentEnabled={requirePayment}
|
||||
eventType={eventType}
|
||||
customClassNames={customClassNames}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+67
-15
@@ -2,7 +2,12 @@ import { useState } from "react";
|
||||
import { useFormContext } from "react-hook-form";
|
||||
|
||||
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
|
||||
import type { EventTypeSetup } from "@calcom/features/eventtypes/lib/types";
|
||||
import type {
|
||||
EventTypeSetup,
|
||||
InputClassNames,
|
||||
SelectClassNames,
|
||||
SettingsToggleClassNames,
|
||||
} from "@calcom/features/eventtypes/lib/types";
|
||||
import type { FormValues } from "@calcom/features/eventtypes/lib/types";
|
||||
import { classNames } from "@calcom/lib";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
@@ -10,14 +15,31 @@ import { Frequency } from "@calcom/prisma/zod-utils";
|
||||
import type { RecurringEvent } from "@calcom/types/Calendar";
|
||||
import { Alert, Select, SettingsToggle, TextField } from "@calcom/ui";
|
||||
|
||||
type RecurringEventControllerProps = {
|
||||
export type RecurringEventControllerProps = {
|
||||
eventType: EventTypeSetup;
|
||||
paymentEnabled: boolean;
|
||||
customClassNames?: EventRecurringTabCustomClassNames;
|
||||
};
|
||||
|
||||
export type EventRecurringTabCustomClassNames = {
|
||||
container?: string;
|
||||
recurringToggle?: SettingsToggleClassNames;
|
||||
frequencyInput?: InputClassNames;
|
||||
frequencyUnitSelect?: SelectClassNames;
|
||||
maxEventsInput?: {
|
||||
countInput?: string;
|
||||
labelText?: string;
|
||||
suffixText?: string;
|
||||
container?: string;
|
||||
};
|
||||
experimentalAlert?: string;
|
||||
paymentAlert?: string;
|
||||
};
|
||||
|
||||
export default function RecurringEventController({
|
||||
eventType,
|
||||
paymentEnabled,
|
||||
customClassNames,
|
||||
}: RecurringEventControllerProps) {
|
||||
const { t } = useLocale();
|
||||
const formMethods = useFormContext<FormValues>();
|
||||
@@ -37,25 +59,31 @@ export default function RecurringEventController({
|
||||
const recurringLocked = shouldLockDisableProps("recurringEvent");
|
||||
|
||||
return (
|
||||
<div className="block items-start sm:flex">
|
||||
<div className={classNames("block items-start sm:flex", customClassNames?.container)}>
|
||||
<div className={!paymentEnabled ? "w-full" : ""}>
|
||||
{paymentEnabled ? (
|
||||
<Alert severity="warning" title={t("warning_payment_recurring_event")} />
|
||||
<Alert
|
||||
severity="warning"
|
||||
className={customClassNames?.paymentAlert}
|
||||
title={t("warning_payment_recurring_event")}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Alert
|
||||
className="mb-4"
|
||||
className={classNames("mb-4", customClassNames?.experimentalAlert)}
|
||||
severity="warning"
|
||||
title="Experimental: Recurring Events are currently experimental and causes some issues sometimes when checking for availability. We are working on fixing this."
|
||||
/>
|
||||
<SettingsToggle
|
||||
labelClassName="text-sm"
|
||||
labelClassName={classNames("text-sm", customClassNames?.recurringToggle?.label)}
|
||||
toggleSwitchAtTheEnd={true}
|
||||
switchContainerClassName={classNames(
|
||||
"border-subtle rounded-lg border py-6 px-4 sm:px-6",
|
||||
recurringEventState !== null && "rounded-b-none"
|
||||
recurringEventState !== null && "rounded-b-none",
|
||||
customClassNames?.recurringToggle?.container
|
||||
)}
|
||||
childrenClassName="lg:ml-0"
|
||||
childrenClassName={classNames("lg:ml-0", customClassNames?.recurringToggle?.children)}
|
||||
descriptionClassName={customClassNames?.recurringToggle?.description}
|
||||
title={t("recurring_event")}
|
||||
{...recurringLocked}
|
||||
description={t("recurring_event_description")}
|
||||
@@ -79,13 +107,19 @@ export default function RecurringEventController({
|
||||
{recurringEventState && (
|
||||
<div data-testid="recurring-event-collapsible" className="text-sm">
|
||||
<div className="flex items-center">
|
||||
<p className="text-emphasis ltr:mr-2 rtl:ml-2">{t("repeats_every")}</p>
|
||||
<p
|
||||
className={classNames(
|
||||
"text-emphasis ltr:mr-2 rtl:ml-2",
|
||||
customClassNames?.frequencyInput?.label
|
||||
)}>
|
||||
{t("repeats_every")}
|
||||
</p>
|
||||
<TextField
|
||||
disabled={recurringLocked.disabled}
|
||||
type="number"
|
||||
min="1"
|
||||
max="20"
|
||||
className="mb-0"
|
||||
className={classNames("mb-0", customClassNames?.frequencyInput?.input)}
|
||||
defaultValue={recurringEventState.interval}
|
||||
onChange={(event) => {
|
||||
const newVal = {
|
||||
@@ -100,7 +134,11 @@ export default function RecurringEventController({
|
||||
options={recurringEventFreqOptions}
|
||||
value={recurringEventFreqOptions[recurringEventState.freq]}
|
||||
isSearchable={false}
|
||||
className="w-18 ml-2 block min-w-0 rounded-md text-sm"
|
||||
className={classNames(
|
||||
"w-18 ml-2 block min-w-0 rounded-md text-sm",
|
||||
customClassNames?.frequencyUnitSelect?.select
|
||||
)}
|
||||
innerClassNames={customClassNames?.frequencyUnitSelect?.innerClassNames}
|
||||
isDisabled={recurringLocked.disabled}
|
||||
onChange={(event) => {
|
||||
const newVal = {
|
||||
@@ -112,15 +150,25 @@ export default function RecurringEventController({
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-4 flex items-center">
|
||||
<p className="text-emphasis ltr:mr-2 rtl:ml-2">{t("for_a_maximum_of")}</p>
|
||||
<div
|
||||
className={classNames(
|
||||
"mt-4 flex items-center",
|
||||
customClassNames?.maxEventsInput?.container
|
||||
)}>
|
||||
<p
|
||||
className={classNames(
|
||||
"text-emphasis ltr:mr-2 rtl:ml-2",
|
||||
customClassNames?.maxEventsInput?.labelText
|
||||
)}>
|
||||
{t("for_a_maximum_of")}
|
||||
</p>
|
||||
<TextField
|
||||
disabled={recurringLocked.disabled}
|
||||
type="number"
|
||||
min="1"
|
||||
max="24"
|
||||
defaultValue={recurringEventState.count}
|
||||
className="mb-0"
|
||||
className={classNames("mb-0", customClassNames?.maxEventsInput?.countInput)}
|
||||
onChange={(event) => {
|
||||
const newVal = {
|
||||
...recurringEventState,
|
||||
@@ -130,7 +178,11 @@ export default function RecurringEventController({
|
||||
setRecurringEventState(newVal);
|
||||
}}
|
||||
/>
|
||||
<p className="text-emphasis ltr:ml-2 rtl:mr-2">
|
||||
<p
|
||||
className={classNames(
|
||||
"text-emphasis ltr:ml-2 rtl:mr-2",
|
||||
customClassNames?.maxEventsInput?.suffixText
|
||||
)}>
|
||||
{t("events", {
|
||||
count: recurringEventState.count,
|
||||
})}
|
||||
|
||||
@@ -166,3 +166,37 @@ export type TabMap = {
|
||||
workflows?: React.ReactNode;
|
||||
payments?: React.ReactNode;
|
||||
};
|
||||
|
||||
export type SettingsToggleClassNames = {
|
||||
container?: string;
|
||||
label?: string;
|
||||
description?: string;
|
||||
children?: string;
|
||||
};
|
||||
|
||||
export type InputClassNames = {
|
||||
container?: string;
|
||||
label?: string;
|
||||
input?: string;
|
||||
addOn?: string;
|
||||
};
|
||||
export type CheckboxClassNames = {
|
||||
checkbox?: string;
|
||||
description?: string;
|
||||
container?: string;
|
||||
};
|
||||
export type SelectClassNames = {
|
||||
innerClassNames?: {
|
||||
input?: string;
|
||||
option?: string;
|
||||
control?: string;
|
||||
singleValue?: string;
|
||||
valueContainer?: string;
|
||||
multiValue?: string;
|
||||
menu?: string;
|
||||
menuList?: string;
|
||||
};
|
||||
select?: string;
|
||||
label?: string;
|
||||
container?: string;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import type { EventRecurringTabProps } from "@calcom/features/eventtypes/components/tabs/recurring/EventRecurringTab";
|
||||
import { EventRecurringTab } from "@calcom/features/eventtypes/components/tabs/recurring/EventRecurringTab";
|
||||
import type { EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
|
||||
|
||||
export type EventRecurringWebWrapperProps = Pick<EventTypeSetupProps, "eventType">;
|
||||
|
||||
const EventRecurringTabPlatformWrapper = (props: EventRecurringWebWrapperProps) => {
|
||||
const EventRecurringTabPlatformWrapper = (props: EventRecurringTabProps) => {
|
||||
return <EventRecurringTab {...props} />;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import type { EventRecurringTabProps } from "@calcom/features/eventtypes/components/tabs/recurring/EventRecurringTab";
|
||||
import { EventRecurringTab } from "@calcom/features/eventtypes/components/tabs/recurring/EventRecurringTab";
|
||||
import type { EventTypeSetupProps } from "@calcom/features/eventtypes/lib/types";
|
||||
|
||||
export type EventRecurringWebWrapperProps = Pick<EventTypeSetupProps, "eventType">;
|
||||
|
||||
const EventRecurringWebWrapper = (props: EventRecurringWebWrapperProps) => {
|
||||
const EventRecurringWebWrapper = (props: EventRecurringTabProps) => {
|
||||
return <EventRecurringTab {...props} />;
|
||||
};
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useRef, useState, useEffect } from "react";
|
||||
import type { ChildrenEventType } from "@calcom/features/eventtypes/components/ChildrenEventTypeSelect";
|
||||
import { EventType as EventTypeComponent } from "@calcom/features/eventtypes/components/EventType";
|
||||
import ManagedEventTypeDialog from "@calcom/features/eventtypes/components/dialogs/ManagedEventDialog";
|
||||
import type { EventRecurringTabCustomClassNames } from "@calcom/features/eventtypes/components/tabs/recurring/RecurringEventController";
|
||||
import type { EventTypeSetupProps, FormValues, TabMap } from "@calcom/features/eventtypes/lib/types";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { SchedulingType } from "@calcom/prisma/enums";
|
||||
@@ -30,6 +31,11 @@ import EventTeamAssignmentTabPlatformWrapper from "./EventTeamAssignmentTabPlatf
|
||||
|
||||
export type PlatformTabs = keyof Omit<TabMap, "workflows" | "webhooks" | "instant" | "ai" | "apps">;
|
||||
|
||||
export type EventTypeCustomClassNames = {
|
||||
atomsWrapper?: string;
|
||||
eventRecurringTab?: EventRecurringTabCustomClassNames;
|
||||
};
|
||||
|
||||
export type EventTypePlatformWrapperProps = {
|
||||
id: number;
|
||||
tabs?: PlatformTabs[];
|
||||
@@ -38,9 +44,7 @@ export type EventTypePlatformWrapperProps = {
|
||||
onDeleteSuccess?: () => void;
|
||||
onDeleteError?: (msg: string) => void;
|
||||
allowDelete: boolean;
|
||||
customClassNames?: {
|
||||
atomsWrapper?: string;
|
||||
};
|
||||
customClassNames?: EventTypeCustomClassNames;
|
||||
disableToasts?: boolean;
|
||||
};
|
||||
|
||||
@@ -178,7 +182,10 @@ const EventType = ({
|
||||
limits: tabs.includes("limits") ? <EventLimitsTabPlatformWrapper eventType={eventType} /> : <></>,
|
||||
instant: <></>,
|
||||
recurring: tabs.includes("recurring") ? (
|
||||
<EventRecurringTabPlatformWrapper eventType={eventType} />
|
||||
<EventRecurringTabPlatformWrapper
|
||||
eventType={eventType}
|
||||
customClassNames={customClassNames?.eventRecurringTab}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
|
||||
@@ -95,7 +95,47 @@ export default function Bookings(props: { calUsername: string; calEmail: string
|
||||
{eventTypeId && (
|
||||
<div>
|
||||
<EventTypeSettings
|
||||
customClassNames={{ atomsWrapper: "!w-[50vw] !m-auto" }}
|
||||
customClassNames={{
|
||||
atomsWrapper: "!w-[50vw] !m-auto",
|
||||
eventRecurringTab: {
|
||||
container: "border border-purple-200 bg-purple-50 rounded-lg shadow-sm",
|
||||
recurringToggle: {
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
label: "text-purple-700",
|
||||
description: "text-purple-500",
|
||||
children: "bg-purple-50 rounded-md",
|
||||
},
|
||||
frequencyInput: {
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
label: "text-purple-700",
|
||||
input: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
addOn: "text-purple-500",
|
||||
},
|
||||
frequencyUnitSelect: {
|
||||
select: "border border-purple-300 rounded-md text-purple-900 bg-purple-50",
|
||||
label: "text-purple-700",
|
||||
container: "mb-4",
|
||||
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: "",
|
||||
},
|
||||
},
|
||||
maxEventsInput: {
|
||||
countInput: "border border-purple-300 rounded-md text-purple-900 bg-white",
|
||||
labelText: "text-purple-700",
|
||||
suffixText: "text-purple-500",
|
||||
container: "border border-purple-200 bg-purple-100 rounded-lg",
|
||||
},
|
||||
experimentalAlert: "border border-red-300 bg-red-50 rounded-lg text-red-900 shadow-sm",
|
||||
paymentAlert: "border border-purple-300 bg-purple-100 rounded-lg text-purple-900 shadow-md",
|
||||
},
|
||||
}}
|
||||
allowDelete={true}
|
||||
id={eventTypeId}
|
||||
tabs={["setup", "limits", "recurring", "advanced", "availability", "team", "payments"]}
|
||||
|
||||
Reference in New Issue
Block a user