generated from nhcarrigan/template
59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
/**
|
|
* @copyright nhcarrigan
|
|
* @license Naomi's Public License
|
|
* @author Naomi Carrigan
|
|
*/
|
|
|
|
import Markdown from "react-markdown";
|
|
import rehypeHighlight from "rehype-highlight";
|
|
import rehypeRaw from "rehype-raw";
|
|
import remarkGfm from "remark-gfm";
|
|
import type { JSX } from "react";
|
|
import { Rule } from "@/components/rule";
|
|
import { getPostData } from "@/lib/posts";
|
|
|
|
/**
|
|
* Renders a blog post.
|
|
* @param props - The properties of the page.
|
|
* @param props.params - The path parameters.
|
|
* @returns The JSX component.
|
|
*/
|
|
const Page = async({
|
|
params,
|
|
}: {
|
|
readonly params: Promise<{ slug: string }>;
|
|
}): Promise<JSX.Element> => {
|
|
const { slug } = await params;
|
|
const post = getPostData(slug);
|
|
return (
|
|
<main>
|
|
<h1>{post.data.title}</h1>
|
|
<p className="italic text-center">{`Published ${post.data.date.toLocaleDateString(
|
|
"en-GB",
|
|
{ day: "numeric", month: "long", weekday: "long", year: "numeric" },
|
|
)}`}</p>
|
|
<h2 className="text-center">{post.data.summary}</h2>
|
|
<p className="text-center">{`A ${post.data.readtime}.`}</p>
|
|
<Rule />
|
|
<Markdown rehypePlugins={[ rehypeRaw, rehypeHighlight ]} remarkPlugins={[ remarkGfm ]}>
|
|
{post.content}
|
|
</Markdown>
|
|
<Rule />
|
|
<p className="text-center">
|
|
{`Love this post? Think Naomi is completely wrong? Have other thoughts you would like to share? `}
|
|
<a
|
|
href="https://chat.nhcarrigan.com"
|
|
rel="noreferrer"
|
|
target="_blank"
|
|
>{`Come tell us on Discord~!`}</a>
|
|
</p>
|
|
<div className="flex flex-row gap-2 w-full justify-center">
|
|
<a href="/">{"← Back to home"}</a>
|
|
<a href={`https://git.nhcarrigan.com/nhcarrigan/blog/commits/branch/main/posts/${slug}.md`} rel="noreferrer" target="_blank">{"See version history"}</a>
|
|
</div>
|
|
</main>
|
|
);
|
|
};
|
|
|
|
export default Page;
|