diff --git a/app/[locale]/error.tsx b/app/[locale]/error.tsx index 3022c2f6b9f46..09751a84cd7df 100644 --- a/app/[locale]/error.tsx +++ b/app/[locale]/error.tsx @@ -1,10 +1,16 @@ 'use client'; import { captureException } from '@sentry/nextjs'; +import { useTranslations } from 'next-intl'; import type { FC } from 'react'; import { useMemo } from 'react'; -const ErrorPage: FC<{ error: Error }> = ({ error }) => { +import Button from '@/components/Common/Button'; +import CenteredLayout from '@/layouts/New/Centered'; +import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; + +/** @deprecated remove legacy component when website redesign is done */ +const LegacyErrorPage: FC<{ error: Error }> = ({ error }) => { useMemo(() => captureException(error), [error]); return ( @@ -15,4 +21,26 @@ const ErrorPage: FC<{ error: Error }> = ({ error }) => { ); }; -export default ErrorPage; +const ErrorPage: FC<{ error: Error }> = ({ error }) => { + captureException(error); + const t = useTranslations(); + + return ( + +
+ +
+ 500 +

+ {t('layouts.error.internalServerError.title')} +

+

+ {t('layouts.error.internalServerError.description')} +

+ +
+ + ); +}; + +export default ENABLE_WEBSITE_REDESIGN ? ErrorPage : LegacyErrorPage; diff --git a/app/[locale]/not-found.tsx b/app/[locale]/not-found.tsx index 15c704c55d4cc..a49f5100116c4 100644 --- a/app/[locale]/not-found.tsx +++ b/app/[locale]/not-found.tsx @@ -3,7 +3,12 @@ import { useTranslations } from 'next-intl'; import type { FC } from 'react'; -const LocalizedNotFound: FC = () => { +import Button from '@/components/Common/Button'; +import CenteredLayout from '@/layouts/New/Centered'; +import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; + +/** @deprecated remove legacy component when website redesign is done */ +const LegacyNotFoundPage: FC = () => { const t = useTranslations(); return ( @@ -14,4 +19,23 @@ const LocalizedNotFound: FC = () => { ); }; -export default LocalizedNotFound; +const NotFoundPage: FC = () => { + const t = useTranslations(); + + return ( + +
+ +
+ 404 +

{t('layouts.error.notFound.title')}

+

+ {t('layouts.error.notFound.description')} +

+ +
+ + ); +}; + +export default ENABLE_WEBSITE_REDESIGN ? NotFoundPage : LegacyNotFoundPage; diff --git a/app/global-error.tsx b/app/global-error.tsx index d8653f56254e5..e67915b8c536a 100644 --- a/app/global-error.tsx +++ b/app/global-error.tsx @@ -5,7 +5,13 @@ import ErrorComponent from 'next/error'; import type { FC } from 'react'; import { useMemo } from 'react'; -const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => { +import Button from '@/components/Common/Button'; +import BaseLayout from '@/layouts/BaseLayout'; +import CenteredLayout from '@/layouts/New/Centered'; +import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; + +/** @deprecated remove legacy component when website redesign is done */ +const LegacyGlobalErrorPage: FC<{ error: Error }> = ({ error }) => { useMemo(() => captureException(error), [error]); return ( @@ -17,4 +23,31 @@ const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => { ); }; -export default GlobalErrorPage; +const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => { + captureException(error); + + return ( + + + + +
+ +
+ 500 +

Internal Server Error

+

+ This page has thrown a non-recoverable error. +

+ +
+ + + + + ); +}; + +export default ENABLE_WEBSITE_REDESIGN + ? GlobalErrorPage + : LegacyGlobalErrorPage; diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 51814c4f8cf38..9f9167c82ceb5 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -208,6 +208,17 @@ "weekly-updates": "Weekly Updates", "wg": "Working Groups" } + }, + "error": { + "notFound": { + "title": "Page could not be found", + "description": "Sorry, we couldn’t find the page you’re after! Try starting again from the homepage." + }, + "internalServerError": { + "title": "Internal Server Error", + "description": "This page has thrown a non-recoverable error." + }, + "backToHome": "Back to Home" } }, "pages": { diff --git a/layouts/New/Centered.tsx b/layouts/New/Centered.tsx new file mode 100644 index 0000000000000..f63f312b451aa --- /dev/null +++ b/layouts/New/Centered.tsx @@ -0,0 +1,18 @@ +import type { FC, PropsWithChildren } from 'react'; + +import WithFooter from '@/components/withFooter'; +import WithNavBar from '@/components/withNavBar'; + +import styles from './layouts.module.css'; + +const CenteredLayout: FC = ({ children }) => ( + <> + + +
{children}
+ + + +); + +export default CenteredLayout; diff --git a/layouts/New/Home.tsx b/layouts/New/Home.tsx index a947f049bb1a2..2a313f3e07b69 100644 --- a/layouts/New/Home.tsx +++ b/layouts/New/Home.tsx @@ -1,22 +1,15 @@ import type { FC, PropsWithChildren } from 'react'; -import WithFooter from '@/components/withFooter'; -import WithNavBar from '@/components/withNavBar'; +import CenteredLayout from '@/layouts/New/Centered'; import styles from './layouts.module.css'; const HomeLayout: FC = ({ children }) => ( - <> - + +
-
-
- -
{children}
-
- - - +
{children}
+ ); export default HomeLayout; diff --git a/layouts/New/layouts.module.css b/layouts/New/layouts.module.css index 91fdf4626f6ae..bdfa1be9e529e 100644 --- a/layouts/New/layouts.module.css +++ b/layouts/New/layouts.module.css @@ -58,7 +58,7 @@ } } -.homeLayout { +.centeredLayout { @apply flex w-full items-center @@ -70,77 +70,80 @@ main { @apply items-center - justify-center - gap-8 - md:flex-row - md:gap-14 - xl:gap-28 - 2xl:gap-32; - - section { - &:nth-of-type(1) { - @apply flex - max-w-[500px] - flex-[1_0] - flex-col - gap-8; - - > div { - @apply flex - max-w-[400px] - flex-col - gap-4; - - p { - @apply text-base - md:text-lg; - } + justify-center; + } +} - small { - @apply text-center - text-sm - text-neutral-800 - xs:text-xs - dark:text-neutral-400; - } - } - } +.homeLayout { + @apply gap-8 + md:flex-row + md:gap-14 + xl:gap-28 + 2xl:gap-32; + + section { + &:nth-of-type(1) { + @apply flex + max-w-[500px] + flex-[1_0] + flex-col + gap-8; - &:nth-of-type(2) { + > div { @apply flex - max-w-md - flex-[1_1] + max-w-[400px] flex-col - items-center - gap-4 - md:max-w-2xl - lg:max-w-3xl; - - > div { - @apply w-fit; - - div[data-state='active'] a { - @apply border-none - bg-neutral-900 - px-3 - py-1.5 - text-sm - font-medium; - - &:hover { - @apply bg-neutral-800; - } - } + gap-4; + + p { + @apply text-base + md:text-lg; } - > p { + small { @apply text-center text-sm text-neutral-800 - dark:text-neutral-200; + xs:text-xs + dark:text-neutral-400; } } } + + &:nth-of-type(2) { + @apply flex + max-w-md + flex-[1_1] + flex-col + items-center + gap-4 + md:max-w-2xl + lg:max-w-3xl; + + > div { + @apply w-fit; + + div[data-state='active'] a { + @apply border-none + bg-neutral-900 + px-3 + py-1.5 + text-sm + font-medium; + + &:hover { + @apply bg-neutral-800; + } + } + } + + > p { + @apply text-center + text-sm + text-neutral-800 + dark:text-neutral-200; + } + } } } diff --git a/next.dynamic.constants.mjs b/next.dynamic.constants.mjs index bbe4da5aa1096..f9dbedd6a5126 100644 --- a/next.dynamic.constants.mjs +++ b/next.dynamic.constants.mjs @@ -15,8 +15,6 @@ import { defaultLocale } from './next.locales.mjs'; * @type {((route: import('./types').RouteSegment) => boolean)[]} A list of Ignored Routes by Regular Expressions */ export const IGNORED_ROUTES = [ - // This is used to ignore the 404 route for the static generation (/404) - ({ pathname }) => pathname === '404', // This is used to ignore all blog routes except for the English language ({ locale, pathname }) => locale !== defaultLocale.code && /^blog\//.test(pathname), diff --git a/pages/en/404.md b/pages/en/404.md deleted file mode 100644 index f3e5a0fc4d15f..0000000000000 --- a/pages/en/404.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page.hbs -permalink: false -title: 404 ---- - -## 404: Page could not be found - -### ENOENT: no such file or directory diff --git a/styles/new/markdown.css b/styles/new/markdown.css index c7e951a6a07db..b3c38b4af92b3 100644 --- a/styles/new/markdown.css +++ b/styles/new/markdown.css @@ -73,6 +73,10 @@ main { dark:text-green-300; } + &[role='button'] { + @apply xs:no-underline; + } + &:has(code) { @apply xs:decoration-neutral-800 dark:xs:decoration-neutral-200; diff --git a/tailwind.config.ts b/tailwind.config.ts index 6badfc908c5d0..54767ff20f8cb 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -8,6 +8,7 @@ export default { './layouts/**/*.tsx', './.storybook/preview.tsx', './.storybook/main.ts', + './app/**/*.tsx', ], theme: { colors: {