Add dynamic pagination for blog posts #1
2 changed files with 126 additions and 32 deletions
|
|
@ -1,32 +0,0 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
import BlogPost from "../components/BlogPost.astro";
|
||||
|
||||
const allPosts = await getCollection("blog");
|
||||
const pageTitle = "Latest Posts";
|
||||
---
|
||||
|
||||
<style>
|
||||
.list-articles {
|
||||
text-align: start;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
</style>
|
||||
<BaseLayout pageTitle={pageTitle}>
|
||||
<div class="list-articles">
|
||||
{
|
||||
allPosts.map((post: any) => (
|
||||
<BlogPost
|
||||
url={`/posts/${post.id}/`}
|
||||
title={post.data.title}
|
||||
datetime={post.data.pubDate.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</BaseLayout>
|
||||
126
src/pages/blog/[...page].astro
Normal file
126
src/pages/blog/[...page].astro
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import BaseLayout from "../../layouts/BaseLayout.astro";
|
||||
import BlogPost from "../../components/BlogPost.astro";
|
||||
|
||||
type Page<T> = {
|
||||
data: T[];
|
||||
currentPage: number;
|
||||
lastPage: number;
|
||||
url: {
|
||||
current: string;
|
||||
first?: string;
|
||||
prev?: string;
|
||||
next?: string;
|
||||
last?: string;
|
||||
};
|
||||
};
|
||||
|
||||
type BlogPostEntry = {
|
||||
id: string;
|
||||
data: {
|
||||
title: string;
|
||||
pubDate: Date;
|
||||
};
|
||||
};
|
||||
|
||||
interface Props {
|
||||
page: Page<BlogPostEntry>;
|
||||
}
|
||||
|
||||
export async function getStaticPaths({
|
||||
paginate
|
||||
} : {
|
||||
paginate: (data: any[], options?: { pageSize?: number; params?: Record<string, string>; props?: Record<string, any> }) => any;
|
||||
}) {
|
||||
const allPosts = await getCollection("blog");
|
||||
|
||||
allPosts.sort(
|
||||
(a, b) => new Date(b.data.pubDate).getTime() - new Date(a.data.pubDate).getTime()
|
||||
);
|
||||
|
||||
return paginate(
|
||||
allPosts,
|
||||
{
|
||||
pageSize: 6,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const { page } = Astro.props as Props;
|
||||
const pageTitle = "Articles";
|
||||
---
|
||||
|
||||
<style>
|
||||
.list-articles {
|
||||
text-align: start;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
nav.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
margin-top: 2rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
nav.pagination a,
|
||||
nav.pagination span {
|
||||
display: inline-block;
|
||||
padding: 12px 24px;
|
||||
background-color: #e0e0e0;
|
||||
color: #333333;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
transition: background-color 0.3s ease, transform 0.3s ease;
|
||||
}
|
||||
nav.pagination a:hover {
|
||||
background-color: #cacaca;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
nav.pagination a.active {
|
||||
background-color: #cacaca;
|
||||
font-weight: bold;
|
||||
pointer-events: none;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
nav.pagination {
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
nav.pagination a,
|
||||
nav.pagination span {
|
||||
padding: 10px 16px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<BaseLayout pageTitle={ pageTitle }>
|
||||
<div class="list-articles">
|
||||
{
|
||||
page.data.map((post) => (
|
||||
<BlogPost
|
||||
url={`/posts/${post.id}/`}
|
||||
title={post.data.title}
|
||||
datetime={post.data.pubDate.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
})}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
|
||||
<nav class="pagination">
|
||||
{page.url.first && <a href={page.url.first}>← First</a>}
|
||||
{page.url.prev && <a href={page.url.prev}>← Previous</a>}
|
||||
<span>Page {page.currentPage} of {page.lastPage}</span>
|
||||
{page.url.next && <a href={page.url.next}>Next →</a>}
|
||||
{page.url.last && <a href={page.url.last}>Last</a>}
|
||||
</nav>
|
||||
</BaseLayout>
|
||||
Loading…
Add table
Add a link
Reference in a new issue