feat: add pagination in tag posts (#201)

* feat: add pagination in tag posts

Implement pagination in tag posts. Refactor and extract pagination logic and pagination component.

Closes: #152

* fix: update breadcrumbs for updated tag pagination
This commit is contained in:
Sat Naing
2023-12-29 10:26:02 +06:30
committed by GitHub
parent b05b8fb842
commit 581826a5af
11 changed files with 262 additions and 140 deletions
+6 -22
View File
@@ -4,7 +4,7 @@ import Posts from "@layouts/Posts.astro";
import PostDetails from "@layouts/PostDetails.astro";
import getSortedPosts from "@utils/getSortedPosts";
import getPageNumbers from "@utils/getPageNumbers";
import { SITE } from "@config";
import getPagination from "@utils/getPagination";
export interface Props {
post: CollectionEntry<"blog">;
@@ -32,26 +32,10 @@ const posts = await getCollection("blog");
const sortedPosts = getSortedPosts(posts);
const totalPages = getPageNumbers(sortedPosts.length);
const currentPage =
slug && !isNaN(Number(slug)) && totalPages.includes(Number(slug))
? Number(slug)
: 0;
const lastPost = currentPage * SITE.postPerPage;
const startPost = lastPost - SITE.postPerPage;
const paginatedPosts = sortedPosts.slice(startPost, lastPost);
const pagination = getPagination({
posts: sortedPosts,
page: slug,
});
---
{
post ? (
<PostDetails post={post} />
) : (
<Posts
posts={paginatedPosts}
pageNum={currentPage}
totalPages={totalPages.length}
/>
)
}
{post ? <PostDetails post={post} /> : <Posts {...pagination} />}
+8 -8
View File
@@ -1,18 +1,18 @@
---
import { SITE } from "@config";
import { getCollection } from "astro:content";
import Posts from "@layouts/Posts.astro";
import getSortedPosts from "@utils/getSortedPosts";
import getPageNumbers from "@utils/getPageNumbers";
import { getCollection } from "astro:content";
import getPagination from "@utils/getPagination";
const posts = await getCollection("blog");
const sortedPosts = getSortedPosts(posts);
const totalPages = getPageNumbers(sortedPosts.length);
const paginatedPosts = sortedPosts.slice(0, SITE.postPerPage);
const pagination = getPagination({
posts: sortedPosts,
page: 1,
isIndex: true,
});
---
<Posts posts={paginatedPosts} pageNum={1} totalPages={totalPages.length} />
<Posts {...pagination} />
-58
View File
@@ -1,58 +0,0 @@
---
import { type CollectionEntry, getCollection } from "astro:content";
import Layout from "@layouts/Layout.astro";
import Main from "@layouts/Main.astro";
import Header from "@components/Header.astro";
import Footer from "@components/Footer.astro";
import Card from "@components/Card";
import getUniqueTags from "@utils/getUniqueTags";
import getPostsByTag from "@utils/getPostsByTag";
import { SITE } from "@config";
import getSortedPosts from "@utils/getSortedPosts";
export interface Props {
post: CollectionEntry<"blog">;
tag: string;
tagName: string;
}
export async function getStaticPaths() {
const posts = await getCollection("blog");
const tags = getUniqueTags(posts);
return tags.map(({ tag, tagName }) => {
return {
params: { tag },
props: { tag, tagName },
};
});
}
const { tag, tagName } = Astro.props;
const posts = await getCollection("blog", ({ data }) => !data.draft);
const tagPosts = getPostsByTag(posts, tag);
const sortTagsPost = getSortedPosts(tagPosts);
---
<Layout title={`Tag: ${tagName} | ${SITE.title}`}>
<Header activeNav="tags" />
<Main
pageTitle={[`Tag:`, `${tagName}`]}
titleTransition={tag}
pageDesc={`All the articles with the tag "${tagName}".`}
>
<h1 slot="title" transition:name={tag}>{`Tag:${tag}`}</h1>
<ul>
{
sortTagsPost.map(({ data, slug }) => (
<Card href={`/posts/${slug}`} frontmatter={data} />
))
}
</ul>
</Main>
<Footer />
</Layout>
+44
View File
@@ -0,0 +1,44 @@
---
import { type CollectionEntry, getCollection } from "astro:content";
import TagPosts from "@layouts/TagPosts.astro";
import getUniqueTags from "@utils/getUniqueTags";
import getPostsByTag from "@utils/getPostsByTag";
import getPageNumbers from "@utils/getPageNumbers";
import getPagination from "@utils/getPagination";
export interface Props {
post: CollectionEntry<"blog">;
tag: string;
tagName: string;
}
export async function getStaticPaths() {
const posts = await getCollection("blog");
const tags = getUniqueTags(posts);
return tags.flatMap(({ tag, tagName }) => {
const tagPosts = getPostsByTag(posts, tag);
const totalPages = getPageNumbers(tagPosts.length);
return totalPages.map(page => ({
params: { tag, page },
props: { tag, tagName },
}));
});
}
const { page } = Astro.params;
const { tag, tagName } = Astro.props;
const posts = await getCollection("blog", ({ data }) => !data.draft);
const postsByTag = getPostsByTag(posts, tag);
const pagination = getPagination({
posts: postsByTag,
page,
});
---
<TagPosts {...pagination} {tag} {tagName} />
+32
View File
@@ -0,0 +1,32 @@
---
import { getCollection } from "astro:content";
import TagPosts from "@layouts/TagPosts.astro";
import getPostsByTag from "@utils/getPostsByTag";
import getPagination from "@utils/getPagination";
import getUniqueTags from "@utils/getUniqueTags";
export async function getStaticPaths() {
const posts = await getCollection("blog");
const tags = getUniqueTags(posts);
return tags.map(({ tag, tagName }) => {
return {
params: { tag },
props: { tag, tagName, posts },
};
});
}
const { tag, tagName, posts } = Astro.props;
const postsByTag = getPostsByTag(posts, tag);
const pagination = getPagination({
posts: postsByTag,
page: 1,
isIndex: true,
});
---
<TagPosts {...pagination} {tag} {tagName} />