diff --git a/.env.example b/.env.example index 8d41876043..f0633dd305 100644 --- a/.env.example +++ b/.env.example @@ -357,10 +357,6 @@ E2E_TEST_OIDC_USER_PASSWORD= # redirected from the legacy to the future pages AB_TEST_BUCKET_PROBABILITY=50 APP_ROUTER_APPS_SLUG_SETUP_ENABLED=0 -# whether we redirect to the future/apps/categories from /apps/categories or not -APP_ROUTER_APPS_CATEGORIES_ENABLED=0 -# whether we redirect to the future/apps/categories/[category] from /apps/categories/[category] or not -APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED=0 APP_ROUTER_APPS_ENABLED=0 APP_ROUTER_TEAM_ENABLED=0 APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED=0 diff --git a/apps/web/abTest/middlewareFactory.ts b/apps/web/abTest/middlewareFactory.ts index 7d8d85fb88..f375ea6a92 100644 --- a/apps/web/abTest/middlewareFactory.ts +++ b/apps/web/abTest/middlewareFactory.ts @@ -6,8 +6,6 @@ import { FUTURE_ROUTES_ENABLED_COOKIE_NAME, FUTURE_ROUTES_OVERRIDE_COOKIE_NAME } const ROUTES: [URLPattern, boolean][] = [ ["/apps/:slug/setup", process.env.APP_ROUTER_APPS_SLUG_SETUP_ENABLED === "1"] as const, - ["/apps/categories", process.env.APP_ROUTER_APPS_CATEGORIES_ENABLED === "1"] as const, - ["/apps/categories/:category", process.env.APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED === "1"] as const, ["/auth/forgot-password/:path*", process.env.APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED === "1"] as const, ["/auth/login", process.env.APP_ROUTER_AUTH_LOGIN_ENABLED === "1"] as const, ["/auth/logout", process.env.APP_ROUTER_AUTH_LOGOUT_ENABLED === "1"] as const, diff --git a/apps/web/app/(use-page-wrapper)/apps/categories/[category]/page.tsx b/apps/web/app/(use-page-wrapper)/apps/categories/[category]/page.tsx new file mode 100644 index 0000000000..43b6b74bd7 --- /dev/null +++ b/apps/web/app/(use-page-wrapper)/apps/categories/[category]/page.tsx @@ -0,0 +1,26 @@ +import type { PageProps } from "app/_types"; +import { redirect } from "next/navigation"; +import { z } from "zod"; + +import { AppCategories } from "@calcom/prisma/enums"; + +import { getStaticProps } from "@lib/apps/categories/[category]/getStaticProps"; + +import CategoryPage from "~/apps/categories/[category]/category-view"; + +const querySchema = z.object({ + category: z.enum(Object.values(AppCategories) as [AppCategories, ...AppCategories[]]), +}); + +async function Page({ params, searchParams }: PageProps) { + const parsed = querySchema.safeParse({ ...params, ...searchParams }); + if (!parsed.success) { + redirect("/apps/categories/calendar"); + } + + const props = await getStaticProps(parsed.data.category); + + return ; +} + +export default Page; diff --git a/apps/web/app/(use-page-wrapper)/apps/categories/layout.tsx b/apps/web/app/(use-page-wrapper)/apps/categories/layout.tsx new file mode 100644 index 0000000000..46785b22c5 --- /dev/null +++ b/apps/web/app/(use-page-wrapper)/apps/categories/layout.tsx @@ -0,0 +1,12 @@ +import { _generateMetadata } from "app/_utils"; + +export const generateMetadata = async () => { + return await _generateMetadata( + (t) => t("app_store"), + (t) => t("app_store_description") + ); +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx b/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx new file mode 100644 index 0000000000..0f07252b77 --- /dev/null +++ b/apps/web/app/(use-page-wrapper)/apps/categories/page.tsx @@ -0,0 +1,18 @@ +import { withAppDirSsr } from "app/WithAppDirSsr"; +import type { PageProps } from "app/_types"; +import { cookies, headers } from "next/headers"; + +import { getServerSideProps } from "@lib/apps/categories/getServerSideProps"; +import { buildLegacyCtx } from "@lib/buildLegacyCtx"; + +import Page from "~/apps/categories/categories-view"; + +const getData = withAppDirSsr(getServerSideProps); + +async function ServerPage({ params, searchParams }: PageProps) { + const props = await getData(buildLegacyCtx(headers(), cookies(), params, searchParams)); + + return ; +} + +export default ServerPage; diff --git a/apps/web/app/future/apps/categories/[category]/page.tsx b/apps/web/app/future/apps/categories/[category]/page.tsx deleted file mode 100644 index 4aae6cb845..0000000000 --- a/apps/web/app/future/apps/categories/[category]/page.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { withAppDirSsg } from "app/WithAppDirSsg"; -import { _generateMetadata } from "app/_utils"; -import { WithLayout } from "app/layoutHOC"; - -import { AppCategories } from "@calcom/prisma/enums"; -import { isPrismaAvailableCheck } from "@calcom/prisma/is-prisma-available-check"; - -import { getStaticProps } from "@lib/apps/categories/[category]/getStaticProps"; - -import CategoryPage, { type PageProps } from "~/apps/categories/[category]/category-view"; - -export const generateMetadata = async () => { - return await _generateMetadata( - (t) => t("app_store"), - (t) => t("app_store_description") - ); -}; - -export const generateStaticParams = async () => { - const paths = Object.keys(AppCategories); - const isPrismaAvailable = await isPrismaAvailableCheck(); - - if (!isPrismaAvailable) { - // Database is not available at build time. Make sure we fall back to building these pages on demand - return []; - } - - return paths.map((category) => ({ category })); -}; - -const getData = withAppDirSsg(getStaticProps, "future/apps/categories/[category]"); - -export default WithLayout({ getData, Page: CategoryPage, getLayout: null })<"P">; -export const dynamic = "force-static"; diff --git a/apps/web/app/future/apps/categories/page.tsx b/apps/web/app/future/apps/categories/page.tsx deleted file mode 100644 index 03eb324018..0000000000 --- a/apps/web/app/future/apps/categories/page.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { withAppDirSsr } from "app/WithAppDirSsr"; -import { _generateMetadata } from "app/_utils"; -import { WithLayout } from "app/layoutHOC"; - -import { getServerSideProps } from "@lib/apps/categories/getServerSideProps"; - -import Page from "~/apps/categories/categories-view"; - -export const generateMetadata = async () => { - return await _generateMetadata( - (t) => t("app_store"), - (t) => t("app_store_description") - ); -}; - -export default WithLayout({ getData: withAppDirSsr(getServerSideProps), Page, getLayout: null })<"P">; diff --git a/apps/web/lib/apps/categories/[category]/getStaticProps.tsx b/apps/web/lib/apps/categories/[category]/getStaticProps.tsx index 7afa898b1c..29daa45a82 100644 --- a/apps/web/lib/apps/categories/[category]/getStaticProps.tsx +++ b/apps/web/lib/apps/categories/[category]/getStaticProps.tsx @@ -1,12 +1,10 @@ -import type { GetStaticPropsContext } from "next"; - import { getAppRegistry } from "@calcom/app-store/_appRegistry"; import prisma from "@calcom/prisma"; import type { AppCategories } from "@calcom/prisma/enums"; -export const getStaticProps = async (context: GetStaticPropsContext) => { - const category = context.params?.category as AppCategories; +export type CategoryDataProps = NonNullable>>; +export const getStaticProps = async (category: AppCategories) => { const appQuery = await prisma.app.findMany({ where: { categories: { @@ -24,8 +22,7 @@ export const getStaticProps = async (context: GetStaticPropsContext) => { const apps = appStore.filter((app) => dbAppsSlugs.includes(app.slug)); return { - props: { - apps, - }, + apps, + category, }; }; diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index ce43261574..a68b06492b 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -177,9 +177,7 @@ export const config = { "/apps/:slug/setup/", "/future/apps/:slug/setup/", "/apps/categories/", - "/future/apps/categories/", "/apps/categories/:category/", - "/future/apps/categories/:category/", "/workflows/:path*", "/getting-started/:path*", "/apps", diff --git a/apps/web/modules/apps/categories/[category]/category-view.tsx b/apps/web/modules/apps/categories/[category]/category-view.tsx index 519dca26dc..6a6fec22cc 100644 --- a/apps/web/modules/apps/categories/[category]/category-view.tsx +++ b/apps/web/modules/apps/categories/[category]/category-view.tsx @@ -1,25 +1,21 @@ "use client"; -import type { InferGetStaticPropsType } from "next"; import Link from "next/link"; import Shell from "@calcom/features/shell/Shell"; -import { useCompatSearchParams } from "@calcom/lib/hooks/useCompatSearchParams"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { AppCard, SkeletonText } from "@calcom/ui"; -import type { getStaticProps } from "@lib/apps/categories/[category]/getStaticProps"; +import type { CategoryDataProps } from "@lib/apps/categories/[category]/getStaticProps"; -export type PageProps = InferGetStaticPropsType; -export default function Apps({ apps }: PageProps) { - const searchParams = useCompatSearchParams(); +export default function Apps({ apps, category }: CategoryDataProps) { const { t, isLocaleReady } = useLocale(); - const category = searchParams?.get("category"); return ( <> +
; -Page.PageWrapper = PageWrapper; - -export const getStaticPaths = async () => { - const paths = Object.keys(AppCategories); - const isPrismaAvailable = await isPrismaAvailableCheck(); - if (!isPrismaAvailable) { - // Database is not available at build time. Make sure we fall back to building these pages on demand - return { - paths: [], - fallback: "blocking", - }; - } - - return { - paths: paths.map((category) => ({ params: { category } })), - fallback: false, - }; -}; - -export default Page; - -export { getStaticProps }; diff --git a/apps/web/pages/apps/categories/index.tsx b/apps/web/pages/apps/categories/index.tsx deleted file mode 100644 index 54c738a5c9..0000000000 --- a/apps/web/pages/apps/categories/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { getServerSideProps } from "@lib/apps/categories/getServerSideProps"; - -import PageWrapper from "@components/PageWrapper"; - -import type { PageProps } from "~/apps/categories/categories-view"; -import Apps from "~/apps/categories/categories-view"; - -const Page = (props: PageProps) => ; -Page.PageWrapper = PageWrapper; - -export default Page; -export { getServerSideProps }; diff --git a/apps/web/scripts/vercel-app-router-deploy.sh b/apps/web/scripts/vercel-app-router-deploy.sh index b6157d9f46..014536edac 100755 --- a/apps/web/scripts/vercel-app-router-deploy.sh +++ b/apps/web/scripts/vercel-app-router-deploy.sh @@ -7,8 +7,6 @@ checkRoute () { # These conditionals are used to remove directories from the build that are not needed in production # This is to reduce the size of the build and prevent OOM errors checkRoute "$APP_ROUTER_APPS_SLUG_SETUP_ENABLED" app/future/apps/\[slug\]/setup -checkRoute "$APP_ROUTER_APPS_CATEGORIES_ENABLED" app/future/apps/categories -checkRoute "$APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED" app/future/apps/categories/\[category\] checkRoute "$APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED" app/future/auth/forgot-password checkRoute "$APP_ROUTER_AUTH_LOGIN_ENABLED" app/future/auth/login checkRoute "$APP_ROUTER_AUTH_LOGOUT_ENABLED" app/future/auth/logout diff --git a/turbo.json b/turbo.json index 40a707ff31..9da10623fe 100644 --- a/turbo.json +++ b/turbo.json @@ -240,8 +240,6 @@ "ALLOWED_HOSTNAMES", "ANALYZE", "API_KEY_PREFIX", - "APP_ROUTER_APPS_CATEGORIES_CATEGORY_ENABLED", - "APP_ROUTER_APPS_CATEGORIES_ENABLED", "APP_ROUTER_APPS_SLUG_SETUP_ENABLED", "APP_ROUTER_AUTH_FORGOT_PASSWORD_ENABLED", "APP_ROUTER_AUTH_LOGIN_ENABLED",