76 lines
2.3 KiB
TypeScript
76 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
|
|
interface NavigationPost {
|
|
title: string;
|
|
path: string;
|
|
}
|
|
|
|
interface PostProps {
|
|
// HTML string for the blog post body
|
|
children: string;
|
|
meta: {
|
|
title: string;
|
|
date: Date;
|
|
readingTime: string;
|
|
previousPost?: NavigationPost | null;
|
|
nextPost?: NavigationPost | null;
|
|
};
|
|
}
|
|
|
|
export function Post({ children, meta }: PostProps) {
|
|
const { previousPost, nextPost } = meta;
|
|
|
|
return (
|
|
<main>
|
|
<article className="blog-post">
|
|
<header className="post-header">
|
|
<div className="back-button">
|
|
<a href="/" className="back-link">
|
|
<span className="back-arrow">←</span> Back to Home
|
|
</a>
|
|
</div>
|
|
<h1>{meta.title}</h1>
|
|
<div className="post-meta">
|
|
{meta.date && meta.date instanceof Date &&
|
|
<>
|
|
|
|
<time dateTime={meta.date.toISOString()}>
|
|
{meta.date.toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric'
|
|
})}
|
|
</time>
|
|
</>
|
|
}
|
|
|
|
{meta.readingTime &&
|
|
<>
|
|
<span className="meta-separator">•</span>
|
|
<span>{meta.readingTime} min read</span>
|
|
</>
|
|
}
|
|
</div>
|
|
</header>
|
|
<div className="post-content" dangerouslySetInnerHTML={{ __html: children }} />
|
|
<footer className="post-navigation">
|
|
<div className="post-nav-links">
|
|
{previousPost && (
|
|
<a href={previousPost.path} className="post-nav-link prev-nav">
|
|
<span className="nav-direction">← Previous</span>
|
|
<span className="nav-title">{previousPost.title}</span>
|
|
</a>
|
|
)}
|
|
{nextPost && (
|
|
<a href={nextPost.path} className="post-nav-link next-nav">
|
|
<span className="nav-direction">Next →</span>
|
|
<span className="nav-title">{nextPost.title}</span>
|
|
</a>
|
|
)}
|
|
</div>
|
|
</footer>
|
|
</article>
|
|
</main>
|
|
)
|
|
}
|