aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils
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/utils
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/utils')
-rw-r--r--src/utils/constants.ts32
-rw-r--r--src/utils/helpers/pages.ts39
-rw-r--r--src/utils/helpers/rss.ts19
-rw-r--r--src/utils/helpers/schema-org.ts13
-rw-r--r--src/utils/hooks/use-breadcrumb.ts (renamed from src/utils/hooks/use-breadcrumb.tsx)24
5 files changed, 82 insertions, 45 deletions
diff --git a/src/utils/constants.ts b/src/utils/constants.ts
new file mode 100644
index 0000000..e642af9
--- /dev/null
+++ b/src/utils/constants.ts
@@ -0,0 +1,32 @@
+export const PERSONAL_LINKS = {
+ GITHUB: 'https://github.com/ArmandPhilippot',
+ GITLAB: 'https://gitlab.com/ArmandPhilippot',
+ LINKEDIN: 'https://www.linkedin.com/in/armandphilippot',
+ SHAARLI: 'https://shaarli.armandphilippot.com/',
+} as const;
+
+/**
+ * App routes.
+ *
+ * All static routes should be configured here to avoid 404 if a route changes.
+ */
+export const ROUTES = {
+ ARTICLE: '/article',
+ BLOG: '/blog',
+ CONTACT: '/contact',
+ CV: '/cv',
+ LEGAL_NOTICE: '/mentions-legales',
+ NOT_FOUND: '/404',
+ PROJECTS: '/projets',
+ RSS: '/feed',
+ SEARCH: '/recherche',
+ THEMATICS: {
+ INDEX: '/thematique',
+ FREE: '/thematique/libre',
+ LINUX: '/thematique/linux',
+ WEB_DEV: '/thematique/developpement-web',
+ },
+ TOPICS: '/sujet',
+} as const;
+
+// cSpell:ignore legales thematique developpement
diff --git a/src/utils/helpers/pages.ts b/src/utils/helpers/pages.ts
index 6b27b6d..84854cd 100644
--- a/src/utils/helpers/pages.ts
+++ b/src/utils/helpers/pages.ts
@@ -1,13 +1,14 @@
-import { type LinksListItems, type Post } from '../../components';
+import type { LinksListItems, Post } from '../../components';
import { getArticleFromRawData } from '../../services/graphql';
-import {
- type Article,
- type EdgesResponse,
- type PageLink,
- type RawArticle,
- type RawThematicPreview,
- type RawTopicPreview,
+import type {
+ Article,
+ EdgesResponse,
+ PageLink,
+ RawArticle,
+ RawThematicPreview,
+ RawTopicPreview,
} from '../../types';
+import { ROUTES } from '../constants';
import { getImageFromRawData } from './images';
/**
@@ -25,11 +26,13 @@ export const getPageLinkFromRawData = (
kind: 'thematic' | 'topic'
): PageLink => {
const { databaseId, featuredImage, slug, title } = data;
- const baseUrl = kind === 'thematic' ? '/thematique/' : '/sujet/';
+ const baseUrl = `${
+ kind === 'thematic' ? ROUTES.THEMATICS.INDEX : ROUTES.TOPICS
+ }/`;
return {
id: databaseId,
- logo: featuredImage ? getImageFromRawData(featuredImage?.node) : undefined,
+ logo: featuredImage ? getImageFromRawData(featuredImage.node) : undefined,
name: title,
url: `${baseUrl}${slug}`,
};
@@ -57,14 +60,13 @@ export const sortPageLinksByName = (a: PageLink, b: PageLink) => {
* @param {PageLink[]} links - An array of page links.
* @returns {LinksListItem[]} An array of links items.
*/
-export const getLinksListItems = (links: PageLink[]): LinksListItems[] => {
- return links.map((link) => {
+export const getLinksListItems = (links: PageLink[]): LinksListItems[] =>
+ links.map((link) => {
return {
name: link.name,
url: link.url,
};
});
-};
/**
* Retrieve the posts list with the article URL.
@@ -72,14 +74,13 @@ export const getLinksListItems = (links: PageLink[]): LinksListItems[] => {
* @param {Article[]} posts - An array of articles.
* @returns {Post[]} An array of posts with full article URL.
*/
-export const getPostsWithUrl = (posts: Article[]): Post[] => {
- return posts.map((post) => {
+export const getPostsWithUrl = (posts: Article[]): Post[] =>
+ posts.map((post) => {
return {
...post,
url: `/article/${post.slug}`,
};
});
-};
/**
* Retrieve the posts list from raw data.
@@ -89,11 +90,11 @@ export const getPostsWithUrl = (posts: Article[]): Post[] => {
*/
export const getPostsList = (rawData: EdgesResponse<RawArticle>[]): Post[] => {
const articlesList: RawArticle[] = [];
- rawData.forEach((articleData) =>
+ rawData.forEach((articleData) => {
articleData.edges.forEach((edge) => {
articlesList.push(edge.node);
- })
- );
+ });
+ });
return getPostsWithUrl(
articlesList.map((article) => getArticleFromRawData(article))
diff --git a/src/utils/helpers/rss.ts b/src/utils/helpers/rss.ts
index 28f3c7b..0381c68 100644
--- a/src/utils/helpers/rss.ts
+++ b/src/utils/helpers/rss.ts
@@ -4,8 +4,9 @@ import {
getArticles,
getTotalArticles,
} from '../../services/graphql';
-import { type Article } from '../../types';
-import { settings } from '../../utils/config';
+import type { Article } from '../../types';
+import { settings } from '../config';
+import { ROUTES } from '../constants';
/**
* Retrieve the data for all the articles.
@@ -17,9 +18,9 @@ const getAllArticles = async (): Promise<Article[]> => {
const rawArticles = await getArticles({ first: totalArticles });
const articles: Article[] = [];
- rawArticles.edges.forEach((edge) =>
- articles.push(getArticleFromRawData(edge.node))
- );
+ rawArticles.edges.forEach((edge) => {
+ articles.push(getArticleFromRawData(edge.node));
+ });
return articles;
};
@@ -43,8 +44,8 @@ export const generateFeed = async (): Promise<Feed> => {
copyright,
description: process.env.APP_FEED_DESCRIPTION,
feedLinks: {
- json: `${settings.url}/feed/json`,
- atom: `${settings.url}/feed/atom`,
+ json: `${settings.url}${ROUTES.RSS}/json`,
+ atom: `${settings.url}${ROUTES.RSS}/atom`,
},
generator: 'Feed & NextJS',
id: settings.url,
@@ -58,10 +59,10 @@ export const generateFeed = async (): Promise<Feed> => {
articles.forEach((article) => {
feed.addItem({
content: article.intro,
- date: new Date(article.meta!.dates.publication),
+ date: new Date(article.meta.dates.publication),
description: article.intro,
id: `${article.id}`,
- link: `${settings.url}/article/${article.slug}`,
+ link: `${settings.url}${ROUTES.ARTICLE}/${article.slug}`,
title: article.title,
});
});
diff --git a/src/utils/helpers/schema-org.ts b/src/utils/helpers/schema-org.ts
index 82f99c2..12bad28 100644
--- a/src/utils/helpers/schema-org.ts
+++ b/src/utils/helpers/schema-org.ts
@@ -1,4 +1,4 @@
-import {
+import type {
AboutPage,
Article,
Blog,
@@ -7,8 +7,9 @@ import {
Graph,
WebPage,
} from 'schema-dts';
-import { type Dates } from '../../types';
-import { settings } from '../../utils/config';
+import type { Dates } from '../../types';
+import { settings } from '../config';
+import { ROUTES } from '../constants';
export type GetBlogSchemaProps = {
/**
@@ -146,7 +147,7 @@ export const getSinglePageSchema = <T extends SinglePageSchemaKind>({
copyrightYear: publicationDate.getFullYear(),
creator: { '@id': `${settings.url}/#branding` },
dateCreated: publicationDate.toISOString(),
- dateModified: updateDate && updateDate.toISOString(),
+ dateModified: updateDate?.toISOString(),
datePublished: publicationDate.toISOString(),
editor: { '@id': `${settings.url}/#branding` },
headline: title,
@@ -157,7 +158,7 @@ export const getSinglePageSchema = <T extends SinglePageSchemaKind>({
isPartOf:
kind === 'post'
? {
- '@id': `${settings.url}/blog`,
+ '@id': `${settings.url}${ROUTES.BLOG}`,
}
: undefined,
mainEntityOfPage: { '@id': `${settings.url}${slug}` },
@@ -206,7 +207,7 @@ export const getWebPageSchema = ({
breadcrumb: { '@id': `${settings.url}/#breadcrumb` },
lastReviewed: updateDate,
name: title,
- description: description,
+ description,
inLanguage: locale,
reviewedBy: { '@id': `${settings.url}/#branding` },
url: `${settings.url}${slug}`,
diff --git a/src/utils/hooks/use-breadcrumb.tsx b/src/utils/hooks/use-breadcrumb.ts
index f4506d7..5839299 100644
--- a/src/utils/hooks/use-breadcrumb.tsx
+++ b/src/utils/hooks/use-breadcrumb.ts
@@ -1,6 +1,8 @@
+/* eslint-disable max-statements */
import { useIntl } from 'react-intl';
-import { BreadcrumbList } from 'schema-dts';
-import { BreadcrumbItem } from '../../components';
+import type { BreadcrumbList } from 'schema-dts';
+import type { BreadcrumbItem } from '../../components';
+import { ROUTES } from '../constants';
import { slugify } from '../helpers';
import { useSettings } from './use-settings';
@@ -38,13 +40,13 @@ export const useBreadcrumb = ({
}: useBreadcrumbProps): useBreadcrumbReturn => {
const intl = useIntl();
const { website } = useSettings();
- const isArticle = url.startsWith('/article/');
+ const isArticle = url.startsWith(`${ROUTES.ARTICLE}/`);
const isHome = url === '/';
const isPageNumber = url.includes('/page/');
- const isProject = url.startsWith('/projets/');
- const isSearch = url.startsWith('/recherche');
- const isThematic = url.startsWith('/thematique/');
- const isTopic = url.startsWith('/sujet/');
+ const isProject = url.startsWith(`${ROUTES.PROJECTS}/`);
+ const isSearch = url.startsWith(ROUTES.SEARCH);
+ const isThematic = url.startsWith(`${ROUTES.THEMATICS.INDEX}/`);
+ const isTopic = url.startsWith(`${ROUTES.TOPICS}/`);
const homeLabel = intl.formatMessage({
defaultMessage: 'Home',
@@ -69,12 +71,12 @@ export const useBreadcrumb = ({
description: 'Breadcrumb: blog label',
id: 'Es52wh',
});
- items.push({ id: 'blog', name: blogLabel, url: '/blog' });
+ items.push({ id: 'blog', name: blogLabel, url: ROUTES.BLOG });
schema.push({
'@type': 'ListItem',
position: 2,
name: blogLabel,
- item: `${website.url}/blog`,
+ item: `${website.url}${ROUTES.BLOG}`,
});
}
@@ -84,12 +86,12 @@ export const useBreadcrumb = ({
description: 'Breadcrumb: projects label',
id: '28GZdv',
});
- items.push({ id: 'blog', name: projectsLabel, url: '/projets' });
+ items.push({ id: 'projects', name: projectsLabel, url: ROUTES.PROJECTS });
schema.push({
'@type': 'ListItem',
position: 2,
name: projectsLabel,
- item: `${website.url}/projets`,
+ item: `${website.url}${ROUTES.PROJECTS}`,
});
}