summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/PostFooter/PostFooter.module.scss5
-rw-r--r--src/components/PostFooter/PostFooter.tsx35
-rw-r--r--src/components/PostHeader/PostHeader.module.scss7
-rw-r--r--src/components/PostHeader/PostHeader.tsx72
-rw-r--r--src/pages/article/[slug].tsx21
-rw-r--r--src/services/graphql/post.ts9
-rw-r--r--src/ts/types/articles.ts10
7 files changed, 153 insertions, 6 deletions
diff --git a/src/components/PostFooter/PostFooter.module.scss b/src/components/PostFooter/PostFooter.module.scss
new file mode 100644
index 0000000..e80f5ed
--- /dev/null
+++ b/src/components/PostFooter/PostFooter.module.scss
@@ -0,0 +1,5 @@
+@use "@styles/abstracts/placeholders";
+
+.list {
+ @extend %flex-list;
+}
diff --git a/src/components/PostFooter/PostFooter.tsx b/src/components/PostFooter/PostFooter.tsx
new file mode 100644
index 0000000..8c09d69
--- /dev/null
+++ b/src/components/PostFooter/PostFooter.tsx
@@ -0,0 +1,35 @@
+import { t } from '@lingui/macro';
+import { SubjectPreview } from '@ts/types/taxonomies';
+import Link from 'next/link';
+import styles from './PostFooter.module.scss';
+
+const PostFooter = ({ subjects }: { subjects: SubjectPreview[] }) => {
+ const getSubjects = () => {
+ return subjects.map((subject) => {
+ return (
+ <li key={subject.id}>
+ <Link href={`/sujet/${subject.slug}`}>
+ <a>{subject.title}</a>
+ </Link>
+ </li>
+ );
+ });
+ };
+
+ return (
+ <footer>
+ {subjects.length > 0 && (
+ <>
+ <dl className={styles.meta}>
+ <dt>{t`Subjects:`}</dt>
+ <dd>
+ <ul className={styles.list}>{getSubjects()}</ul>
+ </dd>
+ </dl>
+ </>
+ )}
+ </footer>
+ );
+};
+
+export default PostFooter;
diff --git a/src/components/PostHeader/PostHeader.module.scss b/src/components/PostHeader/PostHeader.module.scss
new file mode 100644
index 0000000..f013651
--- /dev/null
+++ b/src/components/PostHeader/PostHeader.module.scss
@@ -0,0 +1,7 @@
+.meta {
+ font-size: var(--font-size-sm);
+}
+
+.label {
+ font-weight: inherit;
+}
diff --git a/src/components/PostHeader/PostHeader.tsx b/src/components/PostHeader/PostHeader.tsx
new file mode 100644
index 0000000..5c5aff4
--- /dev/null
+++ b/src/components/PostHeader/PostHeader.tsx
@@ -0,0 +1,72 @@
+import { t } from '@lingui/macro';
+import { ArticleAuthor, ArticleDates } from '@ts/types/articles';
+import { ThematicPreview } from '@ts/types/taxonomies';
+import Link from 'next/link';
+import { useRouter } from 'next/router';
+import styles from './PostHeader.module.scss';
+
+const PostHeader = ({
+ author,
+ date,
+ intro,
+ title,
+ thematics,
+}: {
+ author: ArticleAuthor;
+ date: ArticleDates;
+ intro: string;
+ 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(
+ date.publication
+ )}.`}</li>
+ <li>{t`Last update on ${getLocaleDate(date.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>
+ );
+};
+
+export default PostHeader;
diff --git a/src/pages/article/[slug].tsx b/src/pages/article/[slug].tsx
index b3ab2ed..57982e9 100644
--- a/src/pages/article/[slug].tsx
+++ b/src/pages/article/[slug].tsx
@@ -1,5 +1,7 @@
import CommentsList from '@components/CommentsList/CommentsList';
import Layout from '@components/Layouts/Layout';
+import PostFooter from '@components/PostFooter/PostFooter';
+import PostHeader from '@components/PostHeader/PostHeader';
import { t } from '@lingui/macro';
import { fetchAllPostsSlug } from '@services/graphql/blog';
import { getPostBySlug } from '@services/graphql/post';
@@ -11,16 +13,23 @@ import { ParsedUrlQuery } from 'querystring';
import { ReactElement } from 'react';
const SingleArticle: NextPageWithLayout<ArticleProps> = ({ post }) => {
+ const { author, comments, content, date, intro, subjects, thematics, title } =
+ post;
+
return (
<article>
- <header>
- <h1>{post.title}</h1>
- <div dangerouslySetInnerHTML={{ __html: post.intro }}></div>
- </header>
- <div dangerouslySetInnerHTML={{ __html: post.content }}></div>
+ <PostHeader
+ author={author}
+ date={date}
+ intro={intro}
+ title={title}
+ thematics={thematics}
+ />
+ <div dangerouslySetInnerHTML={{ __html: content }}></div>
+ <PostFooter subjects={subjects} />
<section>
<h2>{t`Comments`}</h2>
- <CommentsList comments={post.comments} />
+ <CommentsList comments={comments} />
</section>
</article>
);
diff --git a/src/services/graphql/post.ts b/src/services/graphql/post.ts
index e827fd4..cc6232a 100644
--- a/src/services/graphql/post.ts
+++ b/src/services/graphql/post.ts
@@ -35,6 +35,13 @@ const fetchPostBySlug: FetchPostByReturn = async (slug: string) => {
}
}
}
+ author {
+ node {
+ firstName
+ lastName
+ name
+ }
+ }
commentCount
comments {
nodes {
@@ -104,6 +111,7 @@ const fetchPostBySlug: FetchPostByReturn = async (slug: string) => {
export const getPostBySlug: GetPostByReturn = async (slug: string) => {
const rawPost = await fetchPostBySlug(slug);
+ const author = rawPost.postBy.author.node;
const comments = rawPost.postBy.comments.nodes.reverse().map((comment) => {
const author = comment.author.node;
return { ...comment, author: author, replies: [] };
@@ -126,6 +134,7 @@ export const getPostBySlug: GetPostByReturn = async (slug: string) => {
const formattedPost: Article = {
...rawPost.postBy,
+ author,
comments,
content,
featuredImage,
diff --git a/src/ts/types/articles.ts b/src/ts/types/articles.ts
index 0bb85c8..afaa3e3 100644
--- a/src/ts/types/articles.ts
+++ b/src/ts/types/articles.ts
@@ -8,6 +8,12 @@ export type ArticleDates = {
update: string;
};
+export type ArticleAuthor = {
+ firstName: string;
+ lastName: string;
+ name: string;
+};
+
export type ArticlePreviewResponse = {
acfPosts: {
postsInSubject: SubjectPreview[] | null;
@@ -40,6 +46,9 @@ export type ArticlePreview = {
};
export type ArticleResponse = ArticlePreviewResponse & {
+ author: {
+ node: ArticleAuthor;
+ };
comments: CommentsResponse;
contentParts: {
afterMore: string;
@@ -48,6 +57,7 @@ export type ArticleResponse = ArticlePreviewResponse & {
};
export type Article = ArticlePreview & {
+ author: ArticleAuthor;
comments: Comment[];
intro: string;
seo: SEO;