From 8331059b7c5180e25a5932983d7d58a0506e2da3 Mon Sep 17 00:00:00 2001 From: Jeroen Reumkens Date: Wed, 14 Jun 2023 11:22:44 +0200 Subject: [PATCH] feat: new booker embed (#9023) * Added embed files for new booker routes. * Updated nextjs config to redirect to correct embed url. * Notify embed of booker size after animation completes. * Don't use animations and 100vh in embed. * Added booker layout toggles to embed settings (wip) * Booker header positioning tweaks * Show correct layout in embed * Don't show pricing event meta if stripe app is not installed * Support custom border booker for embed * wip on passing layout prop to iframe for previews * Only show booker layout settings in embed-create-popup if booker layout feature is enabled. * Made layout prop in preview state for embed optional * Made layout prop in preview state for embed optional * Get layout toggle working * Fixed types * Added themebasis prop * Fix potential circular import that should then fix type errors * Fixed type error by fixing casing. * Type fixes * Added translations * More translations * Remove comment * Removed uneccessary addition to package.json * Removed todo since it's solved in another way --------- Co-authored-by: Hariom Balhara --- apps/web/components/Embed.tsx | 46 ++++++++++++++++++- apps/web/lib/withEmbedSsr.tsx | 3 ++ apps/web/next.config.js | 7 +++ apps/web/pages/new-booker/[user]/[type].tsx | 6 ++- .../pages/new-booker/[user]/[type]/embed.tsx | 11 +++++ apps/web/pages/new-booker/[user]/embed.tsx | 7 +++ .../pages/new-booker/team/[slug]/[type].tsx | 5 +- .../new-booker/team/[slug]/[type]/embed.tsx | 9 ++++ .../pages/new-booker/team/[slug]/embed.tsx | 7 +++ apps/web/public/static/locales/en/common.json | 1 + packages/embeds/embed-core/index.html | 6 +++ .../embeds/embed-core/src/embed-iframe.ts | 8 ++++ packages/features/bookings/Booker/Booker.tsx | 33 +++++++++---- .../bookings/Booker/components/Header.tsx | 9 ++-- packages/features/bookings/Booker/config.ts | 19 +++++--- packages/features/bookings/Booker/store.ts | 11 ++--- .../features/bookings/Booker/utils/layout.ts | 6 +++ .../bookings/components/AvailableTimes.tsx | 2 +- .../bookings/components/TeamFilter.tsx | 8 +++- .../components/event-meta/Details.tsx | 4 +- .../ee/teams/pages/team-members-view.tsx | 4 +- 21 files changed, 176 insertions(+), 36 deletions(-) create mode 100644 apps/web/pages/new-booker/[user]/[type]/embed.tsx create mode 100644 apps/web/pages/new-booker/[user]/embed.tsx create mode 100644 apps/web/pages/new-booker/team/[slug]/[type]/embed.tsx create mode 100644 apps/web/pages/new-booker/team/[slug]/embed.tsx create mode 100644 packages/features/bookings/Booker/utils/layout.ts diff --git a/apps/web/components/Embed.tsx b/apps/web/components/Embed.tsx index 7d5d0d56a1..9b83f85081 100644 --- a/apps/web/components/Embed.tsx +++ b/apps/web/components/Embed.tsx @@ -8,8 +8,11 @@ import { createRef, forwardRef, useRef, useState } from "react"; import type { ControlProps } from "react-select"; import { components } from "react-select"; +import type { BookerLayout } from "@calcom/features/bookings/Booker/types"; +import { useFlagMap } from "@calcom/features/flags/context/provider"; import { APP_NAME, EMBED_LIB_URL, WEBAPP_URL } from "@calcom/lib/constants"; import { useLocale } from "@calcom/lib/hooks/useLocale"; +import { BookerLayouts } from "@calcom/prisma/zod-utils"; import { Button, Dialog, @@ -41,12 +44,13 @@ type PreviewState = { height: string; }; theme: Theme; - floatingPopup: Record; + floatingPopup: Record; elementClick: Record; palette: { brandColor: string; }; hideEventTypeDetails: boolean; + layout: BookerLayouts; }; const queryParamsForDialog = ["embedType", "embedTabName", "embedUrl"]; @@ -129,11 +133,13 @@ const getEmbedUIInstructionString = ({ theme, brandColor, hideEventTypeDetails, + layout, }: { apiName: string; theme?: string; brandColor: string; hideEventTypeDetails: boolean; + layout?: string; }) => { theme = theme !== "auto" ? theme : undefined; return getInstructionString({ @@ -147,6 +153,7 @@ const getEmbedUIInstructionString = ({ }, }, hideEventTypeDetails: hideEventTypeDetails, + layout, }, }); }; @@ -260,6 +267,7 @@ const getEmbedTypeSpecificString = ({ theme: PreviewState["theme"]; brandColor: string; hideEventTypeDetails: boolean; + layout?: BookerLayout; }; if (embedFramework === "react") { uiInstructionStringArg = { @@ -267,6 +275,7 @@ const getEmbedTypeSpecificString = ({ theme: previewState.theme, brandColor: previewState.palette.brandColor, hideEventTypeDetails: previewState.hideEventTypeDetails, + layout: previewState.layout, }; } else { uiInstructionStringArg = { @@ -274,6 +283,7 @@ const getEmbedTypeSpecificString = ({ theme: previewState.theme, brandColor: previewState.palette.brandColor, hideEventTypeDetails: previewState.hideEventTypeDetails, + layout: previewState.layout, }; } if (!frameworkCodes[embedType]) { @@ -626,6 +636,7 @@ const ThemeSelectControl = ({ children, ...props }: ControlProps<{ value: Theme; const ChooseEmbedTypesDialogContent = () => { const { t } = useLocale(); const router = useRouter(); + return (
@@ -671,6 +682,8 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ const router = useRouter(); const iframeRef = useRef(null); const dialogContentRef = useRef(null); + const flags = useFlagMap(); + const isBookerLayoutsEnabled = flags["booker-layouts"] === true; const s = (href: string) => { const searchParams = new URLSearchParams(router.asPath.split("?")[1] || ""); @@ -691,7 +704,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ const [isEmbedCustomizationOpen, setIsEmbedCustomizationOpen] = useState(true); const [isBookingCustomizationOpen, setIsBookingCustomizationOpen] = useState(true); - const [previewState, setPreviewState] = useState({ + const [previewState, setPreviewState] = useState({ inline: { width: "100%", height: "100%", @@ -703,6 +716,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ palette: { brandColor: "#000000", }, + layout: BookerLayouts.MONTH_VIEW, }); const close = () => { @@ -765,6 +779,7 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ arg: { theme: previewState.theme, hideEventTypeDetails: previewState.hideEventTypeDetails, + layout: previewState.layout, styles: { branding: { ...previewState.palette, @@ -798,6 +813,12 @@ const EmbedTypeCodeAndPreviewDialogContent = ({ { value: Theme.light, label: "Light Theme" }, ]; + const layoutOptions = [ + { value: BookerLayouts.MONTH_VIEW, label: t("bookerlayout_month_view") }, + { value: BookerLayouts.WEEK_VIEW, label: t("bookerlayout_week_view") }, + { value: BookerLayouts.COLUMN_VIEW, label: t("bookerlayout_column_view") }, + ]; + const FloatingPopupPositionOptions = [ { value: "bottom-right", @@ -1070,6 +1091,27 @@ const EmbedTypeCodeAndPreviewDialogContent = ({
))} + {isBookerLayoutsEnabled && ( +