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:
Somay Chauhan
2024-11-22 12:30:02 +05:30
committed by GitHub
parent 4b34aec13d
commit d03651312e
7 changed files with 168 additions and 31 deletions
@@ -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}
/>
);
};
@@ -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,
})}
+34
View File
@@ -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"]}