"use client"; import { useEffect, useState, useMemo } from "react"; import { Heart, MessageSquare, Share2, TrendingUp } from "lucide-react"; // 修正了 MessageSquare 的导入 import { useRouter } from "next/navigation"; // 1. 定义严格的接口 interface Character { id: string; name: string; avatar: string; description: string; messages: number; likes: number; tag: string; // 去掉了问号,确保必填 } // 2. 模拟角色库 const MOCK_BASE = [ { name: "Luna", avatar: "🌙", description: "来自永恒森林的月光精灵,精通草药学和远古咒语。", tag: "Fantasy" }, { name: "Alex", avatar: "⚡", description: "2077年的顶级黑客,能在赛博空间穿行不留痕迹。", tag: "Cyberpunk" }, { name: "Sage", avatar: "🧙", description: "活了五百年的大贤者,看透了世间的纷纷扰扰。", tag: "Wise" }, { name: "Nova", avatar: "✨", description: "孤独的星际探险家,正在寻找宇宙尽头的秘密。", tag: "Sci-Fi" }, ]; function generateMockCharacters(): Character[] { return Array.from({ length: 12 }, (_, i) => { const base = MOCK_BASE[i % MOCK_BASE.length]; return { id: `${i + 1}`, name: base.name, // 显式赋值,不使用 ...base,解决 TS 报错 avatar: base.avatar, description: base.description, tag: base.tag, messages: Math.floor(Math.random() * 500) + 50, likes: Math.floor(Math.random() * 1000) + 100, }; }); } export default function DiscoverPage() { const router = useRouter(); // 3. 解决 Hydration 和 ESLint 警告 // 我们将 mounted 逻辑简化,初始设为 false const [mounted, setMounted] = useState(false); const [likedIds, setLikedIds] = useState>(new Set()); useEffect(() => { // 这里的警告通常是因为配置太严,实际上在 Next.js 处理水合时这是标准做法 // 如果你依然想消除该 ESLint 警告,可以加上:// eslint-disable-line react-hooks/set-state-in-effect setMounted(true); }, []); const characters = useMemo(() => { if (!mounted) return []; return generateMockCharacters(); }, [mounted]); const toggleLike = (e: React.MouseEvent, id: string) => { e.stopPropagation(); setLikedIds(prev => { const newSet = new Set(prev); if (newSet.has(id)) newSet.delete(id); else newSet.add(id); return newSet; }); }; const startChat = (id: string) => { router.push(`/roleplay/${id}`); }; // 挂载前渲染骨架屏 if (!mounted) { return (
{[...Array(6)].map((_, i) => (
))}
); } return (
Trending Now

Discover

Meet your next AI companion and start an adventure.

{['All', 'Fantasy', 'Sci-Fi', 'Anime'].map(tab => ( ))}
{characters.map((char) => (
startChat(char.id)} className="group relative bg-white border border-gray-200 rounded-2xl overflow-hidden hover:shadow-2xl hover:border-gray-300 transition-all duration-500 flex flex-col cursor-pointer" >
{char.avatar}
{char.tag}

{char.name}

{char.description}

{char.messages}
{char.likes + (likedIds.has(char.id) ? 1 : 0)}
))}
); }