Skip to content

Commit

Permalink
Migrate /team/* page group
Browse files Browse the repository at this point in the history
improve

import type

Finalize

support isBookingPage

finalize

fix

Fix build error

fix type errors
  • Loading branch information
hbjORbj authored and grzpab committed Jan 12, 2024
1 parent 0bdc45a commit 060f278
Show file tree
Hide file tree
Showing 19 changed files with 369 additions and 253 deletions.
9 changes: 7 additions & 2 deletions apps/web/app/AppDirSSRHOC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { GetServerSideProps, GetServerSidePropsContext } from "next";
import { notFound, redirect } from "next/navigation";

export const withAppDir =
(getServerSideProps: GetServerSideProps) => async (context: GetServerSidePropsContext) => {
<T extends Record<string, any>>(getServerSideProps: GetServerSideProps<T>) =>
async (context: GetServerSidePropsContext): Promise<T> => {
const ssrResponse = await getServerSideProps(context);

if ("redirect" in ssrResponse) {
Expand All @@ -13,5 +14,9 @@ export const withAppDir =
notFound();
}

return ssrResponse.props;
return {
...ssrResponse.props,
// includes dehydratedState required for future page trpcPropvider
...("trpcState" in ssrResponse.props && { dehydratedState: ssrResponse.props.trpcState }),
};
};
8 changes: 4 additions & 4 deletions apps/web/app/future/apps/categories/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import CategoryPage from "@pages/apps/categories/[category]";
import { Prisma } from "@prisma/client";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { type GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import z from "zod";

Expand Down Expand Up @@ -38,8 +39,8 @@ const querySchema = z.object({
category: z.nativeEnum(AppCategories),
});

const getPageProps = async ({ params }: { params: Record<string, string | string[]> }) => {
const p = querySchema.safeParse(params);
const getPageProps = async (context: GetServerSidePropsContext) => {
const p = querySchema.safeParse(context.params);

if (!p.success) {
return notFound();
Expand All @@ -66,6 +67,5 @@ const getPageProps = async ({ params }: { params: Record<string, string | string
};
};

// @ts-expect-error getData arg
export default WithLayout({ getData: getPageProps, Page: CategoryPage })<"P">;
export default WithLayout({ getData: getPageProps, Page: CategoryPage, getLayout: null })<"P">;
export const dynamic = "force-static";
2 changes: 1 addition & 1 deletion apps/web/app/future/apps/categories/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import LegacyPage from "@pages/apps/categories/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { type GetServerSidePropsContext } from "next";

import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/future/apps/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import AppsPage from "@pages/apps";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { type GetServerSidePropsContext } from "next";

import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getLayout } from "@calcom/features/MainLayoutAppDir";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/future/bookings/[status]/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { type GetServerSidePropsContext } from "next";
import { notFound } from "next/navigation";
import { z } from "zod";

Expand Down
8 changes: 2 additions & 6 deletions apps/web/app/future/getting-started/[[...step]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import LegacyPage from "@pages/getting-started/[[...step]]";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";
import { type GetServerSidePropsContext } from "next";
import { redirect } from "next/navigation";

import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
Expand All @@ -10,10 +9,7 @@ import prisma from "@calcom/prisma";
import { ssrInit } from "@server/lib/ssr";

const getData = async (ctx: GetServerSidePropsContext) => {
const req = { headers: headers(), cookies: cookies() };

//@ts-expect-error Type '{ headers: ReadonlyHeaders; cookies: ReadonlyRequestCookies; }' is not assignable to type 'NextApiRequest
const session = await getServerSession({ req });
const session = await getServerSession({ req: ctx.req });

if (!session?.user?.id) {
return redirect("/auth/login");
Expand Down
18 changes: 18 additions & 0 deletions apps/web/app/future/team/[slug]/[type]/embed/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getServerSideProps } from "@pages/team/[slug]/[type]";
import { withAppDir } from "app/AppDirSSRHOC";
import type { PageProps } from "app/_types";
import type { GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";

import { buildLegacyCtx } from "@lib/buildLegacyCtx";
import withEmbedSsr from "@lib/withEmbedSsr";

const Page = async ({ params }: PageProps) => {
const legacyCtx = buildLegacyCtx(headers(), cookies(), params);

await withAppDir(withEmbedSsr(getServerSideProps))(legacyCtx as unknown as GetServerSidePropsContext);

return null;
};

export default Page;
21 changes: 21 additions & 0 deletions apps/web/app/future/team/[slug]/[type]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import LegacyPage, {
type PageProps,
getServerSideProps as _getServerSideProps,
} from "@pages/team/[slug]/[type]";
import { withAppDir } from "app/AppDirSSRHOC";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";

export const generateMetadata = async () =>
await _generateMetadata(
() => "",
() => ""
);
const getData = withAppDir<PageProps>(_getServerSideProps);

export default WithLayout({
Page: LegacyPage,
getData,
getLayout: null,
isBookingPage: true,
})<"P">;
18 changes: 18 additions & 0 deletions apps/web/app/future/team/[slug]/embed/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { getServerSideProps } from "@pages/team/[slug]";
import { withAppDir } from "app/AppDirSSRHOC";
import type { PageProps } from "app/_types";
import type { GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";

import { buildLegacyCtx } from "@lib/buildLegacyCtx";
import withEmbedSsr from "@lib/withEmbedSsr";

const Page = async ({ params }: PageProps) => {
const legacyCtx = buildLegacyCtx(headers(), cookies(), params);

await withAppDir(withEmbedSsr(getServerSideProps))(legacyCtx as unknown as GetServerSidePropsContext);

return null;
};

export default Page;
29 changes: 29 additions & 0 deletions apps/web/app/future/team/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import LegacyPage, { type PageProps, getServerSideProps as _getServerSideProps } from "@pages/team/[slug]";
import { withAppDir } from "app/AppDirSSRHOC";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import { type GetServerSidePropsContext } from "next";
import { cookies, headers } from "next/headers";

import { buildLegacyCtx } from "@lib/buildLegacyCtx";

export const generateMetadata = async ({ params }: { params: Record<string, string | string[]> }) => {
const props = await getData(
buildLegacyCtx(headers(), cookies(), params) as unknown as GetServerSidePropsContext
);
const teamName = props.team.name || "Nameless Team";

return await _generateMetadata(
() => teamName,
() => teamName
);
};

const getData = withAppDir<PageProps>(_getServerSideProps);

export default WithLayout({
Page: LegacyPage,
getData,
getLayout: null,
isBookingPage: true,
})<"P">;
2 changes: 1 addition & 1 deletion apps/web/app/future/teams/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import OldPage from "@pages/teams/index";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import type { GetServerSidePropsContext } from "next";
import { type GetServerSidePropsContext } from "next";
import { redirect } from "next/navigation";

import { getLayout } from "@calcom/features/MainLayoutAppDir";
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/future/video/[uid]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import OldPage from "@pages/video/[uid]";
import { _generateMetadata } from "app/_utils";
import { WithLayout } from "app/layoutHOC";
import MarkdownIt from "markdown-it";
import type { GetServerSidePropsContext } from "next";
import { type GetServerSidePropsContext } from "next";
import { redirect } from "next/navigation";

import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
Expand Down
16 changes: 14 additions & 2 deletions apps/web/app/layoutHOC.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ type WithLayoutParams<T extends Record<string, any>> = {
getLayout: ((page: React.ReactElement) => React.ReactNode) | null;
Page?: (props: T) => React.ReactElement | null;
getData?: (arg: GetServerSidePropsContext) => Promise<T>;
isBookingPage?: boolean;
};

export function WithLayout<T extends Record<string, any>>({ getLayout, getData, Page }: WithLayoutParams<T>) {
export function WithLayout<T extends Record<string, any>>({
getLayout,
getData,
Page,
isBookingPage,
}: WithLayoutParams<T>) {
return async <P extends "P" | "L">(p: P extends "P" ? PageProps : LayoutProps) => {
const h = headers();
const nonce = h.get("x-nonce") ?? undefined;
Expand All @@ -23,7 +29,13 @@ export function WithLayout<T extends Record<string, any>>({ getLayout, getData,
const children = "children" in p ? p.children : null;

return (
<PageWrapper getLayout={getLayout} requiresLicense={false} nonce={nonce} themeBasis={null} {...props}>
<PageWrapper
getLayout={getLayout}
requiresLicense={false}
nonce={nonce}
themeBasis={null}
isBookingPage={isBookingPage}
{...props}>
{Page ? <Page {...props} /> : children}
</PageWrapper>
);
Expand Down
102 changes: 102 additions & 0 deletions apps/web/lib/team/[slug]/[type]/getServerSideProps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import type { GetServerSidePropsContext } from "next";
import { z } from "zod";

import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { getBookingForReschedule, getMultipleDurationValue } from "@calcom/features/bookings/lib/get-booking";
import type { GetBookingType } from "@calcom/features/bookings/lib/get-booking";
import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import slugify from "@calcom/lib/slugify";
import prisma from "@calcom/prisma";
import { RedirectType } from "@calcom/prisma/client";

import { getTemporaryOrgRedirect } from "@lib/getTemporaryOrgRedirect";

const paramsSchema = z.object({
type: z.string().transform((s) => slugify(s)),
slug: z.string().transform((s) => slugify(s)),
});

// Booker page fetches a tiny bit of data server side:
// 1. Check if team exists, to show 404
// 2. If rescheduling, get the booking details
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const session = await getServerSession(context);
const { slug: teamSlug, type: meetingSlug } = paramsSchema.parse(context.params);
const { rescheduleUid, duration: queryDuration, isInstantMeeting: queryIsInstantMeeting } = context.query;
const { ssrInit } = await import("@server/lib/ssr");
const ssr = await ssrInit(context);
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(context.req, context.params?.orgSlug);
const isOrgContext = currentOrgDomain && isValidOrgDomain;

if (!isOrgContext) {
const redirect = await getTemporaryOrgRedirect({
slug: teamSlug,
redirectType: RedirectType.Team,
eventTypeSlug: meetingSlug,
currentQuery: context.query,
});

if (redirect) {
return redirect;
}
}

const team = await prisma.team.findFirst({
where: {
...getSlugOrRequestedSlug(teamSlug),
parent: isValidOrgDomain && currentOrgDomain ? getSlugOrRequestedSlug(currentOrgDomain) : null,
},
select: {
id: true,
hideBranding: true,
},
});

if (!team) {
return {
notFound: true,
} as const;
}

let booking: GetBookingType | null = null;
if (rescheduleUid) {
booking = await getBookingForReschedule(`${rescheduleUid}`, session?.user?.id);
}

const org = isValidOrgDomain ? currentOrgDomain : null;
// 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: teamSlug,
eventSlug: meetingSlug,
isTeamEvent: true,
org,
});

if (!eventData) {
return {
notFound: true,
} as const;
}

return {
props: {
entity: eventData.entity,
duration: getMultipleDurationValue(
eventData.metadata?.multipleDuration,
queryDuration,
eventData.length
),
booking,
away: false,
user: teamSlug,
teamId: team.id,
slug: meetingSlug,
trpcState: ssr.dehydrate(),
isBrandingHidden: team?.hideBranding,
isInstantMeeting: eventData.isInstantEvent && queryIsInstantMeeting ? true : false,
themeBasis: null,
},
};
};
Loading

0 comments on commit 060f278

Please sign in to comment.