studio/AssetManager.tsx

120 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState } from 'react';
import { CharacterData, LocationData, StyleOption, ModelSettings } from '../types';
import { User, MapPin, Info, Wand2, Plus } from 'lucide-react';
import InteractiveAssetEditor from './InteractiveAssetEditor';
interface AssetManagerProps {
characters: CharacterData[];
locations: LocationData[];
styleOption: StyleOption;
onUpdateCharacter: (char: CharacterData) => void;
onUpdateLocation: (loc: LocationData) => void;
onAddCharacter: () => void;
onAddLocation: () => void;
onComplete: () => void;
modelSettings: ModelSettings;
}
const AssetManager: React.FC<AssetManagerProps> = ({
characters,
locations,
styleOption,
onUpdateCharacter,
onUpdateLocation,
onAddCharacter,
onAddLocation,
onComplete,
modelSettings
}) => {
const [activeTab, setActiveTab] = useState<'characters' | 'locations'>('characters');
return (
<div className="animate-fade-in space-y-8 pb-32">
<div className="glass-card rounded-3xl p-8 flex flex-col md:flex-row justify-between items-end gap-6">
<div>
<h2 className="text-3xl font-bold text-white mb-2 text-glow"></h2>
<div className="flex items-center gap-3 text-sm text-zinc-400">
<span> DNA:</span>
<span className="px-3 py-1 bg-indigo-500/10 text-indigo-300 rounded-full border border-indigo-500/20 font-medium shadow-[0_0_10px_rgba(99,102,241,0.2)]">{styleOption.name}</span>
</div>
</div>
<div className="flex items-center gap-2">
<div className="glass-panel p-1 rounded-xl flex">
<button
onClick={() => setActiveTab('characters')}
className={`px-6 py-2.5 rounded-lg text-sm font-bold flex items-center gap-2 transition-all duration-300 ${
activeTab === 'characters' ? 'bg-white/10 text-white shadow-lg' : 'text-zinc-500 hover:text-zinc-300'
}`}
>
<User className="w-4 h-4" />
(Characters)
</button>
<button
onClick={() => setActiveTab('locations')}
className={`px-6 py-2.5 rounded-lg text-sm font-bold flex items-center gap-2 transition-all duration-300 ${
activeTab === 'locations' ? 'bg-white/10 text-white shadow-lg' : 'text-zinc-500 hover:text-zinc-300'
}`}
>
<MapPin className="w-4 h-4" />
(Locations)
</button>
</div>
<button
onClick={activeTab === 'characters' ? onAddCharacter : onAddLocation}
className="glass-btn w-10 h-10 rounded-xl flex items-center justify-center text-emerald-400 hover:bg-emerald-500/10 border-emerald-500/30"
title={activeTab === 'characters' ? "新增角色" : "新增場景"}
>
<Plus className="w-5 h-5" />
</button>
</div>
</div>
<div className="space-y-12">
{activeTab === 'characters' && characters.map(char => (
<InteractiveAssetEditor
key={char.id}
type="character"
data={char}
styleOption={styleOption}
onUpdate={(updated) => onUpdateCharacter(updated as CharacterData)}
modelSettings={modelSettings}
/>
))}
{activeTab === 'locations' && locations.map(loc => (
<InteractiveAssetEditor
key={loc.id}
type="location"
data={loc}
styleOption={styleOption}
onUpdate={(updated) => onUpdateLocation(updated as LocationData)}
modelSettings={modelSettings}
/>
))}
</div>
<div className="fixed bottom-8 left-1/2 -translate-x-1/2 z-40 w-[90%] max-w-4xl">
<div className="glass-card rounded-2xl p-4 flex justify-between items-center shadow-2xl backdrop-blur-xl">
<div className="flex items-center gap-3 px-4">
<div className="w-8 h-8 rounded-full bg-indigo-500/20 flex items-center justify-center text-indigo-400">
<Info className="w-4 h-4" />
</div>
<span className="text-zinc-300 text-sm hidden md:block"></span>
</div>
<button
onClick={onComplete}
className="glass-btn bg-emerald-500/20 border-emerald-500/50 text-white px-8 py-3 rounded-xl font-bold flex items-center gap-2 hover:bg-emerald-500/30 text-shadow-sm"
>
<Wand2 className="w-5 h-5 text-emerald-400" />
</button>
</div>
</div>
</div>
);
};
export default AssetManager;