summaryrefslogtreecommitdiffstats
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/PostHeader/PostHeader.tsx82
-rw-r--r--src/components/PostMeta/PostMeta.module.scss51
-rw-r--r--src/components/PostMeta/PostMeta.tsx102
-rw-r--r--src/components/PostPreview/PostPreview.tsx15
4 files changed, 138 insertions, 112 deletions
diff --git a/src/components/PostHeader/PostHeader.tsx b/src/components/PostHeader/PostHeader.tsx
index 3ee6705..e445b58 100644
--- a/src/components/PostHeader/PostHeader.tsx
+++ b/src/components/PostHeader/PostHeader.tsx
@@ -1,71 +1,37 @@
-import { t } from '@lingui/macro';
-import { Dates } from '@ts/types/app';
-import { ArticleAuthor } from '@ts/types/articles';
-import { ThematicPreview } from '@ts/types/taxonomies';
-import Link from 'next/link';
-import { useRouter } from 'next/router';
+import PostMeta from '@components/PostMeta/PostMeta';
+import { ArticleMeta } from '@ts/types/articles';
+import { Cover } from '@ts/types/cover';
+import Image from 'next/image';
import styles from './PostHeader.module.scss';
const PostHeader = ({
- author,
- dates,
+ cover,
intro,
title,
- thematics,
+ meta,
}: {
- author: ArticleAuthor;
- dates: Dates;
+ cover?: Cover;
intro: string;
+ meta?: ArticleMeta;
title: string;
- thematics: ThematicPreview[];
}) => {
- const { locale } = useRouter();
-
- const getAuthor = () => {
- return author.firstName
- ? `${author.firstName} ${author.lastName}`
- : author.name;
- };
-
- const getLocaleDate = (date: string) => {
- const dateOptions: Intl.DateTimeFormatOptions = {
- day: 'numeric',
- month: 'long',
- year: 'numeric',
- };
- return new Date(date).toLocaleDateString(locale, dateOptions);
- };
-
- const getThematics = () => {
- return thematics.map((thematic) => {
- return (
- <dd key={thematic.id}>
- <Link href={`/thematique/${thematic.slug}`}>
- <a>{thematic.title}</a>
- </Link>
- </dd>
- );
- });
- };
-
return (
- <header>
- <h1>{title}</h1>
- <ul className={styles.meta}>
- <li>{t`Written by ${getAuthor()} on ${getLocaleDate(
- dates.publication
- )}.`}</li>
- <li>{t`Last update on ${getLocaleDate(dates.update)}.`}</li>
- {thematics.length > 0 && (
- <li>
- <dl>
- <dt className={styles.label}>{t`Posted in:`}</dt>
- {getThematics()}
- </dl>
- </li>
- )}
- </ul>
- <div dangerouslySetInnerHTML={{ __html: intro }}></div>
+ <header className={styles.wrapper}>
+ <div className={styles.body}>
+ <h1 className={styles.title}>
+ {cover && (
+ <span className={styles.cover}>
+ <Image src={cover.sourceUrl} alt={cover.altText} layout="fill" />
+ </span>
+ )}
+ {title}
+ </h1>
+ {meta && <PostMeta mode="single" meta={meta} />}
+ <div
+ className={styles.intro}
+ dangerouslySetInnerHTML={{ __html: intro }}
+ ></div>
+ </div>
</header>
);
};
diff --git a/src/components/PostMeta/PostMeta.module.scss b/src/components/PostMeta/PostMeta.module.scss
index 3ec7daf..ac25828 100644
--- a/src/components/PostMeta/PostMeta.module.scss
+++ b/src/components/PostMeta/PostMeta.module.scss
@@ -2,17 +2,50 @@
@use "@styles/abstracts/mixins" as mix;
.wrapper {
- display: grid;
- grid-template-columns: repeat(2, minmax(0, 1fr));
- margin-top: var(--spacing-md);
- font-size: var(--font-size-sm);
+ &--list {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ margin-top: var(--spacing-md);
+ font-size: var(--font-size-sm);
- @include mix.media("screen") {
- @include mix.dimensions("sm") {
+ @include mix.media("screen") {
+ @include mix.dimensions("sm") {
+ display: flex;
+ flex-flow: column nowrap;
+ margin: 0;
+ composes: meta from "@components/PostPreview/PostPreview.module.scss";
+ }
+ }
+ }
+
+ &--single {
+ flex-flow: column wrap;
+ margin: 0;
+ padding: 0 var(--spacing-md);
+
+ @include mix.media("screen") {
+ @include mix.dimensions("xs") {
+ font-size: var(--font-size-sm);
+ }
+ }
+
+ .item {
display: flex;
- flex-flow: column nowrap;
- margin: 0;
- composes: meta from "@components/PostPreview/PostPreview.module.scss";
+ flex-flow: row wrap;
+ }
+
+ .term {
+ margin-right: var(--spacing-2xs);
+ color: var(--color-primary-darker);
+ }
+
+ .description {
+ &:not(:first-of-type) {
+ &::before {
+ content: "/";
+ margin: 0 var(--spacing-2xs);
+ }
+ }
}
}
}
diff --git a/src/components/PostMeta/PostMeta.tsx b/src/components/PostMeta/PostMeta.tsx
index 776d912..6d40048 100644
--- a/src/components/PostMeta/PostMeta.tsx
+++ b/src/components/PostMeta/PostMeta.tsx
@@ -1,20 +1,19 @@
import { t } from '@lingui/macro';
-import { ThematicPreview } from '@ts/types/taxonomies';
+import { ArticleMeta } from '@ts/types/articles';
import Link from 'next/link';
import { useRouter } from 'next/router';
import styles from './PostMeta.module.scss';
+type PostMetaMode = 'list' | 'single';
+
const PostMeta = ({
- commentCount,
- publicationDate,
- updateDate,
- thematics,
+ meta,
+ mode = 'list',
}: {
- commentCount: number | null;
- publicationDate: string;
- updateDate: string;
- thematics: ThematicPreview[];
+ meta: ArticleMeta;
+ mode?: PostMetaMode;
}) => {
+ const { author, commentCount, dates, thematics, website } = meta;
const { locale } = useRouter();
const dateOptions: Intl.DateTimeFormatOptions = {
day: 'numeric',
@@ -23,20 +22,22 @@ const PostMeta = ({
};
const getThematics = () => {
- return thematics.map((thematic) => {
- return (
- <dd key={thematic.id}>
- <Link href={`/thematique/${thematic.slug}`}>
- <a>{thematic.title}</a>
- </Link>
- </dd>
- );
- });
+ return (
+ thematics &&
+ thematics.map((thematic) => {
+ return (
+ <dd key={thematic.id} className={styles.description}>
+ <Link href={`/thematique/${thematic.slug}`}>
+ <a>{thematic.title}</a>
+ </Link>
+ </dd>
+ );
+ })
+ );
};
const getCommentsCount = () => {
switch (commentCount) {
- case null:
case 0:
return t`No comments`;
case 1:
@@ -46,32 +47,57 @@ const PostMeta = ({
}
};
+ const wrapperClass = styles[`wrapper--${mode}`];
+
return (
- <dl className={styles.wrapper}>
- <div>
- <dt>{t`Published on`}</dt>
- <dd>
- {new Date(publicationDate).toLocaleDateString(locale, dateOptions)}
- </dd>
- </div>
- {publicationDate !== updateDate && (
- <div>
- <dt>{t`Updated on`}</dt>
- <dd>
- {new Date(updateDate).toLocaleDateString(locale, dateOptions)}
+ <dl className={wrapperClass}>
+ {author && (
+ <div className={styles.item}>
+ <dt className={styles.term}>{t`Written by`}</dt>
+ <dd className={styles.description}>{author.name}</dd>
+ </div>
+ )}
+ {dates && (
+ <div className={styles.item}>
+ <dt className={styles.term}>{t`Published on`}</dt>
+ <dd className={styles.description}>
+ {new Date(dates.publication).toLocaleDateString(
+ locale,
+ dateOptions
+ )}
</dd>
</div>
)}
- {thematics.length > 0 && (
- <div>
- <dt>{thematics.length > 1 ? t`Thematics` : t`Thematic`}</dt>
+ {dates && dates.publication !== dates.update && (
+ <div className={styles.item}>
+ <dt className={styles.term}>{t`Updated on`}</dt>
+ <dd className={styles.description}>
+ {new Date(dates.update).toLocaleDateString(locale, dateOptions)}
+ </dd>
+ </div>
+ )}
+ {thematics && thematics.length > 0 && (
+ <div className={styles.item}>
+ <dt className={styles.term}>
+ {thematics.length > 1 ? t`Thematics` : t`Thematic`}
+ </dt>
{getThematics()}
</div>
)}
- <div>
- <dt>{t`Comments`}</dt>
- {getCommentsCount()}
- </div>
+ {website && (
+ <div className={styles.item}>
+ <dt className={styles.term}>{t`Website`}</dt>
+ <dd className={styles.description}>
+ <a href={website}>{website}</a>
+ </dd>
+ </div>
+ )}
+ {commentCount !== undefined && (
+ <div className={styles.item}>
+ <dt className={styles.term}>{t`Comments`}</dt>
+ {getCommentsCount()}
+ </div>
+ )}
</dl>
);
};
diff --git a/src/components/PostPreview/PostPreview.tsx b/src/components/PostPreview/PostPreview.tsx
index ccbb9e5..fa8bfd0 100644
--- a/src/components/PostPreview/PostPreview.tsx
+++ b/src/components/PostPreview/PostPreview.tsx
@@ -1,6 +1,6 @@
import PostMeta from '@components/PostMeta/PostMeta';
import { t } from '@lingui/macro';
-import { ArticlePreview } from '@ts/types/articles';
+import { ArticleMeta, ArticlePreview } from '@ts/types/articles';
import Link from 'next/link';
import styles from './PostPreview.module.scss';
import Image from 'next/image';
@@ -18,6 +18,12 @@ const PostPreview = ({
}) => {
const TitleTag = `h${titleLevel}` as keyof JSX.IntrinsicElements;
+ const meta: ArticleMeta = {
+ commentCount: post.commentCount ? post.commentCount : 0,
+ dates: post.dates,
+ thematics: post.thematics,
+ };
+
return (
<article className={styles.wrapper}>
{post.featuredImage && Object.keys(post.featuredImage).length > 0 && (
@@ -55,12 +61,7 @@ const PostPreview = ({
<ArrowIcon />
</ButtonLink>
</footer>
- <PostMeta
- commentCount={post.commentCount}
- publicationDate={post.dates.publication}
- updateDate={post.dates.update}
- thematics={post.thematics}
- />
+ <PostMeta meta={meta} />
</article>
);
};