cosmo/frontend/src/components/Header.tsx

167 lines
6.5 KiB
TypeScript
Raw Normal View History

2025-11-29 15:10:00 +00:00
/**
* Header component - application header with navigation and controls
*/
import { useState } from 'react';
interface HeaderProps {
isTimelineMode: boolean;
onToggleTimeline: () => void;
bodyCount: number;
selectedBodyName?: string;
}
export function Header({
isTimelineMode,
onToggleTimeline,
bodyCount,
selectedBodyName
}: HeaderProps) {
const [showLoginModal, setShowLoginModal] = useState(false);
return (
<>
<header className="absolute top-0 left-0 right-0 z-50 bg-gradient-to-b from-black via-black/80 to-transparent backdrop-blur-sm">
<div className="flex items-center justify-between px-6 py-4">
{/* Left: Logo and Title */}
<div className="flex items-center gap-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-full bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center">
<span className="text-2xl">🌌</span>
</div>
<div>
<h1 className="text-2xl font-bold text-white tracking-tight">Cosmo</h1>
<p className="text-xs text-gray-400"></p>
</div>
</div>
{/* Status Info */}
<div className="ml-6 px-3 py-1.5 bg-white/5 rounded-lg border border-white/10">
<p className="text-xs text-gray-300">
{selectedBodyName ? (
<>
<span className="text-cyan-400"></span> : <span className="text-white font-medium">{selectedBodyName}</span>
</>
) : (
<>
<span className="text-green-400"></span> {bodyCount}
</>
)}
</p>
</div>
</div>
{/* Right: Controls */}
<div className="flex items-center gap-3">
{/* Timeline Mode Toggle */}
<button
onClick={onToggleTimeline}
className={`
group relative px-4 py-2 rounded-lg font-medium text-sm transition-all duration-200
${
isTimelineMode
? 'bg-blue-600 text-white border-2 border-blue-400 shadow-lg shadow-blue-500/50'
: 'bg-white/5 text-gray-300 border border-white/10 hover:bg-white/10 hover:border-white/20'
}
`}
>
<div className="flex items-center gap-2">
<span className="text-lg">📅</span>
<span>{isTimelineMode ? '时间轴已启用' : '启用时间轴'}</span>
</div>
{/* Tooltip */}
{!isTimelineMode && (
<div className="absolute top-full right-0 mt-2 px-3 py-2 bg-gray-900 text-white text-xs rounded-lg shadow-xl opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none whitespace-nowrap">
</div>
)}
</button>
{/* Login Button */}
<button
onClick={() => setShowLoginModal(true)}
className="px-4 py-2 rounded-lg font-medium text-sm bg-white/5 text-gray-300 hover:bg-white/10 border border-white/10 transition-all duration-200"
>
<div className="flex items-center gap-2">
<span className="text-lg">👤</span>
<span></span>
</div>
</button>
</div>
</div>
</header>
{/* Login Modal */}
{showLoginModal && (
<div
className="fixed inset-0 z-[100] flex items-center justify-center bg-black/70 backdrop-blur-sm"
onClick={() => setShowLoginModal(false)}
>
<div
className="bg-gray-900 rounded-2xl p-8 max-w-md w-full mx-4 shadow-2xl border border-gray-700"
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center justify-between mb-6">
<h2 className="text-2xl font-bold text-white"> Cosmo</h2>
<button
onClick={() => setShowLoginModal(false)}
className="text-gray-400 hover:text-white transition-colors"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
</label>
<input
type="text"
placeholder="请输入邮箱或用户名"
className="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-blue-500 transition-colors"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-2">
</label>
<input
type="password"
placeholder="请输入密码"
className="w-full px-4 py-3 bg-gray-800 border border-gray-600 rounded-lg text-white placeholder-gray-500 focus:outline-none focus:border-blue-500 transition-colors"
/>
</div>
<div className="flex items-center justify-between text-sm">
<label className="flex items-center text-gray-300 cursor-pointer">
<input type="checkbox" className="mr-2 rounded" />
</label>
<a href="#" className="text-blue-400 hover:text-blue-300">
?
</a>
</div>
<button className="w-full py-3 bg-gradient-to-r from-blue-600 to-blue-700 text-white rounded-lg font-medium hover:from-blue-700 hover:to-blue-800 transition-all duration-200">
</button>
<div className="text-center text-sm text-gray-400">
{' '}
<a href="#" className="text-blue-400 hover:text-blue-300">
</a>
</div>
</div>
</div>
</div>
)}
</>
);
}