aboutsummaryrefslogtreecommitdiffstats
path: root/src/pages/blog
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-09-26 15:54:28 +0200
committerArmand Philippot <git@armandphilippot.com>2023-10-24 12:23:48 +0200
commit70efcfeaa0603415dd992cb662d8efb960e6e49a (patch)
tree5d37e98fae9aa7e5c3d8ef30a10db9fed9b63e36 /src/pages/blog
parent31695306bfed44409f03006ea717fd2cceff8f87 (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.tsx71
-rw-r--r--src/pages/blog/page/[number].tsx51
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,