Files
jiang13-bbs/frontend/components/sidebar/registry.tsx
freefire d7c6b3a961 feat: 帖子收藏与用户关注
- 新增收藏功能:favorite 服务与 handler、FavoriteButton 组件
- 新增关注功能:follow 服务与 handler、FollowButton 组件
- 用户主页适配关注/粉丝与收藏展示
- flash 消息工具、广告与侧边栏组件微调
2026-09-26 03:02:40 +08:00

164 lines
5.0 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 {
ActiveUser,
AnnouncementSummary,
Board,
BoardModerator,
BoardSidebarStats,
BoardWithCount,
CheckinStatus,
NewUser,
OverviewStats,
PostListItem,
PublicAdItem,
PublicSponsorItem,
SidebarPageItem,
User,
UserProfile,
} from "@/lib/api";
import PostToc, { type TocItem } from "@/components/PostToc";
import { WorkspaceNavPanel } from "@/components/home/WorkspaceNav";
import {
PulseCard,
Announcements,
AdsPanel,
SponsorsPanel,
HotRanking,
NewUsers,
ActiveUsers,
FriendLinks,
AboutSite,
} from "@/components/home/CommunityPanels";
import {
Moderators,
BoardIntro,
BoardPulse,
BoardHot,
BoardActive,
} from "@/components/home/BoardPanels";
import {
BoardCard as PostBoardCard,
AuthorRailCard as PostAuthorCard,
AuthorPosts as PostAuthorPosts,
} from "@/components/post/PostRailBlocks";
// 侧栏块 props 汇总:页面把已有数据整包传入,块按需取用;
// 某块所需数据缺失(如板块态没传 stats)时对应块渲染为空,安全跳过。
export interface SidebarBlockProps {
allowComments: boolean;
user?: User | null;
checkin?: CheckinStatus | null;
// home 范围
boards?: BoardWithCount[];
stats?: OverviewStats;
announcements?: AnnouncementSummary[];
canManageAnnouncements?: boolean;
ads?: PublicAdItem[];
adsPanelTitle?: string;
adsEnabled?: boolean;
sponsors?: PublicSponsorItem[];
sponsorsPanelTitle?: string;
sponsorsEnabled?: boolean;
hot?: PostListItem[];
newUsers?: NewUser[];
activeUsers?: ActiveUser[];
sidebarPages?: SidebarPageItem[];
siteDescription?: string;
canManagePages?: boolean;
// board 范围
board?: BoardWithCount;
moderators?: BoardModerator[];
boardStats?: BoardSidebarStats;
boardHot?: PostListItem[];
boardActiveUsers?: ActiveUser[];
// post 范围
postBoard?: Board;
authorProfile?: UserProfile;
authorPosts?: PostListItem[];
toc?: TocItem[];
// 板块 id → 名称/配色下标:板块管理员徽章展示「{板块名}板块管理员」并对齐板块色
boardNames?: Record<number, string>;
boardColors?: Record<number, number>;
}
// 内置块注册表:key → 组件。数据未就绪或未知 key 返回 null(渲染层静默跳过)。
export function renderSidebarBlock(key: string, p: SidebarBlockProps) {
switch (key) {
case "board_nav":
return p.boards ? <WorkspaceNavPanel boards={p.boards} user={p.user} /> : null;
case "pulse":
return p.stats ? (
<PulseCard stats={p.stats} checkin={p.checkin} allowComments={p.allowComments} />
) : null;
case "announcements":
return p.announcements ? (
<Announcements items={p.announcements} canManageAnnouncements={p.canManageAnnouncements} />
) : null;
case "ads":
return p.ads && p.adsEnabled !== false ? (
<AdsPanel items={p.ads} title={p.adsPanelTitle || "自助推广"} enabled />
) : null;
case "sponsors":
return p.sponsors && p.sponsorsEnabled !== false ? (
<SponsorsPanel
items={p.sponsors}
title={p.sponsorsPanelTitle || "赞助商"}
enabled
/>
) : null;
case "hot":
return p.hot ? <HotRanking posts={p.hot} allowComments={p.allowComments} /> : null;
case "new_users":
return p.newUsers ? <NewUsers users={p.newUsers} /> : null;
case "active_users":
return p.activeUsers ? (
<ActiveUsers users={p.activeUsers} allowComments={p.allowComments} />
) : null;
case "friend_links":
return <FriendLinks />;
case "about_site":
return p.sidebarPages || p.canManagePages ? (
<AboutSite
pages={p.sidebarPages ?? []}
siteDescription={p.siteDescription}
canManagePages={p.canManagePages}
/>
) : null;
case "board_moderators":
return p.moderators ? <Moderators items={p.moderators} /> : null;
case "board_intro":
return p.board ? <BoardIntro board={p.board} /> : null;
case "board_pulse":
return p.boardStats ? (
<BoardPulse stats={p.boardStats} checkin={p.checkin} allowComments={p.allowComments} />
) : null;
case "board_hot":
return p.boardHot ? (
<BoardHot posts={p.boardHot} allowComments={p.allowComments} />
) : null;
case "board_active":
return p.boardActiveUsers ? (
<BoardActive users={p.boardActiveUsers} allowComments={p.allowComments} />
) : null;
case "post_board":
return p.postBoard ? <PostBoardCard board={p.postBoard} /> : null;
case "post_author":
return p.authorProfile ? (
<PostAuthorCard
profile={p.authorProfile}
allowComments={p.allowComments}
boardNames={p.boardNames}
boardColors={p.boardColors}
/>
) : null;
case "post_author_posts":
return p.authorPosts ? <PostAuthorPosts posts={p.authorPosts} /> : null;
case "post_toc":
return p.toc && p.toc.length > 0 ? <PostToc items={p.toc} /> : null;
default:
return null;
}
}