diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-16 11:37:09 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-05-16 11:37:09 +0200 |
| commit | 8a55aa83bd4b64d1d989cb49b7d9c3fdc1cc6ea5 (patch) | |
| tree | 3ac2340383e5fb7bc297f207bfb170fffecca958 /src/pages | |
| parent | 056ed0d5f050158cebad689099214b164539899a (diff) | |
chore: add 404 page
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/404.tsx | 144 |
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; |
