mirror of
https://github.com/soconnor0919/personal-website.git
synced 2025-12-12 23:04:43 -05:00
81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import { notFound } from "next/navigation";
|
|
import { ArrowLeft } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { Button } from "~/components/ui/button";
|
|
import { Badge } from "~/components/ui/badge";
|
|
import fs from "fs";
|
|
import path from "path";
|
|
|
|
interface PageProps {
|
|
params: Promise<{ slug: string }>;
|
|
}
|
|
|
|
export async function generateStaticParams() {
|
|
const contentDir = path.join(process.cwd(), "src/content/blog");
|
|
const files = fs.readdirSync(contentDir);
|
|
|
|
return files
|
|
.filter((file) => file.endsWith(".mdx"))
|
|
.map((file) => ({
|
|
slug: file.replace(".mdx", ""),
|
|
}));
|
|
}
|
|
|
|
export async function generateMetadata({ params }: PageProps) {
|
|
const { slug } = await params;
|
|
try {
|
|
const { metadata } = await import(`~/content/blog/${slug}.mdx`);
|
|
return metadata;
|
|
} catch (e) {
|
|
return {
|
|
title: "Post Not Found",
|
|
};
|
|
}
|
|
}
|
|
|
|
export default async function BlogPost({ params }: PageProps) {
|
|
const { slug } = await params;
|
|
let Post;
|
|
let metadata;
|
|
|
|
try {
|
|
const content = await import(`~/content/blog/${slug}.mdx`);
|
|
Post = content.default;
|
|
metadata = content.metadata;
|
|
} catch (e) {
|
|
notFound();
|
|
}
|
|
|
|
return (
|
|
<article className="animate-fade-in-up space-y-8">
|
|
<div className="mb-8">
|
|
{/* <Button variant="ghost" asChild className="-ml-4 text-muted-foreground mb-4">
|
|
<Link href="/blog">
|
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
Back to Blog
|
|
</Link>
|
|
</Button> */}
|
|
|
|
<h1 className="text-3xl font-bold mb-4">{metadata.title}</h1>
|
|
|
|
<div className="flex flex-wrap gap-4 items-center text-muted-foreground mb-6">
|
|
<time dateTime={metadata.publishedAt}>{metadata.publishedAt}</time>
|
|
{metadata.tags && (
|
|
<div className="flex gap-2">
|
|
{metadata.tags.map((tag: string) => (
|
|
<Badge key={tag} variant="secondary">
|
|
{tag}
|
|
</Badge>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="prose prose-zinc dark:prose-invert max-w-none">
|
|
<Post />
|
|
</div>
|
|
</article>
|
|
);
|
|
}
|