63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import { getAllPostsMeta } from '@/lib/posts'
|
|
import { Post } from '@/components/common/Post'
|
|
import Link from 'next/link'
|
|
|
|
export default function BlogIndex() {
|
|
const posts = getAllPostsMeta()
|
|
|
|
const rest = posts.slice(1)
|
|
const rows = []
|
|
for (let i = 0; i < rest.length; i += 2) {
|
|
rows.push(rest.slice(i, i + 2))
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<main className="max-w-3xl mx-auto px-4 py-8 lg:py-16">
|
|
<section>
|
|
{posts.length === 0 ? (
|
|
<div className="rounded-xl border border-border p-6 text-fg-dim">
|
|
No published posts yet.
|
|
</div>
|
|
) : (
|
|
<>
|
|
<Post post={posts[0]} isLatest />
|
|
<div className="border-t border-border my-6" aria-hidden="true"></div>
|
|
<div className="flex flex-col gap-8 mt-4">
|
|
{rows.map((row) => {
|
|
const rowHasImage = row.some((p) => p.coverImage)
|
|
return (
|
|
<div key={row[0].slug} className="grid grid-cols-1 gap-4 md:grid-cols-2">
|
|
{row.map((post) => (
|
|
<Post post={post} key={post.slug} showImageSlot={rowHasImage} />
|
|
))}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
</>
|
|
)}
|
|
</section>
|
|
</main>
|
|
<aside className="w-80 hidden lg:block px-4 py-8 lg:py-16">
|
|
<div className="sticky top-8">
|
|
<h2 className="text-xl font-bold mb-4">Recently updated</h2>
|
|
<ul className="flex flex-col gap-2 ml-2">
|
|
{posts
|
|
.toSorted(
|
|
(a, b) =>
|
|
new Date(b.updated ?? b.date).getTime() - new Date(a.updated ?? a.date).getTime(),
|
|
)
|
|
.map((post) => (
|
|
<li key={post.slug} className="text-sm text-fg-dim">
|
|
<Link href={`/posts/${post.slug}`} className="hover:underline">
|
|
{post.title}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
</aside>
|
|
</>
|
|
)
|
|
}
|