diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-09-26 15:54:28 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-10-24 12:23:48 +0200 |
| commit | 70efcfeaa0603415dd992cb662d8efb960e6e49a (patch) | |
| tree | 5d37e98fae9aa7e5c3d8ef30a10db9fed9b63e36 /src/pages/blog | |
| parent | 31695306bfed44409f03006ea717fd2cceff8f87 (diff) | |
refactor(routes): replace hardcoded routes with constants
It makes it easier to change a route if needed and it avoid typo
mistakes.
I also refactored a bit the concerned files to be complient with the
new ESlint config. However, I should rewrite the pages to reduce
the number of statements.
Diffstat (limited to 'src/pages/blog')
| -rw-r--r-- | src/pages/blog/index.tsx | 71 | ||||
| -rw-r--r-- | src/pages/blog/page/[number].tsx | 51 |
2 files changed, 72 insertions, 50 deletions
diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index 13a4c57..7f6c540 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -1,7 +1,9 @@ -import { GetStaticProps } from 'next'; +/* eslint-disable max-statements */ +import type { GetStaticProps } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; import Script from 'next/script'; +import { useCallback } from 'react'; import { useIntl } from 'react-intl'; import { getLayout, @@ -18,14 +20,15 @@ import { getTotalThematics, getTotalTopics, } from '../../services/graphql'; -import { - type EdgesResponse, - type NextPageWithLayout, - type RawArticle, - type RawThematicPreview, - type RawTopicPreview, +import type { + EdgesResponse, + NextPageWithLayout, + RawArticle, + RawThematicPreview, + RawTopicPreview, } from '../../types'; import { settings } from '../../utils/config'; +import { ROUTES } from '../../utils/constants'; import { getBlogSchema, getLinksListItems, @@ -62,19 +65,22 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ }); const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ title, - url: '/blog', + url: ROUTES.BLOG, }); const { blog, website } = useSettings(); const { asPath } = useRouter(); - const pageTitle = intl.formatMessage( - { - defaultMessage: 'Blog: development, open source - {websiteName}', - description: 'BlogPage: SEO - Page title', - id: '+Y+tLK', - }, - { websiteName: website.name } - ); + const page = { + title: intl.formatMessage( + { + defaultMessage: 'Blog: development, open source - {websiteName}', + description: 'BlogPage: SEO - Page title', + id: '+Y+tLK', + }, + { websiteName: website.name } + ), + url: `${website.url}${asPath}`, + }; const pageDescription = intl.formatMessage( { defaultMessage: @@ -110,12 +116,9 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ perPage: blog.postsPerPage, }); - /** - * Load more posts handler. - */ - const loadMore = () => { + const loadMore = useCallback(() => { setSize((prevSize) => prevSize + 1); - }; + }, [setSize]); const thematicsListTitle = intl.formatMessage({ defaultMessage: 'Thematics', @@ -128,20 +131,25 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ description: 'BlogPage: topics list widget title', id: '2D9tB5', }); + const postsListBaseUrl = `${ROUTES.BLOG}/page/`; return ( <> <Head> - <title>{pageTitle}</title> + <title>{page.title}</title> + {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} <meta name="description" content={pageDescription} /> - <meta property="og:url" content={`${website.url}${asPath}`} /> + <meta property="og:url" content={page.url} /> + {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */} <meta property="og:type" content="website" /> <meta property="og:title" content={title} /> <meta property="og:description" content={pageDescription} /> </Head> <Script + // eslint-disable-next-line react/jsx-no-literals -- Id allowed id="schema-blog" type="application/ld+json" + // eslint-disable-next-line react/no-danger -- Necessary for schema dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} /> <PageLayout @@ -151,6 +159,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ headerMeta={{ total: totalArticles }} widgets={[ <LinksListWidget + // eslint-disable-next-line react/jsx-no-literals -- Key allowed key="thematics-list" items={getLinksListItems( thematicsList.map((thematic) => @@ -161,6 +170,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ level={2} />, <LinksListWidget + // eslint-disable-next-line react/jsx-no-literals -- Key allowed key="topics-list" items={getLinksListItems( topicsList.map((topic) => getPageLinkFromRawData(topic, 'topic')) @@ -170,20 +180,21 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ />, ]} > - {data && ( + {data ? ( <PostsList - baseUrl="/blog/page/" + baseUrl={postsListBaseUrl} byYear={true} - isLoading={isLoadingMore || isLoadingInitialData} + isLoading={isLoadingMore ?? isLoadingInitialData} loadMore={loadMore} posts={getPostsList(data)} - searchPage="/recherche/" + searchPage={ROUTES.SEARCH} showLoadMoreBtn={hasNextPage} total={totalArticles} /> - )} - {error && ( + ) : null} + {error ? ( <Notice + // eslint-disable-next-line react/jsx-no-literals -- Kind allowed kind="error" message={intl.formatMessage({ defaultMessage: 'Failed to load.', @@ -191,7 +202,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ id: 'C/XGkH', })} /> - )} + ) : null} </PageLayout> </> ); diff --git a/src/pages/blog/page/[number].tsx b/src/pages/blog/page/[number].tsx index 4eaade5..b63fa9b 100644 --- a/src/pages/blog/page/[number].tsx +++ b/src/pages/blog/page/[number].tsx @@ -1,8 +1,9 @@ -import { GetStaticPaths, GetStaticProps } from 'next'; +/* eslint-disable max-statements */ +import type { ParsedUrlQuery } from 'querystring'; +import type { GetStaticPaths, GetStaticProps } from 'next'; import Head from 'next/head'; import { useRouter } from 'next/router'; import Script from 'next/script'; -import { ParsedUrlQuery } from 'querystring'; import { useIntl } from 'react-intl'; import { getLayout, @@ -19,12 +20,12 @@ import { getTotalThematics, getTotalTopics, } from '../../../services/graphql'; -import { - type EdgesResponse, - type NextPageWithLayout, - type RawArticle, - type RawThematicPreview, - type RawTopicPreview, +import type { + EdgesResponse, + NextPageWithLayout, + RawArticle, + RawThematicPreview, + RawTopicPreview, } from '../../../types'; import { settings } from '../../../utils/config'; import { @@ -41,6 +42,7 @@ import { useRedirection, useSettings, } from '../../../utils/hooks'; +import { ROUTES } from 'src/utils/constants'; type BlogPageProps = { articles: EdgesResponse<RawArticle>; @@ -63,7 +65,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ }) => { useRedirection({ query: { param: 'number', value: '1' }, - redirectTo: '/blog', + redirectTo: ROUTES.BLOG, }); const intl = useIntl(); @@ -85,12 +87,15 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ const pageTitleWithPageNumber = `${title} - ${pageNumberTitle}`; const { items: breadcrumbItems, schema: breadcrumbSchema } = useBreadcrumb({ title: pageNumberTitle, - url: `/blog/page/${pageNumber}`, + url: `${ROUTES.BLOG}/page/${pageNumber}`, }); const { website } = useSettings(); const { asPath } = useRouter(); - const pageTitle = `${pageTitleWithPageNumber} - ${website.name}`; + const page = { + title: `${pageTitleWithPageNumber} - ${website.name}`, + url: `${website.url}${asPath}`, + }; const pageDescription = intl.formatMessage( { defaultMessage: @@ -124,20 +129,25 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ description: 'BlogPage: topics list widget title', id: '2D9tB5', }); + const postsListBaseUrl = `${ROUTES.BLOG}/page/`; return ( <> <Head> - <title>{pageTitle}</title> + <title>{page.title}</title> + {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} <meta name="description" content={pageDescription} /> - <meta property="og:url" content={`${website.url}${asPath}`} /> + <meta property="og:url" content={page.url} /> + {/*eslint-disable-next-line react/jsx-no-literals -- Content allowed */} <meta property="og:type" content="website" /> <meta property="og:title" content={pageTitleWithPageNumber} /> <meta property="og:description" content={pageDescription} /> </Head> <Script + // eslint-disable-next-line react/jsx-no-literals -- Id allowed id="schema-blog" type="application/ld+json" + // eslint-disable-next-line react/no-danger -- Necessary for schema dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }} /> <PageLayout @@ -147,6 +157,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ headerMeta={{ total: totalArticles }} widgets={[ <LinksListWidget + // eslint-disable-next-line react/jsx-no-literals -- Key allowed key="thematics-list" items={getLinksListItems( thematicsList.map((thematic) => @@ -157,6 +168,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ level={2} />, <LinksListWidget + // eslint-disable-next-line react/jsx-no-literals -- Key allowed key="topics-list" items={getLinksListItems( topicsList.map((topic) => getPageLinkFromRawData(topic, 'topic')) @@ -167,11 +179,11 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ ]} > <PostsList - baseUrl="/blog/page/" + baseUrl={postsListBaseUrl} byYear={true} pageNumber={pageNumber} posts={getPostsList([articles])} - searchPage="/recherche/" + searchPage={ROUTES.SEARCH} total={totalArticles} /> </PageLayout> @@ -182,18 +194,17 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ BlogPage.getLayout = (page) => getLayout(page, { useGrid: true, withExtraPadding: true }); -interface BlogPageParams extends ParsedUrlQuery { +type BlogPageParams = { number: string; -} +} & ParsedUrlQuery; export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ locale, params, }) => { - const pageNumber = Number(params!.number as BlogPageParams['number']); - const queriedPostsNumber = settings.postsPerPage * pageNumber; + const pageNumber = Number((params as BlogPageParams).number); const lastCursor = await getArticlesEndCursor({ - first: queriedPostsNumber, + first: settings.postsPerPage * pageNumber, }); const articles = await getArticles({ first: settings.postsPerPage, |
