mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-01 10:22:30 +02:00
91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
/**
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
import React from 'react';
|
|
import Layout from '@theme/Layout';
|
|
import Link from '@docusaurus/Link';
|
|
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
|
|
import {translate} from '@docusaurus/Translate';
|
|
|
|
type YearProp = {
|
|
year: string;
|
|
posts: ArchiveBlogPost[];
|
|
};
|
|
|
|
function Year({year, posts}: YearProp) {
|
|
return (
|
|
<>
|
|
<h3>{year}</h3>
|
|
<ul>
|
|
{posts.map((post) => (
|
|
<li key={post.metadata.date}>
|
|
<Link to={post.metadata.permalink}>
|
|
{post.metadata.formattedDate} - {post.metadata.title}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function YearsSection({years}: {years: YearProp[]}) {
|
|
return (
|
|
<section className="margin-vert--lg">
|
|
<div className="container">
|
|
<div className="row">
|
|
{years.map((_props, idx) => (
|
|
<div key={idx} className="col col--4 margin-vert--lg">
|
|
<Year {..._props} />
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
function listPostsByYears(blogPosts: readonly ArchiveBlogPost[]): YearProp[] {
|
|
const postsByYear: Map<string, ArchiveBlogPost[]> = blogPosts.reduceRight(
|
|
(posts, post) => {
|
|
const year = post.metadata.date.split('-')[0];
|
|
const yearPosts = posts.get(year) || [];
|
|
return posts.set(year, [post, ...yearPosts]);
|
|
},
|
|
new Map(),
|
|
);
|
|
|
|
return Array.from(postsByYear, ([year, posts]) => ({
|
|
year,
|
|
posts,
|
|
}));
|
|
}
|
|
|
|
export default function BlogArchive({archive}: Props): JSX.Element {
|
|
const title = translate({
|
|
id: 'theme.blog.archive.title',
|
|
message: 'Archive',
|
|
description: 'The page & hero title of the blog archive page',
|
|
});
|
|
const description = translate({
|
|
id: 'theme.blog.archive.description',
|
|
message: 'Archive',
|
|
description: 'The page & hero description of the blog archive page',
|
|
});
|
|
const years = listPostsByYears(archive.blogPosts);
|
|
return (
|
|
<Layout title={title} description={description}>
|
|
<header className="hero hero--primary">
|
|
<div className="container">
|
|
<h1 className="hero__title">{title}</h1>
|
|
<p className="hero__subtitle">{description}</p>
|
|
</div>
|
|
</header>
|
|
<main>{years.length > 0 && <YearsSection years={years} />}</main>
|
|
</Layout>
|
|
);
|
|
}
|