Some checks failed
CI / Frontend Lint & Type Check (push) Has been cancelled
CI / Frontend Build (push) Has been cancelled
CI / Backend Lint (push) Has been cancelled
CI / Backend Tests (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
Deploy / Build & Push Images (push) Has been cancelled
Deploy / Deploy to Server (push) Has been cancelled
Deploy / Notify (push) Has been cancelled
241 lines
9.4 KiB
TypeScript
241 lines
9.4 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { usePathname } from 'next/navigation'
|
|
import { useStore } from '@/lib/store'
|
|
import {
|
|
Menu,
|
|
X,
|
|
TrendingUp,
|
|
Gavel,
|
|
CreditCard,
|
|
LayoutDashboard,
|
|
Coins,
|
|
ArrowRight,
|
|
Sparkles,
|
|
Target,
|
|
LogOut,
|
|
User,
|
|
} from 'lucide-react'
|
|
import { useState, useEffect } from 'react'
|
|
import Image from 'next/image'
|
|
import clsx from 'clsx'
|
|
|
|
export function Header() {
|
|
const pathname = usePathname()
|
|
const { isAuthenticated, user, logout, subscription } = useStore()
|
|
const [menuOpen, setMenuOpen] = useState(false)
|
|
|
|
useEffect(() => {
|
|
setMenuOpen(false)
|
|
}, [pathname])
|
|
|
|
const tierName = subscription?.tier_name || subscription?.tier || 'Scout'
|
|
|
|
const publicNavItems = [
|
|
{ href: '/discover', label: 'Discover', icon: TrendingUp },
|
|
{ href: '/acquire', label: 'Acquire', icon: Gavel },
|
|
{ href: '/intelligence', label: 'Intel', icon: TrendingUp },
|
|
{ href: '/pricing', label: 'Pricing', icon: CreditCard },
|
|
]
|
|
|
|
const isActive = (href: string) => {
|
|
if (href === '/') return pathname === '/'
|
|
return pathname.startsWith(href)
|
|
}
|
|
|
|
const isCommandCenterPage = pathname.startsWith('/terminal') || pathname.startsWith('/admin')
|
|
|
|
if (isAuthenticated && isCommandCenterPage) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<header className="fixed top-0 left-0 right-0 z-50 bg-[#020202]/95 backdrop-blur-md border-b border-white/[0.08]">
|
|
<div className="w-full px-4 sm:px-6 lg:px-8 h-14 sm:h-16 flex items-center justify-between">
|
|
{/* Logo */}
|
|
<Link href="/" className="flex items-center gap-3 h-full hover:opacity-80 transition-opacity">
|
|
<div className="relative w-7 h-7 sm:w-8 sm:h-8">
|
|
<Image src="/pounce-puma.png" alt="Pounce" fill className="object-contain" />
|
|
</div>
|
|
<span className="text-base sm:text-lg font-black tracking-[0.1em] text-white font-display">
|
|
POUNCE
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Desktop Nav */}
|
|
<nav className="hidden lg:flex items-center h-full gap-1">
|
|
{publicNavItems.map((item) => (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
className={clsx(
|
|
"flex items-center h-9 px-4 text-xs font-mono uppercase tracking-wider transition-all",
|
|
isActive(item.href)
|
|
? "text-white border-b-2 border-accent"
|
|
: "text-white/50 hover:text-white"
|
|
)}
|
|
>
|
|
{item.label}
|
|
</Link>
|
|
))}
|
|
</nav>
|
|
|
|
{/* Desktop Auth */}
|
|
<nav className="hidden sm:flex items-center h-full gap-3">
|
|
{isAuthenticated ? (
|
|
<Link
|
|
href="/terminal/hunt"
|
|
className="flex items-center gap-2 h-9 px-5 text-xs bg-accent text-black font-bold uppercase tracking-wider hover:bg-white transition-colors"
|
|
>
|
|
<Target className="w-4 h-4" />
|
|
Enter Terminal
|
|
</Link>
|
|
) : (
|
|
<>
|
|
<Link
|
|
href="/login"
|
|
className="flex items-center h-9 px-4 text-xs text-white/50 hover:text-white font-mono uppercase tracking-wider transition-colors"
|
|
>
|
|
Sign In
|
|
</Link>
|
|
<Link
|
|
href="/register"
|
|
className="flex items-center h-9 px-5 text-xs bg-accent text-black font-bold uppercase tracking-wider hover:bg-white transition-colors"
|
|
>
|
|
Enter Terminal
|
|
</Link>
|
|
</>
|
|
)}
|
|
</nav>
|
|
|
|
{/* Mobile Menu Button */}
|
|
<button
|
|
className="sm:hidden w-10 h-10 flex items-center justify-center text-white/60 hover:text-white transition-colors"
|
|
onClick={() => setMenuOpen(!menuOpen)}
|
|
>
|
|
{menuOpen ? <X className="w-5 h-5" /> : <Menu className="w-5 h-5" />}
|
|
</button>
|
|
</div>
|
|
</header>
|
|
|
|
{/* Mobile Drawer */}
|
|
{menuOpen && (
|
|
<div className="sm:hidden fixed inset-0 z-[100]">
|
|
<div
|
|
className="absolute inset-0 bg-black/80 animate-in fade-in duration-200"
|
|
onClick={() => setMenuOpen(false)}
|
|
/>
|
|
|
|
<div
|
|
className="absolute top-0 right-0 bottom-0 w-[85%] max-w-[320px] bg-[#0A0A0A] border-l border-white/[0.08] animate-in slide-in-from-right duration-300 flex flex-col"
|
|
style={{ paddingTop: 'env(safe-area-inset-top)', paddingBottom: 'env(safe-area-inset-bottom)' }}
|
|
>
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between p-4 border-b border-white/[0.08]">
|
|
<div className="flex items-center gap-3">
|
|
<Image src="/pounce-puma.png" alt="Pounce" width={28} height={28} className="object-contain" />
|
|
<div>
|
|
<p className="text-sm font-bold text-white">Pounce</p>
|
|
<p className="text-[9px] text-white/40 font-mono uppercase tracking-widest">Domain Intelligence</p>
|
|
</div>
|
|
</div>
|
|
<button
|
|
onClick={() => setMenuOpen(false)}
|
|
className="w-8 h-8 flex items-center justify-center border border-white/10 text-white/60 hover:text-white transition-all"
|
|
>
|
|
<X className="w-4 h-4" />
|
|
</button>
|
|
</div>
|
|
|
|
{/* Navigation */}
|
|
<div className="flex-1 overflow-y-auto py-4">
|
|
<div className="mb-4">
|
|
<div className="flex items-center gap-2 px-4 mb-2">
|
|
<div className="w-1 h-3 bg-accent" />
|
|
<span className="text-[9px] font-bold text-white/30 uppercase tracking-[0.2em]">Explore</span>
|
|
</div>
|
|
{publicNavItems.map((item) => (
|
|
<Link
|
|
key={item.href}
|
|
href={item.href}
|
|
onClick={() => setMenuOpen(false)}
|
|
className={clsx(
|
|
"flex items-center gap-3 px-4 py-3 transition-colors border-l-2",
|
|
isActive(item.href)
|
|
? "border-accent text-white bg-white/[0.03]"
|
|
: "border-transparent text-white/60 active:text-white active:bg-white/[0.03]"
|
|
)}
|
|
>
|
|
<item.icon className="w-4 h-4 text-white/30" />
|
|
<span className="text-sm font-medium">{item.label}</span>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
|
|
{/* Terminal section removed - "Open Terminal" button is in footer */}
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="p-4 bg-white/[0.02] border-t border-white/[0.08]">
|
|
{isAuthenticated ? (
|
|
<>
|
|
<div className="flex items-center gap-3 mb-3">
|
|
<div className="w-8 h-8 bg-accent/10 border border-accent/20 flex items-center justify-center">
|
|
<User className="w-4 h-4 text-accent" />
|
|
</div>
|
|
<div className="flex-1 min-w-0">
|
|
<p className="text-sm font-bold text-white truncate">
|
|
{user?.name || user?.email?.split('@')[0] || 'User'}
|
|
</p>
|
|
<p className="text-[9px] font-mono text-white/40 uppercase tracking-wider">{tierName}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<Link
|
|
href="/terminal/hunt"
|
|
onClick={() => setMenuOpen(false)}
|
|
className="flex items-center justify-center gap-2 w-full py-3 bg-accent text-black text-xs font-bold uppercase tracking-wider active:scale-[0.98] transition-all mb-2"
|
|
>
|
|
<Target className="w-3 h-3" />
|
|
Enter Terminal
|
|
</Link>
|
|
|
|
<button
|
|
onClick={() => { logout(); setMenuOpen(false) }}
|
|
className="flex items-center justify-center gap-2 w-full py-2 border border-white/10 text-white/40 text-[10px] font-mono uppercase tracking-wider active:bg-white/5 transition-all"
|
|
>
|
|
<LogOut className="w-3 h-3" />
|
|
Sign out
|
|
</button>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Link
|
|
href="/register"
|
|
onClick={() => setMenuOpen(false)}
|
|
className="flex items-center justify-center gap-2 w-full py-3 bg-accent text-black text-xs font-bold uppercase tracking-wider active:scale-[0.98] transition-all mb-2"
|
|
>
|
|
<Sparkles className="w-3 h-3" />
|
|
Enter Terminal
|
|
</Link>
|
|
|
|
<Link
|
|
href="/login"
|
|
onClick={() => setMenuOpen(false)}
|
|
className="flex items-center justify-center gap-2 w-full py-2 border border-white/10 text-white/50 text-[10px] font-mono uppercase tracking-wider active:bg-white/5 transition-all"
|
|
>
|
|
Sign In
|
|
<ArrowRight className="w-3 h-3" />
|
|
</Link>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
)
|
|
}
|