diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-11-15 12:24:42 +0100 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-15 17:26:16 +0100 |
| commit | 0f38aee374029213a47ef7c29bd164093fe63c85 (patch) | |
| tree | 290cb6471fdfe81e4c42f4da4729247536b04ee7 /src | |
| parent | be4d907efb4e2fa658baa7c9b276ed282eb920db (diff) | |
refactor(hooks): remove useSettings hook
It does not make sense to re-export an existing object through a hook.
On some pages both the hook and the object was imported...
It is better to use the CONFIG (previously settings) object directly
and by doing it we avoid potential errors because of conditional hooks.
Diffstat (limited to 'src')
25 files changed, 162 insertions, 276 deletions
diff --git a/src/components/atoms/layout/time/time.test.tsx b/src/components/atoms/layout/time/time.test.tsx index 910285d..f3da8b5 100644 --- a/src/components/atoms/layout/time/time.test.tsx +++ b/src/components/atoms/layout/time/time.test.tsx @@ -1,6 +1,6 @@ import { describe, expect, it } from '@jest/globals'; import { render, screen as rtlScreen } from '../../../../../tests/utils'; -import { settings } from '../../../../utils/config'; +import { CONFIG } from '../../../../utils/config'; import { Time } from './time'; describe('Time', () => { @@ -31,7 +31,7 @@ describe('Time', () => { expect( rtlScreen.getByText(new RegExp(`${date.getFullYear()}`)) ).toHaveTextContent( - new Intl.DateTimeFormat(settings.locales.defaultLocale, { + new Intl.DateTimeFormat(CONFIG.locales.defaultLocale, { weekday: 'long', }).format(date) ); diff --git a/src/components/atoms/layout/time/time.tsx b/src/components/atoms/layout/time/time.tsx index 02b4763..886fee0 100644 --- a/src/components/atoms/layout/time/time.tsx +++ b/src/components/atoms/layout/time/time.tsx @@ -4,7 +4,7 @@ import { forwardRef, } from 'react'; import { useIntl } from 'react-intl'; -import { settings } from '../../../../utils/config'; +import { CONFIG } from '../../../../utils/config'; type GetDateOptionsConfig = { hasDay: boolean; @@ -65,7 +65,7 @@ export type TimeProps = Omit< /** * The current locale. * - * @default settings.locales.defaultLocale + * @default CONFIG.locales.defaultLocale */ locale?: string; /** @@ -88,7 +88,7 @@ const TimeWithRef: ForwardRefRenderFunction<HTMLTimeElement, TimeProps> = ( hideDay = false, hideMonth = false, hideYear = false, - locale = settings.locales.defaultLocale, + locale = CONFIG.locales.defaultLocale, showTime = false, showWeekDay = false, ...props diff --git a/src/components/templates/layout/layout.tsx b/src/components/templates/layout/layout.tsx index 8332ba4..c7b8dbd 100644 --- a/src/components/templates/layout/layout.tsx +++ b/src/components/templates/layout/layout.tsx @@ -15,13 +15,13 @@ import { import { useIntl } from 'react-intl'; import type { Person, SearchAction, WebSite, WithContext } from 'schema-dts'; import type { NextPageWithLayoutOptions } from '../../../types'; +import { CONFIG } from '../../../utils/config'; import { ROUTES } from '../../../utils/constants'; import { useAutofocus, useBoolean, useRouteChange, useScrollPosition, - useSettings, } from '../../../utils/hooks'; import { ButtonLink, @@ -89,8 +89,7 @@ export const Layout: FC<LayoutProps> = ({ }) => { const router = useRouter(); const intl = useIntl(); - const { website } = useSettings(); - const { baseline, copyright, locales, name, url } = website; + const { baseline, copyright, locales, name, url } = CONFIG; const articleGridClass = useGrid ? 'article--grid' : ''; const articleCommentsClass = withExtraPadding ? 'article--padding' : ''; @@ -350,10 +349,10 @@ export const Layout: FC<LayoutProps> = ({ description: baseline, url, author: { '@id': `${url}/#branding` }, - copyrightYear: Number(copyright.start), + copyrightYear: Number(copyright.startYear), creator: { '@id': `${url}/#branding` }, editor: { '@id': `${url}/#branding` }, - inLanguage: locales.default, + inLanguage: locales.defaultLocale, potentialAction: searchActionSchema, }; @@ -469,7 +468,11 @@ export const Layout: FC<LayoutProps> = ({ <Footer className={styles.footer}> <Colophon copyright={ - <Copyright from={copyright.start} owner={name} to={copyright.end} /> + <Copyright + from={copyright.startYear} + owner={name} + to={copyright.endYear} + /> } license={<Icon heading={copyrightTitle} shape="cc-by-sa" size="lg" />} links={footerNav} diff --git a/src/pages/404.tsx b/src/pages/404.tsx index 2b6ddf3..75e2205 100644 --- a/src/pages/404.tsx +++ b/src/pages/404.tsx @@ -24,10 +24,11 @@ import type { RawThematicPreview, RawTopicPreview, } from '../types'; +import { CONFIG } from '../utils/config'; import { ROUTES } from '../utils/constants'; import { getLinksItemData, getPageLinkFromRawData } from '../utils/helpers'; import { loadTranslation, type Messages } from '../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../utils/hooks'; +import { useBreadcrumb } from '../utils/hooks'; type Error404PageProps = { thematicsList: RawThematicPreview[]; @@ -44,7 +45,6 @@ const Error404Page: NextPageWithLayout<Error404PageProps> = ({ }) => { const router = useRouter(); const intl = useIntl(); - const { website } = useSettings(); const title = intl.formatMessage({ defaultMessage: 'Page not found', description: 'Error404Page: page title', @@ -71,7 +71,7 @@ const Error404Page: NextPageWithLayout<Error404PageProps> = ({ description: '404Page: SEO - Page title', id: '310o3F', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const pageDescription = intl.formatMessage({ defaultMessage: 'Page not found.', diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index caf4a96..525335f 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -2,7 +2,7 @@ import { useRouter } from 'next/router'; import { IntlProvider } from 'react-intl'; import '../styles/globals.scss'; import type { AppPropsWithLayout } from '../types'; -import { settings } from '../utils/config'; +import { CONFIG } from '../utils/config'; import { PRISM_THEME_ATTRIBUTE, STORAGE_KEY } from '../utils/constants'; import { AckeeProvider, @@ -13,14 +13,14 @@ import { const App = ({ Component, pageProps }: AppPropsWithLayout) => { const { locale, defaultLocale } = useRouter(); - const appLocale: string = locale ?? settings.locales.defaultLocale; + const appLocale: string = locale ?? CONFIG.locales.defaultLocale; const getLayout = Component.getLayout ?? ((page) => page); const { translation, ...componentProps } = pageProps; return ( <AckeeProvider - domainId={settings.ackee.siteId} - server={settings.ackee.url} + domainId={CONFIG.ackee.siteId} + server={CONFIG.ackee.url} storageKey={STORAGE_KEY.ACKEE} tracking="full" > diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx index 4eb7f2b..7875d1d 100644 --- a/src/pages/article/[slug].tsx +++ b/src/pages/article/[slug].tsx @@ -27,6 +27,7 @@ import { } from '../../services/graphql'; import styles from '../../styles/pages/article.module.scss'; import type { Article, NextPageWithLayout, SingleComment } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getBlogSchema, @@ -41,7 +42,6 @@ import { useComments, usePrism, useReadingTime, - useSettings, } from '../../utils/hooks'; type ArticlePageProps = { @@ -84,7 +84,6 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({ url: `${ROUTES.ARTICLE}/${slug}`, }); const readingTime = useReadingTime(article?.meta.wordsCount ?? 0, true); - const { website } = useSettings(); const { attributes, className } = usePrism({ attributes: { 'data-toolbar-order': 'show-language,copy-to-clipboard,color-scheme', @@ -211,14 +210,14 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({ const webpageSchema = getWebPageSchema({ description: intro, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug, title, updateDate: dates.update, }); const blogSchema = getBlogSchema({ isSinglePage: true, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug, }); const blogPostSchema = getSinglePageSchema({ @@ -229,7 +228,7 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({ description: intro, id: 'article', kind: 'post', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug, title, }); @@ -237,12 +236,12 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({ ? commentsData.map((comment) => { return { '@context': 'https://schema.org', - '@id': `${website.url}/#comment-${comment.id}`, + '@id': `${CONFIG.url}/#comment-${comment.id}`, '@type': 'Comment', parentItem: comment.parentId - ? { '@id': `${website.url}/#comment-${comment.parentId}` } + ? { '@id': `${CONFIG.url}/#comment-${comment.parentId}` } : undefined, - about: { '@type': 'Article', '@id': `${website.url}/#article` }, + about: { '@type': 'Article', '@id': `${CONFIG.url}/#article` }, author: { '@type': 'Person', name: comment.meta.author.name, @@ -301,7 +300,7 @@ const ArticlePage: NextPageWithLayout<ArticlePageProps> = ({ prismClassNameReplacer ); - const pageUrl = `${website.url}${slug}`; + const pageUrl = `${CONFIG.url}${slug}`; const sharingWidgetTitle = intl.formatMessage({ defaultMessage: 'Share', id: 'HKKkQk', diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx index e5fc2c2..5a13e3e 100644 --- a/src/pages/blog/index.tsx +++ b/src/pages/blog/index.tsx @@ -33,7 +33,7 @@ import type { RawThematicPreview, RawTopicPreview, } from '../../types'; -import { settings } from '../../utils/config'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getBlogSchema, @@ -43,12 +43,7 @@ import { getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; -import { - useBreadcrumb, - useIsMounted, - usePostsList, - useSettings, -} from '../../utils/hooks'; +import { useBreadcrumb, useIsMounted, usePostsList } from '../../utils/hooks'; type BlogPageProps = { articles: EdgesResponse<RawArticle>; @@ -79,7 +74,6 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ }); const postsListRef = useRef<HTMLDivElement>(null); const isMounted = useIsMounted(postsListRef); - const { blog, website } = useSettings(); const { asPath } = useRouter(); const page = { title: intl.formatMessage( @@ -88,9 +82,9 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ description: 'BlogPage: SEO - Page title', id: '+Y+tLK', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ), - url: `${website.url}${asPath}`, + url: `${CONFIG.url}${asPath}`, }; const pageDescription = intl.formatMessage( { @@ -99,17 +93,17 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ description: 'BlogPage: SEO - Meta description', id: '18h/t0', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); const blogSchema = getBlogSchema({ isSinglePage: false, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, }); const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); @@ -126,7 +120,7 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ } = usePostsList({ fallback: [articles], fetcher: getArticles, - perPage: blog.postsPerPage, + perPage: CONFIG.postsPerPage, }); const thematicsListTitle = intl.formatMessage({ @@ -315,7 +309,7 @@ BlogPage.getLayout = (page) => export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ locale, }) => { - const articles = await getArticles({ first: settings.postsPerPage }); + const articles = await getArticles({ first: CONFIG.postsPerPage }); const totalArticles = await getTotalArticles(); const totalThematics = await getTotalThematics(); const thematics = await getThematicsPreview({ first: totalThematics }); diff --git a/src/pages/blog/page/[number].tsx b/src/pages/blog/page/[number].tsx index 5f6a2d6..49b5eb4 100644 --- a/src/pages/blog/page/[number].tsx +++ b/src/pages/blog/page/[number].tsx @@ -33,7 +33,8 @@ import type { RawThematicPreview, RawTopicPreview, } from '../../../types'; -import { settings } from '../../../utils/config'; +import { CONFIG } from '../../../utils/config'; +import { ROUTES } from '../../../utils/constants'; import { getBlogSchema, getLinksItemData, @@ -43,12 +44,7 @@ import { getWebPageSchema, } from '../../../utils/helpers'; import { loadTranslation, type Messages } from '../../../utils/helpers/server'; -import { - useBreadcrumb, - useRedirection, - useSettings, -} from '../../../utils/hooks'; -import { ROUTES } from 'src/utils/constants'; +import { useBreadcrumb, useRedirection } from '../../../utils/hooks'; type BlogPageProps = { articles: EdgesResponse<RawArticle>; @@ -96,11 +92,10 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ url: `${ROUTES.BLOG}/page/${pageNumber}`, }); - const { website } = useSettings(); const { asPath } = useRouter(); const page = { - title: `${pageTitleWithPageNumber} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${pageTitleWithPageNumber} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; const pageDescription = intl.formatMessage( { @@ -109,17 +104,17 @@ const BlogPage: NextPageWithLayout<BlogPageProps> = ({ description: 'BlogPage: SEO - Meta description', id: '18h/t0', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); const blogSchema = getBlogSchema({ isSinglePage: false, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, }); const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); @@ -292,10 +287,10 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ }) => { const pageNumber = Number((params as BlogPageParams).number); const lastCursor = await getArticlesEndCursor({ - first: settings.postsPerPage * pageNumber, + first: CONFIG.postsPerPage * pageNumber, }); const articles = await getArticles({ - first: settings.postsPerPage, + first: CONFIG.postsPerPage, after: lastCursor, }); const totalArticles = await getTotalArticles(); @@ -319,7 +314,7 @@ export const getStaticProps: GetStaticProps<BlogPageProps> = async ({ export const getStaticPaths: GetStaticPaths = async () => { const totalArticles = await getTotalArticles(); - const totalPages = Math.ceil(totalArticles / settings.postsPerPage); + const totalPages = Math.ceil(totalArticles / CONFIG.postsPerPage); const pagesArray = Array.from( { length: totalPages }, (_, index) => index + 1 diff --git a/src/pages/contact.tsx b/src/pages/contact.tsx index 916e04c..f316143 100644 --- a/src/pages/contact.tsx +++ b/src/pages/contact.tsx @@ -16,6 +16,7 @@ import { import { meta } from '../content/pages/contact.mdx'; import { sendMail } from '../services/graphql'; import type { NextPageWithLayout } from '../types'; +import { CONFIG } from '../utils/config'; import { ROUTES } from '../utils/constants'; import { getSchemaJson, @@ -23,7 +24,7 @@ import { getWebPageSchema, } from '../utils/helpers'; import { loadTranslation } from '../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../utils/hooks'; +import { useBreadcrumb } from '../utils/hooks'; const ContactPage: NextPageWithLayout = () => { const { dates, intro, seo, title } = meta; @@ -44,11 +45,10 @@ const ContactPage: NextPageWithLayout = () => { id: 'Qh2CwH', }); - const { website } = useSettings(); const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -58,7 +58,7 @@ const ContactPage: NextPageWithLayout = () => { description: intro, id: 'contact', kind: 'contact', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); @@ -120,7 +120,7 @@ const ContactPage: NextPageWithLayout = () => { const submitMail: ContactFormSubmit = useCallback( async ({ email, message, name, object }) => { const messageHTML = message.replace(/\r?\n/g, '<br />'); - const body = `Message received from ${name} <${email}> on ${website.url}.<br /><br />${messageHTML}`; + const body = `Message received from ${name} <${email}> on ${CONFIG.url}.<br /><br />${messageHTML}`; const replyTo = `${name} <${email}>`; const mailData = { body, @@ -155,11 +155,11 @@ const ContactPage: NextPageWithLayout = () => { validator: () => sent, }; }, - [intl, website.url] + [intl] ); const page = { - title: `${seo.title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${seo.title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; return ( diff --git a/src/pages/cv.tsx b/src/pages/cv.tsx index e2d1ae5..5157249 100644 --- a/src/pages/cv.tsx +++ b/src/pages/cv.tsx @@ -25,6 +25,7 @@ import { } from '../components'; import CVContent, { data, meta } from '../content/pages/cv.mdx'; import type { NextPageWithLayout } from '../types'; +import { CONFIG } from '../utils/config'; import { PERSONAL_LINKS, ROUTES } from '../utils/constants'; import { getSchemaJson, @@ -32,7 +33,7 @@ import { getWebPageSchema, } from '../utils/helpers'; import { loadTranslation } from '../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../utils/hooks'; +import { useBreadcrumb } from '../utils/hooks'; const ExternalLink = ({ children = '', @@ -179,7 +180,6 @@ const CVPage: NextPageWithLayout = () => { (item): item is MetaItemData => !!item ); - const { website } = useSettings(); const cvCaption = intl.formatMessage( { defaultMessage: '<link>Download the CV in PDF</link>', @@ -257,7 +257,7 @@ const CVPage: NextPageWithLayout = () => { const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -268,14 +268,14 @@ const CVPage: NextPageWithLayout = () => { description: intro, id: 'cv', kind: 'about', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); const schemaJsonLd = getSchemaJson([webpageSchema, cvSchema]); const page = { - title: `${seo.title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${seo.title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; return ( diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 7ff1379..0306736 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -30,10 +30,11 @@ import HomePageContent from '../content/pages/homepage.mdx'; import { getArticlesCard } from '../services/graphql'; import styles from '../styles/pages/home.module.scss'; import type { ArticleCard, NextPageWithLayout } from '../types'; +import { CONFIG } from '../utils/config'; import { PERSONAL_LINKS, ROUTES } from '../utils/constants'; import { getSchemaJson, getWebPageSchema } from '../utils/helpers'; import { loadTranslation, type Messages } from '../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../utils/hooks'; +import { useBreadcrumb } from '../utils/hooks'; /** * Column component. @@ -388,15 +389,13 @@ const HomePage: NextPageWithLayout<HomeProps> = ({ recentPosts }) => { ShaarliLink, }; - const { website } = useSettings(); - const pageTitle = intl.formatMessage( { defaultMessage: '{websiteName} | Front-end developer: WordPress/React', description: 'HomePage: SEO - Page title', id: 'PXp2hv', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const pageDescription = intl.formatMessage( { @@ -405,11 +404,11 @@ const HomePage: NextPageWithLayout<HomeProps> = ({ recentPosts }) => { description: 'HomePage: SEO - Meta description', id: 'tMuNTy', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: '', title: pageTitle, }); @@ -421,7 +420,7 @@ const HomePage: NextPageWithLayout<HomeProps> = ({ recentPosts }) => { <title>{pageTitle}</title> {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */} <meta name="description" content={pageDescription} /> - <meta property="og:url" content={website.url} /> + <meta property="og:url" content={CONFIG.url} /> <meta property="og:title" content={pageTitle} /> <meta property="og:description" content={pageDescription} /> </Head> diff --git a/src/pages/mentions-legales.tsx b/src/pages/mentions-legales.tsx index 4e14d90..50f60f5 100644 --- a/src/pages/mentions-legales.tsx +++ b/src/pages/mentions-legales.tsx @@ -16,6 +16,7 @@ import { } from '../components'; import LegalNoticeContent, { meta } from '../content/pages/legal-notice.mdx'; import type { NextPageWithLayout } from '../types'; +import { CONFIG } from '../utils/config'; import { ROUTES } from '../utils/constants'; import { getSchemaJson, @@ -23,7 +24,7 @@ import { getWebPageSchema, } from '../utils/helpers'; import { loadTranslation } from '../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../utils/hooks'; +import { useBreadcrumb } from '../utils/hooks'; const ResponsiveImage = (props: NextImageProps) => ( <Figure> @@ -73,11 +74,10 @@ const LegalNoticePage: NextPageWithLayout = () => { (item): item is MetaItemData => !!item ); - const { website } = useSettings(); const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -87,14 +87,14 @@ const LegalNoticePage: NextPageWithLayout = () => { description: intro, id: 'legal-notice', kind: 'page', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); const schemaJsonLd = getSchemaJson([webpageSchema, articleSchema]); const page = { - title: `${seo.title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${seo.title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; return ( diff --git a/src/pages/projets/[slug].tsx b/src/pages/projets/[slug].tsx index fa8f43a..1aa9e7f 100644 --- a/src/pages/projets/[slug].tsx +++ b/src/pages/projets/[slug].tsx @@ -28,6 +28,7 @@ import { } from '../../components'; import styles from '../../styles/pages/project.module.scss'; import type { NextPageWithLayout, ProjectPreview, Repos } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getSchemaJson, @@ -40,7 +41,7 @@ import { loadTranslation, type Messages, } from '../../utils/helpers/server'; -import { useBreadcrumb, useGithubApi, useSettings } from '../../utils/hooks'; +import { useBreadcrumb, useGithubApi } from '../../utils/hooks'; const BorderedImage = (props: NextImageProps) => ( <Figure hasBorders> @@ -170,11 +171,10 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => { } ); - const { website } = useSettings(); const { asPath } = useRouter(); const page = { - title: `${seo.title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${seo.title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; const headerMeta: (MetaItemData | undefined)[] = [ @@ -273,7 +273,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => { const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -284,7 +284,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => { description: intro, id: 'project', kind: 'page', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); diff --git a/src/pages/projets/index.tsx b/src/pages/projets/index.tsx index 6ae476e..97b43e3 100644 --- a/src/pages/projets/index.tsx +++ b/src/pages/projets/index.tsx @@ -23,6 +23,7 @@ import { import PageContent, { meta } from '../../content/pages/projects.mdx'; import styles from '../../styles/pages/projects.module.scss'; import type { NextPageWithLayout, ProjectCard } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getSchemaJson, @@ -34,7 +35,7 @@ import { loadTranslation, type Messages, } from '../../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../../utils/hooks'; +import { useBreadcrumb } from '../../utils/hooks'; const components: MDXComponents = { Link, @@ -116,11 +117,10 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => { } ); - const { website } = useSettings(); const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -130,14 +130,14 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => { description: seo.description, id: 'projects', kind: 'page', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); const schemaJsonLd = getSchemaJson([webpageSchema, articleSchema]); const page = { - title: `${seo.title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${seo.title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; return ( diff --git a/src/pages/recherche/index.tsx b/src/pages/recherche/index.tsx index 87e6171..92035b0 100644 --- a/src/pages/recherche/index.tsx +++ b/src/pages/recherche/index.tsx @@ -31,6 +31,7 @@ import type { RawThematicPreview, RawTopicPreview, } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getBlogSchema, @@ -40,12 +41,7 @@ import { getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; -import { - useBreadcrumb, - useDataFromAPI, - usePostsList, - useSettings, -} from '../../utils/hooks'; +import { useBreadcrumb, useDataFromAPI, usePostsList } from '../../utils/hooks'; type SearchPageProps = { thematicsList: RawThematicPreview[]; @@ -81,10 +77,9 @@ const SearchPage: NextPageWithLayout<SearchPageProps> = ({ url: ROUTES.SEARCH, }); - const { blog, website } = useSettings(); const page = { - title: `${title} - ${website.name}`, - url: `${website.url}${asPath}`, + title: `${title} - ${CONFIG.name}`, + url: `${CONFIG.url}${asPath}`, }; const pageDescription = query.s ? intl.formatMessage( @@ -94,7 +89,7 @@ const SearchPage: NextPageWithLayout<SearchPageProps> = ({ description: 'SearchPage: SEO - Meta description', id: 'pg26sn', }, - { query: query.s as string, websiteName: website.name } + { query: query.s as string, websiteName: CONFIG.name } ) : intl.formatMessage( { @@ -102,17 +97,17 @@ const SearchPage: NextPageWithLayout<SearchPageProps> = ({ description: 'SearchPage: SEO - Meta description', id: 'npisb3', }, - { websiteName: website.name } + { websiteName: CONFIG.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: page.title, }); const blogSchema = getBlogSchema({ isSinglePage: false, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, }); const schemaJsonLd = getSchemaJson([webpageSchema, blogSchema]); @@ -129,7 +124,7 @@ const SearchPage: NextPageWithLayout<SearchPageProps> = ({ } = usePostsList({ fallback: [], fetcher: getArticles, - perPage: blog.postsPerPage, + perPage: CONFIG.postsPerPage, searchQuery: query.s as string, }); diff --git a/src/pages/sujet/[slug].tsx b/src/pages/sujet/[slug].tsx index d841b73..a475df9 100644 --- a/src/pages/sujet/[slug].tsx +++ b/src/pages/sujet/[slug].tsx @@ -23,6 +23,7 @@ import { } from '../../services/graphql'; import styles from '../../styles/pages/blog.module.scss'; import type { NextPageWithLayout, PageLink, Topic } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getLinksItemData, @@ -33,7 +34,7 @@ import { getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../../utils/hooks'; +import { useBreadcrumb } from '../../utils/hooks'; export type TopicPageProps = { currentTopic: Topic; @@ -116,11 +117,10 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({ (item): item is MetaItemData => !!item ); - const { website } = useSettings(); const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -131,7 +131,7 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({ description: intro, id: 'topic', kind: 'page', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); @@ -155,7 +155,7 @@ const TopicPage: NextPageWithLayout<TopicPageProps> = ({ {title} </> ); - const pageUrl = `${website.url}${asPath}`; + const pageUrl = `${CONFIG.url}${asPath}`; return ( <> diff --git a/src/pages/thematique/[slug].tsx b/src/pages/thematique/[slug].tsx index 20c1ee8..ea8c6b0 100644 --- a/src/pages/thematique/[slug].tsx +++ b/src/pages/thematique/[slug].tsx @@ -22,6 +22,7 @@ import { } from '../../services/graphql'; import styles from '../../styles/pages/blog.module.scss'; import type { NextPageWithLayout, PageLink, Thematic } from '../../types'; +import { CONFIG } from '../../utils/config'; import { ROUTES } from '../../utils/constants'; import { getLinksItemData, @@ -32,7 +33,7 @@ import { getWebPageSchema, } from '../../utils/helpers'; import { loadTranslation, type Messages } from '../../utils/helpers/server'; -import { useBreadcrumb, useSettings } from '../../utils/hooks'; +import { useBreadcrumb } from '../../utils/hooks'; export type ThematicPageProps = { currentThematic: Thematic; @@ -97,11 +98,10 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({ (item): item is MetaItemData => !!item ); - const { website } = useSettings(); const { asPath } = useRouter(); const webpageSchema = getWebPageSchema({ description: seo.description, - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title: seo.title, updateDate: dates.update, @@ -111,7 +111,7 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({ description: intro, id: 'thematic', kind: 'page', - locale: website.locales.default, + locale: CONFIG.locales.defaultLocale, slug: asPath, title, }); @@ -128,7 +128,7 @@ const ThematicPage: NextPageWithLayout<ThematicPageProps> = ({ description: 'ThematicPage: related topics list widget title', id: '/42Z0z', }); - const pageUrl = `${website.url}${asPath}`; + const pageUrl = `${CONFIG.url}${asPath}`; return ( <> diff --git a/src/services/graphql/api.ts b/src/services/graphql/api.ts index 5f32a78..003f92d 100644 --- a/src/services/graphql/api.ts +++ b/src/services/graphql/api.ts @@ -1,4 +1,4 @@ -import { +import type { Mutations, MutationsInputMap, MutationsResponseMap, @@ -6,7 +6,7 @@ import { QueriesInputMap, QueriesResponseMap, } from '../../types'; -import { settings } from '../../utils/config'; +import { CONFIG } from '../../utils/config'; /** * Retrieve the API url from settings. @@ -14,7 +14,7 @@ import { settings } from '../../utils/config'; * @returns {string} The API url. */ export const getAPIUrl = (): string => { - const { url } = settings.api; + const { url } = CONFIG.api; if (!url) { throw new Error('API url is not defined.'); @@ -65,7 +65,7 @@ export const fetchAPI = async <T, K extends Queries | Mutations>({ type JSONResponse = { data?: FetchAPIResponse<T, K>; - errors?: Array<{ message: string }>; + errors?: { message: string }[]; }; const { data, errors }: JSONResponse = await response.json(); @@ -74,11 +74,10 @@ export const fetchAPI = async <T, K extends Queries | Mutations>({ if (!data) return Promise.reject(new Error(`No data found"`)); return data; - } else { - console.error('Failed to fetch API'); - const error = new Error( - errors?.map((e) => e.message).join('\n') ?? 'unknown' - ); - return Promise.reject(error); } + console.error('Failed to fetch API'); + const error = new Error( + errors?.map((e) => e.message).join('\n') ?? 'unknown' + ); + return Promise.reject(error); }; diff --git a/src/utils/config.ts b/src/utils/config.ts index 61a46b4..edd9b2f 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -1,10 +1,12 @@ const isStaging = process.env.NEXT_PUBLIC_APP_ENV === 'staging'; -export const settings = { +export const CONFIG = { ackee: { - filename: process.env.NEXT_PUBLIC_ACKEE_FILENAME || 'tracker.js', - siteId: process.env.NEXT_PUBLIC_ACKEE_SITE_ID || '', - url: `https://${process.env.NEXT_PUBLIC_ACKEE_DOMAIN}` || '', + filename: process.env.NEXT_PUBLIC_ACKEE_FILENAME ?? 'tracker.js', + siteId: process.env.NEXT_PUBLIC_ACKEE_SITE_ID ?? '', + url: process.env.NEXT_PUBLIC_ACKEE_DOMAIN + ? `https://${process.env.NEXT_PUBLIC_ACKEE_DOMAIN}` + : '', }, api: { url: isStaging @@ -12,15 +14,12 @@ export const settings = { : process.env.NEXT_PUBLIC_GRAPHQL_API, }, name: 'Armand Philippot', - baseline: { - en: 'Front-end developer', - fr: 'Intégrateur web', - }, + baseline: 'Intégrateur web', copyright: { startYear: '2012', endYear: new Date().getFullYear().toString(), }, - email: process.env.APP_AUTHOR_EMAIL || '', + email: process.env.APP_AUTHOR_EMAIL ?? '', locales: { defaultLocale: 'fr', defaultCountry: 'FR', @@ -31,5 +30,5 @@ export const settings = { url: (isStaging ? process.env.NEXT_PUBLIC_STAGING_APP_URL - : process.env.NEXT_PUBLIC_APP_URL) || '', + : process.env.NEXT_PUBLIC_APP_URL) ?? '', }; diff --git a/src/utils/helpers/rss.ts b/src/utils/helpers/rss.ts index 0381c68..6de60cc 100644 --- a/src/utils/helpers/rss.ts +++ b/src/utils/helpers/rss.ts @@ -5,7 +5,7 @@ import { getTotalArticles, } from '../../services/graphql'; import type { Article } from '../../types'; -import { settings } from '../config'; +import { CONFIG } from '../config'; import { ROUTES } from '../constants'; /** @@ -32,25 +32,25 @@ const getAllArticles = async (): Promise<Article[]> => { */ export const generateFeed = async (): Promise<Feed> => { const author = { - name: settings.name, + name: CONFIG.name, email: process.env.APP_AUTHOR_EMAIL, - link: settings.url, + link: CONFIG.url, }; - const copyright = `${settings.name} CC BY SA ${settings.copyright.startYear} - ${settings.copyright.endYear}`; - const title = `${settings.name} | ${settings.baseline.fr}`; + const copyright = `${CONFIG.name} CC BY SA ${CONFIG.copyright.startYear} - ${CONFIG.copyright.endYear}`; + const title = `${CONFIG.name} | ${CONFIG.baseline}`; const feed = new Feed({ author, copyright, description: process.env.APP_FEED_DESCRIPTION, feedLinks: { - json: `${settings.url}${ROUTES.RSS}/json`, - atom: `${settings.url}${ROUTES.RSS}/atom`, + json: `${CONFIG.url}${ROUTES.RSS}/json`, + atom: `${CONFIG.url}${ROUTES.RSS}/atom`, }, generator: 'Feed & NextJS', - id: settings.url, - language: settings.locales.defaultLocale, - link: settings.url, + id: CONFIG.url, + language: CONFIG.locales.defaultLocale, + link: CONFIG.url, title, }); @@ -62,7 +62,7 @@ export const generateFeed = async (): Promise<Feed> => { date: new Date(article.meta.dates.publication), description: article.intro, id: `${article.id}`, - link: `${settings.url}${ROUTES.ARTICLE}/${article.slug}`, + link: `${CONFIG.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 12bad28..2edc11b 100644 --- a/src/utils/helpers/schema-org.ts +++ b/src/utils/helpers/schema-org.ts @@ -8,7 +8,7 @@ import type { WebPage, } from 'schema-dts'; import type { Dates } from '../../types'; -import { settings } from '../config'; +import { CONFIG } from '../config'; import { ROUTES } from '../constants'; export type GetBlogSchemaProps = { @@ -38,22 +38,22 @@ export const getBlogSchema = ({ slug, }: GetBlogSchemaProps): Blog => { return { - '@id': `${settings.url}/#blog`, + '@id': `${CONFIG.url}/#blog`, '@type': 'Blog', - author: { '@id': `${settings.url}/#branding` }, - creator: { '@id': `${settings.url}/#branding` }, - editor: { '@id': `${settings.url}/#branding` }, - blogPost: isSinglePage ? { '@id': `${settings.url}/#article` } : undefined, + author: { '@id': `${CONFIG.url}/#branding` }, + creator: { '@id': `${CONFIG.url}/#branding` }, + editor: { '@id': `${CONFIG.url}/#branding` }, + blogPost: isSinglePage ? { '@id': `${CONFIG.url}/#article` } : undefined, inLanguage: locale, isPartOf: isSinglePage ? { - '@id': `${settings.url}${slug}`, + '@id': `${CONFIG.url}${slug}`, } : undefined, license: 'https://creativecommons.org/licenses/by-sa/4.0/deed.fr', mainEntityOfPage: isSinglePage ? undefined - : { '@id': `${settings.url}${slug}` }, + : { '@id': `${CONFIG.url}${slug}` }, }; }; @@ -137,19 +137,19 @@ export const getSinglePageSchema = <T extends SinglePageSchemaKind>({ }; return { - '@id': `${settings.url}/#${id}`, + '@id': `${CONFIG.url}/#${id}`, '@type': singlePageSchemaType[kind], name: title, description, articleBody: content, - author: { '@id': `${settings.url}/#branding` }, + author: { '@id': `${CONFIG.url}/#branding` }, commentCount: commentsCount, copyrightYear: publicationDate.getFullYear(), - creator: { '@id': `${settings.url}/#branding` }, + creator: { '@id': `${CONFIG.url}/#branding` }, dateCreated: publicationDate.toISOString(), dateModified: updateDate?.toISOString(), datePublished: publicationDate.toISOString(), - editor: { '@id': `${settings.url}/#branding` }, + editor: { '@id': `${CONFIG.url}/#branding` }, headline: title, image: cover, inLanguage: locale, @@ -158,10 +158,10 @@ export const getSinglePageSchema = <T extends SinglePageSchemaKind>({ isPartOf: kind === 'post' ? { - '@id': `${settings.url}${ROUTES.BLOG}`, + '@id': `${CONFIG.url}${ROUTES.BLOG}`, } : undefined, - mainEntityOfPage: { '@id': `${settings.url}${slug}` }, + mainEntityOfPage: { '@id': `${CONFIG.url}${slug}` }, } as SinglePageSchemaReturn[T]; }; @@ -202,17 +202,17 @@ export const getWebPageSchema = ({ updateDate, }: GetWebPageSchemaProps): WebPage => { return { - '@id': `${settings.url}${slug}`, + '@id': `${CONFIG.url}${slug}`, '@type': 'WebPage', - breadcrumb: { '@id': `${settings.url}/#breadcrumb` }, + breadcrumb: { '@id': `${CONFIG.url}/#breadcrumb` }, lastReviewed: updateDate, name: title, description, inLanguage: locale, - reviewedBy: { '@id': `${settings.url}/#branding` }, - url: `${settings.url}${slug}`, + reviewedBy: { '@id': `${CONFIG.url}/#branding` }, + url: `${CONFIG.url}${slug}`, isPartOf: { - '@id': `${settings.url}`, + '@id': `${CONFIG.url}`, }, }; }; diff --git a/src/utils/helpers/server/i18n.ts b/src/utils/helpers/server/i18n.ts index dbbc4e5..8abd92e 100644 --- a/src/utils/helpers/server/i18n.ts +++ b/src/utils/helpers/server/i18n.ts @@ -1,10 +1,10 @@ import { readFile } from 'fs/promises'; import path from 'path'; -import { settings } from '../../config'; +import { CONFIG } from '../../config'; -export type Messages = { [key: string]: string }; +export type Messages = Record<string, string>; -export const defaultLocale = settings.locales.defaultLocale; +export const { defaultLocale } = CONFIG.locales; /** * Load the translation for the provided locale. diff --git a/src/utils/hooks/index.ts b/src/utils/hooks/index.ts index 68fb7ce..ad412c8 100644 --- a/src/utils/hooks/index.ts +++ b/src/utils/hooks/index.ts @@ -24,7 +24,6 @@ export * from './use-route-change'; export * from './use-scroll-lock'; export * from './use-scroll-position'; export * from './use-scrollbar-width'; -export * from './use-settings'; export * from './use-state-change'; export * from './use-system-color-scheme'; export * from './use-theme'; diff --git a/src/utils/hooks/use-breadcrumb.ts b/src/utils/hooks/use-breadcrumb.ts index 57c27bd..1cd18d9 100644 --- a/src/utils/hooks/use-breadcrumb.ts +++ b/src/utils/hooks/use-breadcrumb.ts @@ -2,9 +2,9 @@ import { useIntl } from 'react-intl'; import type { BreadcrumbList } from 'schema-dts'; import type { BreadcrumbsItem } from '../../components'; +import { CONFIG } from '../config'; import { ROUTES } from '../constants'; import { slugify } from '../helpers'; -import { useSettings } from './use-settings'; const isArticle = (url: string) => url.startsWith(`${ROUTES.ARTICLE}/`); @@ -61,7 +61,6 @@ export const useBreadcrumb = ({ url, }: useBreadcrumbProps): useBreadcrumbReturn => { const intl = useIntl(); - const { website } = useSettings(); const labels = { home: intl.formatMessage({ defaultMessage: 'Home', @@ -88,7 +87,7 @@ export const useBreadcrumb = ({ '@type': 'ListItem', position: 1, name: labels.home, - item: website.url, + item: CONFIG.url, }, ]; @@ -100,7 +99,7 @@ export const useBreadcrumb = ({ '@type': 'ListItem', position: 2, name: labels.blog, - item: `${website.url}${ROUTES.BLOG}`, + item: `${CONFIG.url}${ROUTES.BLOG}`, }); } @@ -110,7 +109,7 @@ export const useBreadcrumb = ({ '@type': 'ListItem', position: 2, name: labels.projects, - item: `${website.url}${ROUTES.PROJECTS}`, + item: `${CONFIG.url}${ROUTES.PROJECTS}`, }); } @@ -119,7 +118,7 @@ export const useBreadcrumb = ({ '@type': 'ListItem', position: schema.length + 1, name: title, - item: `${website.url}${url}`, + item: `${CONFIG.url}${url}`, }); return { items, schema }; diff --git a/src/utils/hooks/use-settings.tsx b/src/utils/hooks/use-settings.tsx deleted file mode 100644 index 968930d..0000000 --- a/src/utils/hooks/use-settings.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useRouter } from 'next/router'; -import { settings } from '../config'; - -export type BlogSettings = { - /** - * The number of posts per page. - */ - postsPerPage: number; -}; - -export type CopyrightSettings = { - /** - * The copyright end year. - */ - end: string; - /** - * The copyright start year. - */ - start: string; -}; - -export type LocaleSettings = { - /** - * The default locale. - */ - default: string; - /** - * The supported locales. - */ - supported: string[]; -}; - -export type WebsiteSettings = { - /** - * The website name. - */ - name: string; - /** - * The website baseline. - */ - baseline: string; - /** - * The website copyright dates. - */ - copyright: CopyrightSettings; - /** - * The website admin email. - */ - email: string; - /** - * The website locales. - */ - locales: LocaleSettings; - /** - * The website url. - */ - url: string; -}; - -export type UseSettingsReturn = { - blog: BlogSettings; - website: WebsiteSettings; -}; - -/** - * Retrieve the website and blog settings. - * - * @returns {UseSettingsReturn} - An object describing settings. - */ -export const useSettings = (): UseSettingsReturn => { - const { baseline, copyright, email, locales, name, postsPerPage, url } = - settings; - const router = useRouter(); - const locale = router.locale ?? locales.defaultLocale; - - return { - blog: { - postsPerPage, - }, - website: { - baseline: locale.startsWith('en') ? baseline.en : baseline.fr, - copyright: { - end: copyright.endYear, - start: copyright.startYear, - }, - email, - locales: { - default: locales.defaultLocale, - supported: locales.supported, - }, - name, - url, - }, - }; -}; |
