diff --git a/packages/core/EventManager.ts b/packages/core/EventManager.ts
index 4b3b3564b1..283b49e047 100644
--- a/packages/core/EventManager.ts
+++ b/packages/core/EventManager.ts
@@ -455,9 +455,9 @@ export default class EventManager {
return [];
}
const { uid: bookingRefUid, externalCalendarId: bookingExternalCalendarId } = calendarReference;
-
- if (!bookingExternalCalendarId) {
- throw new Error("externalCalendarId");
+ let calenderExternalId: string | null = null;
+ if (bookingExternalCalendarId) {
+ calenderExternalId = bookingExternalCalendarId;
}
let result = [];
@@ -465,13 +465,13 @@ export default class EventManager {
credential = this.calendarCredentials.filter(
(credential) => credential.id === calendarReference?.credentialId
)[0];
- result.push(updateEvent(credential, event, bookingRefUid, bookingExternalCalendarId));
+ result.push(updateEvent(credential, event, bookingRefUid, calenderExternalId));
} else {
const credentials = this.calendarCredentials.filter(
(credential) => credential.type === calendarReference?.type
);
for (const credential of credentials) {
- result.push(updateEvent(credential, event, bookingRefUid, bookingExternalCalendarId));
+ result.push(updateEvent(credential, event, bookingRefUid, calenderExternalId));
}
}
diff --git a/packages/emails/src/components/CallToAction.tsx b/packages/emails/src/components/CallToAction.tsx
index 04007623c7..e7f09d14d6 100644
--- a/packages/emails/src/components/CallToAction.tsx
+++ b/packages/emails/src/components/CallToAction.tsx
@@ -65,11 +65,10 @@ export const CallToAction = (props: {
marginLeft: 0,
}}
iconName={startIconName}
- secondary={secondary}
/>
)}
{label}
- {endIconName &&
}
+ {endIconName &&
}
);
diff --git a/packages/emails/src/components/CallToActionIcon.tsx b/packages/emails/src/components/CallToActionIcon.tsx
index c90be53867..872149ac9b 100644
--- a/packages/emails/src/components/CallToActionIcon.tsx
+++ b/packages/emails/src/components/CallToActionIcon.tsx
@@ -2,15 +2,7 @@ import React from "react";
import { WEBAPP_URL } from "@calcom/lib/constants";
-export const CallToActionIcon = ({
- secondary,
- iconName,
- style,
-}: {
- secondary?: boolean;
- iconName: string;
- style?: React.CSSProperties;
-}) => (
+export const CallToActionIcon = ({ iconName, style }: { iconName: string; style?: React.CSSProperties }) => (

]+)>)/gi, "");
}
}
diff --git a/packages/embeds/embed-core/playground.ts b/packages/embeds/embed-core/playground.ts
index 4295396420..ff5c9b7a50 100644
--- a/packages/embeds/embed-core/playground.ts
+++ b/packages/embeds/embed-core/playground.ts
@@ -55,6 +55,7 @@ if (only === "all" || only === "ns:second") {
iframeAttrs: {
id: "cal-booking-place-second-iframe",
},
+ theme: "auto",
},
},
]);
@@ -333,6 +334,16 @@ Cal("init", "routingFormDark", {
if (only === "all" || only == "ns:floatingButton") {
Cal.ns.floatingButton("floatingButton", {
- calLink: "pro",
+ calLink: "pro/30min",
+ config: {
+ iframeAttrs: {
+ id: "floatingtest",
+ },
+ name: "John",
+ email: "johndoe@gmail.com",
+ notes: "Test Meeting",
+ guests: ["janedoe@example.com", "test@example.com"],
+ theme: "dark",
+ },
});
}
diff --git a/packages/embeds/embed-core/src/FloatingButton/FloatingButton.ts b/packages/embeds/embed-core/src/FloatingButton/FloatingButton.ts
index 64dcb55f2a..b5e8168a10 100644
--- a/packages/embeds/embed-core/src/FloatingButton/FloatingButton.ts
+++ b/packages/embeds/embed-core/src/FloatingButton/FloatingButton.ts
@@ -4,6 +4,7 @@ type ModalTargetDatasetProps = {
calLink: string;
calNamespace: string;
calOrigin: string;
+ calConfig: string;
};
type CamelCase
= T extends `${infer U}${infer V}` ? `${Uppercase}${V}` : T;
diff --git a/packages/embeds/embed-core/src/embed-iframe.ts b/packages/embeds/embed-core/src/embed-iframe.ts
index 8f09414430..974db94e85 100644
--- a/packages/embeds/embed-core/src/embed-iframe.ts
+++ b/packages/embeds/embed-core/src/embed-iframe.ts
@@ -8,10 +8,10 @@ import type { Message } from "./embed";
import { sdkActionManager } from "./sdk-event";
type Theme = "dark" | "light";
-
+export type EmbedThemeConfig = Theme | "auto";
export type UiConfig = {
hideEventTypeDetails?: boolean;
- theme?: Theme | "auto";
+ theme?: EmbedThemeConfig;
styles?: EmbedStyles & EmbedNonStylesConfig;
//TODO: Extract from tailwind the list of all custom variables and support them in auto-completion as well as runtime validation. Followup with listing all variables in Embed Snippet Generator UI.
cssVarsPerTheme?: Record>;
@@ -31,7 +31,7 @@ const embedStore = {
reactNonStylesStateSetters: {} as Record,
parentInformedAboutContentHeight: false,
windowLoadEventFired: false,
- setTheme: undefined as ((arg0: string) => void) | undefined,
+ setTheme: undefined as ((arg0: EmbedThemeConfig) => void) | undefined,
theme: undefined as UiConfig["theme"],
uiConfig: undefined as Omit | undefined,
setUiConfig: undefined as ((arg0: UiConfig) => void) | undefined,
@@ -170,14 +170,14 @@ function isValidNamespace(ns: string | null | undefined) {
export const useEmbedTheme = () => {
const router = useRouter();
- const [theme, setTheme] = useState(embedStore.theme || (router.query.theme as string));
+ const [theme, setTheme] = useState(embedStore.theme || (router.query.theme as typeof embedStore.theme));
useEffect(() => {
router.events.on("routeChangeComplete", () => {
sdkActionManager?.fire("__routeChanged", {});
});
}, [router.events]);
embedStore.setTheme = setTheme;
- return theme === "auto" ? null : theme;
+ return theme;
};
export const useEmbedUiConfig = () => {
@@ -434,7 +434,7 @@ if (isBrowser) {
// Exposes certain global variables/fns that are used by the app to get interface with the embed.
embedInit();
const url = new URL(document.URL);
- embedStore.theme = (window?.getEmbedTheme?.() || "auto") as UiConfig["theme"];
+ embedStore.theme = window?.getEmbedTheme?.() as UiConfig["theme"];
if (url.searchParams.get("prerender") !== "true" && window?.isEmbed?.()) {
log("Initializing embed-iframe");
// HACK
diff --git a/packages/embeds/embed-core/src/embed.ts b/packages/embeds/embed-core/src/embed.ts
index 87bf77f703..a457d1d39a 100644
--- a/packages/embeds/embed-core/src/embed.ts
+++ b/packages/embeds/embed-core/src/embed.ts
@@ -2,7 +2,7 @@
import { FloatingButton } from "./FloatingButton/FloatingButton";
import { Inline } from "./Inline/inline";
import { ModalBox } from "./ModalBox/ModalBox";
-import type { InterfaceWithParent, interfaceWithParent, UiConfig } from "./embed-iframe";
+import type { InterfaceWithParent, interfaceWithParent, UiConfig, EmbedThemeConfig } from "./embed-iframe";
import css from "./embed.css";
import type { EventData, EventDataMap } from "./sdk-action-manager";
import { SdkActionManager } from "./sdk-action-manager";
@@ -129,6 +129,7 @@ type PrefillAndIframeAttrsConfig = Record & {
id?: string;
};
+ theme?: EmbedThemeConfig;
};
export class Cal {
@@ -435,6 +436,7 @@ class CalApi {
buttonColor = "rgb(0, 0, 0)",
buttonTextColor = "rgb(255, 255, 255)",
calOrigin,
+ config,
}: {
calLink: string;
buttonText?: string;
@@ -444,6 +446,7 @@ class CalApi {
buttonColor?: string;
buttonTextColor?: string;
calOrigin?: string;
+ config?: PrefillAndIframeAttrsConfig;
}) {
// validate(arguments[0], {
// required: true,
@@ -466,6 +469,10 @@ class CalApi {
el.dataset.calLink = calLink;
el.dataset.calNamespace = this.cal.namespace;
el.dataset.calOrigin = calOrigin ?? "";
+ if (config) {
+ el.dataset.calConfig = JSON.stringify(config);
+ }
+
if (attributes?.id) {
el.id = attributes.id;
}
diff --git a/packages/features/bookings/Booker/Booker.tsx b/packages/features/bookings/Booker/Booker.tsx
index 796129c920..a25f9cc4f6 100644
--- a/packages/features/bookings/Booker/Booker.tsx
+++ b/packages/features/bookings/Booker/Booker.tsx
@@ -5,10 +5,9 @@ import StickyBox from "react-sticky-box";
import { shallow } from "zustand/shallow";
import classNames from "@calcom/lib/classNames";
-import useGetBrandingColours from "@calcom/lib/getBrandColours";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import useMediaQuery from "@calcom/lib/hooks/useMediaQuery";
-import { ToggleGroup, useCalcomTheme } from "@calcom/ui";
+import { ToggleGroup } from "@calcom/ui";
import { Calendar, Columns, Grid } from "@calcom/ui/components/icon";
import { AvailableTimeSlots } from "./components/AvailableTimeSlots";
@@ -23,21 +22,20 @@ import { fadeInLeft, getBookerSizeClassNames, useBookerResizeAnimation } from ".
import { useBookerStore, useInitializeBookerStore } from "./store";
import type { BookerLayout, BookerProps } from "./types";
import { useEvent } from "./utils/event";
+import { useBrandColors } from "./utils/use-brand-colors";
const PoweredBy = dynamic(() => import("@calcom/ee/components/PoweredBy"));
const DatePicker = dynamic(() => import("./components/DatePicker").then((mod) => mod.DatePicker), {
ssr: false,
});
-const useBrandColors = ({ brandColor, darkBrandColor }: { brandColor?: string; darkBrandColor?: string }) => {
- const brandTheme = useGetBrandingColours({
- lightVal: brandColor,
- darkVal: darkBrandColor,
- });
- useCalcomTheme(brandTheme);
-};
-
-const BookerComponent = ({ username, eventSlug, month, rescheduleBooking }: BookerProps) => {
+const BookerComponent = ({
+ username,
+ eventSlug,
+ month,
+ rescheduleBooking,
+ hideBranding = false,
+}: BookerProps) => {
const { t } = useLocale();
const isMobile = useMediaQuery("(max-width: 768px)");
const isTablet = useMediaQuery("(max-width: 1024px)");
@@ -61,6 +59,7 @@ const BookerComponent = ({ username, eventSlug, month, rescheduleBooking }: Book
useBrandColors({
brandColor: event.data?.profile.brandColor,
darkBrandColor: event.data?.profile.darkBrandColor,
+ theme: event.data?.profile.theme,
});
useInitializeBookerStore({
@@ -209,7 +208,7 @@ const BookerComponent = ({ username, eventSlug, month, rescheduleBooking }: Book
"mt-auto mb-6 pt-6 [&_img]:h-[15px]",
layout === "small_calendar" ? "block" : "hidden"
)}>
-
+ {!hideBranding ? : null}
diff --git a/packages/features/bookings/Booker/utils/use-brand-colors.tsx b/packages/features/bookings/Booker/utils/use-brand-colors.tsx
new file mode 100644
index 0000000000..dd590d7751
--- /dev/null
+++ b/packages/features/bookings/Booker/utils/use-brand-colors.tsx
@@ -0,0 +1,26 @@
+import { useEffect } from "react";
+
+import useGetBrandingColours from "@calcom/lib/getBrandColours";
+import useTheme from "@calcom/lib/hooks/useTheme";
+import { useCalcomTheme } from "@calcom/ui";
+
+export const useBrandColors = ({
+ brandColor,
+ darkBrandColor,
+ theme,
+}: {
+ brandColor?: string;
+ darkBrandColor?: string;
+ theme?: string | null;
+}) => {
+ const brandTheme = useGetBrandingColours({
+ lightVal: brandColor,
+ darkVal: darkBrandColor,
+ });
+ useCalcomTheme(brandTheme);
+ const { setTheme } = useTheme(theme);
+
+ useEffect(() => {
+ if (theme) setTheme(theme);
+ }, [setTheme, theme]);
+};
diff --git a/packages/features/bookings/components/TeamFilter.tsx b/packages/features/bookings/components/TeamFilter.tsx
index e36f2351f3..6a96691187 100644
--- a/packages/features/bookings/components/TeamFilter.tsx
+++ b/packages/features/bookings/components/TeamFilter.tsx
@@ -11,7 +11,7 @@ import { useFilterQuery } from "../lib/useFilterQuery";
export const TeamsMemberFilter = () => {
const { t } = useLocale();
const session = useSession();
- const { data: query, pushItemToKey, removeItemByKeyAndValue, removeByKey } = useFilterQuery();
+ const { data: query, pushItemToKey, removeItemByKeyAndValue, removeByKey, removeAllQueryParams } = useFilterQuery();
const { data } = trpc.viewer.teams.list.useQuery();
const [dropdownTitle, setDropdownTitle] = useState