chore: better code - migrate getServerSideProps file directly to RSC for /apps (#20926)

* migrate getServerSideProps file directly to RSC for /apps

* fix
This commit is contained in:
Benny Joo
2025-04-25 06:41:21 -07:00
committed by GitHub
parent 78c0203a45
commit 220897ba86
5 changed files with 58 additions and 66 deletions
@@ -1,10 +1,12 @@
import { withAppDirSsr } from "app/WithAppDirSsr";
import type { PageProps } from "app/_types";
import { _generateMetadata } from "app/_utils";
import { cookies, headers } from "next/headers";
import { getServerSideProps } from "@lib/apps/getServerSideProps";
import { buildLegacyCtx } from "@lib/buildLegacyCtx";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { UserRepository } from "@calcom/lib/server/repository/user";
import type { AppCategories } from "@calcom/prisma/enums";
import { buildLegacyRequest } from "@lib/buildLegacyCtx";
import AppsPage from "~/apps/apps-view";
@@ -18,13 +20,43 @@ export const generateMetadata = async () => {
);
};
const getData = withAppDirSsr(getServerSideProps);
const ServerPage = async () => {
const req = buildLegacyRequest(await headers(), await cookies());
const session = await getServerSession({ req });
let appStore, userAdminTeamsIds: number[];
if (session?.user?.id) {
const userAdminTeams = await UserRepository.getUserAdminTeams(session.user.id);
userAdminTeamsIds = userAdminTeams?.teams?.map(({ team }) => team.id) ?? [];
appStore = await getAppRegistryWithCredentials(session.user.id, userAdminTeamsIds);
} else {
appStore = await getAppRegistry();
userAdminTeamsIds = [];
}
const ServerPage = async ({ params, searchParams }: PageProps) => {
const context = buildLegacyCtx(await headers(), await cookies(), await params, await searchParams);
const props = await getData(context);
const categoryQuery = appStore.map(({ categories }) => ({
categories: categories || [],
}));
const categories = categoryQuery.reduce((c, app) => {
for (const category of app.categories) {
c[category] = c[category] ? c[category] + 1 : 1;
}
return c;
}, {} as Record<string, number>);
return <AppsPage {...props} />;
const props = {
categories: Object.entries(categories)
.map(([name, count]): { name: AppCategories; count: number } => ({
name: name as AppCategories,
count,
}))
.sort(function (a, b) {
return b.count - a.count;
}),
appStore,
userAdminTeams: userAdminTeamsIds,
};
return <AppsPage {...props} isAdmin={session?.user?.role === "ADMIN"} />;
};
export default ServerPage;
@@ -13,7 +13,8 @@ export function AppHomePageSkeleton() {
isPublic
heading={t("app_store")}
subtitle={t("app_store_description")}
headerClassName="sm:hidden lg:block hidden">
headerClassName="sm:hidden lg:block hidden"
isAdmin={false}>
<SkeletonContainer>
<div className="flex flex-col gap-y-8">
{/* Featured Categories section */}
@@ -1,4 +1,3 @@
import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation";
import type { ComponentProps } from "react";
import React from "react";
@@ -9,15 +8,14 @@ import { EmptyScreen } from "@calcom/ui/components/empty-screen";
type AppsLayoutProps = {
children: React.ReactNode;
isAdmin: boolean;
actions?: (className?: string) => JSX.Element;
emptyStore?: boolean;
} & Omit<ComponentProps<typeof Shell>, "actions">;
export default function AppsLayout({ children, actions, emptyStore, ...rest }: AppsLayoutProps) {
export default function AppsLayout({ children, actions, emptyStore, isAdmin, ...rest }: AppsLayoutProps) {
const { t } = useLocale();
const session = useSession();
const router = useRouter();
const isAdmin = session.data?.user.role === "ADMIN";
return (
<Shell {...rest} actions={actions?.("block")}>
-47
View File
@@ -1,47 +0,0 @@
import type { GetServerSidePropsContext } from "next";
import { getAppRegistry, getAppRegistryWithCredentials } from "@calcom/app-store/_appRegistry";
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
import { UserRepository } from "@calcom/lib/server/repository/user";
import type { AppCategories } from "@calcom/prisma/enums";
export const getServerSideProps = async (context: GetServerSidePropsContext) => {
const { req } = context;
const session = await getServerSession({ req });
let appStore, userAdminTeamsIds: number[];
if (session?.user?.id) {
const userAdminTeams = await UserRepository.getUserAdminTeams(session.user.id);
userAdminTeamsIds = userAdminTeams?.teams?.map(({ team }) => team.id) ?? [];
appStore = await getAppRegistryWithCredentials(session.user.id, userAdminTeamsIds);
} else {
appStore = await getAppRegistry();
userAdminTeamsIds = [];
}
const categoryQuery = appStore.map(({ categories }) => ({
categories: categories || [],
}));
const categories = categoryQuery.reduce((c, app) => {
for (const category of app.categories) {
c[category] = c[category] ? c[category] + 1 : 1;
}
return c;
}, {} as Record<string, number>);
return {
props: {
categories: Object.entries(categories)
.map(([name, count]): { name: AppCategories; count: number } => ({
name: name as AppCategories,
count,
}))
.sort(function (a, b) {
return b.count - a.count;
}),
appStore,
userAdminTeams: userAdminTeamsIds,
},
};
};
+13 -5
View File
@@ -8,15 +8,14 @@ import { AppStoreCategories } from "@calcom/features/apps/components/Categories"
import { PopularAppsSlider } from "@calcom/features/apps/components/PopularAppsSlider";
import { RecentAppsSlider } from "@calcom/features/apps/components/RecentAppsSlider";
import { useLocale } from "@calcom/lib/hooks/useLocale";
import type { inferSSRProps } from "@calcom/types/inferSSRProps";
import type { AppCategories } from "@calcom/prisma/enums";
import type { AppFrontendPayload } from "@calcom/types/App";
import classNames from "@calcom/ui/classNames";
import { TextField } from "@calcom/ui/components/form";
import { Icon } from "@calcom/ui/components/icon";
import type { HorizontalTabItemProps } from "@calcom/ui/components/navigation";
import { HorizontalTabs } from "@calcom/ui/components/navigation";
import { type getServerSideProps } from "@lib/apps/getServerSideProps";
import AppsLayout from "@components/apps/layouts/AppsLayout";
const tabs: HorizontalTabItemProps[] = [
@@ -51,15 +50,24 @@ function AppsSearch({
);
}
export type PageProps = inferSSRProps<typeof getServerSideProps>;
export type PageProps = {
categories: {
name: AppCategories;
count: number;
}[];
appStore: AppFrontendPayload[];
userAdminTeams: number[];
isAdmin: boolean;
};
export default function Apps({ categories, appStore, userAdminTeams }: PageProps) {
export default function Apps({ isAdmin, categories, appStore, userAdminTeams }: PageProps) {
const { t } = useLocale();
const [searchText, setSearchText] = useState<string | undefined>(undefined);
return (
<AppsLayout
isPublic
isAdmin={isAdmin}
heading={t("app_store")}
subtitle={t("app_store_description")}
actions={(className) => (