58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { formatDate } from '@/app/blog/utils'
|
|
import { cn } from '@/lib/utils'
|
|
|
|
type PostHeaderProps = {
|
|
title: string
|
|
publishedAt: string
|
|
readingTimeText?: string
|
|
tags?: string[]
|
|
summary?: string
|
|
className?: string
|
|
}
|
|
|
|
export default function PostHeader({
|
|
title,
|
|
publishedAt,
|
|
readingTimeText,
|
|
tags,
|
|
summary,
|
|
className,
|
|
}: PostHeaderProps) {
|
|
return (
|
|
<header className={cn('mx-auto max-w-3xl', className)}>
|
|
<h1 className="mb-3 text-3xl font-semibold leading-tight tracking-tighter text-neutral-900 dark:text-neutral-100 sm:text-4xl">
|
|
{title}
|
|
</h1>
|
|
{summary ? (
|
|
<p className="mb-4 text-base leading-7 text-neutral-700 dark:text-neutral-300">
|
|
{summary}
|
|
</p>
|
|
) : null}
|
|
<div className="flex flex-wrap items-center gap-2 text-xs text-neutral-600 dark:text-neutral-400">
|
|
<time dateTime={publishedAt}>{formatDate(publishedAt, false)}</time>
|
|
{readingTimeText ? (
|
|
<>
|
|
<span aria-hidden="true">•</span>
|
|
<span>{readingTimeText}</span>
|
|
</>
|
|
) : null}
|
|
{Array.isArray(tags) && tags.length > 0 ? (
|
|
<>
|
|
<span aria-hidden="true">•</span>
|
|
<ul className="flex flex-wrap gap-1.5">
|
|
{tags.slice(0, 4).map((tag) => (
|
|
<li
|
|
key={tag}
|
|
className="rounded-full border border-black/10 bg-white/40 px-2 py-0.5 text-[11px] leading-5 dark:border-white/10 dark:bg-white/[0.06]"
|
|
>
|
|
{tag}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</>
|
|
) : null}
|
|
</div>
|
|
</header>
|
|
)
|
|
}
|