diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 3295c7c57c..2496c521ff 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -215,6 +215,11 @@ const nextConfig = { destination: "/new-booker/team/:slug/:type", has: [{ type: "cookie", key: "new-booker-enabled" }], }, + { + source: "/d/:link/:slug", + destination: "/new-booker/d/:link/:slug", + has: [{ type: "cookie", key: "new-booker-enabled" }], + }, ]; }, async headers() { diff --git a/apps/web/pages/new-booker/d/[link]/[slug].tsx b/apps/web/pages/new-booker/d/[link]/[slug].tsx new file mode 100644 index 0000000000..f61d876526 --- /dev/null +++ b/apps/web/pages/new-booker/d/[link]/[slug].tsx @@ -0,0 +1,120 @@ +import type { GetServerSidePropsContext } from "next"; +import { z } from "zod"; + +import { Booker } from "@calcom/atoms"; +import { BookerSeo } from "@calcom/features/bookings/components/BookerSeo"; +import { getBookingByUidOrRescheduleUid } from "@calcom/features/bookings/lib/get-booking"; +import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking"; +import prisma from "@calcom/prisma"; + +import type { inferSSRProps } from "@lib/types/inferSSRProps"; + +import PageWrapper from "@components/PageWrapper"; + +type PageProps = inferSSRProps; + +export default function Type({ slug, user, booking, away, isBrandingHidden }: PageProps) { + return ( +
+ + +
+ ); +} + +Type.PageWrapper = PageWrapper; + +async function getUserPageProps(context: GetServerSidePropsContext) { + const { link, slug } = paramsSchema.parse(context.params); + const { rescheduleUid } = context.query; + + const { ssrInit } = await import("@server/lib/ssr"); + const ssr = await ssrInit(context); + + const hashedLink = await prisma.hashedLink.findUnique({ + where: { + link, + }, + select: { + eventTypeId: true, + eventType: { + select: { + users: { + select: { + username: true, + }, + }, + }, + }, + }, + }); + + const username = hashedLink?.eventType.users[0]?.username; + + if (!hashedLink || !username) { + return { + notFound: true, + }; + } + + const user = await prisma.user.findUnique({ + where: { + username, + }, + select: { + away: true, + hideBranding: true, + }, + }); + + if (!user) { + return { + notFound: true, + }; + } + + let booking: GetBookingType | null = null; + if (rescheduleUid) { + booking = await getBookingByUidOrRescheduleUid(`${rescheduleUid}`); + } + + // We use this to both prefetch the query on the server, + // as well as to check if the event exist, so we c an show a 404 otherwise. + const eventData = await ssr.viewer.public.event.fetch({ username, eventSlug: slug }); + + if (!eventData) { + return { + notFound: true, + }; + } + + return { + props: { + booking, + away: user?.away, + user: username, + slug, + trpcState: ssr.dehydrate(), + isBrandingHidden: user?.hideBranding, + }, + }; +} + +const paramsSchema = z.object({ link: z.string(), slug: z.string() }); + +// Booker page fetches a tiny bit of data server side, to determine early +// whether the page should show an away state or dynamic booking not allowed. +export const getServerSideProps = async (context: GetServerSidePropsContext) => { + return await getUserPageProps(context); +};