chore: added headless routing link to embed (#22921)
* added headless routing link to embed * Update apps/web/public/static/locales/en/common.json * Update apps/web/public/static/locales/en/common.json * fix: add missing headless embed type handlers to resolve TypeScript errors - Add headless handlers for react, react-atom, and HTML frameworks in EmbedCodes.tsx - Add headless case handling in EmbedTabs.tsx getEmbedTypeSpecificString function - Add embedCalOrigin parameter to HTML framework handlers for type consistency - All handlers return documentation comments directing users to headless routing docs Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * temp: enable IS_CALCOM for localhost testing Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: change headless handlers to return null instead of documentation code Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * revert: remove temporary IS_CALCOM localhost change Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * refactor: remove unnecessary parameter destructuring from headless embed handlers - Headless handlers now take no parameters since they only return null - Simplified function signatures to avoid unused parameter warnings - Maintains existing functionality while improving code clarity Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: hariom@cal.com <hariombalhara@gmail.com>
This commit is contained in:
co-authored by
hariom@cal.com
Devin AI
parent
86f6e8bac3
commit
09b1643478
@@ -2251,6 +2251,8 @@
|
||||
"floating_button_trigger_modal": "Puts a floating button on your site that triggers a modal with your event type.",
|
||||
"pop_up_element_click": "Pop up via element click",
|
||||
"open_dialog_with_element_click": "Open your calendar as a dialog when someone clicks an element.",
|
||||
"use_my_own_form": "Use my own form",
|
||||
"use_our_headless_routing_api": "Use our headless routing API and use your own form for submissions.",
|
||||
"need_help_embedding": "Need help? See our guides for embedding Cal on Wix, Squarespace, or WordPress, check our common questions, or explore advanced embed options.",
|
||||
"book_my_cal": "Book my Cal",
|
||||
"first_name": "First name",
|
||||
|
||||
@@ -207,9 +207,13 @@ const ChooseEmbedTypesDialogContent = ({
|
||||
key={index}
|
||||
data-testid={embed.type}
|
||||
onClick={() => {
|
||||
gotoState({
|
||||
embedType: embed.type as EmbedType,
|
||||
});
|
||||
if (embed.type === "headless") {
|
||||
window.open("https://cal.com/help/routing/headless-routing", "_blank");
|
||||
} else {
|
||||
gotoState({
|
||||
embedType: embed.type as EmbedType,
|
||||
});
|
||||
}
|
||||
}}>
|
||||
<div className="bg-default order-none box-border flex-none rounded-md border border-solid transition dark:bg-transparent dark:invert">
|
||||
{embed.illustration}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { ComponentProps } from "react";
|
||||
|
||||
import { EmbedDialog, EmbedButton } from "@calcom/features/embed/Embed";
|
||||
import { IS_CALCOM } from "@calcom/lib/constants";
|
||||
import { useLocale } from "@calcom/lib/hooks/useLocale";
|
||||
import { trpc } from "@calcom/trpc/react";
|
||||
|
||||
import { tabs } from "./lib/EmbedTabs";
|
||||
@@ -8,11 +10,63 @@ import { useEmbedTypes } from "./lib/hooks";
|
||||
|
||||
export const RoutingFormEmbedDialog = () => {
|
||||
const types = useEmbedTypes();
|
||||
const { t } = useLocale();
|
||||
const { data: user } = trpc.viewer.me.get.useQuery();
|
||||
const routingFormTypes = types.filter((type) => type.type !== "email");
|
||||
|
||||
// Add the headless option specifically for routing forms
|
||||
const headlessType = {
|
||||
title: t("use_my_own_form"),
|
||||
subtitle: t("use_our_headless_routing_api"),
|
||||
type: "headless",
|
||||
illustration: (
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
className="rounded-md"
|
||||
viewBox="0 0 308 265"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M0 1.99999C0 0.895423 0.895431 0 2 0H306C307.105 0 308 0.895431 308 2V263C308 264.105 307.105 265 306 265H2C0.895431 265 0 264.105 0 263V1.99999Z"
|
||||
fill="white"
|
||||
/>
|
||||
<rect x="24" width="260" height="38.5" rx="6" fill="#F3F4F6" />
|
||||
<rect x="24" y="50.5" width="139" height="163" rx="6" fill="#F8F8F8" />
|
||||
<g opacity="0.8">
|
||||
<rect x="42" y="74" width="20" height="20" rx="2" fill="#374151" />
|
||||
<path
|
||||
d="M48 81L52 85L56 81"
|
||||
stroke="white"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>
|
||||
<rect x="48" y="106" width="80" height="8" rx="6" fill="#F3F4F6" />
|
||||
<rect x="48" y="118" width="48" height="4" rx="6" fill="#F3F4F6" />
|
||||
<rect x="48" y="130" width="64" height="4" rx="6" fill="#F3F4F6" />
|
||||
<rect x="48" y="142" width="32" height="4" rx="6" fill="#F3F4F6" />
|
||||
<rect x="48" y="160" width="72" height="6" rx="3" fill="#292929" />
|
||||
<rect x="176" y="50.5" width="108" height="164" rx="6" fill="#F3F4F6" />
|
||||
<text x="220" y="120" textAnchor="middle" className="fill-gray-400" fontSize="8">
|
||||
API
|
||||
</text>
|
||||
<rect x="200" y="125" width="40" height="2" rx="1" fill="#9CA3AF" />
|
||||
<rect x="200" y="130" width="32" height="2" rx="1" fill="#9CA3AF" />
|
||||
<rect x="200" y="135" width="36" height="2" rx="1" fill="#9CA3AF" />
|
||||
<rect x="24" y="226.5" width="260" height="38.5" rx="6" fill="#F3F4F6" />
|
||||
</svg>
|
||||
),
|
||||
};
|
||||
|
||||
const routingFormTypesWithHeadless = IS_CALCOM
|
||||
? [...routingFormTypes, headlessType]
|
||||
: routingFormTypes;
|
||||
|
||||
return (
|
||||
<EmbedDialog
|
||||
types={routingFormTypes}
|
||||
types={routingFormTypesWithHeadless}
|
||||
tabs={tabs}
|
||||
eventTypeHideOptionDisabled={true}
|
||||
defaultBrandColor={user ? { brandColor: user.brandColor, darkBrandColor: user.darkBrandColor } : null}
|
||||
|
||||
@@ -113,6 +113,9 @@ export default function MyApp() {
|
||||
>Click me</button>;
|
||||
};`;
|
||||
},
|
||||
headless: () => {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
"react-atom": {
|
||||
inline: ({
|
||||
@@ -230,17 +233,22 @@ export default function Booker( props : BookerProps ) {
|
||||
);
|
||||
};`;
|
||||
},
|
||||
headless: () => {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
HTML: {
|
||||
inline: ({
|
||||
calLink,
|
||||
uiInstructionCode,
|
||||
previewState,
|
||||
embedCalOrigin,
|
||||
namespace,
|
||||
}: {
|
||||
calLink: string;
|
||||
uiInstructionCode: string;
|
||||
previewState: PreviewState["inline"];
|
||||
embedCalOrigin: string;
|
||||
namespace: string;
|
||||
}) => {
|
||||
return code`${getApiNameForVanillaJsSnippet({ namespace, mainApiName: "Cal" })}("inline", {
|
||||
@@ -251,16 +259,17 @@ export default function Booker( props : BookerProps ) {
|
||||
|
||||
${uiInstructionCode}`;
|
||||
},
|
||||
|
||||
"floating-popup": ({
|
||||
calLink,
|
||||
uiInstructionCode,
|
||||
previewState,
|
||||
embedCalOrigin,
|
||||
namespace,
|
||||
}: {
|
||||
calLink: string;
|
||||
uiInstructionCode: string;
|
||||
previewState: PreviewState["floatingPopup"];
|
||||
embedCalOrigin: string;
|
||||
namespace: string;
|
||||
}) => {
|
||||
const floatingButtonArg = JSON.stringify({
|
||||
@@ -277,11 +286,13 @@ export default function Booker( props : BookerProps ) {
|
||||
calLink,
|
||||
uiInstructionCode,
|
||||
previewState,
|
||||
embedCalOrigin,
|
||||
namespace,
|
||||
}: {
|
||||
calLink: string;
|
||||
uiInstructionCode: string;
|
||||
previewState: PreviewState["elementClick"];
|
||||
embedCalOrigin: string;
|
||||
namespace: string;
|
||||
}) => {
|
||||
return code`
|
||||
@@ -292,6 +303,9 @@ export default function Booker( props : BookerProps ) {
|
||||
|
||||
${uiInstructionCode}`;
|
||||
},
|
||||
headless: () => {
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -283,6 +283,8 @@ const getEmbedTypeSpecificString = ({
|
||||
...codeGeneratorInput,
|
||||
previewState: previewState.elementClick,
|
||||
});
|
||||
} else if (embedType === "headless") {
|
||||
return frameworkCodes[embedType]();
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { Brand } from "@calcom/types/utils";
|
||||
import type { tabs } from "../lib/EmbedTabs";
|
||||
import type { useEmbedTypes } from "../lib/hooks";
|
||||
|
||||
export type EmbedType = "inline" | "floating-popup" | "element-click" | "email";
|
||||
export type EmbedType = "inline" | "floating-popup" | "element-click" | "email" | "headless";
|
||||
type EmbedConfig = {
|
||||
layout?: BookerLayouts;
|
||||
theme?: Theme;
|
||||
|
||||
Reference in New Issue
Block a user