81 lines
3.4 KiB
TypeScript
81 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import Link from 'next/link';
|
|
import { usePathname } from 'next/navigation';
|
|
import { LayoutDashboard, List, Search, Globe, Settings, TerminalSquare, Rocket } from 'lucide-react';
|
|
import { motion } from 'framer-motion';
|
|
import { ThemeToggle } from './theme-toggle';
|
|
|
|
const navItems = [
|
|
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard },
|
|
{ name: 'Listings', href: '/listings', icon: List },
|
|
{ name: 'Targets', href: '/keywords', icon: Search },
|
|
{ name: 'Sites', href: '/sites', icon: Globe },
|
|
{ name: 'AI Log', href: '/ai-log', icon: TerminalSquare },
|
|
{ name: 'Settings', href: '/settings', icon: Settings },
|
|
];
|
|
|
|
export default function Navbar() {
|
|
const pathname = usePathname();
|
|
|
|
return (
|
|
<motion.header
|
|
initial={{ y: -100, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.8, type: "spring" as const, bounce: 0.4 }}
|
|
className="sticky top-0 z-50 w-full border-b border-border/40 bg-background/70 backdrop-blur-2xl transition-all shadow-sm"
|
|
>
|
|
<div className="container mx-auto flex h-16 items-center justify-between px-4">
|
|
<Link href="/" className="flex items-center gap-2 group">
|
|
<motion.div
|
|
whileHover={{ scale: 1.1, rotate: 10 }}
|
|
whileTap={{ scale: 0.9 }}
|
|
className="bg-primary/10 p-2 rounded-xl transition-colors duration-300"
|
|
>
|
|
<Rocket className="h-6 w-6 text-primary group-hover:fill-primary/20 transition-all" />
|
|
</motion.div>
|
|
<span className="font-bold text-xl tracking-tight text-foreground group-hover:text-primary transition-colors">
|
|
BidWraith
|
|
</span>
|
|
</Link>
|
|
<nav className="hidden md:flex gap-1 bg-secondary/30 p-1.5 rounded-full border border-white/5">
|
|
{navItems.map((item, idx) => {
|
|
const isActive = pathname.startsWith(item.href);
|
|
return (
|
|
<Link
|
|
key={item.name}
|
|
href={item.href}
|
|
className={`relative flex items-center gap-2 px-4 py-2 rounded-full text-sm font-bold transition-all duration-300 ${
|
|
isActive ? 'text-primary-foreground shadow-md' : 'text-muted-foreground hover:text-foreground hover:bg-secondary/80'
|
|
}`}
|
|
>
|
|
{isActive && (
|
|
<motion.div
|
|
layoutId="nav-pill"
|
|
className="absolute inset-0 bg-primary rounded-full -z-10 shadow-[0_0_15px_rgba(139,92,246,0.4)]"
|
|
transition={{ type: 'spring', stiffness: 400, damping: 30 }}
|
|
/>
|
|
)}
|
|
<item.icon className={`h-4 w-4 ${isActive ? 'text-primary-foreground' : ''}`} />
|
|
{item.name}
|
|
</Link>
|
|
);
|
|
})}
|
|
</nav>
|
|
<div className="flex items-center gap-4">
|
|
<ThemeToggle />
|
|
<motion.div
|
|
initial={{ scale: 0 }}
|
|
animate={{ scale: 1 }}
|
|
transition={{ delay: 0.5, type: "spring" as const }}
|
|
className="hidden lg:flex items-center gap-2 px-4 py-1.5 rounded-full bg-secondary text-xs font-bold text-primary shadow-inner border border-primary/20"
|
|
>
|
|
<span className="w-2.5 h-2.5 rounded-full bg-green-500 animate-pulse shadow-[0_0_10px_rgba(34,197,94,0.8)]"></span>
|
|
SYSTEM_ACTIVE
|
|
</motion.div>
|
|
</div>
|
|
</div>
|
|
</motion.header>
|
|
);
|
|
}
|