Add blog CMS with tracked public posts
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import Link from "next/link";
|
||||
import { Navbar } from "@/components/Navbar";
|
||||
import { Footer } from "@/sections/Footer";
|
||||
import { BlogCard } from "@/components/BlogCard";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { toBlogSummary } from "@/lib/blogs";
|
||||
|
||||
export const metadata = {
|
||||
title: "Blog | Paul W. Portfolio",
|
||||
description: "Notes on infrastructure, tooling, and shipping software.",
|
||||
};
|
||||
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function BlogsPage() {
|
||||
const posts = await prisma.blogPost.findMany({
|
||||
where: { isPublished: true },
|
||||
orderBy: [{ publishedAt: "desc" }, { createdAt: "desc" }],
|
||||
});
|
||||
|
||||
const blogs = posts.map(toBlogSummary);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
<div className="mx-auto w-full max-w-6xl px-4 pb-20 pt-28 sm:pt-32">
|
||||
<section className="rounded-[2rem] border border-white/10 bg-white/[0.03] px-6 py-10 sm:px-10 sm:py-14">
|
||||
<p className="text-[11px] font-semibold uppercase tracking-[0.32em] text-gray-500">
|
||||
writing
|
||||
</p>
|
||||
<h1 className="mt-4 max-w-3xl text-4xl font-semibold text-white sm:text-5xl">
|
||||
Build notes, infra thoughts, and the occasional strongly held opinion.
|
||||
</h1>
|
||||
<p className="mt-4 max-w-2xl text-sm leading-7 text-gray-400 sm:text-base">
|
||||
Posts live in the same database-backed admin system as the rest of the site, with markdown
|
||||
authoring and public view tracking.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mt-10">
|
||||
{blogs.length === 0 ? (
|
||||
<div className="rounded-[1.75rem] border border-white/10 bg-white/[0.03] px-6 py-10 text-center text-gray-400">
|
||||
No published posts yet.
|
||||
</div>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3">
|
||||
{blogs.map((blog) => (
|
||||
<BlogCard key={blog.id} blog={blog} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div className="mt-10 flex justify-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="inline-flex items-center gap-2 rounded-full border border-white/15 bg-white/5 px-6 py-3 text-sm font-semibold text-white transition-all duration-300 hover:border-white/30 hover:bg-white/10"
|
||||
>
|
||||
Back home
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user