summaryrefslogtreecommitdiffstats
path: root/src/pages
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-16 11:37:09 +0200
committerArmand Philippot <git@armandphilippot.com>2022-05-16 11:37:09 +0200
commit8a55aa83bd4b64d1d989cb49b7d9c3fdc1cc6ea5 (patch)
tree3ac2340383e5fb7bc297f207bfb170fffecca958 /src/pages
parent056ed0d5f050158cebad689099214b164539899a (diff)
chore: add 404 page
Diffstat (limited to 'src/pages')
-rw-r--r--src/pages/404.tsx144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/pages/404.tsx b/src/pages/404.tsx
new file mode 100644
index 0000000..7459c80
--- /dev/null
+++ b/src/pages/404.tsx
@@ -0,0 +1,144 @@
+import Link from '@components/atoms/links/link';
+import { type BreadcrumbItem } from '@components/molecules/nav/breadcrumb';
+import LinksListWidget from '@components/organisms/widgets/links-list-widget';
+import PageLayout from '@components/templates/page/page-layout';
+import {
+ getThematicsPreview,
+ getTotalThematics,
+} from '@services/graphql/thematics';
+import { getTopicsPreview, getTotalTopics } from '@services/graphql/topics';
+import {
+ type RawThematicPreview,
+ type RawTopicPreview,
+} from '@ts/types/raw-data';
+import { loadTranslation, type Messages } from '@utils/helpers/i18n';
+import {
+ getLinksListItems,
+ getPageLinkFromRawData,
+} from '@utils/helpers/pages';
+import useSettings from '@utils/hooks/use-settings';
+import { GetStaticProps, NextPage } from 'next';
+import Head from 'next/head';
+import { ReactNode } from 'react';
+import { useIntl } from 'react-intl';
+
+type Error404PageProps = {
+ thematicsList: RawThematicPreview[];
+ topicsList: RawTopicPreview[];
+ translation: Messages;
+};
+
+/**
+ * Error 404 page.
+ */
+const Error404Page: NextPage<Error404PageProps> = ({
+ thematicsList,
+ topicsList,
+}) => {
+ const intl = useIntl();
+ const { website } = useSettings();
+ const title = intl.formatMessage({
+ defaultMessage: 'Page not found',
+ description: 'Error404Page: page title',
+ id: 'KnWeKh',
+ });
+ const body = intl.formatMessage(
+ {
+ defaultMessage:
+ 'Sorry, it seems that the page your are looking for does not exist. If you think this path should work, feel free to <link>contact me</link> with the necessary information so that I can fix the problem.',
+ id: '9sGNKq',
+ description: 'Error404Page: page body',
+ },
+ {
+ link: (chunks: ReactNode) => <Link href="/contact">{chunks}</Link>,
+ }
+ );
+ const homeLabel = intl.formatMessage({
+ defaultMessage: 'Home',
+ description: 'Breadcrumb: home label',
+ id: 'j5k9Fe',
+ });
+ const breadcrumb: BreadcrumbItem[] = [
+ { id: 'home', name: homeLabel, url: '/' },
+ { id: 'error-404', name: title, url: '/404' },
+ ];
+ const pageTitle = intl.formatMessage(
+ {
+ defaultMessage: 'Error 404: Page not found - {websiteName}',
+ description: '404Page: SEO - Page title',
+ id: '310o3F',
+ },
+ { websiteName: website.name }
+ );
+ const pageDescription = intl.formatMessage({
+ defaultMessage: 'Page not found.',
+ description: '404Page: SEO - Meta description',
+ id: '48Ww//',
+ });
+ const thematicsListTitle = intl.formatMessage({
+ defaultMessage: 'Thematics',
+ description: 'Error404Page: thematics list widget title',
+ id: 'HohQPh',
+ });
+
+ const topicsListTitle = intl.formatMessage({
+ defaultMessage: 'Topics',
+ description: 'Error404Page: topics list widget title',
+ id: 'GVpTIl',
+ });
+
+ return (
+ <>
+ <Head>
+ <title>{pageTitle}</title>
+ <meta name="description" content={pageDescription} />
+ </Head>
+ <PageLayout
+ title={title}
+ breadcrumb={breadcrumb}
+ widgets={[
+ <LinksListWidget
+ key="thematics-list"
+ items={getLinksListItems(
+ thematicsList.map(getPageLinkFromRawData),
+ 'thematic'
+ )}
+ title={thematicsListTitle}
+ level={2}
+ />,
+ <LinksListWidget
+ key="topics-list"
+ items={getLinksListItems(
+ topicsList.map(getPageLinkFromRawData),
+ 'topic'
+ )}
+ title={topicsListTitle}
+ level={2}
+ />,
+ ]}
+ >
+ {body}
+ </PageLayout>
+ </>
+ );
+};
+
+export const getStaticProps: GetStaticProps<Error404PageProps> = async ({
+ locale,
+}) => {
+ const totalThematics = await getTotalThematics();
+ const thematics = await getThematicsPreview({ first: totalThematics });
+ const totalTopics = await getTotalTopics();
+ const topics = await getTopicsPreview({ first: totalTopics });
+ const translation = await loadTranslation(locale);
+
+ return {
+ props: {
+ thematicsList: thematics.edges.map((edge) => edge.node),
+ topicsList: topics.edges.map((edge) => edge.node),
+ translation,
+ },
+ };
+};
+
+export default Error404Page;