From de1885fe8fe279c95c2c2b101fad916958dadd4a Mon Sep 17 00:00:00 2001
From: Valentin Popov <valentin@popov.link>
Date: Thu, 12 Sep 2024 22:10:31 +0000
Subject: Added Pagination component

---
 src/components/Pagination.astro  | 46 ++++++++++++++++++++++++++++++++++++
 src/components/PostElement.astro | 51 ----------------------------------------
 src/components/PostSummary.astro | 51 ++++++++++++++++++++++++++++++++++++++++
 src/pages/[...page].astro        | 30 +++++++++++++++++++++++
 src/pages/index.astro            | 14 -----------
 5 files changed, 127 insertions(+), 65 deletions(-)
 create mode 100644 src/components/Pagination.astro
 delete mode 100644 src/components/PostElement.astro
 create mode 100644 src/components/PostSummary.astro
 create mode 100644 src/pages/[...page].astro
 delete mode 100644 src/pages/index.astro

(limited to 'src')

diff --git a/src/components/Pagination.astro b/src/components/Pagination.astro
new file mode 100644
index 0000000..e9fbc69
--- /dev/null
+++ b/src/components/Pagination.astro
@@ -0,0 +1,46 @@
+---
+type Props = {
+	readonly prevUrl?: string;
+	readonly nextUrl?: string;
+};
+
+const { prevUrl, nextUrl } = Astro.props;
+---
+
+<style lang="scss">
+	.pagination {
+		overflow: hidden;
+		padding: 3rem 0;
+		width: 100%;
+	}
+
+	.prev,
+	.next {
+		max-width: 40%;
+	}
+
+	.prev {
+		float: left;
+	}
+
+	.next {
+		float: right;
+	}
+</style>
+
+<div class="pagination">
+	{
+		prevUrl && (
+			<span class="prev">
+				<a href={prevUrl}>&lt; Prev</a>
+			</span>
+		)
+	}
+	{
+		nextUrl && (
+			<span class="next">
+				<a href={nextUrl}>Next &gt;</a>
+			</span>
+		)
+	}
+</div>
diff --git a/src/components/PostElement.astro b/src/components/PostElement.astro
deleted file mode 100644
index 2f98130..0000000
--- a/src/components/PostElement.astro
+++ /dev/null
@@ -1,51 +0,0 @@
----
-import { type CollectionEntry } from "astro:content";
-import dayjs from "dayjs";
-
-type Props = {
-	readonly post: CollectionEntry<"blog">;
-};
-
-const { post } = Astro.props;
----
-
-<style lang="scss">
-	@import "../scss/_variables.scss";
-
-	/* Post */
-	.post {
-		padding-bottom: 3rem;
-	}
-
-	.link {
-		color: $colorText;
-	}
-
-	/* Meta */
-	.meta {
-		padding-bottom: 1.5rem;
-	}
-
-	.date {
-		opacity: 0.5;
-	}
-
-	.tag {
-		display: none;
-	}
-</style>
-
-<article class="post">
-	<h2><a class="link" href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
-	<div class="meta">
-		<time class="date" datetime={post.data.pubDate.toISOString()}>
-			{dayjs(post.data.pubDate.toString()).format("YYYY-MM-DD")}
-		</time>
-		<ul class="tag">
-			<li><a href="#">tag1</a></li>
-			<li><a href="#">tag2</a></li>
-		</ul>
-	</div>
-	<p>{post.data.description}</p>
-	<a href={`/blog/${post.slug}`}>Read More</a>
-</article>
diff --git a/src/components/PostSummary.astro b/src/components/PostSummary.astro
new file mode 100644
index 0000000..2f98130
--- /dev/null
+++ b/src/components/PostSummary.astro
@@ -0,0 +1,51 @@
+---
+import { type CollectionEntry } from "astro:content";
+import dayjs from "dayjs";
+
+type Props = {
+	readonly post: CollectionEntry<"blog">;
+};
+
+const { post } = Astro.props;
+---
+
+<style lang="scss">
+	@import "../scss/_variables.scss";
+
+	/* Post */
+	.post {
+		padding-bottom: 3rem;
+	}
+
+	.link {
+		color: $colorText;
+	}
+
+	/* Meta */
+	.meta {
+		padding-bottom: 1.5rem;
+	}
+
+	.date {
+		opacity: 0.5;
+	}
+
+	.tag {
+		display: none;
+	}
+</style>
+
+<article class="post">
+	<h2><a class="link" href={`/blog/${post.slug}`}>{post.data.title}</a></h2>
+	<div class="meta">
+		<time class="date" datetime={post.data.pubDate.toISOString()}>
+			{dayjs(post.data.pubDate.toString()).format("YYYY-MM-DD")}
+		</time>
+		<ul class="tag">
+			<li><a href="#">tag1</a></li>
+			<li><a href="#">tag2</a></li>
+		</ul>
+	</div>
+	<p>{post.data.description}</p>
+	<a href={`/blog/${post.slug}`}>Read More</a>
+</article>
diff --git a/src/pages/[...page].astro b/src/pages/[...page].astro
new file mode 100644
index 0000000..23a5d51
--- /dev/null
+++ b/src/pages/[...page].astro
@@ -0,0 +1,30 @@
+---
+import type { GetStaticPaths, InferGetStaticPropsType } from "astro";
+import { getCollection } from "astro:content";
+import Layout from "../layouts/BaseLayout.astro";
+import Pagination from "../components/Pagination.astro";
+import PostSummary from "../components/PostSummary.astro";
+
+export const getStaticPaths = (async ({ paginate }) => {
+	const posts = await getCollection("blog");
+	posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
+
+	return paginate(posts, {
+		pageSize: 5,
+	});
+}) satisfies GetStaticPaths;
+
+type Props = InferGetStaticPropsType<typeof getStaticPaths>;
+
+const { page } = Astro.props;
+---
+
+<Layout>
+	<section>
+		{page.data.map((post) => <PostSummary post={post} />)}
+	</section>
+
+	<section>
+		<Pagination prevUrl={page.url.prev} nextUrl={page.url.next} />
+	</section>
+</Layout>
diff --git a/src/pages/index.astro b/src/pages/index.astro
deleted file mode 100644
index 6575ca6..0000000
--- a/src/pages/index.astro
+++ /dev/null
@@ -1,14 +0,0 @@
----
-import { getCollection } from "astro:content";
-import Element from "../components/PostElement.astro";
-import Layout from "../layouts/BaseLayout.astro";
-
-const posts = await getCollection("blog");
-posts.sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());
----
-
-<Layout>
-	<section>
-		{posts.map((post) => <Element post={post} />)}
-	</section>
-</Layout>
-- 
cgit v1.2.3