76 lines
3.2 KiB
TypeScript
76 lines
3.2 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { useEngineStore } from '@/store/engineStore'
|
|
import { cn } from '@/lib/utils'
|
|
import ThemeToggle from '@/components/layout/ThemeToggle'
|
|
|
|
export default function Header() {
|
|
const status = useEngineStore((s) => s.status)
|
|
const call = (path: string) => fetch(`/api/engine/${path}`, { method: 'POST' })
|
|
|
|
const isRunning = status === 'Running'
|
|
const isPaused = status === 'Paused'
|
|
|
|
return (
|
|
<header className="glass-strong sticky top-0 z-40">
|
|
{/* Gradient border at bottom */}
|
|
<div className="absolute bottom-0 inset-x-0 h-px bg-gradient-to-r from-transparent via-g-green/30 to-transparent" />
|
|
|
|
<div className="flex items-center justify-between px-6 h-[56px]">
|
|
{/* Brand */}
|
|
<Link href="/" className="flex items-center gap-3.5 group cursor-pointer">
|
|
<div className="relative">
|
|
<div className="flex h-9 w-9 items-center justify-center rounded-xl bg-gradient-to-br from-g-green/25 to-g-cyan/15 border border-g-green/20 group-hover:border-g-green/40 transition-colors">
|
|
<span className="font-extrabold text-g-green text-sm leading-none">G</span>
|
|
</div>
|
|
{/* Glow behind logo */}
|
|
<div className="absolute inset-0 rounded-xl bg-g-green/10 blur-lg -z-10 group-hover:bg-g-green/20 transition-colors" />
|
|
</div>
|
|
<div className="flex flex-col">
|
|
<span className="text-[15px] font-bold text-g-text tracking-tight leading-none group-hover:text-g-green transition-colors">
|
|
Ghost Node
|
|
</span>
|
|
<span className="text-[10px] text-g-faint leading-none mt-1 tracking-[0.15em] uppercase">
|
|
Auction Sniper · v2.7
|
|
</span>
|
|
</div>
|
|
</Link>
|
|
|
|
{/* Controls */}
|
|
<div className="flex items-center gap-2.5">
|
|
{/* Status pill */}
|
|
<div className={cn(
|
|
'flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold mr-1 border transition-all duration-300',
|
|
isRunning
|
|
? 'bg-g-green/8 border-g-green/20 text-g-green shadow-[0_0_16px_rgba(0,232,123,0.08)]'
|
|
: isPaused
|
|
? 'bg-g-amber/8 border-g-amber/20 text-g-amber'
|
|
: 'bg-g-faint/10 border-g-border text-g-muted'
|
|
)}>
|
|
<span className={cn(
|
|
'w-2 h-2 rounded-full transition-all duration-300',
|
|
isRunning
|
|
? 'bg-g-green shadow-[0_0_8px_rgba(0,232,123,0.8)] animate-pulse'
|
|
: isPaused ? 'bg-g-amber' : 'bg-g-faint'
|
|
)} />
|
|
{status}
|
|
</div>
|
|
|
|
<button onClick={() => call('pause')} className="g-btn text-xs h-8">Pause</button>
|
|
<button onClick={() => call('resume')} className="g-btn text-xs h-8">Resume</button>
|
|
<button onClick={() => call('restart')} className="g-btn text-xs h-8">Restart</button>
|
|
<button
|
|
onClick={() => { if (confirm('Kill the engine?')) call('kill') }}
|
|
className="g-btn-danger text-xs h-8"
|
|
>
|
|
Kill
|
|
</button>
|
|
<div className="w-px h-5 bg-g-border/50 mx-0.5" />
|
|
<ThemeToggle />
|
|
</div>
|
|
</div>
|
|
</header>
|
|
)
|
|
}
|