Files
jiang13-bbs/frontend/app/u/[id]/UserProfileContent.tsx
freefire d93635c961 feat: 全站评论开关,并统一后台表单控件
关闭评论后前台隐藏评论能力;外观/设置/公告改用 AdminField 与 Stepper。

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

132 lines
5.4 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 Link from "next/link";
import { FileText, MessageCircle, AlertCircle } from "lucide-react";
import Pagination from "@/components/Pagination";
import { IconComment, IconEye, IconHeart } from "@/components/Icons";
import type { UserProfile, UserCommentsResponse } from "@/lib/api";
/**
* 用户主页内容区(纯服务端渲染):
* tab 与分页全部走 URL(?tab=comments&page=N),刷新/后退/分享链接均保持一致。
* Tab 切换栏已移至 page.tsx 统一渲染(含 settings / security),此组件仅负责 posts / comments 列表。
*/
export default function UserProfileContent({
userId,
profile,
tab,
commentData,
commentError,
page,
allowComments = true,
}: {
userId: string;
profile: UserProfile;
tab: "posts" | "comments";
commentData: UserCommentsResponse | null;
commentError: boolean;
page: number;
allowComments?: boolean;
}) {
return (
<div>
{tab === "posts" ? (
<div>
{Array.isArray(profile.posts) && profile.posts.length > 0 ? (
<div className="panel overflow-hidden p-0">
{profile.posts.map((post, i) => (
<Link
key={post.id}
href={`/post/${post.id}`}
className="group block px-4 sm:px-5 py-4 transition-colors hover:bg-[var(--accent-soft)] focus-visible:bg-[var(--accent-soft)]"
style={{ borderTop: i === 0 ? "none" : "1px solid var(--line)" }}
>
<div className="flex items-center gap-2 mb-2 flex-wrap">
<span className="j13-board-tag">{post.board.name}</span>
{post.pinned > 0 && <span className="badge-pin">置顶</span>}
{post.recommended && <span className="badge-rec">推荐</span>}
</div>
<h2
className="font-semibold mb-2 leading-snug transition-colors group-hover:text-[var(--accent)]"
style={{ color: "var(--ink)" }}
>
{post.title}
</h2>
<div className="flex items-center gap-4 meta text-[12px]">
<span className="tabular-nums">{new Date(post.created_at).toLocaleDateString("zh-CN")}</span>
{allowComments ? (
<span className="inline-flex items-center gap-1">
<IconComment size={12} /> {post.comment_count}
</span>
) : null}
<span className="inline-flex items-center gap-1">
<IconEye size={12} /> {post.view_count}
</span>
<span className="inline-flex items-center gap-1">
<IconHeart size={12} /> {post.like_count}
</span>
</div>
</Link>
))}
</div>
) : (
<div className="panel text-center py-16 px-6">
<FileText size={26} className="mx-auto mb-3" style={{ color: "var(--ink-3)" }} />
<p className="text-sm font-semibold" style={{ color: "var(--ink-2)" }}>暂无发帖</p>
</div>
)}
<Pagination
total={profile.posts_total}
page={page}
size={20}
basePath={`/u/${userId}`}
/>
</div>
) : commentError ? (
<div className="panel text-center py-16 px-6" role="alert">
<AlertCircle size={26} className="mx-auto mb-3" style={{ color: "var(--danger)" }} />
<p className="text-sm font-semibold" style={{ color: "var(--ink-2)" }}>评论加载失败</p>
<p className="meta mt-1.5 mb-4">网络异常,请稍后重试</p>
<Link href={`/u/${userId}?tab=comments`} className="btn btn-line btn-sm">重新加载</Link>
</div>
) : commentData && (commentData.comments?.length ?? 0) > 0 ? (
<div>
<div className="panel overflow-hidden p-0">
{(commentData.comments ?? []).map((c, i) => (
<Link
key={c.id}
href={`/post/${c.post_id}`}
className="block px-4 sm:px-5 py-4 transition-colors hover:bg-[var(--accent-soft)] focus-visible:bg-[var(--accent-soft)]"
style={{ borderTop: i === 0 ? "none" : "1px solid var(--line)" }}
>
<div className="meta text-xs mb-2">
评论于《<span style={{ color: "var(--accent)" }}>{c.post_title}</span>》
</div>
<p
className="text-[15px] leading-relaxed line-clamp-2"
style={{ color: "var(--ink)" }}
>
{c.content}
</p>
<div className="meta text-xs mt-2 tabular-nums">
{new Date(c.created_at).toLocaleString("zh-CN")}
</div>
</Link>
))}
</div>
<Pagination
total={commentData.total}
page={commentData.page}
size={20}
basePath={`/u/${userId}`}
query={{ tab: "comments" }}
/>
</div>
) : (
<div className="panel text-center py-16 px-6">
<MessageCircle size={26} className="mx-auto mb-3" style={{ color: "var(--ink-3)" }} />
<p className="text-sm font-semibold" style={{ color: "var(--ink-2)" }}>暂无评论</p>
</div>
)}
</div>
);
}