Files
Nexus_Mat/components/Navbar.tsx

102 lines
4.7 KiB
TypeScript

import React from 'react';
import Link from 'next/link';
import { Layers, Plus, Search, Hexagon } from 'lucide-react';
import { UserDTO } from '../types';
interface NavbarProps {
user: UserDTO | null;
onOpenCreate: () => void;
onProfileClick: () => void;
searchQuery?: string;
onSearch?: (q: string) => void;
}
export const Navbar: React.FC<NavbarProps> = ({ user, onOpenCreate, onProfileClick, searchQuery, onSearch }) => {
const siteIconSvg = encodeURIComponent(
`<svg xmlns='http://www.w3.org/2000/svg' width='64' height='64'>`+
`<rect width='100%' height='100%' fill='#0b0b0b'/>`+
`<circle cx='32' cy='32' r='28' fill='#111' stroke='#39ff14'/>`+
`<text x='50%' y='56%' dominant-baseline='middle' text-anchor='middle' fill='#39ff14' font-size='18' font-family='monospace'>NM</text>`+
`</svg>`
);
const avatarSrc = user && user.avatarUrl && user.avatarUrl.trim()
? user.avatarUrl
: `data:image/svg+xml;utf8,${siteIconSvg}`;
return (
<nav className="sticky top-0 z-50 w-full backdrop-blur-md bg-cyber-black/80 border-b border-cyber-glass">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
{/* Logo Area */}
<div className="flex items-center gap-2 group cursor-pointer" onClick={() => window.location.hash = ''}>
<Hexagon className="text-cyber-neon w-8 h-8 group-hover:rotate-180 transition-transform duration-700" />
<span className="text-2xl font-mono font-bold tracking-tighter text-white">
NEXUS_MAT<span className="text-cyber-neon">.OS</span>
</span>
</div>
{/* Search Bar */}
<div className="hidden md:flex flex-1 max-w-lg mx-8">
<div className="relative w-full">
<div className="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<Search className="h-4 w-4 text-gray-500" />
</div>
<input
type="text"
className="block w-full pl-10 pr-3 py-2 border border-cyber-panel rounded-sm leading-5 bg-cyber-dark text-gray-300 placeholder-gray-600 focus:outline-none focus:border-cyber-neon focus:ring-1 focus:ring-cyber-neon sm:text-sm font-mono transition-all"
placeholder="SEARCH_PROTOCOL..."
value={searchQuery ?? ''}
onChange={(e) => onSearch?.(e.target.value)}
/>
</div>
</div>
{/* Actions */}
<div className="flex items-center gap-4">
{user ? (
<>
<button
onClick={onOpenCreate}
className="flex items-center gap-2 px-4 py-2 bg-cyber-neon/10 border border-cyber-neon text-cyber-neon hover:bg-cyber-neon hover:text-black transition-all duration-300 font-mono text-sm uppercase tracking-wide group"
>
<Plus className="w-4 h-4 group-hover:rotate-90 transition-transform" />
<span className="hidden sm:inline">Upload_Data</span>
</button>
<div
onClick={onProfileClick}
className="relative cursor-pointer group"
>
<div className="w-10 h-10 rounded-full border border-cyber-panel overflow-hidden bg-cyber-panel group-hover:border-cyber-pink group-hover:shadow-[0_0_15px_rgba(255,0,85,0.4)] transition-all duration-300">
<img src={avatarSrc} alt="User" width={40} height={40} className="w-full h-full object-cover" />
</div>
<div className="absolute bottom-0 right-0 w-3 h-3 bg-cyber-neon rounded-full border-2 border-black"></div>
</div>
</>
) : (
<>
<Link
href="/auth/login"
className="flex items-center gap-2 px-4 py-2 bg-cyber-neon/10 border border-cyber-neon text-cyber-neon hover:bg-cyber-neon hover:text-black transition-all duration-300 font-mono text-sm uppercase tracking-wide"
>
<span>Login</span>
</Link>
<Link
href="/auth/register"
className="flex items-center gap-2 px-4 py-2 bg-cyber-pink text-white hover:bg-white hover:text-black transition-all duration-300 font-mono text-sm uppercase tracking-wide"
>
<span>Register</span>
</Link>
</>
)}
</div>
</div>
</div>
{/* Decorative Line */}
<div className="h-[1px] w-full bg-gradient-to-r from-transparent via-cyber-neon/50 to-transparent"></div>
</nav>
);
};