From 139a7c8249b82fe86f92d9a1bf2c27f26ee59516 Mon Sep 17 00:00:00 2001 From: DmytroHryshyn <125881252+DmytroHryshyn@users.noreply.github.com> Date: Wed, 25 Oct 2023 23:58:08 +0300 Subject: [PATCH] chore: [app dir bootstrapping 5] add RootLayout (#11982) Co-authored-by: zomars Co-authored-by: Greg Pabian <35925521+grzpab@users.noreply.github.com> --- ...honenumber-js-npm-1.10.12-51c84f8bf1.patch | 15 + apps/web/app/layout.tsx | 109 +++++++ apps/web/components/PageWrapperAppDir.tsx | 88 ++++++ apps/web/lib/app-providers-app-dir.tsx | 291 ++++++++++++++++++ package.json | 3 +- yarn.lock | 15 +- 6 files changed, 516 insertions(+), 5 deletions(-) create mode 100644 .yarn/patches/libphonenumber-js-npm-1.10.12-51c84f8bf1.patch create mode 100644 apps/web/app/layout.tsx create mode 100644 apps/web/components/PageWrapperAppDir.tsx create mode 100644 apps/web/lib/app-providers-app-dir.tsx diff --git a/.yarn/patches/libphonenumber-js-npm-1.10.12-51c84f8bf1.patch b/.yarn/patches/libphonenumber-js-npm-1.10.12-51c84f8bf1.patch new file mode 100644 index 0000000000..7cfa242404 --- /dev/null +++ b/.yarn/patches/libphonenumber-js-npm-1.10.12-51c84f8bf1.patch @@ -0,0 +1,15 @@ +diff --git a/index.cjs b/index.cjs +index b645707a3549fc298508726e404243499bbed499..f34b0891e99b275a9218e253f303f43d31ef3f73 100644 +--- a/index.cjs ++++ b/index.cjs +@@ -13,8 +13,8 @@ function withMetadataArgument(func, _arguments) { + // https://github.com/babel/babel/issues/2212#issuecomment-131827986 + // An alternative approach: + // https://www.npmjs.com/package/babel-plugin-add-module-exports +-exports = module.exports = min.parsePhoneNumberFromString +-exports['default'] = min.parsePhoneNumberFromString ++// exports = module.exports = min.parsePhoneNumberFromString ++// exports['default'] = min.parsePhoneNumberFromString + + // `parsePhoneNumberFromString()` named export is now considered legacy: + // it has been promoted to a default export due to being too verbose. diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx new file mode 100644 index 0000000000..23d224b6e1 --- /dev/null +++ b/apps/web/app/layout.tsx @@ -0,0 +1,109 @@ +import type { Metadata } from "next"; +import { headers as nextHeaders, cookies as nextCookies } from "next/headers"; +import Script from "next/script"; +import React from "react"; + +import { getLocale } from "@calcom/features/auth/lib/getLocale"; +import { IS_PRODUCTION } from "@calcom/lib/constants"; + +import "../styles/globals.css"; + +export const metadata: Metadata = { + icons: { + icon: [ + { + sizes: "32x32", + url: "/api/logo?type=favicon-32", + }, + { + sizes: "16x16", + url: "/api/logo?type=favicon-16", + }, + ], + apple: { + sizes: "180x180", + url: "/api/logo?type=apple-touch-icon", + }, + other: [ + { + url: "/safari-pinned-tab.svg", + rel: "mask-icon", + }, + ], + }, + manifest: "/site.webmanifest", + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#f9fafb" }, + { media: "(prefers-color-scheme: dark)", color: "#1C1C1C" }, + ], + other: { + "msapplication-TileColor": "#000000", + }, +}; + +const getInitialProps = async ( + url: string, + headers: ReturnType, + cookies: ReturnType +) => { + const { pathname, searchParams } = new URL(url); + + const isEmbed = pathname.endsWith("/embed") || (searchParams?.get("embedType") ?? null) !== null; + const embedColorScheme = searchParams?.get("ui.color-scheme"); + + // @ts-expect-error we cannot access ctx.req in app dir, however headers and cookies are only properties needed to extract the locale + const newLocale = await getLocale({ headers, cookies }); + let direction = "ltr"; + + try { + const intlLocale = new Intl.Locale(newLocale); + // @ts-expect-error INFO: Typescript does not know about the Intl.Locale textInfo attribute + direction = intlLocale.textInfo?.direction; + } catch (e) { + console.error(e); + } + + return { isEmbed, embedColorScheme, locale: newLocale, direction }; +}; + +export default async function RootLayout({ children }: { children: React.ReactNode }) { + const headers = nextHeaders(); + const cookies = nextCookies(); + + const fullUrl = headers.get("x-url") ?? ""; + const nonce = headers.get("x-csp") ?? ""; + + const { locale, direction, isEmbed, embedColorScheme } = await getInitialProps(fullUrl, headers, cookies); + return ( + + + {!IS_PRODUCTION && process.env.VERCEL_ENV === "preview" && ( + // eslint-disable-next-line @next/next/no-sync-scripts +