aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/templates/layout/layout.tsx
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2022-05-02 18:57:29 +0200
committerArmand Philippot <git@armandphilippot.com>2022-05-03 15:22:24 +0200
commit732d0943f8041d76262222a092b014f2557085ef (patch)
tree16f6f76648b479a9591400ab15bb3e9c914f2226 /src/components/templates/layout/layout.tsx
parentca921d7536cfe950b5a7d442977bbf900b48faf4 (diff)
chore: add homepage
Diffstat (limited to 'src/components/templates/layout/layout.tsx')
-rw-r--r--src/components/templates/layout/layout.tsx107
1 files changed, 88 insertions, 19 deletions
diff --git a/src/components/templates/layout/layout.tsx b/src/components/templates/layout/layout.tsx
index 601ced4..e1be1af 100644
--- a/src/components/templates/layout/layout.tsx
+++ b/src/components/templates/layout/layout.tsx
@@ -1,4 +1,3 @@
-import photo from '@assets/images/armand-philippot.jpg';
import ButtonLink from '@components/atoms/buttons/button-link';
import Career from '@components/atoms/icons/career';
import CCBySA from '@components/atoms/icons/cc-by-sa';
@@ -8,13 +7,19 @@ import Home from '@components/atoms/icons/home';
import PostsStack from '@components/atoms/icons/posts-stack';
import Main from '@components/atoms/layout/main';
import NoScript from '@components/atoms/layout/no-script';
-import Footer from '@components/organisms/layout/footer';
-import Header, { HeaderProps } from '@components/organisms/layout/header';
-import { settings } from '@utils/config';
+import Footer, { FooterProps } from '@components/organisms/layout/footer';
+import Header, { type HeaderProps } from '@components/organisms/layout/header';
+import useSettings from '@utils/hooks/use-settings';
+import Script from 'next/script';
import { FC, ReactNode } from 'react';
import { useIntl } from 'react-intl';
+import { Person, SearchAction, WebSite, WithContext } from 'schema-dts';
import styles from './layout.module.scss';
+export type QueryAction = SearchAction & {
+ 'query-input': string;
+};
+
export type LayoutProps = Pick<HeaderProps, 'isHome'> & {
/**
* The layout main content.
@@ -33,6 +38,9 @@ export type LayoutProps = Pick<HeaderProps, 'isHome'> & {
*/
const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
const intl = useIntl();
+ const { website } = useSettings();
+ const { baseline, copyright, locales, name, picture, url } = website;
+
const skipToContent = intl.formatMessage({
defaultMessage: 'Skip to content',
description: 'Layout: Skip to content link',
@@ -45,12 +53,12 @@ const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
id: '7jVUT6',
});
- const copyright = {
+ const copyrightData = {
dates: {
- start: settings.copyright.startYear,
- end: settings.copyright.endYear,
+ start: copyright.start,
+ end: copyright.end,
},
- owner: settings.name,
+ owner: name,
icon: <CCBySA />,
};
@@ -80,21 +88,77 @@ const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
id: 'AE4kCD',
});
- const nav: HeaderProps['nav'] = [
- { id: 'home', label: homeLabel, href: '#', logo: <Home /> },
- { id: 'blog', label: blogLabel, href: '#', logo: <PostsStack /> },
+ const mainNav: HeaderProps['nav'] = [
+ { id: 'home', label: homeLabel, href: '/', logo: <Home /> },
+ { id: 'blog', label: blogLabel, href: '/blog', logo: <PostsStack /> },
{
id: 'projects',
label: projectsLabel,
- href: '#',
+ href: '/projets',
logo: <ComputerScreen />,
},
- { id: 'cv', label: cvLabel, href: '#', logo: <Career /> },
- { id: 'contact', label: contactLabel, href: '#', logo: <Envelop /> },
+ { id: 'cv', label: cvLabel, href: '/cv', logo: <Career /> },
+ { id: 'contact', label: contactLabel, href: '/contact', logo: <Envelop /> },
+ ];
+
+ const legalNoticeLabel = intl.formatMessage({
+ defaultMessage: 'Legal notice',
+ description: 'Layout: Legal notice label',
+ id: 'nwbzKm',
+ });
+
+ const footerNav: FooterProps['navItems'] = [
+ { id: 'legal-notice', label: legalNoticeLabel, href: '/mentions-legales' },
];
+ const searchActionSchema: QueryAction = {
+ '@type': 'SearchAction',
+ target: {
+ '@type': 'EntryPoint',
+ urlTemplate: `${url}/recherche?s={search_term_string}`,
+ },
+ query: 'required',
+ 'query-input': 'required name=search_term_string',
+ };
+
+ const schemaJsonLd: WithContext<WebSite> = {
+ '@context': 'https://schema.org',
+ '@id': `${url}`,
+ '@type': 'WebSite',
+ name: name,
+ description: baseline,
+ url: url,
+ author: { '@id': `${url}/#branding` },
+ copyrightYear: Number(copyright.start),
+ creator: { '@id': `${url}/#branding` },
+ editor: { '@id': `${url}/#branding` },
+ inLanguage: locales.default,
+ potentialAction: searchActionSchema,
+ };
+
+ const brandingSchema: WithContext<Person> = {
+ '@context': 'https://schema.org',
+ '@type': 'Person',
+ '@id': `${url}/#branding`,
+ name: name,
+ url: url,
+ jobTitle: baseline,
+ image: picture.src,
+ subjectOf: { '@id': `${url}` },
+ };
+
return (
<>
+ <Script
+ id="schema-layout"
+ type="application/ld+json"
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
+ ></Script>
+ <Script
+ id="schema-branding"
+ type="application/ld+json"
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(brandingSchema) }}
+ />
<noscript>
<div className={styles['noscript-spacing']}></div>
</noscript>
@@ -103,10 +167,10 @@ const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
{skipToContent}
</ButtonLink>
<Header
- title={settings.name}
- baseline={settings.baseline.fr}
- photo={photo.src}
- nav={nav}
+ title={name}
+ baseline={baseline}
+ photo={picture}
+ nav={mainNav}
isHome={isHome}
className={styles.header}
withLink={true}
@@ -114,7 +178,12 @@ const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
<Main id="main" className={styles.main}>
<article {...props}>{children}</article>
</Main>
- <Footer copyright={copyright} topId="top" className={styles.footer} />
+ <Footer
+ copyright={copyrightData}
+ navItems={footerNav}
+ topId="top"
+ className={styles.footer}
+ />
<noscript>
<NoScript message={noScript} position="top" />
</noscript>