Untitled
unknown
plain_text
9 months ago
7.2 kB
2
Indexable
import React, { useState, useRef } from 'react';
import { Camera, X, Edit2, Save } from 'lucide-react';
const AdvancedCharacterCard = ({
initialName,
initialKoreanName,
initialTitle,
initialDescription,
rank = 'S',
backgroundTheme = 'gold',
initialImage = '/api/placeholder/400/600'
}) => {
// State for editable fields
const [isEditing, setIsEditing] = useState(false);
const [name, setName] = useState(initialName);
const [koreanName, setKoreanName] = useState(initialKoreanName);
const [title, setTitle] = useState(initialTitle);
const [description, setDescription] = useState(initialDescription);
const [image, setImage] = useState(initialImage);
const [isHovered, setIsHovered] = useState(false);
// Ref for file input
const fileInputRef = useRef(null);
// Background themes with hover effects
const backgroundColors = {
gold: 'bg-gradient-to-r from-yellow-700 to-yellow-600 hover:from-yellow-600 hover:to-yellow-500',
blue: 'bg-gradient-to-r from-blue-900 to-blue-800 hover:from-blue-800 hover:to-blue-700'
};
// Handle image upload
const handleImageUpload = (event) => {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = (e) => {
setImage(e.target.result);
};
reader.readAsDataURL(file);
}
};
// Advanced animation classes
const hoverAnimation = isHovered ? 'transform scale-105 shadow-2xl' : '';
return (
<div
className={`w-full max-w-4xl rounded-xl overflow-hidden shadow-lg ${backgroundColors[backgroundTheme]} p-6 relative transition-all duration-300 ${hoverAnimation}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
{/* Navigation Bar with Animation */}
<nav className="flex justify-between items-center mb-8 animate-fadeIn">
<div className="flex space-x-6 text-white">
{['Home', 'Characters', 'Help'].map((item) => (
<button
key={item}
className="hover:opacity-80 transition-all duration-300 hover:-translate-y-1"
>
{item}
</button>
))}
</div>
<div className="flex items-center space-x-4">
<button className="bg-transparent border border-white/20 rounded-full px-4 py-1 text-white hover:bg-white/10 transition-all duration-300 hover:scale-105">
Sign Up
</button>
<div className="relative">
<input
type="search"
placeholder="Search here..."
className="bg-white/10 rounded-full px-4 py-1 text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-white/30 transition-all duration-300"
/>
</div>
</div>
</nav>
{/* Main Content with Edit Mode */}
<div className="flex justify-between relative">
<div className="text-white space-y-4 max-w-xl">
{/* Edit/Save Button */}
<button
onClick={() => setIsEditing(!isEditing)}
className="absolute top-0 right-0 p-2 rounded-full bg-white/10 hover:bg-white/20 transition-all duration-300"
>
{isEditing ? <Save className="w-5 h-5" /> : <Edit2 className="w-5 h-5" />}
</button>
{/* Rank Badge with Animation */}
<div className="flex items-center space-x-2 mb-4 animate-pulse">
<span className="text-2xl font-bold text-yellow-300">{rank}</span>
<span className="text-sm opacity-80">RANK</span>
</div>
{/* Editable Fields */}
<div className="space-y-2">
{isEditing ? (
<>
<input
value={title}
onChange={(e) => setTitle(e.target.value)}
className="bg-white/10 rounded px-2 py-1 w-full"
/>
<input
value={name}
onChange={(e) => setName(e.target.value)}
className="bg-white/10 rounded px-2 py-1 w-full text-2xl font-bold"
/>
<input
value={koreanName}
onChange={(e) => setKoreanName(e.target.value)}
className="bg-white/10 rounded px-2 py-1 w-full"
/>
</>
) : (
<>
<p className="text-sm opacity-80">{title}</p>
<h1 className="text-3xl font-bold">{name}</h1>
<p className="text-sm opacity-80">{koreanName}</p>
</>
)}
</div>
{/* Editable Description */}
{isEditing ? (
<textarea
value={description}
onChange={(e) => setDescription(e.target.value)}
className="bg-white/10 rounded px-2 py-1 w-full h-32"
/>
) : (
<p className="text-sm opacity-90 leading-relaxed">{description}</p>
)}
</div>
{/* Image Upload Section */}
<div className="relative w-64 h-64 group">
<img
src={image}
alt={name}
className="w-full h-full object-cover rounded-lg transition-all duration-300 group-hover:opacity-75"
/>
<button
onClick={() => fileInputRef.current.click()}
className="absolute inset-0 flex items-center justify-center bg-black/50 opacity-0 group-hover:opacity-100 transition-all duration-300"
>
<Camera className="w-8 h-8 text-white" />
</button>
<input
type="file"
ref={fileInputRef}
onChange={handleImageUpload}
className="hidden"
accept="image/*"
/>
</div>
</div>
{/* Enhanced Particle Effect */}
<div className="absolute inset-0 pointer-events-none overflow-hidden">
{[...Array(30)].map((_, i) => (
<div
key={i}
className="particle absolute w-1 h-1 rounded-full"
style={{
background: backgroundTheme === 'gold' ? '#FCD34D' : '#60A5FA',
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animation: `float ${2 + Math.random() * 3}s ease-in infinite`,
animationDelay: `${Math.random() * 5}s`,
opacity: 0.6,
transform: `scale(${1 + Math.random()})`,
}}
/>
))}
</div>
</div>
);
};
// Add enhanced animations
const style = document.createElement('style');
style.textContent = `
@keyframes float {
0% { transform: translateY(0) rotate(0deg); opacity: 0; }
50% { transform: translateY(-50px) rotate(180deg); opacity: 0.8; }
100% { transform: translateY(-100px) rotate(360deg); opacity: 0; }
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fadeIn {
animation: fadeIn 0.5s ease-out forwards;
}
.particle {
pointer-events: none;
}
`;
document.head.appendChild(style);
export default AdvancedCharacterCard;Editor is loading...
Leave a Comment