import { NestedMDXComponents } from 'mdx/types'; import { GetStaticProps } from 'next'; import Head from 'next/head'; import Script from 'next/script'; import { ReactElement } from 'react'; import { useIntl } from 'react-intl'; import FeedIcon from '../assets/images/icon-feed.svg'; import ButtonLink from '../components/atoms/buttons/button-link'; import Envelop from '../components/atoms/icons/envelop'; import Column from '../components/atoms/layout/column'; import Section, { type SectionProps } from '../components/atoms/layout/section'; import List, { type ListItem } from '../components/atoms/lists/list'; import ResponsiveImage from '../components/molecules/images/responsive-image'; import Columns, { type ColumnsProps, } from '../components/molecules/layout/columns'; import CardsList, { type CardsListItem, } from '../components/organisms/layout/cards-list'; import { getLayout } from '../components/templates/layout/layout'; import HomePageContent from '../content/pages/homepage.mdx'; import { getArticlesCard } from '../services/graphql/articles'; import styles from '../styles/pages/home.module.scss'; import { type ArticleCard, type NextPageWithLayout } from '../types/app'; import { loadTranslation, type Messages } from '../utils/helpers/i18n'; import { getSchemaJson, getWebPageSchema } from '../utils/helpers/schema-org'; import useBreadcrumb from '../utils/hooks/use-breadcrumb'; import useSettings from '../utils/hooks/use-settings'; /** * Retrieve a list of coding links. * * @returns {JSX.Element} - A list of links. */ const CodingLinks = (): JSX.Element => { const intl = useIntl(); const links: ListItem[] = [ { id: 'web-development', value: ( {intl.formatMessage({ defaultMessage: 'Web development', description: 'HomePage: link to web development thematic', id: 'vkF/RP', })} ), }, { id: 'projects', value: ( {intl.formatMessage({ defaultMessage: 'Projects', description: 'HomePage: link to projects', id: 'N44SOc', })} ), }, ]; return ; }; /** * Retrieve a list of Coldark repositories. * * @returns {JSX.Element} - A list of links. */ const ColdarkRepos = (): JSX.Element => { const intl = useIntl(); const links: ListItem[] = [ { id: 'coldark-github', value: ( {intl.formatMessage({ defaultMessage: 'Github', description: 'HomePage: Github link', id: '3f3PzH', })} ), }, { id: 'coldark-gitlab', value: ( {intl.formatMessage({ defaultMessage: 'Gitlab', description: 'HomePage: Gitlab link', id: '7AnwZ7', })} ), }, ]; return ; }; /** * Retrieve a list of links related to Free thematic. * * @returns {JSX.Element} - A list of links. */ const LibreLinks = (): JSX.Element => { const intl = useIntl(); const links: ListItem[] = [ { id: 'free', value: ( {intl.formatMessage({ defaultMessage: 'Free', description: 'HomePage: link to free thematic', id: 'w8GrOf', })} ), }, { id: 'linux', value: ( {intl.formatMessage({ defaultMessage: 'Linux', description: 'HomePage: link to Linux thematic', id: 'jASD7k', })} ), }, ]; return ; }; /** * Retrieve the Shaarli link. * * @returns {JSX.Element} - A list of links */ const ShaarliLink = (): JSX.Element => { const intl = useIntl(); const links: ListItem[] = [ { id: 'shaarli', value: ( {intl.formatMessage({ defaultMessage: 'Shaarli', description: 'HomePage: link to Shaarli', id: 'i5L19t', })} ), }, ]; return ; }; /** * Retrieve the additional links. * * @returns {JSX.Element} - A list of links. */ const MoreLinks = (): JSX.Element => { const intl = useIntl(); const links: ListItem[] = [ { id: 'contact-me', value: ( {intl.formatMessage({ defaultMessage: 'Contact me', description: 'HomePage: contact button text', id: 'sO/Iwj', })} ), }, { id: 'rss-feed', value: ( {intl.formatMessage({ defaultMessage: 'Subscribe', description: 'HomePage: RSS feed subscription text', id: 'T4YA64', })} ), }, ]; return ; }; const StyledColumns = (props: ColumnsProps) => { return ; }; type HomeProps = { recentPosts: ArticleCard[]; translation?: Messages; }; /** * Home page. */ const HomePage: NextPageWithLayout = ({ recentPosts }) => { const intl = useIntl(); 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: CardsListItem[] = recentPosts.map((post) => { return { cover: post.cover, id: post.slug, meta: { publication: { date: post.dates.publication } }, title: post.title, url: `/article/${post.slug}`, }; }); return ( ); }; /** * Create the page sections. * * @param {object} obj - An object containing the section body. * @param {ReactElement[]} obj.children - The section body. * @returns {JSX.Element} A section element. */ const getSection = ({ children, variant, }: { children: ReactElement[]; variant: SectionProps['variant']; }): JSX.Element => { const [headingEl, ...content] = children; const title = headingEl.props.children; return (
); }; const components: NestedMDXComponents = { CodingLinks: CodingLinks, ColdarkRepos: ColdarkRepos, Column: Column, Columns: StyledColumns, Image: ResponsiveImage, LibreLinks: LibreLinks, MoreLinks: MoreLinks, RecentPosts: getRecentPosts, Section: getSection, ShaarliLink: ShaarliLink, }; const { website } = useSettings(); const pageTitle = intl.formatMessage( { defaultMessage: '{websiteName} | Front-end developer: WordPress/React', description: 'HomePage: SEO - Page title', id: 'PXp2hv', }, { websiteName: website.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: website.name } ); const webpageSchema = getWebPageSchema({ description: pageDescription, locale: website.locales.default, slug: '', title: pageTitle, }); const schemaJsonLd = getSchemaJson([webpageSchema]); return ( <> {pageTitle}