/* eslint-disable max-statements */ import type { MDXComponents } from 'mdx/types'; import type { GetStaticProps } from 'next'; import Head from 'next/head'; import NextImage, { type ImageProps as NextImageProps } 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, Figure, getLayout, Grid, type GridItem, Heading, Icon, List, ListItem, Section, type SectionProps, Time, MetaItem, } from '../components'; 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}
); const H1 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const H2 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const H3 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const H4 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const H5 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const H6 = ({ children = '', ...props }: HTMLAttributes) => ( {children} ); const ResponsiveImage = (props: NextImageProps) => (
); /** * 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(); const shaarliUrl = PERSONAL_LINKS.SHAARLI; 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[] }) => ( { return { id: `${index}`, item: child }; })} sizeMin="250px" /> ); /** * 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 posts: GridItem[] = recentPosts.map((post) => { return { item: ( ) : undefined } meta={ } /> } isCentered linkTo={`${ROUTES.ARTICLE}/${post.slug}`} > {post.title} ), id: `${post.id}`, }; }); const listClass = `${styles.list} ${styles['list--cards']}`; return ( ); }; const components: MDXComponents = { CodingLinks, ColdarkRepos, Column, Grid: StyledGrid, h1: H1, h2: H2, h3: H3, h4: H4, h5: H5, h6: H6, Image: ResponsiveImage, 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 */}