summaryrefslogtreecommitdiffstats
path: root/src/components/templates/layout/layout.tsx
blob: 601ced42981ea88e02e77760aefc3c1ec6ff1611 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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';
import ComputerScreen from '@components/atoms/icons/computer-screen';
import Envelop from '@components/atoms/icons/envelop';
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 { FC, ReactNode } from 'react';
import { useIntl } from 'react-intl';
import styles from './layout.module.scss';

export type LayoutProps = Pick<HeaderProps, 'isHome'> & {
  /**
   * The layout main content.
   */
  children: ReactNode;
  /**
   * Set additional classnames to the article element.
   */
  className?: string;
};

/**
 * Layout component
 *
 * Render the base layout used by all pages.
 */
const Layout: FC<LayoutProps> = ({ children, isHome, ...props }) => {
  const intl = useIntl();
  const skipToContent = intl.formatMessage({
    defaultMessage: 'Skip to content',
    description: 'Layout: Skip to content link',
    id: 'K4rYdT',
  });
  const noScript = intl.formatMessage({
    defaultMessage:
      'Warning: If you want to benefit from all features (search for example), please activate Javascript.',
    description: 'Layout: noscript message',
    id: '7jVUT6',
  });

  const copyright = {
    dates: {
      start: settings.copyright.startYear,
      end: settings.copyright.endYear,
    },
    owner: settings.name,
    icon: <CCBySA />,
  };

  const homeLabel = intl.formatMessage({
    defaultMessage: 'Home',
    description: 'Layout: main nav - home link',
    id: 'bojYF5',
  });
  const blogLabel = intl.formatMessage({
    defaultMessage: 'Blog',
    description: 'Layout: main nav - blog link',
    id: 'D8vB38',
  });
  const projectsLabel = intl.formatMessage({
    defaultMessage: 'Projects',
    description: 'Layout: main nav - projects link',
    id: 'qnwsWV',
  });
  const cvLabel = intl.formatMessage({
    defaultMessage: 'CV',
    description: 'Layout: main nav - cv link',
    id: 'R895yC',
  });
  const contactLabel = intl.formatMessage({
    defaultMessage: 'Contact',
    description: 'Layout: main nav - contact link',
    id: 'AE4kCD',
  });

  const nav: HeaderProps['nav'] = [
    { id: 'home', label: homeLabel, href: '#', logo: <Home /> },
    { id: 'blog', label: blogLabel, href: '#', logo: <PostsStack /> },
    {
      id: 'projects',
      label: projectsLabel,
      href: '#',
      logo: <ComputerScreen />,
    },
    { id: 'cv', label: cvLabel, href: '#', logo: <Career /> },
    { id: 'contact', label: contactLabel, href: '#', logo: <Envelop /> },
  ];

  return (
    <>
      <noscript>
        <div className={styles['noscript-spacing']}></div>
      </noscript>
      <span tabIndex={-1}></span>
      <ButtonLink target="#main" className="screen-reader-text">
        {skipToContent}
      </ButtonLink>
      <Header
        title={settings.name}
        baseline={settings.baseline.fr}
        photo={photo.src}
        nav={nav}
        isHome={isHome}
        className={styles.header}
        withLink={true}
      />
      <Main id="main" className={styles.main}>
        <article {...props}>{children}</article>
      </Main>
      <Footer copyright={copyright} topId="top" className={styles.footer} />
      <noscript>
        <NoScript message={noScript} position="top" />
      </noscript>
    </>
  );
};

export default Layout;