Compare commits

...

2 Commits

Author SHA1 Message Date
Hariom Balhara 55e9d89376 Remove´ payment page top margin for embed 2022-10-10 19:37:11 +05:30
Hariom Balhara c299821747 Make [user]/[type] page accept embed as part of dynami path 2022-10-10 19:16:13 +05:30
10 changed files with 62 additions and 28 deletions

View File

@ -42,7 +42,7 @@ import EventTypeDescriptionSafeHTML from "@components/eventtype/EventTypeDescrip
import { HeadSeo } from "@components/seo/head-seo"; import { HeadSeo } from "@components/seo/head-seo";
import PoweredByCal from "@components/ui/PoweredByCal"; import PoweredByCal from "@components/ui/PoweredByCal";
import type { AvailabilityPageProps } from "../../../pages/[user]/[type]"; //import type { AvailabilityPageProps } from "../../../pages/[user]/[...type]";
import type { DynamicAvailabilityPageProps } from "../../../pages/d/[link]/[slug]"; import type { DynamicAvailabilityPageProps } from "../../../pages/d/[link]/[slug]";
import type { AvailabilityTeamPageProps } from "../../../pages/team/[slug]/[type]"; import type { AvailabilityTeamPageProps } from "../../../pages/team/[slug]/[type]";
import { AvailableEventLocations } from "../AvailableEventLocations"; import { AvailableEventLocations } from "../AvailableEventLocations";
@ -301,11 +301,11 @@ const timeFormatTotimeFormatString = (timeFormat?: number | null) => {
return timeFormat === 24 ? "HH:mm" : "h:mma"; return timeFormat === 24 ? "HH:mm" : "h:mma";
}; };
const AvailabilityPage = ({ profile, eventType }: Props) => { const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => {
const { data: user } = trpc.useQuery(["viewer.me"]); const { data: user } = trpc.useQuery(["viewer.me"]);
const timeFormatFromProfile = timeFormatTotimeFormatString(user?.timeFormat); const timeFormatFromProfile = timeFormatTotimeFormatString(user?.timeFormat);
const router = useRouter(); const router = useRouter();
const isEmbed = useIsEmbed(); const isEmbed = useIsEmbed(restProps.isEmbed);
const query = dateQuerySchema.parse(router.query); const query = dateQuerySchema.parse(router.query);
const { rescheduleUid } = query; const { rescheduleUid } = query;
useTheme(profile.theme); useTheme(profile.theme);

View File

@ -81,9 +81,10 @@ const BookingPage = ({
recurringEventCount, recurringEventCount,
hasHashedBookingLink, hasHashedBookingLink,
hashedLink, hashedLink,
...restProps
}: BookingPageProps) => { }: BookingPageProps) => {
const { t, i18n } = useLocale(); const { t, i18n } = useLocale();
const isEmbed = useIsEmbed(); const isEmbed = useIsEmbed(restProps.isEmbed);
const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left"; const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left";
const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed; const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed;
const router = useRouter(); const router = useRouter();

View File

@ -52,6 +52,13 @@ const middleware: NextMiddleware = async (req) => {
return NextResponse.rewrite(url); return NextResponse.rewrite(url);
} }
if (url.pathname.endsWith("/embed")) {
if (typeof url.searchParams.get("embed") !== "string") {
url.searchParams.set("embed", "");
return NextResponse.redirect(url);
}
}
/** Display available V2 pages */ /** Display available V2 pages */
if ( if (
!V2_BLACKLIST.some((p) => url.pathname.startsWith(p)) && !V2_BLACKLIST.some((p) => url.pathname.startsWith(p)) &&

View File

@ -57,7 +57,7 @@ export default function Type(props: AvailabilityPageProps) {
Type.isThemeSupported = true; Type.isThemeSupported = true;
async function getUserPageProps(context: GetStaticPropsContext) { async function getUserPageProps(context: GetStaticPropsContext) {
const { type: slug, user: username } = paramsSchema.parse(context.params); const { type, user: username } = paramsSchema.parse(context.params);
const { ssgInit } = await import("@server/lib/ssg"); const { ssgInit } = await import("@server/lib/ssg");
const ssg = await ssgInit(context); const ssg = await ssgInit(context);
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
@ -92,7 +92,9 @@ async function getUserPageProps(context: GetStaticPropsContext) {
}); });
if (!user) return { notFound: true }; if (!user) return { notFound: true };
const slug = type[0];
const isEmbed = type[1] === "embed";
//TODO: Reject any other type[1] value as of now.
const eventTypes = await prisma.eventType.findMany({ const eventTypes = await prisma.eventType.findMany({
where: { where: {
slug, slug,
@ -161,10 +163,11 @@ async function getUserPageProps(context: GetStaticPropsContext) {
}); });
const profile = eventType.users[0] || user; const profile = eventType.users[0] || user;
console.log("isEmbed", isEmbed);
return { return {
props: { props: {
eventType: eventTypeObject, eventType: eventTypeObject,
isEmbed,
profile: { profile: {
theme: user.theme, theme: user.theme,
name: user.name, name: user.name,
@ -282,10 +285,12 @@ async function getDynamicGroupPageProps(context: GetStaticPropsContext) {
}; };
} }
const paramsSchema = z.object({ type: z.string(), user: z.string() }); const paramsSchema = z.object({ type: z.array(z.string()), user: z.string() });
export const getStaticProps = async (context: GetStaticPropsContext) => { export const getStaticProps = async (context: GetStaticPropsContext) => {
console.log("Params,", context.params);
const { user: userParam } = paramsSchema.parse(context.params); const { user: userParam } = paramsSchema.parse(context.params);
console.log("User Param", userParam);
// dynamic groups are not generated at build time, but otherwise are probably cached until infinity. // dynamic groups are not generated at build time, but otherwise are probably cached until infinity.
const isDynamicGroup = userParam.includes("+"); const isDynamicGroup = userParam.includes("+");
if (isDynamicGroup) { if (isDynamicGroup) {

View File

@ -67,6 +67,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
const usernameList = getUsernameList(asStringOrThrow(context.query.user as string)); const usernameList = getUsernameList(asStringOrThrow(context.query.user as string));
const eventTypeSlug = context.query.slug as string; const eventTypeSlug = context.query.slug as string;
const recurringEventCountQuery = asStringOrNull(context.query.count); const recurringEventCountQuery = asStringOrNull(context.query.count);
const isEmbed = typeof context.query.embed === "string";
const users = await prisma.user.findMany({ const users = await prisma.user.findMany({
where: { where: {
username: { username: {
@ -188,6 +189,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
return { return {
props: { props: {
isEmbed,
away: user.away, away: user.away,
profile, profile,
eventType: eventTypeObject, eventType: eventTypeObject,

View File

@ -217,11 +217,10 @@ function getEmbedType() {
} }
} }
export const useIsEmbed = () => { export const useIsEmbed = (isEmbed: boolean) => {
// We can't simply return isEmbed() from this method. // We can't simply return isEmbed() from this method.
// isEmbed() returns different values on server and browser, which messes up the hydration. // isEmbed() returns different values on server and browser, which messes up the hydration.
// TODO: We can avoid using document.URL and instead use Router. // TODO: We can avoid using document.URL and instead use Router.
const [isEmbed, setIsEmbed] = useState<boolean | null>(null);
useEffect(() => { useEffect(() => {
const namespace = getNamespace(); const namespace = getNamespace();
const _isValidNamespace = isValidNamespace(namespace); const _isValidNamespace = isValidNamespace(namespace);
@ -230,7 +229,6 @@ export const useIsEmbed = () => {
"Looks like you have iframed cal.com but not using Embed Snippet. Directly using an iframe isn't recommended." "Looks like you have iframed cal.com but not using Embed Snippet. Directly using an iframe isn't recommended."
); );
} }
setIsEmbed(window.isEmbed());
}, []); }, []);
return isEmbed; return isEmbed;
}; };

View File

@ -263,7 +263,7 @@ export class Cal {
throw new Error("Element not found"); throw new Error("Element not found");
} }
const template = document.createElement("template"); const template = document.createElement("template");
template.innerHTML = `<cal-inline style="max-height:inherit;height:inherit;min-height:inherit;display:flex;position:relative;flex-wrap:wrap;width:100%"></cal-inline>`; template.innerHTML = `<cal-inline loading="done" style="max-height:inherit;height:inherit;min-height:inherit;display:flex;position:relative;flex-wrap:wrap;width:100%"></cal-inline>`;
this.inlineEl = template.content.children[0]; this.inlineEl = template.content.children[0];
(this.inlineEl as unknown as any).__CalAutoScroll = config.__autoScroll; (this.inlineEl as unknown as any).__CalAutoScroll = config.__autoScroll;
this.inlineEl.appendChild(iframe); this.inlineEl.appendChild(iframe);

View File

@ -24,7 +24,7 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
const [date, setDate] = useState(dayjs.utc(props.booking.startTime)); const [date, setDate] = useState(dayjs.utc(props.booking.startTime));
const [timezone, setTimezone] = useState<string | null>(null); const [timezone, setTimezone] = useState<string | null>(null);
useTheme(props.profile.theme); useTheme(props.profile.theme);
const isEmbed = useIsEmbed(); const isEmbed = useIsEmbed(props.isEmbed);
useEffect(() => { useEffect(() => {
let embedIframeWidth = 0; let embedIframeWidth = 0;
const _timezone = localStorage.getItem("timeOption.preferredTimeZone") || dayjs.tz.guess(); const _timezone = localStorage.getItem("timeOption.preferredTimeZone") || dayjs.tz.guess();
@ -64,9 +64,6 @@ const PaymentPage: FC<PaymentPageProps> = (props) => {
<div className="fixed inset-0 z-50 overflow-y-auto"> <div className="fixed inset-0 z-50 overflow-y-auto">
<div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0"> <div className="flex min-h-screen items-end justify-center px-4 pt-4 pb-20 text-center sm:block sm:p-0">
<div className="fixed inset-0 my-4 transition-opacity sm:my-0" aria-hidden="true"> <div className="fixed inset-0 my-4 transition-opacity sm:my-0" aria-hidden="true">
<span className="hidden sm:inline-block sm:h-screen sm:align-middle" aria-hidden="true">
&#8203;
</span>
<div <div
className={classNames( className={classNames(
"main inline-block transform overflow-hidden rounded-lg border border-neutral-200 bg-white px-8 pt-5 pb-4 text-left align-bottom transition-all dark:border-neutral-700 dark:bg-gray-800 sm:w-full sm:max-w-lg sm:py-6 sm:align-middle", "main inline-block transform overflow-hidden rounded-lg border border-neutral-200 bg-white px-8 pt-5 pb-4 text-left align-bottom transition-all dark:border-neutral-700 dark:bg-gray-800 sm:w-full sm:max-w-lg sm:py-6 sm:align-middle",

View File

@ -15,6 +15,7 @@ const querySchema = z.object({
export const getServerSideProps = async (context: GetServerSidePropsContext) => { export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const ssr = await ssrInit(context); const ssr = await ssrInit(context);
const isEmbed = typeof context.query.embed === "string";
const { uid } = querySchema.parse(context.query); const { uid } = querySchema.parse(context.query);
const rawPayment = await prisma.payment.findFirst({ const rawPayment = await prisma.payment.findFirst({
@ -106,6 +107,7 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) =>
user, user,
eventType, eventType,
booking, booking,
isEmbed,
trpcState: ssr.dehydrate(), trpcState: ssr.dehydrate(),
payment, payment,
profile, profile,

View File

@ -2,68 +2,90 @@
{ {
"/*": "This file is auto-generated and updated by `yarn app-store create/edit`. Don't edit it manually", "/*": "This file is auto-generated and updated by `yarn app-store create/edit`. Don't edit it manually",
"dirName": "routing-forms", "dirName": "routing-forms",
"categories": ["other"], "categories": [
"other"
],
"slug": "routing-forms", "slug": "routing-forms",
"type": "routing-forms_other" "type": "routing-forms_other"
}, },
{ {
"dirName": "whereby", "dirName": "whereby",
"categories": ["video"], "categories": [
"video"
],
"slug": "whereby", "slug": "whereby",
"type": "whereby_video" "type": "whereby_video"
}, },
{ {
"dirName": "around", "dirName": "around",
"categories": ["video"], "categories": [
"video"
],
"slug": "around", "slug": "around",
"type": "around_video" "type": "around_video"
}, },
{ {
"dirName": "riverside", "dirName": "riverside",
"categories": ["video"], "categories": [
"video"
],
"slug": "riverside", "slug": "riverside",
"type": "riverside_video" "type": "riverside_video"
}, },
{ {
"dirName": "typeform", "dirName": "typeform",
"categories": ["other"], "categories": [
"other"
],
"slug": "typeform", "slug": "typeform",
"type": "typeform_other" "type": "typeform_other"
}, },
{ {
"dirName": "ping", "dirName": "ping",
"categories": ["video"], "categories": [
"video"
],
"slug": "ping", "slug": "ping",
"type": "ping_video" "type": "ping_video"
}, },
{ {
"dirName": "campfire", "dirName": "campfire",
"categories": ["video"], "categories": [
"video"
],
"slug": "campfire", "slug": "campfire",
"type": "campfire_video" "type": "campfire_video"
}, },
{ {
"dirName": "rainbow", "dirName": "rainbow",
"categories": ["web3"], "categories": [
"web3"
],
"slug": "rainbow", "slug": "rainbow",
"type": "rainbow_web3" "type": "rainbow_web3"
}, },
{ {
"dirName": "raycast", "dirName": "raycast",
"categories": ["other"], "categories": [
"other"
],
"slug": "raycast", "slug": "raycast",
"type": "raycast_other" "type": "raycast_other"
}, },
{ {
"dirName": "n8n", "dirName": "n8n",
"categories": ["automation"], "categories": [
"automation"
],
"slug": "n8n", "slug": "n8n",
"type": "n8n_automation" "type": "n8n_automation"
}, },
{ {
"dirName": "exchangecalendar", "dirName": "exchangecalendar",
"categories": ["calendar"], "categories": [
"calendar"
],
"slug": "exchange", "slug": "exchange",
"type": "exchange_calendar" "type": "exchange_calendar"
} }
] ]