167 lines
6.5 KiB
TypeScript
167 lines
6.5 KiB
TypeScript
|
|
/**
|
|||
|
|
* 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>
|
|||
|
|
)}
|
|||
|
|
</>
|
|||
|
|
);
|
|||
|
|
}
|