Files
frontend/src/app/character-center/page.tsx

121 lines
4.6 KiB
TypeScript
Raw Normal View History

// 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;
}
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[] = [];
// 渲染客户端组件
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>
);
}