import type { MDXComponents } from 'mdx/types'; import type { GetStaticProps } from 'next'; import Head from 'next/head'; import NextImage from 'next/image'; import Script from 'next/script'; import type { FC, HTMLAttributes, ReactNode } from 'react'; import { useIntl } from 'react-intl'; import { ButtonLink, Card, CardCover, CardFooter, CardHeader, CardMeta, CardTitle, getLayout, Grid, Icon, List, ListItem, Section, type SectionProps, Time, MetaItem, } from '../components'; import { mdxComponents } from '../components/mdx'; 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 } from '../utils/hooks'; /** * Column component. * * Render the body as a column. */ const Column = ({ children, ...props }: HTMLAttributes) => (
{children}
); /** * Retrieve a list of coding links. * * @returns {JSX.Element} - A list of links. */ const CodingLinks: FC = () => { const intl = useIntl(); return ( {intl.formatMessage({ defaultMessage: 'Web development', description: 'HomePage: link to web development thematic', id: 'vkF/RP', })} {intl.formatMessage({ defaultMessage: 'Projects', description: 'HomePage: link to projects', id: 'N44SOc', })} ); }; /** * Retrieve a list of Coldark repositories. * * @returns {JSX.Element} - A list of links. */ const ColdarkRepos: FC = () => { const intl = useIntl(); const repo = { github: 'https://github.com/ArmandPhilippot/coldark', gitlab: 'https://gitlab.com/ArmandPhilippot/coldark', }; return ( {intl.formatMessage({ defaultMessage: 'Github', description: 'HomePage: Github link', id: '3f3PzH', })} {intl.formatMessage({ defaultMessage: 'Gitlab', description: 'HomePage: Gitlab link', id: '7AnwZ7', })} ); }; /** * Retrieve a list of links related to Free thematic. * * @returns {JSX.Element} - A list of links. */ const LibreLinks: FC = () => { const intl = useIntl(); return ( {intl.formatMessage({ defaultMessage: 'Free', description: 'HomePage: link to free thematic', id: 'w8GrOf', })} {intl.formatMessage({ defaultMessage: 'Linux', description: 'HomePage: link to Linux thematic', id: 'jASD7k', })} ); }; /** * Retrieve the Shaarli link. * * @returns {JSX.Element} - A list of links */ const ShaarliLink: FC = () => { const intl = useIntl(); return ( {intl.formatMessage({ defaultMessage: 'Shaarli', description: 'HomePage: link to Shaarli', id: 'i5L19t', })} ); }; /** * Retrieve the additional links. * * @returns {JSX.Element} - A list of links. */ const MoreLinks: FC = () => { const intl = useIntl(); return ( {intl.formatMessage({ defaultMessage: 'Contact me', description: 'HomePage: contact button text', id: 'sO/Iwj', })} {intl.formatMessage({ defaultMessage: 'Subscribe', description: 'HomePage: RSS feed subscription text', id: 'T4YA64', })} ); }; const StyledGrid = ({ children }: { children: ReactNode }) => ( {children} ); /** * Create the page sections. * * @param {object} obj - An object containing the section body. * @param {ReactNode[]} obj.children - The section body. * @returns {JSX.Element} A section element. */ const HomePageSection: FC = ({ children, hasBorder = true, variant, }) => (
{children}
); type HomeProps = { recentPosts: ArticleCard[]; translation?: Messages; }; /** * Home page. */ const HomePage: NextPageWithLayout = ({ recentPosts }) => { const intl = useIntl(); const publicationDate = intl.formatMessage({ defaultMessage: 'Published on:', description: 'HomePage: publication date label', id: 'pT5nHk', }); const { schema: breadcrumbSchema } = useBreadcrumb({ title: '', url: `/`, }); /** * Get a cards list of recent posts. * * @returns {JSX.Element} - The cards list. */ const getRecentPosts = (): JSX.Element => { const listClass = `${styles.list} ${styles['list--cards']}`; return ( {recentPosts.map((post) => ( ) : undefined } key={post.id} meta={ } /> } isCentered linkTo={`${ROUTES.ARTICLE}/${post.slug}`} > {post.title} ))} ); }; const components: MDXComponents = { ...mdxComponents, CodingLinks, ColdarkRepos, Column, Grid: StyledGrid, LibreLinks, MoreLinks, RecentPosts: getRecentPosts, Section: HomePageSection, ShaarliLink, }; const pageTitle = intl.formatMessage( { defaultMessage: '{websiteName} | Front-end developer: WordPress/React', description: 'HomePage: SEO - Page title', id: 'PXp2hv', }, { websiteName: CONFIG.name } ); const pageDescription = intl.formatMessage( { defaultMessage: '{websiteName} is a front-end developer located in France. He codes and he writes mostly about web development and open-source.', description: 'HomePage: SEO - Meta description', id: 'tMuNTy', }, { websiteName: CONFIG.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, locale: CONFIG.locales.defaultLocale, slug: '', title: pageTitle, }); const schemaJsonLd = getSchemaJson([webpageSchema]); return ( <> {pageTitle} {/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */}