diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/404.tsx | 194 |
1 files changed, 117 insertions, 77 deletions
diff --git a/src/pages/404.tsx b/src/pages/404.tsx index a98931f..6ef0c55 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -1,4 +1,3 @@ -/* eslint-disable max-statements */ import type { GetStaticProps } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; @@ -15,6 +14,7 @@ import { PageHeader, PageSidebar, SearchForm, + Spinner, type SearchFormSubmit, } from '../components'; import { @@ -25,7 +25,9 @@ import { fetchTopicsCount, fetchTopicsList, } from '../services/graphql'; +import styles from '../styles/pages/blog.module.scss'; import type { + GraphQLConnection, NextPageWithLayout, WPThematicPreview, WPTopicPreview, @@ -34,82 +36,100 @@ import { CONFIG } from '../utils/config'; import { ROUTES } from '../utils/constants'; import { getLinksItemData } from '../utils/helpers'; import { loadTranslation, type Messages } from '../utils/helpers/server'; -import { useBreadcrumb } from '../utils/hooks'; +import { useBreadcrumb, useThematicsList, useTopicsList } from '../utils/hooks'; + +const link = (chunks: ReactNode) => <Link href={ROUTES.CONTACT}>{chunks}</Link>; type Error404PageProps = { - thematicsList: WPThematicPreview[]; - topicsList: WPTopicPreview[]; + data: { + thematics: GraphQLConnection<WPThematicPreview>; + topics: GraphQLConnection<WPTopicPreview>; + }; translation: Messages; }; /** * Error 404 page. */ -const Error404Page: NextPageWithLayout<Error404PageProps> = ({ - thematicsList, - topicsList, -}) => { +const Error404Page: NextPageWithLayout<Error404PageProps> = ({ data }) => { const router = useRouter(); const intl = useIntl(); - const title = intl.formatMessage({ - defaultMessage: 'Page not found', - description: 'Error404Page: page title', - id: 'KnWeKh', + const { isLoading: areThematicsLoading, thematics } = useThematicsList({ + fallback: data.thematics, + input: { first: data.thematics.pageInfo.total }, }); - 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', + const { isLoading: areTopicsLoading, topics } = useTopicsList({ + fallback: data.topics, + input: { first: data.topics.pageInfo.total }, + }); + const messages = { + loading: { + thematicsList: intl.formatMessage({ + defaultMessage: 'Thematics are loading...', + description: 'Error404Page: loading thematics message', + id: '6IAJYx', + }), + topicsList: intl.formatMessage({ + defaultMessage: 'Topics are loading...', + description: 'Error404Page: loading topics message', + id: 'HnMf0i', + }), }, - { - link: (chunks: ReactNode) => <Link href={ROUTES.CONTACT}>{chunks}</Link>, - } - ); + page: { + title: intl.formatMessage({ + defaultMessage: 'Page not found', + description: 'Error404Page: page title', + id: 'KnWeKh', + }), + }, + seo: { + title: intl.formatMessage( + { + defaultMessage: 'Error 404: Page not found - {websiteName}', + description: 'Error404Page: SEO - Page title', + id: 'pNIIU1', + }, + { websiteName: CONFIG.name } + ), + metaDesc: intl.formatMessage({ + defaultMessage: 'Page not found.', + description: 'Error404Page: SEO - Meta description', + id: 'yKoGqg', + }), + }, + widgets: { + thematicsListTitle: intl.formatMessage({ + defaultMessage: 'Thematics', + description: 'Error404Page: thematics list widget title', + id: 'HohQPh', + }), + topicsListTitle: intl.formatMessage({ + defaultMessage: 'Topics', + description: 'Error404Page: topics list widget title', + id: 'GVpTIl', + }), + }, + }; const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ - title, + title: messages.page.title, url: ROUTES.NOT_FOUND, }); - const pageTitle = intl.formatMessage( - { - defaultMessage: 'Error 404: Page not found - {websiteName}', - description: '404Page: SEO - Page title', - id: '310o3F', - }, - { websiteName: CONFIG.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', - }); const searchSubmitHandler: SearchFormSubmit = useCallback( - ({ query }) => { + async ({ query }) => { if (!query) return { messages: { error: intl.formatMessage({ defaultMessage: 'Query must be longer than one character.', - description: '404Page: invalid query message', - id: 'C6oK7h', + description: 'Error404Page: invalid query message', + id: '3u29G5', }), }, validator: (value) => value.query.length > 1, }; - router.push({ pathname: ROUTES.SEARCH, query: { s: query } }); + await router.push({ pathname: ROUTES.SEARCH, query: { s: query } }); return undefined; }, @@ -119,9 +139,9 @@ const Error404Page: NextPageWithLayout<Error404PageProps> = ({ return ( <Page breadcrumbs={breadcrumbItems}> <Head> - <title>{pageTitle}</title> + <title>{messages.seo.title}</title> {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} - <meta name="description" content={pageDescription} /> + <meta name="description" content={messages.seo.metaDesc} /> </Head> <Script dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }} @@ -129,9 +149,19 @@ const Error404Page: NextPageWithLayout<Error404PageProps> = ({ id="schema-breadcrumb" type="application/ld+json" /> - <PageHeader heading={title} /> - <PageBody> - {body} + <PageHeader heading={messages.page.title} /> + <PageBody className={styles['no-results']}> + <p> + {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 } + )} + </p> <p> {intl.formatMessage({ defaultMessage: 'You can also try a search:', @@ -142,26 +172,34 @@ const Error404Page: NextPageWithLayout<Error404PageProps> = ({ <SearchForm isLabelHidden onSubmit={searchSubmitHandler} /> </PageBody> <PageSidebar> - <LinksWidget - heading={ - <Heading isFake level={3}> - {thematicsListTitle} - </Heading> - } - items={getLinksItemData( - thematicsList.map(convertWPThematicPreviewToPageLink) - )} - /> - <LinksWidget - heading={ - <Heading isFake level={3}> - {topicsListTitle} - </Heading> - } - items={getLinksItemData( - topicsList.map(convertWPTopicPreviewToPageLink) - )} - /> + {areThematicsLoading ? ( + <Spinner>{messages.loading.thematicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.thematicsListTitle}</Heading> + } + items={getLinksItemData( + thematics.edges.map((edge) => + convertWPThematicPreviewToPageLink(edge.node) + ) + )} + /> + )} + {areTopicsLoading ? ( + <Spinner>{messages.loading.topicsList}</Spinner> + ) : ( + <LinksWidget + heading={ + <Heading level={2}>{messages.widgets.topicsListTitle}</Heading> + } + items={getLinksItemData( + topics.edges.map((edge) => + convertWPTopicPreviewToPageLink(edge.node) + ) + )} + /> + )} </PageSidebar> </Page> ); @@ -180,8 +218,10 @@ export const getStaticProps: GetStaticProps<Error404PageProps> = async ({ return { props: { - thematicsList: thematics.edges.map((edge) => edge.node), - topicsList: topics.edges.map((edge) => edge.node), + data: { + thematics, + topics, + }, translation, }, }; |
