"use client" import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card" import { EmptyState } from "@/components/ui/empty-state" import { listGames, listPosts } from "@/lib/api" import { roleLabels } from "@/lib/constants" import type { Game, Post } from "@/lib/types" import { Heart, MessageCircle, PenSquare, Pin } from "lucide-react" import Link from "next/link" import { useEffect, useState } from "react" export default function CommunityPage() { const [games, setGames] = useState([]) const [posts, setPosts] = useState([]) const [postsLoading, setPostsLoading] = useState(true) const [sortMode, setSortMode] = useState<"latest" | "hot">("latest") const [selectedGame, setSelectedGame] = useState(null) useEffect(() => { let cancelled = false Promise.all([listGames(), listPosts()]) .then(([gamesItems, postsItems]) => { if (cancelled) return setGames(gamesItems) setPosts(postsItems) setPostsLoading(false) }) .catch(() => { if (cancelled) return setGames([]) setPosts([]) setPostsLoading(false) }) return () => { cancelled = true } }, []) const filteredPosts = posts .filter((post) => { if (!selectedGame) return true return post.tags.includes(selectedGame) }) .sort((a, b) => { if (sortMode === "latest") { return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() } const scoreA = a.likeCount + a.commentCount const scoreB = b.likeCount + b.commentCount return scoreB - scoreA }) return (

社区

{games.map((game) => ( ))}
{postsLoading ? (
加载中...
) : filteredPosts.length === 0 ? ( ) : ( filteredPosts.map((post) => (
{post.author.nickname[0]}
{post.author.nickname} {roleLabels[post.author.role]} {post.pinned && }
{new Date(post.createdAt).toLocaleDateString("zh-CN")}

{post.title}

{post.content}

{post.tags.length > 0 && (
{post.tags.map((tag) => ( {tag} ))}
)}
{post.likeCount} {post.commentCount}
)) )}
) }