From d4b05162352c88776e5563e36e9cebb761515351 Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Fri, 6 Sep 2024 13:22:05 -0400 Subject: [PATCH] chore: App router migration - (`/more`, `/maintenance`, `/connect-and-join`, `/upgrade`) finish migration (#16497) * more: extract client component into /modules folder * maintenance: extract client component into /modules folder * upgrade: extract client component into /modules folder * improve WithLayout wrapper * connect-and-join: extract client component into /modules folder * add env vars --- .env.example | 4 + apps/web/abTest/middlewareFactory.ts | 4 + apps/web/app/future/connect-and-join/page.tsx | 11 ++- apps/web/app/future/maintenance/page.tsx | 5 +- apps/web/app/future/more/page.tsx | 11 ++- apps/web/app/future/upgrade/page.tsx | 12 +++ apps/web/app/layoutHOC.tsx | 4 +- .../connect-and-join-view.tsx | 90 ++++++++++++++++++ .../modules/maintenance/maintenance-view.tsx | 25 +++++ apps/web/modules/more/more-page-view.tsx | 16 ++++ apps/web/modules/upgrade/upgrade-view.tsx | 59 ++++++++++++ apps/web/pages/connect-and-join.tsx | 93 +------------------ apps/web/pages/maintenance.tsx | 26 +----- apps/web/pages/more.tsx | 23 ++--- apps/web/pages/upgrade.tsx | 62 +------------ apps/web/scripts/vercel-app-router-deploy.sh | 7 +- turbo.json | 4 + 17 files changed, 259 insertions(+), 197 deletions(-) create mode 100644 apps/web/app/future/upgrade/page.tsx create mode 100644 apps/web/modules/connect-and-join/connect-and-join-view.tsx create mode 100644 apps/web/modules/maintenance/maintenance-view.tsx create mode 100644 apps/web/modules/more/more-page-view.tsx create mode 100644 apps/web/modules/upgrade/upgrade-view.tsx diff --git a/.env.example b/.env.example index 7f7e020437..876a670317 100644 --- a/.env.example +++ b/.env.example @@ -357,6 +357,10 @@ APP_ROUTER_AUTH_SAML_ENABLED=0 APP_ROUTER_AUTH_ERROR_ENABLED=0 APP_ROUTER_AUTH_PLATFORM_ENABLED=0 APP_ROUTER_AUTH_OAUTH2_ENABLED=0 +APP_ROUTER_MORE_ENABLED=0 +APP_ROUTER_MAINTENANCE_ENABLED=0 +APP_ROUTER_UPGRADE_ENABLED=0 +APP_ROUTER_CONNECT_AND_JOIN_ENABLED=0 # disable setry server source maps SENTRY_DISABLE_SERVER_WEBPACK_PLUGIN=1 diff --git a/apps/web/abTest/middlewareFactory.ts b/apps/web/abTest/middlewareFactory.ts index 7122d67318..8fdf1720f3 100644 --- a/apps/web/abTest/middlewareFactory.ts +++ b/apps/web/abTest/middlewareFactory.ts @@ -28,6 +28,10 @@ const ROUTES: [URLPattern, boolean][] = [ ["/bookings/:status", process.env.APP_ROUTER_BOOKINGS_STATUS_ENABLED === "1"] as const, ["/video/:path*", process.env.APP_ROUTER_VIDEO_ENABLED === "1"] as const, ["/teams", process.env.APP_ROUTER_TEAMS_ENABLED === "1"] as const, + ["/more", process.env.APP_ROUTER_MORE_ENABLED === "1"] as const, + ["/maintenance", process.env.APP_ROUTER_MAINTENANCE_ENABLED === "1"] as const, + ["/upgrade", process.env.APP_ROUTER_UPGRADE_ENABLED === "1"] as const, + ["/connect-and-join", process.env.APP_ROUTER_CONNECT_AND_JOIN_ENABLED === "1"] as const, ["/availability", process.env.APP_ROUTER_AVAILABILITY_ENABLED === "1"] as const, ].map(([pathname, enabled]) => [ new URLPattern({ diff --git a/apps/web/app/future/connect-and-join/page.tsx b/apps/web/app/future/connect-and-join/page.tsx index 0dea6c11c8..b429d5be7a 100644 --- a/apps/web/app/future/connect-and-join/page.tsx +++ b/apps/web/app/future/connect-and-join/page.tsx @@ -1,4 +1,13 @@ -import LegacyPage from "@pages/connect-and-join"; +import { _generateMetadata } from "app/_utils"; import { WithLayout } from "app/layoutHOC"; +import LegacyPage from "~/connect-and-join/connect-and-join-view"; + +export const generateMetadata = async () => { + return await _generateMetadata( + () => "Connect and Join", + () => "" + ); +}; + export default WithLayout({ getLayout: null, Page: LegacyPage })<"P">; diff --git a/apps/web/app/future/maintenance/page.tsx b/apps/web/app/future/maintenance/page.tsx index 919c175775..1067014dbc 100644 --- a/apps/web/app/future/maintenance/page.tsx +++ b/apps/web/app/future/maintenance/page.tsx @@ -1,12 +1,13 @@ -import LegacyPage from "@pages/maintenance"; import { _generateMetadata } from "app/_utils"; import { WithLayout } from "app/layoutHOC"; import { APP_NAME } from "@calcom/lib/constants"; +import LegacyPage from "~/maintenance/maintenance-view"; + export const generateMetadata = async () => await _generateMetadata( - (t) => `${t("under_maintenance")}`, + (t) => t("under_maintenance"), (t) => t("under_maintenance_description", { appName: APP_NAME }) ); diff --git a/apps/web/app/future/more/page.tsx b/apps/web/app/future/more/page.tsx index c6eb75321a..1980555ae0 100644 --- a/apps/web/app/future/more/page.tsx +++ b/apps/web/app/future/more/page.tsx @@ -1,4 +1,13 @@ -import Page from "@pages/more"; +import { _generateMetadata } from "app/_utils"; import { WithLayout } from "app/layoutHOC"; +import Page from "~/more/more-page-view"; + +export const generateMetadata = async () => { + return await _generateMetadata( + () => "More", + () => "" + ); +}; + export default WithLayout({ getLayout: null, Page })<"P">; diff --git a/apps/web/app/future/upgrade/page.tsx b/apps/web/app/future/upgrade/page.tsx new file mode 100644 index 0000000000..aff0a0e14e --- /dev/null +++ b/apps/web/app/future/upgrade/page.tsx @@ -0,0 +1,12 @@ +import { _generateMetadata } from "app/_utils"; +import { WithLayout } from "app/layoutHOC"; + +import LegacyPage from "~/upgrade/upgrade-view"; + +export const generateMetadata = async () => + await _generateMetadata( + () => "Upgrade", + () => "" + ); + +export default WithLayout({ getLayout: null, Page: LegacyPage })<"P">; diff --git a/apps/web/app/layoutHOC.tsx b/apps/web/app/layoutHOC.tsx index 320e8d95cd..9ea33df3fd 100644 --- a/apps/web/app/layoutHOC.tsx +++ b/apps/web/app/layoutHOC.tsx @@ -11,6 +11,7 @@ type WithLayoutParams> = { Page?: (props: T) => React.ReactElement | null; getData?: (arg: GetServerSidePropsContext) => Promise; isBookingPage?: boolean; + requiresLicense?: boolean; }; export function WithLayout>({ @@ -18,6 +19,7 @@ export function WithLayout>({ getData, Page, isBookingPage, + requiresLicense, }: WithLayoutParams) { return async

(p: P extends "P" ? PageProps : LayoutProps) => { const h = headers(); @@ -33,7 +35,7 @@ export function WithLayout>({ return ( (null); + const [errorMessage, setErrorMessage] = useState(); + + const session = useSession(); + const isUserPartOfOrg = session.status === "authenticated" && !!session.data.user?.org; + + const mutation = trpc.viewer.connectAndJoin.useMutation({ + onSuccess: (res) => { + if (res.meetingUrl && !res.isBookingAlreadyAcceptedBySomeoneElse) { + router.push(res.meetingUrl); + } else if (res.isBookingAlreadyAcceptedBySomeoneElse && res.meetingUrl) { + setMeetingUrl(res.meetingUrl); + } + }, + onError: (err) => { + console.log("err", err, err instanceof TRPCClientError); + if (err instanceof TRPCClientError) { + setErrorMessage(t(err.message)); + } else { + setErrorMessage(t("something_went_wrong")); + } + }, + }); + + if (session.status === "loading") return

{t("loading")}

; + + if (!token) return

{t("token_not_found")}

; + + return ( +
+ {session ? ( + + {meetingUrl ? ( +
+ + Some other host already accepted the meeting. Do you still want to join? + + Continue to Meeting + + +
+ ) : ( + + )} + {errorMessage && } +
+ } + /> + ) : ( +
{t("you_must_be_logged_in_to", { url: WEBAPP_URL })}
+ )} + + ); +} + +ConnectAndJoin.requiresLicense = true; + +export default ConnectAndJoin; diff --git a/apps/web/modules/maintenance/maintenance-view.tsx b/apps/web/modules/maintenance/maintenance-view.tsx new file mode 100644 index 0000000000..605174f723 --- /dev/null +++ b/apps/web/modules/maintenance/maintenance-view.tsx @@ -0,0 +1,25 @@ +"use client"; + +import Head from "next/head"; + +import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants"; +import { Button } from "@calcom/ui"; + +export default function MaintenancePage() { + return ( +
+ + Under Maintenance | {APP_NAME} + + +
+

Down for maintenance

+

+ The Cal.com team are performing scheduled maintenance. If you have any questions, please contact + support. +

+ +
+
+ ); +} diff --git a/apps/web/modules/more/more-page-view.tsx b/apps/web/modules/more/more-page-view.tsx new file mode 100644 index 0000000000..ae5ff2c01d --- /dev/null +++ b/apps/web/modules/more/more-page-view.tsx @@ -0,0 +1,16 @@ +"use client"; + +import Shell, { MobileNavigationMoreItems } from "@calcom/features/shell/Shell"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; + +export default function MorePage() { + const { t } = useLocale(); + return ( + +
+ +

{t("more_page_footer")}

+
+
+ ); +} diff --git a/apps/web/modules/upgrade/upgrade-view.tsx b/apps/web/modules/upgrade/upgrade-view.tsx new file mode 100644 index 0000000000..cb3e8ff866 --- /dev/null +++ b/apps/web/modules/upgrade/upgrade-view.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useRouter } from "next/navigation"; + +import Shell from "@calcom/features/shell/Shell"; +import { useLocale } from "@calcom/lib/hooks/useLocale"; +import type { RouterOutputs } from "@calcom/trpc/react"; +import { trpc } from "@calcom/trpc/react"; +import { Button, EmptyScreen } from "@calcom/ui"; +import { showToast } from "@calcom/ui"; + +export type OrgUpgradeBannerProps = { + data: RouterOutputs["viewer"]["getUserTopBanners"]["orgUpgradeBanner"]; +}; + +export default function UpgradePage() { + const { t } = useLocale(); + + const router = useRouter(); + const publishOrgMutation = trpc.viewer.organizations.publish.useMutation({ + onSuccess(data) { + router.push(data.url); + }, + onError: (error) => { + showToast(error.message, "error"); + }, + }); + + const doesUserHaveOrgToUpgrade = trpc.viewer.organizations.checkIfOrgNeedsUpgrade.useQuery(); + + return ( + +
+ {doesUserHaveOrgToUpgrade.data ? ( + { + publishOrgMutation.mutate(); + }}> + {t("upgrade")} + + } + /> + ) : ( + {t("contact_support")}} + /> + )} +
+
+ ); +} diff --git a/apps/web/pages/connect-and-join.tsx b/apps/web/pages/connect-and-join.tsx index 38d27f56d4..6dae34a2f0 100644 --- a/apps/web/pages/connect-and-join.tsx +++ b/apps/web/pages/connect-and-join.tsx @@ -1,93 +1,8 @@ -"use client"; - -import { useSession } from "next-auth/react"; -import { Trans } from "next-i18next"; -import Link from "next/link"; -import { useRouter } from "next/navigation"; -import { useState } from "react"; - -import { getQueryParam } from "@calcom/features/bookings/Booker/utils/query-param"; -import { WEBAPP_URL } from "@calcom/lib/constants"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import { trpc } from "@calcom/trpc"; -import { TRPCClientError } from "@calcom/trpc/react"; -import { Button, EmptyScreen, Alert } from "@calcom/ui"; - import PageWrapper from "@components/PageWrapper"; -function ConnectAndJoin() { - const { t } = useLocale(); - const router = useRouter(); - const token = getQueryParam("token"); - const [meetingUrl, setMeetingUrl] = useState(null); - const [errorMessage, setErrorMessage] = useState(); +import ConnectAndJoinPage from "~/connect-and-join/connect-and-join-view"; - const session = useSession(); - const isUserPartOfOrg = session.status === "authenticated" && !!session.data.user?.org; +const Page = () => ; +Page.PageWrapper = PageWrapper; - const mutation = trpc.viewer.connectAndJoin.useMutation({ - onSuccess: (res) => { - if (res.meetingUrl && !res.isBookingAlreadyAcceptedBySomeoneElse) { - router.push(res.meetingUrl); - } else if (res.isBookingAlreadyAcceptedBySomeoneElse && res.meetingUrl) { - setMeetingUrl(res.meetingUrl); - } - }, - onError: (err) => { - console.log("err", err, err instanceof TRPCClientError); - if (err instanceof TRPCClientError) { - setErrorMessage(t(err.message)); - } else { - setErrorMessage(t("something_went_wrong")); - } - }, - }); - - if (session.status === "loading") return

{t("loading")}

; - - if (!token) return

{t("token_not_found")}

; - - return ( -
- {session ? ( - - {meetingUrl ? ( -
- - Some other host already accepted the meeting. Do you still want to join? - - Continue to Meeting - - -
- ) : ( - - )} - {errorMessage && } -
- } - /> - ) : ( -
{t("you_must_be_logged_in_to", { url: WEBAPP_URL })}
- )} - - ); -} - -ConnectAndJoin.requiresLicense = true; -ConnectAndJoin.PageWrapper = PageWrapper; - -export default ConnectAndJoin; +export default Page; diff --git a/apps/web/pages/maintenance.tsx b/apps/web/pages/maintenance.tsx index 605174f723..3428f9f126 100644 --- a/apps/web/pages/maintenance.tsx +++ b/apps/web/pages/maintenance.tsx @@ -1,25 +1 @@ -"use client"; - -import Head from "next/head"; - -import { APP_NAME, WEBSITE_URL } from "@calcom/lib/constants"; -import { Button } from "@calcom/ui"; - -export default function MaintenancePage() { - return ( -
- - Under Maintenance | {APP_NAME} - - -
-

Down for maintenance

-

- The Cal.com team are performing scheduled maintenance. If you have any questions, please contact - support. -

- -
-
- ); -} +export { default } from "~/maintenance/maintenance-view"; diff --git a/apps/web/pages/more.tsx b/apps/web/pages/more.tsx index d746d327ac..0e82af955f 100644 --- a/apps/web/pages/more.tsx +++ b/apps/web/pages/more.tsx @@ -1,19 +1,8 @@ -"use client"; - -import Shell, { MobileNavigationMoreItems } from "@calcom/features/shell/Shell"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; - import PageWrapper from "@components/PageWrapper"; -export default function MorePage() { - const { t } = useLocale(); - return ( - -
- -

{t("more_page_footer")}

-
-
- ); -} -MorePage.PageWrapper = PageWrapper; +import MorePage from "~/more/more-page-view"; + +const Page = () => ; +Page.PageWrapper = PageWrapper; + +export default Page; diff --git a/apps/web/pages/upgrade.tsx b/apps/web/pages/upgrade.tsx index 55bccb8059..a805294b0b 100644 --- a/apps/web/pages/upgrade.tsx +++ b/apps/web/pages/upgrade.tsx @@ -1,62 +1,8 @@ -"use client"; - -import { useRouter } from "next/navigation"; - -import Shell from "@calcom/features/shell/Shell"; -import { useLocale } from "@calcom/lib/hooks/useLocale"; -import type { RouterOutputs } from "@calcom/trpc/react"; -import { trpc } from "@calcom/trpc/react"; -import { Button, EmptyScreen } from "@calcom/ui"; -import { showToast } from "@calcom/ui"; - import PageWrapper from "@components/PageWrapper"; -export type OrgUpgradeBannerProps = { - data: RouterOutputs["viewer"]["getUserTopBanners"]["orgUpgradeBanner"]; -}; +import UpgradePage from "~/upgrade/upgrade-view"; -export default function UpgradePage() { - const { t } = useLocale(); +const Page = () => ; +Page.PageWrapper = PageWrapper; - const router = useRouter(); - const publishOrgMutation = trpc.viewer.organizations.publish.useMutation({ - onSuccess(data) { - router.push(data.url); - }, - onError: (error) => { - showToast(error.message, "error"); - }, - }); - - const doesUserHaveOrgToUpgrade = trpc.viewer.organizations.checkIfOrgNeedsUpgrade.useQuery(); - - return ( - -
- {doesUserHaveOrgToUpgrade.data ? ( - { - publishOrgMutation.mutate(); - }}> - {t("upgrade")} - - } - /> - ) : ( - {t("contact_support")}} - /> - )} -
-
- ); -} -UpgradePage.PageWrapper = PageWrapper; +export default Page; diff --git a/apps/web/scripts/vercel-app-router-deploy.sh b/apps/web/scripts/vercel-app-router-deploy.sh index 19b667505d..8153fb8823 100755 --- a/apps/web/scripts/vercel-app-router-deploy.sh +++ b/apps/web/scripts/vercel-app-router-deploy.sh @@ -29,18 +29,19 @@ checkRoute "$APP_ROUTER_APPS_ENABLED" app/future/apps checkRoute "$APP_ROUTER_BOOKINGS_STATUS_ENABLED" app/future/bookings checkRoute "$APP_ROUTER_VIDEO_ENABLED" app/future/video checkRoute "$APP_ROUTER_TEAMS_ENABLED" app/future/teams +checkRoute "$APP_ROUTER_MORE_ENABLED" app/future/more +checkRoute "$APP_ROUTER_MAINTENANCE_ENABLED" app/future/maintenance +checkRoute "$APP_ROUTER_UPGRADE_ENABLED" app/future/upgrade +checkRoute "$APP_ROUTER_CONNECT_AND_JOIN_ENABLED" app/future/connect-and-join # These are routes that don't have and environment variable to enable or disable them # Will stop removing gradually as we test and confirm that they are working rm -rf \ app/future/[user]\ app/future/booking\ - app/future/connect-and-join\ app/future/d\ app/future/enterprise\ app/future/insights\ - app/future/maintenance\ - app/future/more\ app/future/org\ app/future/payment\ app/future/reschedule\ diff --git a/turbo.json b/turbo.json index 18ec904aac..42223ff478 100644 --- a/turbo.json +++ b/turbo.json @@ -247,6 +247,10 @@ "APP_ROUTER_AUTH_ERROR_ENABLED", "APP_ROUTER_AUTH_PLATFORM_ENABLED", "APP_ROUTER_AUTH_OAUTH2_ENABLED", + "APP_ROUTER_MORE_ENABLED", + "APP_ROUTER_MAINTENANCE_ENABLED", + "APP_ROUTER_UPGRADE_ENABLED", + "APP_ROUTER_CONNECT_AND_JOIN_ENABLED", "APP_ROUTER_TEAMS_ENABLED", "APP_ROUTER_AVAILABILITY_ENABLED", "APP_USER_NAME",