refactor(CharacterDetail): 重构角色详情页面布局和功能
- 更新页面布局,将头像和导航栏移到左侧,主要内容移到右侧- 添加页面滚动重置功能,确保每次打开详情页时从顶部开始 - 优化各个部分内容的样式和间距,提升可读性和美观度 - 更新角色列表页面中的角色图片链接 - 在导航栏中添加角色列表页面的链接
This commit is contained in:
@@ -13,7 +13,7 @@ interface NavItem {
|
||||
const navItems: NavItem[] = [
|
||||
{ path: "/", label: "对战阵容" },
|
||||
// { path: "/home", label: "主页" },
|
||||
// { path: "/characters", label: "角色列表" },
|
||||
{ path: "/characters", label: "角色列表" },
|
||||
// { path: "/builds", label: "配装攻略" },
|
||||
// { path: "/battles", label: "对战信息" },
|
||||
// { path: "/news", label: "资讯中心" },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
export interface Skill {
|
||||
name: string;
|
||||
@@ -42,6 +42,10 @@ interface CharacterDetailProps {
|
||||
}
|
||||
|
||||
const CharacterDetail: React.FC<CharacterDetailProps> = ({ character }) => {
|
||||
useEffect(() => {
|
||||
window.scrollTo({ top: 0, behavior: 'auto' });
|
||||
}, []);
|
||||
|
||||
const renderStars = (count: number) => {
|
||||
return Array(count)
|
||||
.fill(0)
|
||||
@@ -74,141 +78,128 @@ const CharacterDetail: React.FC<CharacterDetailProps> = ({ character }) => {
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-[#1A1412] text-white font-sans">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
|
||||
{/* 角色基本信息 */}
|
||||
<div className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 mb-8 border border-[#C17F59]/30">
|
||||
<div className="flex items-start space-x-6">
|
||||
<div className="w-32 h-32 rounded-full overflow-hidden border-4 border-[#C17F59]">
|
||||
<img
|
||||
src={character.imageUrl}
|
||||
alt={character.name}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex">
|
||||
{/* 左侧:头像+导航 */}
|
||||
<aside className="w-80 flex-shrink-0 pr-6 flex flex-col pt-12">
|
||||
{/* 头像卡片 */}
|
||||
<div className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 mb-12 border border-[#C17F59]/30 flex flex-col items-center">
|
||||
<div className="w-28 h-28 rounded-full overflow-hidden border-4 border-[#C17F59] mb-3">
|
||||
<img src={character.imageUrl} alt={character.name} className="w-full h-full object-cover" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold text-[#E6B17E] mb-2">
|
||||
{character.name}
|
||||
</h1>
|
||||
<div className="flex items-center space-x-4 mb-4">
|
||||
<div className="flex">
|
||||
{renderStars(character.stars)}
|
||||
</div>
|
||||
<span className="text-[#9B8579]">{character.class}</span>
|
||||
<h1 className="text-2xl font-bold text-[#E6B17E] mb-1">{character.name}</h1>
|
||||
<div className="flex mb-1">{renderStars(character.stars)}</div>
|
||||
<span className="text-[#9B8579] mb-2">{character.class}</span>
|
||||
</div>
|
||||
{/* 导航卡片 */}
|
||||
<nav className="sticky top-12 z-30">
|
||||
<div className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 border border-[#C17F59]/30">
|
||||
<h2 className="text-lg font-bold mb-3 text-white">Table of Contents</h2>
|
||||
<ul className="space-y-2">
|
||||
<li>
|
||||
<a href="#base-stats" className="hover:text-[#E6B17E] transition">Base Stats</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#skills" className="hover:text-[#E6B17E] transition">Skills</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#imprint" className="hover:text-[#E6B17E] transition">Imprint Concentration</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
{/* 右侧:详细内容 */}
|
||||
<main className="flex-1 max-w-4xl mx-auto space-y-8">
|
||||
{/* 基础属性 */}
|
||||
<section id="base-stats" className="scroll-mt-24 bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 border border-[#C17F59]/30 mt-12">
|
||||
<h2 className="text-xl font-bold text-[#E6B17E] mb-4">Base Stats</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-sword text-[#C17F59]"></i>
|
||||
<span>Attack: {character.baseStats.attack}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-heart text-[#C17F59]"></i>
|
||||
<span>Health: {character.baseStats.health}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-shield-alt text-[#C17F59]"></i>
|
||||
<span>Defense: {character.baseStats.defense}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-wind text-[#C17F59]"></i>
|
||||
<span>Speed: {character.baseStats.speed}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 基础属性 */}
|
||||
<div className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 mb-8 border border-[#C17F59]/30">
|
||||
<h2 className="text-xl font-bold text-[#E6B17E] mb-4">Base Stats</h2>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-sword text-[#C17F59]"></i>
|
||||
<span>Attack: {character.baseStats.attack}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-heart text-[#C17F59]"></i>
|
||||
<span>Health: {character.baseStats.health}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-shield-alt text-[#C17F59]"></i>
|
||||
<span>Defense: {character.baseStats.defense}</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-2">
|
||||
<i className="fas fa-wind text-[#C17F59]"></i>
|
||||
<span>Speed: {character.baseStats.speed}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 技能列表 */}
|
||||
<div className="space-y-6">
|
||||
{character.skills.map((skill, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 border border-[#C17F59]/30"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-xl font-bold text-[#E6B17E]">
|
||||
{skill.name}
|
||||
</h3>
|
||||
<div className="flex items-center">
|
||||
{renderSkillType(skill.type)}
|
||||
{renderSoulBurn(skill.soulBurn)}
|
||||
</div>
|
||||
</div>
|
||||
<p className="text-[#9B8579] mb-4">{skill.description}</p>
|
||||
|
||||
{skill.enhancements && skill.enhancements.length > 0 && (
|
||||
<div className="mt-4">
|
||||
<h4 className="text-lg font-semibold text-[#E6B17E] mb-2">
|
||||
Skill Enhancements
|
||||
</h4>
|
||||
<div className="space-y-2">
|
||||
{skill.enhancements.map((enhancement, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="flex items-center space-x-4 text-sm"
|
||||
>
|
||||
<div className="flex">
|
||||
{renderStars(enhancement.stars)}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{enhancement.attack && (
|
||||
<span className="text-[#9B8579]">
|
||||
Attack {enhancement.attack}
|
||||
</span>
|
||||
)}
|
||||
{enhancement.health && (
|
||||
<span className="text-[#9B8579]">
|
||||
Health {enhancement.health}
|
||||
</span>
|
||||
)}
|
||||
{enhancement.defense && (
|
||||
<span className="text-[#9B8579]">
|
||||
Defense {enhancement.defense}
|
||||
</span>
|
||||
)}
|
||||
{enhancement.effectiveness && (
|
||||
<span className="text-[#9B8579]">
|
||||
Effectiveness {enhancement.effectiveness}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{/* 技能列表 */}
|
||||
<section id="skills" className="scroll-mt-24 space-y-6">
|
||||
{character.skills.map((skill, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 border border-[#C17F59]/30"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-xl font-bold text-[#E6B17E]">{skill.name}</h3>
|
||||
<div className="flex items-center">
|
||||
{renderSkillType(skill.type)}
|
||||
{renderSoulBurn(skill.soulBurn)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 印记集中 */}
|
||||
<div className="bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 mt-8 border border-[#C17F59]/30">
|
||||
<h2 className="text-xl font-bold text-[#E6B17E] mb-4">
|
||||
Imprint Concentration
|
||||
</h2>
|
||||
{character.imprintConcentration.map((imprint, index) => (
|
||||
<div key={index} className="mb-4">
|
||||
<h3 className="text-lg font-semibold text-[#C17F59] mb-2">
|
||||
{imprint.type}
|
||||
</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{imprint.values.map((value, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="flex items-center justify-between bg-[#1A1412] p-2 rounded border border-[#C17F59]/30"
|
||||
>
|
||||
<span className="text-[#E6B17E]">{value.rank}</span>
|
||||
<span className="text-[#9B8579]">{value.value}</span>
|
||||
<p className="text-[#9B8579] mb-4">{skill.description}</p>
|
||||
{skill.enhancements && skill.enhancements.length > 0 && (
|
||||
<div className="mt-4">
|
||||
<h4 className="text-lg font-semibold text-[#E6B17E] mb-2">Skill Enhancements</h4>
|
||||
<div className="space-y-2">
|
||||
{skill.enhancements.map((enhancement, idx) => (
|
||||
<div key={idx} className="flex items-center space-x-4 text-sm">
|
||||
<div className="flex">{renderStars(enhancement.stars)}</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{enhancement.attack && (
|
||||
<span className="text-[#9B8579]">Attack {enhancement.attack}</span>
|
||||
)}
|
||||
{enhancement.health && (
|
||||
<span className="text-[#9B8579]">Health {enhancement.health}</span>
|
||||
)}
|
||||
{enhancement.defense && (
|
||||
<span className="text-[#9B8579]">Defense {enhancement.defense}</span>
|
||||
)}
|
||||
{enhancement.effectiveness && (
|
||||
<span className="text-[#9B8579]">Effectiveness {enhancement.effectiveness}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
|
||||
{/* 印记集中 */}
|
||||
<section id="imprint" className="scroll-mt-24 bg-gradient-to-br from-[#2A211E] to-[#1A1412] rounded-lg p-6 border border-[#C17F59]/30">
|
||||
<h2 className="text-xl font-bold text-[#E6B17E] mb-4">Imprint Concentration</h2>
|
||||
{character.imprintConcentration.map((imprint, index) => (
|
||||
<div key={index} className="mb-4">
|
||||
<h3 className="text-lg font-semibold text-[#C17F59] mb-2">{imprint.type}</h3>
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||
{imprint.values.map((value, idx) => (
|
||||
<div
|
||||
key={idx}
|
||||
className="flex items-center justify-between bg-[#1A1412] p-2 rounded border border-[#C17F59]/30"
|
||||
>
|
||||
<span className="text-[#E6B17E]">{value.rank}</span>
|
||||
<span className="text-[#9B8579]">{value.value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ const Characters: React.FC = () => {
|
||||
element: "fire",
|
||||
class: "Fire Warrior",
|
||||
imageUrl:
|
||||
"https://readdy.ai/api/search-image?query=anime%20style%20game%20character%20portrait%20of%20a%20female%20warrior%20with%20pink%20hair%20and%20red%20eyes%2C%20fantasy%20RPG%20character%20icon%2C%20detailed%20face%2C%20high%20quality%2C%20digital%20art&width=100&height=100&seq=1&orientation=squarish",
|
||||
"https://epic7db.com/images/heroes/abigail.webp",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
|
||||
Reference in New Issue
Block a user