diff options
| author | Armand Philippot <git@armandphilippot.com> | 2022-05-02 18:57:29 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2022-05-03 15:22:24 +0200 |
| commit | 732d0943f8041d76262222a092b014f2557085ef (patch) | |
| tree | 16f6f76648b479a9591400ab15bb3e9c914f2226 /src/components/templates/layout | |
| parent | ca921d7536cfe950b5a7d442977bbf900b48faf4 (diff) | |
chore: add homepage
Diffstat (limited to 'src/components/templates/layout')
| -rw-r--r-- | src/components/templates/layout/layout.module.scss | 9 | ||||
| -rw-r--r-- | src/components/templates/layout/layout.stories.tsx | 10 | ||||
| -rw-r--r-- | src/components/templates/layout/layout.tsx | 107 |
3 files changed, 97 insertions, 29 deletions
diff --git a/src/components/templates/layout/layout.module.scss b/src/components/templates/layout/layout.module.scss index 3533257..806d2d7 100644 --- a/src/components/templates/layout/layout.module.scss +++ b/src/components/templates/layout/layout.module.scss @@ -1,15 +1,6 @@ @use "@styles/abstracts/functions" as fun; @use "@styles/abstracts/mixins" as mix; -:global { - #__next { - flex: 1; - display: flex; - flex-flow: column nowrap; - min-height: 100vh; - } -} - .header { border-bottom: fun.convert-px(3) solid var(--color-border-light); } diff --git a/src/components/templates/layout/layout.stories.tsx b/src/components/templates/layout/layout.stories.tsx index f3579e3..2415412 100644 --- a/src/components/templates/layout/layout.stories.tsx +++ b/src/components/templates/layout/layout.stories.tsx @@ -36,7 +36,15 @@ export default { decorators: [ (Story) => ( <IntlProvider locale="en"> - <div id="__next"> + <div + id="__next" + style={{ + flex: 1, + display: 'flex', + flexFlow: 'column nowrap', + minHeight: '100vh', + }} + > <Story /> </div> </IntlProvider> 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> |
