aboutsummaryrefslogtreecommitdiffstats
path: root/src/pages/projets
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-11-20 12:27:46 +0100
committerArmand Philippot <git@armandphilippot.com>2023-11-20 19:32:09 +0100
commit70b4f633a6fbedb58c8b9134ac64ede854d489de (patch)
treec757bb12ad9a588e23b25cdb8b46710ac14dbcb1 /src/pages/projets
parent9a481f066e1427d53a06cf7aeec525a745abf03f (diff)
refactor(components): replace PageLayout template with Page
* split pages in smaller components (it is both easier to maintain and more readable, we avoid the use of fragments in pages directory) * extract breadcrumbs from article tag (the navigation is not related to the page contents) * remove useReadingTime hook * remove layout options except `isHome`
Diffstat (limited to 'src/pages/projets')
-rw-r--r--src/pages/projets/[slug].tsx112
-rw-r--r--src/pages/projets/index.tsx28
2 files changed, 72 insertions, 68 deletions
diff --git a/src/pages/projets/[slug].tsx b/src/pages/projets/[slug].tsx
index a8a4fea..82d9149 100644
--- a/src/pages/projets/[slug].tsx
+++ b/src/pages/projets/[slug].tsx
@@ -12,20 +12,21 @@ import {
Code,
getLayout,
Link,
- PageLayout,
SharingWidget,
Spinner,
Heading,
List,
ListItem,
Figure,
- Time,
Grid,
ProjectOverview,
type ProjectMeta,
type Repository,
- MetaList,
- MetaItem,
+ Page,
+ PageHeader,
+ PageSidebar,
+ TocWidget,
+ PageBody,
} from '../../components';
import styles from '../../styles/pages/project.module.scss';
import type { NextPageWithLayout, ProjectPreview, Repos } from '../../types';
@@ -42,7 +43,11 @@ import {
loadTranslation,
type Messages,
} from '../../utils/helpers/server';
-import { useBreadcrumb, useGithubApi } from '../../utils/hooks';
+import {
+ useBreadcrumb,
+ useGithubApi,
+ useHeadingsTree,
+} from '../../utils/hooks';
const BorderedImage = (props: NextImageProps) => (
<Figure hasBorders>
@@ -164,6 +169,7 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
title,
url: `${ROUTES.PROJECTS}/${id}`,
});
+ const { ref, tree } = useHeadingsTree({ fromLevel: 2 });
const ProjectContent: ComponentType<MDXComponents> = dynamic(
async () => import(`../../content/projects/${id}.mdx`),
@@ -269,9 +275,14 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
id: 'HKKkQk',
description: 'SharingWidget: widget title',
});
+ const tocTitle = intl.formatMessage({
+ defaultMessage: 'Table of Contents',
+ description: 'PageLayout: table of contents title',
+ id: 'eys2uX',
+ });
return (
- <>
+ <Page breadcrumbs={breadcrumbItems} isBodyLastChild>
<Head>
<title>{page.title}</title>
{/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */}
@@ -289,67 +300,54 @@ const ProjectPage: NextPageWithLayout<ProjectPageProps> = ({ project }) => {
// eslint-disable-next-line react/no-danger -- Necessary for schema
dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
/>
- <PageLayout
- title={title}
+ <Script
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
+ // eslint-disable-next-line react/jsx-no-literals -- Id allowed
+ id="schema-breadcrumb"
+ type="application/ld+json"
+ />
+ <PageHeader
+ heading={title}
intro={intro}
- breadcrumb={breadcrumbItems}
- breadcrumbSchema={breadcrumbSchema}
- headerMeta={
- <MetaList>
- <MetaItem
- isInline
- label={intl.formatMessage({
- defaultMessage: 'Published on:',
- description: 'Page: publication date label',
- id: '4QbTDq',
- })}
- value={<Time date={dates.publication} />}
- />
- {dates.update ? (
- <MetaItem
- isInline
- label={intl.formatMessage({
- defaultMessage: 'Updated on:',
- description: 'Page: update date label',
- id: 'Ez8Qim',
- })}
- value={<Time date={dates.update} />}
- />
- ) : null}
- </MetaList>
- }
- withToC={true}
- widgets={[
- <SharingWidget
- // eslint-disable-next-line react/jsx-no-literals -- Key allowed
- key="sharing-widget"
- data={{ excerpt: intro, title, url: page.url }}
- heading={<Heading level={3}>{sharingWidgetTitle}</Heading>}
- media={[
- 'diaspora',
- 'email',
- 'facebook',
- 'journal-du-hacker',
- 'linkedin',
- 'twitter',
- ]}
- className={styles.widget}
- />,
- ]}
- >
+ meta={{
+ publicationDate: dates.publication,
+ updateDate: dates.update,
+ }}
+ />
+ <PageSidebar>
+ <TocWidget
+ heading={<Heading level={3}>{tocTitle}</Heading>}
+ tree={tree}
+ />
+ </PageSidebar>
+ <PageBody ref={ref}>
<ProjectOverview
cover={cover ? <NextImage {...cover} /> : undefined}
meta={overviewMeta}
name={project.title}
/>
<ProjectContent components={components} />
- </PageLayout>
- </>
+ </PageBody>
+ <PageSidebar>
+ <SharingWidget
+ data={{ excerpt: intro, title, url: page.url }}
+ heading={<Heading level={3}>{sharingWidgetTitle}</Heading>}
+ media={[
+ 'diaspora',
+ 'email',
+ 'facebook',
+ 'journal-du-hacker',
+ 'linkedin',
+ 'twitter',
+ ]}
+ className={styles.widget}
+ />
+ </PageSidebar>
+ </Page>
);
};
-ProjectPage.getLayout = (page) =>
- getLayout(page, { useGrid: true, withExtraPadding: true });
+ProjectPage.getLayout = (page) => getLayout(page);
export const getStaticProps: GetStaticProps<ProjectPageProps> = async ({
locale,
diff --git a/src/pages/projets/index.tsx b/src/pages/projets/index.tsx
index 8feb701..0b9a91c 100644
--- a/src/pages/projets/index.tsx
+++ b/src/pages/projets/index.tsx
@@ -18,8 +18,10 @@ import {
type GridItem,
Link,
MetaList,
- PageLayout,
MetaItem,
+ Page,
+ PageHeader,
+ PageBody,
} from '../../components';
import PageContent, { meta } from '../../content/pages/projects.mdx';
import styles from '../../styles/pages/projects.module.scss';
@@ -139,7 +141,7 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => {
};
return (
- <>
+ <Page breadcrumbs={breadcrumbItems} isBodyLastChild>
<Head>
<title>{page.title}</title>
{/*eslint-disable-next-line react/jsx-no-literals -- Name allowed */}
@@ -157,12 +159,17 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => {
// eslint-disable-next-line react/no-danger -- Necessary for schema
dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaJsonLd) }}
/>
- <PageLayout
- title={title}
+ <Script
+ dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbSchema) }}
+ // eslint-disable-next-line react/jsx-no-literals -- Id allowed
+ id="schema-breadcrumb"
+ type="application/ld+json"
+ />
+ <PageHeader
+ heading={title}
intro={<PageContent components={components} />}
- breadcrumb={breadcrumbItems}
- breadcrumbSchema={breadcrumbSchema}
- >
+ />
+ <PageBody className={styles.body}>
<Grid
className={styles.list}
gap="sm"
@@ -170,13 +177,12 @@ const ProjectsPage: NextPageWithLayout<ProjectsPageProps> = ({ projects }) => {
items={items}
sizeMax="30ch"
/>
- </PageLayout>
- </>
+ </PageBody>
+ </Page>
);
};
-ProjectsPage.getLayout = (page) =>
- getLayout(page, { useGrid: true, withExtraPadding: true });
+ProjectsPage.getLayout = (page) => getLayout(page);
export const getStaticProps: GetStaticProps<ProjectsPageProps> = async ({
locale,