aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/PostPreview/PostPreview.module.scss1
-rw-r--r--src/components/PostPreview/PostPreview.tsx8
-rw-r--r--src/components/PostsList/PostsList.module.scss2
-rw-r--r--src/components/PostsList/PostsList.tsx40
-rw-r--r--src/pages/blog/index.tsx2
-rw-r--r--src/ts/types/articles.ts4
-rw-r--r--src/ts/types/cover.ts4
-rw-r--r--src/utils/helpers/sort.ts19
8 files changed, 55 insertions, 25 deletions
diff --git a/src/components/PostPreview/PostPreview.module.scss b/src/components/PostPreview/PostPreview.module.scss
index d188b18..ccdae9b 100644
--- a/src/components/PostPreview/PostPreview.module.scss
+++ b/src/components/PostPreview/PostPreview.module.scss
@@ -101,6 +101,7 @@
.header {
grid-column: 1;
grid-row: 1;
+ align-self: center;
}
.meta {
diff --git a/src/components/PostPreview/PostPreview.tsx b/src/components/PostPreview/PostPreview.tsx
index 8f3e0da..3dfef73 100644
--- a/src/components/PostPreview/PostPreview.tsx
+++ b/src/components/PostPreview/PostPreview.tsx
@@ -6,13 +6,17 @@ import ArrowRightIcon from '@assets/images/icon-arrow-right.svg';
import styles from './PostPreview.module.scss';
import Image from 'next/image';
+type TitleLevel = 2 | 3 | 4 | 5 | 6;
+
const PostPreview = ({
post,
- TitleTag,
+ titleLevel,
}: {
post: ArticlePreview;
- TitleTag: keyof JSX.IntrinsicElements;
+ titleLevel: TitleLevel;
}) => {
+ const TitleTag = `h${titleLevel}` as keyof JSX.IntrinsicElements;
+
return (
<article className={styles.wrapper}>
{post.featuredImage && (
diff --git a/src/components/PostsList/PostsList.module.scss b/src/components/PostsList/PostsList.module.scss
index fe63cbc..0b9aa2d 100644
--- a/src/components/PostsList/PostsList.module.scss
+++ b/src/components/PostsList/PostsList.module.scss
@@ -1,6 +1,6 @@
@use "@styles/abstracts/placeholders";
-.wrapper {
+.list {
@extend %reset-ordered-list;
margin: var(--spacing-md) auto;
diff --git a/src/components/PostsList/PostsList.tsx b/src/components/PostsList/PostsList.tsx
index 31cdbf6..6e56c24 100644
--- a/src/components/PostsList/PostsList.tsx
+++ b/src/components/PostsList/PostsList.tsx
@@ -6,11 +6,11 @@ import { PostsList as PostsListData } from '@ts/types/blog';
import styles from './PostsList.module.scss';
import PostPreview from '@components/PostPreview/PostPreview';
import { Button } from '@components/Buttons';
+import { Fragment } from 'react';
+import { sortPostsByYear } from '@utils/helpers/sort';
-type TitleLevel = 2 | 3 | 4 | 5 | 6;
-
-const PostsList = ({ titleLevel }: { titleLevel: TitleLevel }) => {
- const TitleTag = `h${titleLevel}` as keyof JSX.IntrinsicElements;
+const PostsList = ({ showYears }: { showYears: boolean }) => {
+ const titleLevel = showYears ? 3 : 2;
const getKey = (pageIndex: number, previousData: PostsListData) => {
if (previousData && !previousData.posts) return null;
@@ -40,18 +40,24 @@ const PostsList = ({ titleLevel }: { titleLevel: TitleLevel }) => {
if (!data) return <div>{t`Loading...`}</div>;
const getPostsList = () => {
- return data.map((page) => {
- if (page.posts.length === 0) {
- return t`No results found.`;
- } else {
- return page.posts.map((post) => {
- return (
- <li key={post.id} className={styles.item}>
- <PostPreview post={post} TitleTag={TitleTag} />
- </li>
- );
- });
- }
+ const posts = sortPostsByYear(data);
+ const years = Object.keys(posts).reverse();
+
+ return years.map((year) => {
+ return (
+ <Fragment key={year}>
+ {showYears && <h2>{year}</h2>}
+ <ol className={styles.list}>
+ {posts[year].map((post) => {
+ return (
+ <li key={post.id} className={styles.item}>
+ <PostPreview post={post} titleLevel={titleLevel} />
+ </li>
+ );
+ })}
+ </ol>
+ </Fragment>
+ );
});
};
@@ -59,7 +65,7 @@ const PostsList = ({ titleLevel }: { titleLevel: TitleLevel }) => {
return (
<>
- <ol className={styles.wrapper}>{getPostsList()}</ol>
+ {getPostsList()}
{hasNextPage && (
<Button
isDisabled={isLoadingMore}
diff --git a/src/pages/blog/index.tsx b/src/pages/blog/index.tsx
index 083ad97..1c3a5d9 100644
--- a/src/pages/blog/index.tsx
+++ b/src/pages/blog/index.tsx
@@ -21,7 +21,7 @@ const Blog: NextPageWithLayout<BlogPageProps> = ({ fallback }) => {
</Head>
<h1>{t`Blog`}</h1>
<SWRConfig value={{ fallback }}>
- <PostsList titleLevel={2} />
+ <PostsList showYears={true} />
</SWRConfig>
</>
);
diff --git a/src/ts/types/articles.ts b/src/ts/types/articles.ts
index 91703a2..0bb85c8 100644
--- a/src/ts/types/articles.ts
+++ b/src/ts/types/articles.ts
@@ -19,7 +19,7 @@ export type ArticlePreviewResponse = {
};
databaseId: number;
date: string;
- featuredImage: CoverResponse | null;
+ featuredImage: CoverResponse;
id: string;
modified: string;
slug: string;
@@ -31,7 +31,7 @@ export type ArticlePreview = {
content: string;
databaseId: number;
date: ArticleDates;
- featuredImage?: Cover | object;
+ featuredImage: Cover | null;
id: string;
slug: string;
subjects: SubjectPreview[] | [];
diff --git a/src/ts/types/cover.ts b/src/ts/types/cover.ts
index 165a26f..2a565ef 100644
--- a/src/ts/types/cover.ts
+++ b/src/ts/types/cover.ts
@@ -2,8 +2,8 @@ export type Cover = {
altText: string;
sourceUrl: string;
title: string;
-};
+} | null;
export type CoverResponse = {
node: Cover;
-};
+} | null;
diff --git a/src/utils/helpers/sort.ts b/src/utils/helpers/sort.ts
new file mode 100644
index 0000000..ade82d0
--- /dev/null
+++ b/src/utils/helpers/sort.ts
@@ -0,0 +1,19 @@
+import { ArticlePreview } from '@ts/types/articles';
+import { PostsList } from '@ts/types/blog';
+
+type YearCollection = {
+ [key: string]: ArticlePreview[];
+};
+
+export const sortPostsByYear = (data: PostsList[]) => {
+ const yearCollection: YearCollection = {};
+
+ data.forEach((page) => {
+ page.posts.forEach((post) => {
+ const postYear = new Date(post.date.publication).getFullYear().toString();
+ yearCollection[postYear] = [...(yearCollection[postYear] || []), post];
+ });
+ });
+
+ return yearCollection;
+};