import Link from "next/link"; import { Flame, Users, MessageCircle, Heart, UserPlus, Link2, Megaphone, BarChart3, PenLine, Activity, TrendingUp, Pin, ChevronRight, CircleDollarSign, Handshake, } from "lucide-react"; import type { PostListItem, ActiveUser, OverviewStats, AnnouncementSummary, NewUser, CheckinStatus, SidebarPageItem, PublicAdItem, PublicSponsorItem, } from "@/lib/api"; import Avatar from "@/components/Avatar"; import { AdText } from "@/components/AdText"; import { PulseCheckin } from "./CheckinCard"; import { FRIEND_LINKS } from "@/lib/friendLinks"; import { formatCompact, formatShortDate } from "@/lib/format"; import { pageGlyph } from "@/lib/pageGlyph"; import { AboutSiteHeader } from "@/components/site-doc"; import { AD_IMAGE_HEIGHT, AD_IMAGE_SIZE_LABEL, AD_IMAGE_WIDTH, AD_TIP_DELAY_MS, adHoverTip, } from "@/lib/ads"; /* ---------- 站点数据(2×2 bento 统计瓦片) ---------- */ export function PulseCard({ stats, checkin, allowComments, }: { stats: OverviewStats; checkin?: CheckinStatus | null; allowComments: boolean; }) { const cells = [ { icon: , label: "注册用户", value: formatCompact(stats.users), foot: `+${formatCompact(stats.today_users)} 今日`, up: true, }, { icon: , label: "话题总数", value: formatCompact(stats.posts), foot: `+${formatCompact(stats.today_posts)} 今日`, up: true, }, ...(allowComments ? [ { icon: , label: "回复总数", value: formatCompact(stats.comments), foot: `+${formatCompact(stats.today_comments)} 今日`, up: true, }, ] : [ { icon: , label: "今日新帖", value: formatCompact(stats.today_posts), foot: "本日新增", up: stats.today_posts > 0, }, ]), { icon: , label: "在线用户", value: formatCompact(stats.online), foot: `峰值 ${formatCompact(stats.peak_online)}`, up: false, }, ]; return (

站点数据

{cells.map((c) => (

{c.label}

{c.value}

{c.up &&

))}
); } /* ---------- 关于本站(侧栏页目录,置于右栏最底) ---------- */ export function AboutSite({ pages, siteDescription, canManagePages, }: { pages: SidebarPageItem[]; siteDescription?: string; canManagePages?: boolean; }) { if (pages.length === 0 && !canManagePages) return null; const lead = siteDescription?.trim() ?? ""; return (
{lead ?

{lead}

: null} {pages.length === 0 ? (

暂无介绍

) : (
    {pages.map((p) => { const Icon = pageGlyph(p.slug); return (
  • {p.title} {p.excerpt ? {p.excerpt} : null}
  • ); })}
)}
); } /* ---------- 站点公告 ---------- */ export function Announcements({ items, canManageAnnouncements, }: { items: AnnouncementSummary[]; canManageAnnouncements?: boolean; }) { return (

站点公告

全部 {canManageAnnouncements ? ( 管理 ) : null}
{items.length === 0 ? (

暂无公告

) : (
    {items.map((a) => (
  • {a.pinned ? ( ) : null} {a.title} {a.tag ? ( {a.tag} ) : null} {formatShortDate(a.created_at)}
  • ))}
)}
); } /* ---------- 热门榜 ---------- */ export function HotRanking({ posts, allowComments }: { posts: PostListItem[]; allowComments: boolean }) { return (

热门讨论

{posts.length === 0 ? (

还没有热门讨论

) : (
    {posts.map((p, i) => (
  1. {i + 1} {p.title} {allowComments ? ( {p.comment_count} ) : null} {p.like_count}
  2. ))}
)}
); } /* ---------- 最新注册 ---------- */ export function NewUsers({ users }: { users: NewUser[] }) { if (users.length === 0) return null; return (

最新注册

    {users.map((u) => { const name = u.nickname || u.username; return (
  • {name}
  • ); })}
); } /* ---------- 活跃成员(本周发帖 / 回复) ---------- */ export function ActiveUsers({ users, allowComments }: { users: ActiveUser[]; allowComments: boolean }) { return (

活跃成员 本周

{users.length === 0 ? (

本周还没有人互动

) : (
    {users.map((u) => { const name = u.nickname || u.username; return (
  • {name} 发帖 {u.post_count} {allowComments ? ( 回复 {u.comment_count} ) : null} {allowComments ? u.post_count + u.comment_count : u.post_count}
  • ); })}
)}
); } /* ---------- 友情链接 ---------- */ export function FriendLinks() { if (FRIEND_LINKS.length === 0) return null; return (

友情链接 申请

{FRIEND_LINKS.map((l) => l.href.startsWith("http") ? ( {l.name} ) : ( {l.name} ) )}
); } /* ---------- 桌面 / 移动两种装配 ---------- */ type PanelsProps = { stats: OverviewStats; hot: PostListItem[]; activeUsers: ActiveUser[]; announcements: AnnouncementSummary[]; newUsers: NewUser[]; checkin?: CheckinStatus | null; allowComments: boolean; canManageAnnouncements?: boolean; canManagePages?: boolean; sidebarPages?: SidebarPageItem[]; siteDescription?: string; ads?: PublicAdItem[]; adsPanelTitle?: string; adsEnabled?: boolean; sponsors?: PublicSponsorItem[]; sponsorsPanelTitle?: string; sponsorsEnabled?: boolean; }; export function AdsPanel({ items, title, enabled, }: { items: PublicAdItem[]; title: string; enabled: boolean; }) { if (!enabled) return null; const IMAGE_SLOTS = 5; const TEXT_SLOTS = 6; const images = items.filter((a) => a.kind === "image").slice(0, IMAGE_SLOTS); const texts = items.filter((a) => a.kind === "text").slice(0, TEXT_SLOTS); const imageSlots = Array.from({ length: IMAGE_SLOTS }, (_, i) => images[i] ?? null); const textSlots = Array.from({ length: TEXT_SLOTS }, (_, i) => texts[i] ?? null); return (

{title || "自助推广"} 购买广告位

    {textSlots.map((ad, i) => ad ? (
  • ) : (
  • 文字广告位
  • ) )}
); } export function SponsorsPanel({ items, title, enabled, }: { items: PublicSponsorItem[]; title: string; enabled: boolean; }) { if (!enabled || items.length === 0) return null; return (

{title || "赞助商"}

    {items.map((sp) => { const tip = (sp.hover_text || sp.name || "").trim(); const href = sp.link_url?.trim() || undefined; const inner = ( // eslint-disable-next-line @next/next/no-img-element {sp.name} ); return (
  • {href ? ( {inner} ) : ( {inner} )}
  • ); })}
); } function CommunityPanelsBody({ stats, hot, activeUsers, announcements, newUsers, checkin, allowComments, canManageAnnouncements, canManagePages, sidebarPages = [], siteDescription, ads = [], adsPanelTitle = "自助推广", adsEnabled = true, sponsors = [], sponsorsPanelTitle = "赞助商", sponsorsEnabled = true, }: PanelsProps) { return ( <> ); } export function CommunityPanels(props: PanelsProps) { return ( ); } export function CommunityPanelsMobile(props: PanelsProps) { return (
); }