import { MDXComponents } 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: MDXComponents = {
CodingLinks,
ColdarkRepos,
Column,
Columns: StyledColumns,
Image: ResponsiveImage,
LibreLinks,
MoreLinks,
RecentPosts: getRecentPosts,
Section: getSection,
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}
>
);
};
HomePage.getLayout = (page) =>
getLayout(page, { isHome: true, withExtraPadding: false });
export const getStaticProps: GetStaticProps = async ({ locale }) => {
const translation = await loadTranslation(locale);
const recentPosts = await getArticlesCard({ first: 3 });
return {
props: {
recentPosts,
translation,
},
};
};
export default HomePage;