Commit e0f8a9a
Changed files (2)
src
components
widgets
pages
posts
src/components/widgets/PostsList.astro
@@ -0,0 +1,57 @@
+---
+import type { CollectionEntry } from "astro:content";
+
+import { url } from "@/utils/url.ts";
+
+interface Props {
+ posts: CollectionEntry<"posts">[];
+}
+
+const { posts } = Astro.props;
+---
+<nav class="posts-list">
+ <ol>
+ {
+ posts.map((post) => {
+ const dt = Temporal.ZonedDateTime.from(post.data.date).toPlainDateTime();
+ return (
+ <li>
+ <a href={url(`/posts/${post.id}`)}>{post.data.title}</a>
+ <time datetime={dt.toString()}>
+ {dt.toPlainDate().toLocaleString()}
+ </time>
+ </li>
+ );
+ })
+ }
+ </ol>
+</nav>
+
+<style lang="scss" is:inline>
+nav.posts-list ol li {
+ display: grid;
+ align-items: first baseline;
+ grid-template-columns: 1fr auto;
+ gap: 1rem;
+
+ &::before {
+ /* remove ::before */
+ content: initial;
+ }
+
+ a {
+ color: inherit;
+ text-decoration-color: color-mix(in oklab, var(--color-base-content) 60%,
+ transparent);
+
+ &:hover {
+ text-decoration-color: var(--color-base-content);
+ }
+ }
+
+ time {
+ font-size: 0.875rem;
+ color: color-mix(in oklab, var(--color-base-content) 80%, transparent);
+ }
+}
+</style>
src/pages/posts/index.astro
@@ -1,19 +1,35 @@
---
import { getCollection } from "astro:content";
-import { url } from "@/utils/url";
import BaseLayout from "@/layouts/BaseLayout.astro";
+import PostsList from "@/components/widgets/PostsList.astro";
const posts = await getCollection("posts");
+const sortedPosts = posts.sort(
+ (a, b) => Temporal.ZonedDateTime.compare(b.data.date, a.data.date),
+);
+const postsByYear = sortedPosts.reduce(
+ (acc, post) => {
+ const year = Temporal.ZonedDateTime.from(post.data.date).year;
+ if (!acc[year]) {
+ acc[year] = [];
+ }
+ acc[year].push(post);
+ return acc;
+ },
+ {} as Record<number, typeof posts>,
+);
---
<BaseLayout title="Posts">
<h1>Posts</h1>
{
- posts.map((post) => (
- <li>
- <a href={url("/posts/" + post.id)}>{post.data.title}</a>
- <time>{Temporal.ZonedDateTime.from(post.data.date).toPlainDateTime().toLocaleString("en-US")}</time>
- </li>)
- )
+ Object.entries(postsByYear)
+ .reverse()
+ .map(([year, posts]) => (
+ <section>
+ <h2>{year}</h2>
+ <PostsList posts={posts} />
+ </section>
+ ))
}
</BaseLayout>