Files
jiang13-bbs/frontend/components/site-doc/SiteDocMasthead.tsx
freefire 0b60c4299b feat: 公文三栏单页布局,并修复时间线目录跳转与样式
公告/单页对齐帖子详情三栏壳;时间线按日锚点可跳转,条目改为日志行并用暖金日期区分 feat 色。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-17 21:15:15 +08:00

95 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ReactNode } from "react";
import { Clock } from "lucide-react";
import { formatDate } from "@/lib/format";
function formatDateTime(dateStr: string) {
return new Date(dateStr).toLocaleString("zh-CN", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
});
}
/** 公文头:kicker / 标签 / 大标题 / 导语 / 元信息 */
export default function SiteDocMasthead({
kicker,
title,
excerpt,
createdAt,
updatedAt,
readingMinutes,
badges,
showTimeOfDay = false,
}: {
kicker: string;
title: string;
excerpt?: string;
createdAt: string;
updatedAt?: string;
readingMinutes?: number;
badges?: ReactNode;
/** 详情页用完整日期时间;列表头图可用短日期 */
showTimeOfDay?: boolean;
}) {
const edited =
updatedAt &&
new Date(updatedAt).getTime() - new Date(createdAt).getTime() > 60_000;
const publishedLabel = showTimeOfDay ? formatDateTime(createdAt) : formatDate(createdAt);
const updatedLabel =
edited && updatedAt
? showTimeOfDay
? formatDateTime(updatedAt)
: formatDate(updatedAt)
: null;
return (
<header className="mb-6 sm:mb-7">
<div className="flex items-center gap-2 flex-wrap mb-3">
<span
className="inline-flex items-center rounded-full px-2.5 py-0.5 text-[11.5px] font-semibold tracking-wide"
style={{ background: "var(--accent-soft)", color: "var(--accent)" }}
>
{kicker}
</span>
{badges}
</div>
<h1
className="text-[26px] sm:text-[34px] font-extrabold leading-tight tracking-tight"
style={{ color: "var(--ink)" }}
>
{title}
</h1>
{excerpt ? (
<p
className="mt-3.5 text-[15px] sm:text-[15.5px] leading-relaxed"
style={{ color: "var(--ink-2)" }}
>
{excerpt}
</p>
) : null}
<div
className="mt-5 pt-4 flex flex-wrap items-center gap-x-4 gap-y-2"
style={{ borderTop: "1px solid var(--line)" }}
>
<p className="meta text-[12.5px]">
发布于 {publishedLabel}
{updatedLabel ? <> · 更新于 {updatedLabel}</> : null}
</p>
{readingMinutes != null ? (
<span
className="meta inline-flex items-center gap-1.5 text-[12.5px] sm:ml-auto"
aria-label={`阅读约需 ${readingMinutes} 分钟`}
>
<Clock size={13} /> 约 {readingMinutes} 分钟读完
</span>
) : null}
</div>
</header>
);
}