2025-10-06 18:54:26 +08:00
|
|
|
|
// src/app/character-center/page.tsx
|
|
|
|
|
|
// 角色中心页面 - 仅登录用户可访问
|
|
|
|
|
|
import { getServerSession } from 'next-auth';
|
|
|
|
|
|
import { authOptions } from '@/lib/api/auth';
|
|
|
|
|
|
import { redirect } from 'next/navigation';
|
|
|
|
|
|
import CharacterCenterClient from './CharacterCenterClient';
|
|
|
|
|
|
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card';
|
|
|
|
|
|
import { Button } from '@/components/ui/button';
|
|
|
|
|
|
|
2025-10-09 23:42:41 +08:00
|
|
|
|
// 角色类型定义
|
|
|
|
|
|
interface Character {
|
|
|
|
|
|
id: string;
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
skinId: string;
|
|
|
|
|
|
created: string;
|
|
|
|
|
|
level: number;
|
|
|
|
|
|
description?: string;
|
|
|
|
|
|
isActive: boolean;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-06 18:54:26 +08:00
|
|
|
|
export default async function CharacterCenter() {
|
|
|
|
|
|
// 检查用户登录状态
|
|
|
|
|
|
const session = await getServerSession(authOptions);
|
|
|
|
|
|
|
|
|
|
|
|
if (!session) {
|
|
|
|
|
|
// 未登录用户重定向到登录页面
|
|
|
|
|
|
redirect('/');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 安全地获取用户信息
|
|
|
|
|
|
const userName = session.user?.name || '玩家';
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟的角色数据
|
2025-10-09 23:42:41 +08:00
|
|
|
|
const characters: Character[] = [];
|
2025-10-06 18:54:26 +08:00
|
|
|
|
|
|
|
|
|
|
// 渲染客户端组件
|
|
|
|
|
|
return <CharacterCenterClient userName={userName} characters={characters} />;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 角色卡片组件
|
|
|
|
|
|
function CharacterCard({ character }: { character: any }) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Card className="overflow-hidden hover:shadow-lg transition-all duration-300 border-0 shadow-md">
|
|
|
|
|
|
<div className="relative">
|
|
|
|
|
|
{/* 角色状态标签 */}
|
|
|
|
|
|
<div className="absolute top-3 right-3 bg-green-500 text-white text-xs px-2 py-1 rounded-full">
|
|
|
|
|
|
活跃
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 角色皮肤预览 */}
|
|
|
|
|
|
<div className="h-48 bg-gradient-to-b from-blue-50 to-green-50 dark:from-gray-700 dark:to-gray-800 flex items-center justify-center p-4">
|
|
|
|
|
|
<div className="relative w-28 h-48">
|
|
|
|
|
|
<img
|
|
|
|
|
|
src="/test-skin.png"
|
|
|
|
|
|
alt={character.name}
|
|
|
|
|
|
className="object-contain w-full h-full"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<CardHeader className="pb-2">
|
|
|
|
|
|
<CardTitle className="text-xl">{character.name}</CardTitle>
|
|
|
|
|
|
<div className="text-sm text-gray-500 dark:text-gray-400">
|
|
|
|
|
|
等级 {character.level} • 创建于 {character.created}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
|
|
|
|
|
|
<CardContent>
|
|
|
|
|
|
<div className="space-y-3">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">角色进度</div>
|
|
|
|
|
|
<div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2">
|
|
|
|
|
|
<div
|
|
|
|
|
|
className="bg-green-600 h-2 rounded-full"
|
|
|
|
|
|
style={{ width: `${(character.level / 100) * 100}%` }}
|
|
|
|
|
|
></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
|
|
|
|
|
|
<CardFooter className="flex justify-between border-t pt-4">
|
|
|
|
|
|
<Button variant="ghost" size="sm" className="text-gray-600 dark:text-gray-300">
|
|
|
|
|
|
编辑
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<Button size="sm" className="bg-green-600 hover:bg-green-700">
|
|
|
|
|
|
切换到
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</CardFooter>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 添加角色卡片组件
|
|
|
|
|
|
function AddCharacterCard() {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Card className="overflow-hidden hover:shadow-lg transition-all duration-300 border-2 border-dashed border-gray-300 dark:border-gray-600 bg-gray-50 dark:bg-gray-800 h-full flex flex-col items-center justify-center p-6 cursor-pointer">
|
|
|
|
|
|
<div className="text-6xl mb-4">➕</div>
|
|
|
|
|
|
<h3 className="text-lg font-bold text-gray-700 dark:text-gray-300 mb-2">添加新角色</h3>
|
|
|
|
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 text-center">
|
|
|
|
|
|
创建一个新的游戏角色
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 统计卡片组件
|
|
|
|
|
|
function StatCard({ title, value, icon }: { title: string; value: string; icon: string }) {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Card className="border-0 shadow-md">
|
|
|
|
|
|
<CardHeader>
|
|
|
|
|
|
<div className="text-4xl mb-2">{icon}</div>
|
|
|
|
|
|
<CardTitle className="text-lg">{title}</CardTitle>
|
|
|
|
|
|
</CardHeader>
|
|
|
|
|
|
<CardContent>
|
|
|
|
|
|
<div className="text-3xl font-bold">{value}</div>
|
|
|
|
|
|
</CardContent>
|
|
|
|
|
|
</Card>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|