astro-deploy/src/pages/blog/[...page].astro
2024-10-05 10:03:20 +02:00

195 lines
5.7 KiB
Plaintext

---
import { getCollection } from 'astro:content';
import BaseLayout from '@/layouts/BaseLayout.astro';
import Heading from '@/components/ui/Heading.astro';
import Search from '@/components/blog/Search.astro';
import {
Pagination,
PaginationContent,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination';
import { Image } from 'astro:assets';
interface BlogPost {
data: {
title: string;
description: string;
datePublished?: string;
dateModified?: string;
author?: [
{
type?: string;
name: string;
url?: string;
},
];
image?: string;
isDraft?: boolean;
};
slug: string;
}
export async function getStaticPaths({ paginate }: { paginate: Function }) {
const allBlogposts = await getCollection('blog');
const publishedBlogPosts: any = (post: BlogPost) => !post.data.isDraft;
const sortedPosts = allBlogposts.filter(publishedBlogPosts).sort((a, b) => {
const dateA = a.data.dateModified
? new Date(a.data.dateModified)
: a.data.datePublished
? new Date(a.data.datePublished)
: new Date(0);
const dateB = b.data.dateModified
? new Date(b.data.dateModified)
: b.data.datePublished
? new Date(b.data.datePublished)
: new Date(0);
return dateB.getTime() - dateA.getTime();
});
const postsPerPage = 6;
return paginate(sortedPosts, {
pageSize: postsPerPage,
});
}
const {
page,
}: {
page: {
data: BlogPost[];
url: { prev: string; current: string; next: string };
currentPage: number;
lastPage: number;
};
} = Astro.props;
---
<BaseLayout
title={`Blog Page ${page.currentPage} | Astro Deploy`}
description="Explore insightful articles on our Blog: Dive into a world of knowledge through posts crafted with expertise. Discover, learn, and grow with us.">
<div class="container mx-auto max-w-6xl px-4 py-12 sm:px-6 lg:px-8 lg:py-16">
<div class="mb-12 text-center">
<Heading level={1}>Blog</Heading>
<Search />
<p class="mt-4 text-xl text-zinc-600 dark:text-zinc-400">
Here are some blogposts, they are located in the repository as mdx files.
</p>
</div>
<hr class="my-8 border-t border-zinc-300 dark:border-zinc-700" />
<div class="grid grid-cols-1 gap-8 md:grid-cols-2 xl:grid-cols-3">
{
page.data.map((post) => (
<div class="overflow-hidden rounded-lg bg-white p-6 shadow-lg transition duration-500 ease-in-out hover:-translate-y-1 hover:shadow-2xl dark:bg-zinc-800">
{post.data.image && (
<a href={`/blog/${post.slug}/`}>
<Image
src={post.data.image}
alt={post.data.title}
inferSize
class="h-48 w-full object-cover transition duration-500 ease-in-out hover:scale-105"
/>
</a>
)}
<div class="p-6">
<h2
transition:name={post.data.title}
class="mb-3 text-2xl font-bold leading-tight text-zinc-800 transition duration-300 ease-in-out hover:text-primary-600 dark:text-zinc-100 dark:hover:text-primary-400">
<a href={`/blog/${post.slug}/`}>{post.data.title}</a>
</h2>
<div class="mb-4 text-sm text-zinc-600 dark:text-zinc-400">
<div class="mb-2 flex flex-wrap items-center">
{post.data.author && (
<>
<span class="mr-2">By</span>
{post.data.author.map((author, index) => (
<span class="mr-2">
{author.url ? (
<a
href={author.url}
class="font-medium text-primary-600 underline hover:text-primary-500 dark:text-primary-400 dark:hover:text-primary-300">
{author.name}
</a>
) : (
<span class="font-medium text-primary-600 dark:text-primary-400">
{author.name}
</span>
)}
{post.data.author && index < post.data.author.length - 1 && (
<span>, </span>
)}
</span>
))}
</>
)}
</div>
<div class="flex flex-wrap items-center">
{post.data.datePublished && (
<time datetime={post.data.datePublished} class="mr-4">
<span class="mr-1">Published:</span>
{new Date(post.data.datePublished).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</time>
)}
{post.data.dateModified && (
<time datetime={post.data.dateModified}>
<span class="mr-1">Updated:</span>
{new Date(post.data.dateModified).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
})}
</time>
)}
</div>
</div>
<p class="text-zinc-600 dark:text-zinc-400">{post.data.description}</p>
</div>
</div>
))
}
</div>
<div class="mt-12 text-center text-black dark:text-white">
<Pagination>
<PaginationContent>
{
page.currentPage > 1 && (
<>
<PaginationItem>
<PaginationPrevious href={`${page.url.prev}/`} />
</PaginationItem>
<PaginationItem>
<PaginationLink href="/blog/">1</PaginationLink>
</PaginationItem>
</>
)
}
<PaginationItem>
<PaginationLink href={`${page.url.current}/`} isActive
>{page.currentPage}
</PaginationLink>
</PaginationItem>
{
page.currentPage < page.lastPage && (
<>
<PaginationItem>
<PaginationLink href={`/blog/${page.lastPage}/`}>{page.lastPage}</PaginationLink>
</PaginationItem>
<PaginationItem>
<PaginationNext href={`${page.url.next}/`} />
</PaginationItem>
</>
)
}
</PaginationContent>
</Pagination>
</div>
</div>
</BaseLayout>