aboutsummaryrefslogtreecommitdiffstats
path: root/src/pages/projets
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-10-10 19:37:51 +0200
committerArmand Philippot <git@armandphilippot.com>2023-11-11 18:14:41 +0100
commitc87c615b5866b8a8f361eeb0764bfdea85740e90 (patch)
treec27bda05fd96bbe3154472e170ba1abd5f9ea499 /src/pages/projets
parent15522ec9146f6f1956620355c44dea2a6a75b67c (diff)
refactor(components): replace Meta component with MetaList
It removes items complexity by allowing consumers to use any label/value association. Translations should also be defined by the consumer. Each item can now be configured separately (borders, layout...).
Diffstat (limited to 'src/pages/projets')
-rw-r--r--src/pages/projets/[slug].tsx168
-rw-r--r--src/pages/projets/index.tsx20
2 files changed, 152 insertions, 36 deletions
diff --git a/src/pages/projets/[slug].tsx b/src/pages/projets/[slug].tsx
index 0b94a4e..6ef3df5 100644
--- a/src/pages/projets/[slug].tsx
+++ b/src/pages/projets/[slug].tsx
@@ -14,21 +14,22 @@ import {
getLayout,
Link,
Overview,
- type OverviewMeta,
PageLayout,
Sharing,
SocialLink,
Spinner,
- type MetaData,
Heading,
List,
ListItem,
Figure,
+ type MetaItemData,
+ type MetaValues,
} from '../../components';
import styles from '../../styles/pages/project.module.scss';
import type { NextPageWithLayout, ProjectPreview, Repos } from '../../types';
import { ROUTES } from '../../utils/constants';
import {
+ getFormattedDate,
getSchemaJson,
getSinglePageSchema,
getWebPageSchema,
@@ -166,22 +167,52 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
url: `${website.url}${asPath}`,
};
- const headerMeta: MetaData = {
- publication: { date: dates.publication },
- update:
- dates.update && dates.update !== dates.publication
- ? { date: dates.update }
- : undefined,
+ /**
+ * Retrieve a formatted date (and time).
+ *
+ * @param {string} date - A date string.
+ * @returns {JSX.Element} The formatted date wrapped in a time element.
+ */
+ const getDate = (date: string): JSX.Element => {
+ const isoDate = new Date(`${date}`).toISOString();
+
+ return <time dateTime={isoDate}>{getFormattedDate(date)}</time>;
};
+ const headerMeta: (MetaItemData | undefined)[] = [
+ {
+ id: 'publication-date',
+ label: intl.formatMessage({
+ defaultMessage: 'Published on:',
+ description: 'ProjectsPage: publication date label',
+ id: 'HxZvY4',
+ }),
+ value: getDate(dates.publication),
+ },
+ dates.update && dates.update !== dates.publication
+ ? {
+ id: 'update-date',
+ label: intl.formatMessage({
+ defaultMessage: 'Updated on:',
+ description: 'ProjectsPage: update date label',
+ id: 'wQrvgw',
+ }),
+ value: getDate(dates.update),
+ }
+ : undefined,
+ ];
+ const filteredHeaderMeta = headerMeta.filter(
+ (item): item is MetaItemData => !!item
+ );
+
/**
* Retrieve the repositories links.
*
* @param {Repos} repositories - A repositories object.
- * @returns {JSX.Element[]} - An array of SocialLink.
+ * @returns {MetaValues[]} - An array of meta values.
*/
- const getReposLinks = (repositories: Repos): JSX.Element[] => {
- const links = [];
+ const getReposLinks = (repositories: Repos): MetaValues[] => {
+ const links: MetaValues[] = [];
const githubLabel = intl.formatMessage({
defaultMessage: 'Github profile',
description: 'ProjectsPage: Github profile link',
@@ -194,22 +225,28 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
});
if (repositories.github)
- links.push(
- <SocialLink
- icon="Github"
- label={githubLabel}
- url={repositories.github}
- />
- );
+ links.push({
+ id: 'github',
+ value: (
+ <SocialLink
+ icon="Github"
+ label={githubLabel}
+ url={repositories.github}
+ />
+ ),
+ });
if (repositories.gitlab)
- links.push(
- <SocialLink
- icon="Gitlab"
- label={gitlabLabel}
- url={repositories.gitlab}
- />
- );
+ links.push({
+ id: 'gitlab',
+ value: (
+ <SocialLink
+ icon="Gitlab"
+ label={gitlabLabel}
+ url={repositories.gitlab}
+ />
+ ),
+ });
return links;
};
@@ -254,14 +291,75 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
);
};
- const overviewData: OverviewMeta = {
- creation: { date: data.created_at },
- update: { date: data.updated_at },
- license,
- popularity: repos?.github && getRepoPopularity(repos.github),
- repositories: repos ? getReposLinks(repos) : undefined,
- technologies,
- };
+ const overviewMeta: (MetaItemData | undefined)[] = [
+ {
+ id: 'creation-date',
+ label: intl.formatMessage({
+ defaultMessage: 'Created on:',
+ description: 'ProjectsPage: creation date label',
+ id: 'wVFA4m',
+ }),
+ value: getDate(data.created_at),
+ },
+ {
+ id: 'update-date',
+ label: intl.formatMessage({
+ defaultMessage: 'Updated on:',
+ description: 'ProjectsPage: update date label',
+ id: 'wQrvgw',
+ }),
+ value: getDate(data.updated_at),
+ },
+ license
+ ? {
+ id: 'license',
+ label: intl.formatMessage({
+ defaultMessage: 'License:',
+ description: 'ProjectsPage: license label',
+ id: 'VtYzuv',
+ }),
+ value: license,
+ }
+ : undefined,
+ repos?.github
+ ? {
+ id: 'popularity',
+ label: intl.formatMessage({
+ defaultMessage: 'Popularity:',
+ description: 'ProjectsPage: popularity label',
+ id: 'KrNvQi',
+ }),
+ value: getRepoPopularity(repos.github),
+ }
+ : undefined,
+ repos
+ ? {
+ id: 'repositories',
+ label: intl.formatMessage({
+ defaultMessage: 'Repositories:',
+ description: 'ProjectsPage: repositories label',
+ id: 'iDIKb7',
+ }),
+ value: getReposLinks(repos),
+ }
+ : undefined,
+ technologies
+ ? {
+ id: 'technologies',
+ label: intl.formatMessage({
+ defaultMessage: 'Technologies:',
+ description: 'ProjectsPage: technologies label',
+ id: 'RwNZ6p',
+ }),
+ value: technologies.map((techno) => {
+ return { id: techno, value: techno };
+ }),
+ }
+ : undefined,
+ ];
+ const filteredOverviewMeta = overviewMeta.filter(
+ (item): item is MetaItemData => !!item
+ );
const webpageSchema = getWebPageSchema({
description: seo.description,
@@ -306,7 +404,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
intro={intro}
breadcrumb={breadcrumbItems}
breadcrumbSchema={breadcrumbSchema}
- headerMeta={headerMeta}
+ headerMeta={filteredHeaderMeta}
withToC={true}
widgets={[
<Sharing
@@ -325,7 +423,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
/>,
]}
>
- <Overview cover={cover} meta={overviewData} />
+ <Overview cover={cover} meta={filteredOverviewMeta} />
<ProjectContent components={components} />
</PageLayout>
</>
diff --git a/src/pages/projets/index.tsx b/src/pages/projets/index.tsx
index 97963dd..44354ce 100644
--- a/src/pages/projets/index.tsx
+++ b/src/pages/projets/index.tsx
@@ -1,8 +1,10 @@
+/* eslint-disable max-statements */
import type { MDXComponents } from 'mdx/types';
import type { GetStaticProps } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
import Script from 'next/script';
+import { useIntl } from 'react-intl';
import {
CardsList,
type CardsListItem,
@@ -44,6 +46,12 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => {
title,
url: ROUTES.PROJECTS,
});
+ const intl = useIntl();
+ const metaLabel = intl.formatMessage({
+ defaultMessage: 'Technologies:',
+ description: 'Meta: technologies label',
+ id: 'ADQmDF',
+ });
const items: CardsListItem[] = projects.map(
({ id, meta: projectMeta, slug, title: projectTitle }) => {
@@ -52,7 +60,17 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => {
return {
cover,
id: id as string,
- meta: { technologies },
+ meta: technologies?.length
+ ? [
+ {
+ id: 'technologies',
+ label: metaLabel,
+ value: technologies.map((techno) => {
+ return { id: techno, value: techno };
+ }),
+ },
+ ]
+ : [],
tagline,
title: projectTitle,
url: `${ROUTES.PROJECTS}/${slug}`,