feat: 站点单页、时间线导入与行级 BBCode 短代码
首页右栏接入单页入口与公告置顶/全部页;Markdown 编辑器支持可视化时间线与 Git 导入;隐藏块改为 [hide]/[timeline] 命名闭合,并修复单页/公告 GORM 更新只改 updated_at 的问题。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,6 +11,8 @@ import {
|
||||
PenLine,
|
||||
Activity,
|
||||
TrendingUp,
|
||||
Info,
|
||||
Pin,
|
||||
} from "lucide-react";
|
||||
import type {
|
||||
PostListItem,
|
||||
@@ -19,6 +21,7 @@ import type {
|
||||
AnnouncementSummary,
|
||||
NewUser,
|
||||
CheckinStatus,
|
||||
SidebarPageItem,
|
||||
} from "@/lib/api";
|
||||
import Avatar from "@/components/Avatar";
|
||||
import { PulseCheckin } from "./CheckinCard";
|
||||
@@ -117,14 +120,82 @@ function PulseCard({
|
||||
);
|
||||
}
|
||||
|
||||
/* ---------- 关于本站(侧栏单页) ---------- */
|
||||
|
||||
function AboutSite({ pages }: { pages: SidebarPageItem[] }) {
|
||||
if (pages.length === 0) return null;
|
||||
|
||||
if (pages.length === 1) {
|
||||
const p = pages[0];
|
||||
return (
|
||||
<section className="j13-module" aria-label="关于本站">
|
||||
<p className="j13-module-title">
|
||||
<Info size={15} style={{ color: "var(--accent)" }} /> 关于本站
|
||||
</p>
|
||||
<Link href={`/p/${p.slug}`} className="block mt-2 rounded-lg px-0.5 py-1 transition-colors hover:bg-[var(--accent-soft)]">
|
||||
<p className="text-[14px] font-semibold leading-snug" style={{ color: "var(--ink)" }}>
|
||||
{p.title}
|
||||
</p>
|
||||
{p.excerpt ? (
|
||||
<p className="meta text-[12.5px] mt-1.5 leading-relaxed line-clamp-3">{p.excerpt}</p>
|
||||
) : null}
|
||||
</Link>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="j13-module" aria-label="关于本站">
|
||||
<p className="j13-module-title mb-1.5">
|
||||
<Info size={15} style={{ color: "var(--accent)" }} /> 关于本站
|
||||
</p>
|
||||
<ul className="space-y-0.5">
|
||||
{pages.map((p) => (
|
||||
<li key={p.id}>
|
||||
<Link href={`/p/${p.slug}`} className="j13-raillink" data-tip={p.title}>
|
||||
<span className="flex-1 min-w-0 truncate text-[13px] font-medium" style={{ color: "var(--ink)" }}>
|
||||
{p.title}
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
/* ---------- 站点公告 ---------- */
|
||||
|
||||
function Announcements({ items }: { items: AnnouncementSummary[] }) {
|
||||
function Announcements({
|
||||
items,
|
||||
canManageAnnouncements,
|
||||
}: {
|
||||
items: AnnouncementSummary[];
|
||||
canManageAnnouncements?: boolean;
|
||||
}) {
|
||||
return (
|
||||
<section className="j13-module" aria-label="站点公告">
|
||||
<p className="j13-module-title">
|
||||
<Megaphone size={15} style={{ color: "var(--accent)" }} /> 站点公告
|
||||
</p>
|
||||
<div className="flex items-center justify-between gap-2">
|
||||
<p className="j13-module-title !mb-0">
|
||||
<Megaphone size={15} style={{ color: "var(--accent)" }} /> 站点公告
|
||||
</p>
|
||||
<span className="inline-flex items-center gap-2 shrink-0">
|
||||
<Link
|
||||
href="/announcements"
|
||||
className="meta text-[12px] font-normal transition-colors hover:text-[var(--accent)]"
|
||||
>
|
||||
全部
|
||||
</Link>
|
||||
{canManageAnnouncements ? (
|
||||
<Link
|
||||
href="/admin/announcements"
|
||||
className="meta text-[12px] font-normal transition-colors hover:text-[var(--accent)]"
|
||||
>
|
||||
管理
|
||||
</Link>
|
||||
) : null}
|
||||
</span>
|
||||
</div>
|
||||
{items.length === 0 ? (
|
||||
<p className="meta mt-2 px-0.5">暂无公告</p>
|
||||
) : (
|
||||
@@ -137,7 +208,17 @@ function Announcements({ items }: { items: AnnouncementSummary[] }) {
|
||||
data-tip={a.title}
|
||||
>
|
||||
<span className="j13-anno-item-body">
|
||||
<span className="j13-anno-item-title truncate">{a.title}</span>
|
||||
<span className="j13-anno-item-title truncate inline-flex items-center gap-1 min-w-0">
|
||||
{a.pinned ? (
|
||||
<Pin
|
||||
size={11}
|
||||
className="shrink-0"
|
||||
style={{ color: "var(--accent)" }}
|
||||
aria-label="置顶"
|
||||
/>
|
||||
) : null}
|
||||
<span className="truncate">{a.title}</span>
|
||||
</span>
|
||||
<span className="j13-anno-item-meta">
|
||||
{a.tag ? (
|
||||
<span className={`j13-anno-tag is-${a.tag_color}`}>{a.tag}</span>
|
||||
@@ -338,6 +419,8 @@ type PanelsProps = {
|
||||
newUsers: NewUser[];
|
||||
checkin?: CheckinStatus | null;
|
||||
allowComments: boolean;
|
||||
canManageAnnouncements?: boolean;
|
||||
sidebarPages?: SidebarPageItem[];
|
||||
};
|
||||
|
||||
function CommunityPanelsBody({
|
||||
@@ -348,11 +431,14 @@ function CommunityPanelsBody({
|
||||
newUsers,
|
||||
checkin,
|
||||
allowComments,
|
||||
canManageAnnouncements,
|
||||
sidebarPages = [],
|
||||
}: PanelsProps) {
|
||||
return (
|
||||
<>
|
||||
<PulseCard stats={stats} checkin={checkin} allowComments={allowComments} />
|
||||
<Announcements items={announcements} />
|
||||
<AboutSite pages={sidebarPages} />
|
||||
<Announcements items={announcements} canManageAnnouncements={canManageAnnouncements} />
|
||||
<HotRanking posts={hot} allowComments={allowComments} />
|
||||
<NewUsers users={newUsers} />
|
||||
<ActiveUsers users={activeUsers} allowComments={allowComments} />
|
||||
|
||||
Reference in New Issue
Block a user