aboutsummaryrefslogtreecommitdiff
path: root/app/blog
diff options
context:
space:
mode:
authorschererleander <leander@schererleander.de>2025-12-25 23:33:25 +0000
committerschererleander <leander@schererleander.de>2025-12-25 23:33:25 +0000
commitd82fb3b552d20a279efdd9408042183cfa02fb48 (patch)
tree4ffe818e591e54da71f7592506c873abf0d9d481 /app/blog
parentd7edbf05ab0e90eedcb99e4462e3a61793b2eff9 (diff)
initial commit
Diffstat (limited to 'app/blog')
-rw-r--r--app/blog/[slug]/page.tsx35
-rw-r--r--app/blog/page.tsx34
2 files changed, 69 insertions, 0 deletions
diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx
new file mode 100644
index 0000000..a066779
--- /dev/null
+++ b/app/blog/[slug]/page.tsx
@@ -0,0 +1,35 @@
+// app/blog/[slug]/page.tsx
+import { format, parseISO } from 'date-fns'
+import { allPosts } from 'contentlayer/generated'
+import { MDXContent } from '@/components/mdx-content'
+
+export const generateStaticParams = async () => allPosts.map((post) => ({ slug: post._raw.flattenedPath }))
+
+export const generateMetadata = async ({ params }: { params: Promise<{ slug: string }> }) => {
+ const { slug } = await params
+ const post = allPosts.find((post) => post._raw.flattenedPath === slug)
+ if (!post) throw new Error(`Post not found for slug: ${slug}`)
+ return { title: post.title }
+}
+
+const PostLayout = async ({ params }: { params: Promise<{ slug: string }> }) => {
+ const { slug } = await params
+ const post = allPosts.find((post) => post._raw.flattenedPath === slug)
+ if (!post) throw new Error(`Post not found for slug: ${slug}`)
+
+ return (
+ <article className="mx-auto max-w-xl py-8">
+ <div className="mb-8">
+ <h1 className="text-3xl font-bold">{post.title}</h1>
+ <time dateTime={post.date} className="text-xs text-muted-foreground/60">
+ {format(parseISO(post.date), 'LLLL d, yyyy')}
+ </time>
+ </div>
+ <div className="prose dark:prose-invert prose-neutral max-w-none [&>*]:mb-3 [&>*:last-child]:mb-0">
+ <MDXContent code={post.body.code} />
+ </div>
+ </article>
+ )
+}
+
+export default PostLayout
diff --git a/app/blog/page.tsx b/app/blog/page.tsx
new file mode 100644
index 0000000..abc3394
--- /dev/null
+++ b/app/blog/page.tsx
@@ -0,0 +1,34 @@
+
+import { format, parseISO } from 'date-fns'
+import { allPosts } from 'contentlayer/generated'
+import Link from 'next/link'
+
+export default function BlogPage() {
+ const posts = allPosts.sort((a, b) => compareDesc(new Date(a.date), new Date(b.date)))
+
+ return (
+ <div className="max-w-2xl mx-auto py-12">
+ <h1 className="text-3xl font-bold mb-8">Blog</h1>
+ <div className="space-y-8">
+ {posts.map((post) => (
+ <article key={post._id} className="group relative flex flex-col items-start">
+ <h2 className="text-xl font-semibold tracking-tight">
+ <Link href={post.url} className="hover:underline">
+ {post.title}
+ </Link>
+ </h2>
+ <time dateTime={post.date} className="text-sm text-muted-foreground mb-2">
+ {format(parseISO(post.date), 'LLLL d, yyyy')}
+ </time>
+ </article>
+ ))}
+ </div>
+ </div>
+ )
+}
+
+function compareDesc(a: Date, b: Date) {
+ if (a > b) return -1
+ if (a < b) return 1
+ return 0
+}