diff --git a/package-lock.json b/package-lock.json
index 9d49be2..1e733db 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "astro-erudite",
- "version": "0.0.1",
+ "version": "1.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "astro-erudite",
- "version": "0.0.1",
+ "version": "1.1.0",
"dependencies": {
"@astrojs/check": "^0.7.0",
"@astrojs/markdown-remark": "^5.2.0",
diff --git a/package.json b/package.json
index be430cf..a324863 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "astro-erudite",
"type": "module",
- "version": "0.0.1",
+ "version": "1.1.0",
"private": true,
"scripts": {
"dev": "astro dev",
diff --git a/src/components/Footer.astro b/src/components/Footer.astro
index 9e98152..58a62b7 100644
--- a/src/components/Footer.astro
+++ b/src/components/Footer.astro
@@ -10,7 +10,7 @@ import SocialIcons from './SocialIcons.astro'
class="flex flex-col items-center justify-center gap-y-2 sm:flex-row sm:justify-between"
>
-
+
© {new Date().getFullYear()} All rights reserved.
diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx
new file mode 100644
index 0000000..50b4739
--- /dev/null
+++ b/src/components/ui/pagination.tsx
@@ -0,0 +1,174 @@
+import * as React from 'react'
+import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react'
+
+import { cn } from '@/lib/utils'
+import { type ButtonProps, buttonVariants } from '@/components/ui/button'
+
+const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => (
+
+)
+Pagination.displayName = 'Pagination'
+
+const PaginationContent = React.forwardRef<
+ HTMLUListElement,
+ React.ComponentProps<'ul'>
+>(({ className, ...props }, ref) => (
+
+))
+PaginationContent.displayName = 'PaginationContent'
+
+const PaginationItem = React.forwardRef<
+ HTMLLIElement,
+ React.ComponentProps<'li'>
+>(({ className, ...props }, ref) => (
+
+))
+PaginationItem.displayName = 'PaginationItem'
+
+type PaginationLinkProps = {
+ isActive?: boolean
+ isDisabled?: boolean
+} & Pick &
+ React.ComponentProps<'a'>
+
+const PaginationLink = ({
+ className,
+ isActive,
+ isDisabled,
+ size = 'icon',
+ ...props
+}: PaginationLinkProps) => (
+
+)
+PaginationLink.displayName = 'PaginationLink'
+
+const PaginationPrevious = ({
+ className,
+ isDisabled,
+ ...props
+}: React.ComponentProps) => (
+
+
+ Previous
+
+)
+PaginationPrevious.displayName = 'PaginationPrevious'
+
+const PaginationNext = ({
+ className,
+ isDisabled,
+ ...props
+}: React.ComponentProps) => (
+
+ Next
+
+
+)
+PaginationNext.displayName = 'PaginationNext'
+
+const PaginationEllipsis = ({
+ className,
+ ...props
+}: React.ComponentProps<'span'>) => (
+
+
+ More pages
+
+)
+PaginationEllipsis.displayName = 'PaginationEllipsis'
+
+interface PaginationProps {
+ currentPage: number
+ totalPages: number
+ baseUrl: string
+}
+
+const PaginationComponent: React.FC = ({
+ currentPage,
+ totalPages,
+ baseUrl,
+}) => {
+ const pages = Array.from({ length: totalPages }, (_, i) => i + 1)
+
+ const getPageUrl = (page: number) => {
+ if (page === 1) return baseUrl
+ return `${baseUrl}${page}`
+ }
+
+ return (
+
+
+
+ 1 ? getPageUrl(currentPage - 1) : undefined}
+ isDisabled={currentPage === 1}
+ />
+
+
+ {pages.map((page) => (
+
+
+ {page}
+
+
+ ))}
+
+ {totalPages > 5 && (
+
+
+
+ )}
+
+
+
+
+
+
+ )
+}
+
+export default PaginationComponent
diff --git a/src/consts.ts b/src/consts.ts
index 64a20a4..54cbc6d 100644
--- a/src/consts.ts
+++ b/src/consts.ts
@@ -3,6 +3,7 @@ export type Site = {
DESCRIPTION: string
EMAIL: string
NUM_POSTS_ON_HOMEPAGE: number
+ POSTS_PER_PAGE: number
SITEURL: string
}
@@ -17,6 +18,7 @@ export const SITE: Site = {
'astro-erudite is a opinionated, no-frills blogging template—built with Astro, Tailwind, and shadcn/ui.',
EMAIL: 'jason@enscribe.dev',
NUM_POSTS_ON_HOMEPAGE: 2,
+ POSTS_PER_PAGE: 3,
SITEURL: 'https://astro-erudite.vercel.app',
}
diff --git a/src/content/blog/2022-post/index.mdx b/src/content/blog/2022-post/index.mdx
index b02b3e1..b9e364a 100644
--- a/src/content/blog/2022-post/index.mdx
+++ b/src/content/blog/2022-post/index.mdx
@@ -1,7 +1,7 @@
---
title: '2022 Post'
description: 'This a dummy post written in the year 2022.'
-date: 2022-01-01
+date: 2022-06-01
tags: ['dummy', 'placeholder']
image: './2022.png'
---
diff --git a/src/content/blog/2023-post/index.mdx b/src/content/blog/2023-post/index.mdx
index 816cee8..cc33ffc 100644
--- a/src/content/blog/2023-post/index.mdx
+++ b/src/content/blog/2023-post/index.mdx
@@ -1,7 +1,7 @@
---
title: '2023 Post'
description: 'This a dummy post written in the year 2023.'
-date: 2023-01-01
+date: 2023-06-01
tags: ['dummy', 'placeholder']
image: './2023.png'
authors: ['enscribe']
diff --git a/src/content/blog/2024-post/index.mdx b/src/content/blog/2024-post/index.mdx
index 5ea7023..03689ea 100644
--- a/src/content/blog/2024-post/index.mdx
+++ b/src/content/blog/2024-post/index.mdx
@@ -1,7 +1,7 @@
---
title: '2024 Post'
description: 'This a dummy post written in the year 2024 (with multiple authors).'
-date: 2024-01-01
+date: 2024-06-01
tags: ['dummy', 'placeholder']
image: './2024.png'
authors: ['enscribe', 'jktrn']
diff --git a/src/pages/blog/[page].astro b/src/pages/blog/[page].astro
new file mode 100644
index 0000000..721f1b6
--- /dev/null
+++ b/src/pages/blog/[page].astro
@@ -0,0 +1,70 @@
+---
+import Breadcrumbs from '@/components/Breadcrumbs.astro'
+import PaginationComponent from '@/components/ui/pagination'
+import { SITE } from '@/consts'
+import BlogCard from '@components/BlogCard.astro'
+import Container from '@components/Container.astro'
+import Layout from '@layouts/Layout.astro'
+import type { PaginateFunction } from 'astro'
+import { type CollectionEntry, getCollection } from 'astro:content'
+
+export async function getStaticPaths({
+ paginate,
+}: {
+ paginate: PaginateFunction
+}) {
+ const allPosts = await getCollection('blog', ({ data }) => !data.draft)
+ return paginate(
+ allPosts.sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf()),
+ { pageSize: SITE.POSTS_PER_PAGE },
+ )
+}
+
+const { page } = Astro.props
+
+const postsByYear = page.data.reduce(
+ (acc: Record[]>, post) => {
+ const year = post.data.date.getFullYear().toString()
+ ;(acc[year] ??= []).push(post)
+ return acc
+ },
+ {},
+)
+
+const years = Object.keys(postsByYear).sort((a, b) => parseInt(b) - parseInt(a))
+---
+
+
+
+
+
+
+ {
+ years.map((year) => (
+
+ {year}
+
+ {postsByYear[year].map((post) => (
+ -
+
+
+ ))}
+
+
+ ))
+ }
+
+
+
+
+
diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro
index 0a7bc91..a940735 100644
--- a/src/pages/blog/index.astro
+++ b/src/pages/blog/index.astro
@@ -1,51 +1,5 @@
---
-import Breadcrumbs from '@/components/Breadcrumbs.astro'
-import BlogCard from '@components/BlogCard.astro'
-import Container from '@components/Container.astro'
-import Layout from '@layouts/Layout.astro'
-import { type CollectionEntry, getCollection } from 'astro:content'
+export const prerender = true
-const data = (await getCollection('blog'))
- .filter((post) => !post.data.draft)
- .sort((a, b) => b.data.date.valueOf() - a.data.date.valueOf())
-
-type Acc = {
- [year: string]: CollectionEntry<'blog'>[]
-}
-
-const posts = data.reduce((acc: Acc, post) => {
- const year = post.data.date.getFullYear().toString()
- if (!acc[year]) {
- acc[year] = []
- }
- acc[year].push(post)
- return acc
-}, {})
-
-const years = Object.keys(posts).sort((a, b) => parseInt(b) - parseInt(a))
+return Astro.redirect('/blog/1')
---
-
-
-
-
-
-
- {
- years.map((year) => (
-
- {year}
-
-
- {posts[year].map((post) => (
- -
-
-
- ))}
-
-
-
- ))
- }
-
-
-