botWebWars/frontend/src/components/Header.tsx

146 lines
5.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
interface HeaderProps {
isConnected: boolean;
gameStarted: boolean;
onStartGame: () => void;
onOpenRegister: () => void;
onQuickSpawn: () => void;
onResetBoard: () => void;
playerCount: number;
isConcluded?: boolean;
onOpenScoreboard?: () => void;
}
export const Header: React.FC<HeaderProps> = ({
isConnected,
gameStarted,
onStartGame,
onOpenRegister,
onQuickSpawn,
onResetBoard,
playerCount,
isConcluded,
onOpenScoreboard,
}) => {
return (
<header className="h-16 border-b border-slate-800 bg-slate-900/90 backdrop-blur px-6 flex items-center justify-between z-10">
{/* Brand & Stats */}
<div className="flex items-center gap-6">
<div className="flex items-center gap-3">
<div className="w-8 h-8 rounded-lg bg-gradient-to-tr from-sky-500 to-indigo-600 flex items-center justify-center font-black text-white text-base shadow-lg shadow-sky-500/20">
W
</div>
<div>
<h1 className="text-base font-bold tracking-tight text-white flex items-center gap-2">
botWebWars
<span className="text-[10px] uppercase font-mono px-1.5 py-0.5 rounded bg-sky-950 text-sky-400 border border-sky-800">
v{import.meta.env.VITE_APP_VERSION || '1.3'}
</span>
</h1>
<p className="text-[11px] text-slate-400 font-mono">
64×64 Grid Arena Coords (0,0) to (64,64)
</p>
</div>
</div>
{/* Live status badge */}
<div className="flex items-center gap-2 px-2.5 py-1 rounded-full bg-slate-800 border border-slate-700 text-xs font-mono">
<span
className={`w-2 h-2 rounded-full ${
isConnected ? 'bg-emerald-400 shadow-[0_0_8px_#34d399]' : 'bg-amber-400 animate-ping'
}`}
/>
<span className={isConnected ? 'text-slate-300' : 'text-amber-300'}>
{isConnected ? 'LIVE SYNC' : 'CONNECTING...'}
</span>
</div>
{/* Game Phase Badge */}
{!isConcluded && (
<div className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-slate-800 border border-slate-700 text-xs font-mono">
{gameStarted ? (
<span className="flex items-center gap-1.5 text-emerald-400 font-semibold">
<span className="w-2 h-2 rounded-full bg-emerald-400 animate-pulse" />
GAME IN PROGRESS
</span>
) : (
<span className="flex items-center gap-1.5 text-amber-300 font-medium">
<span className="w-2 h-2 rounded-full bg-amber-400 animate-ping" />
LOBBY (WAITING TO START)
</span>
)}
</div>
)}
{/* Game concluded banner tag */}
{isConcluded && (
<div className="flex items-center gap-1.5 px-3 py-1 rounded-full bg-amber-500/20 border border-amber-400 text-amber-300 text-xs font-bold animate-pulse">
<span>🏆</span> GAME CONCLUDED
</div>
)}
</div>
{/* Action Buttons */}
<div className="flex items-center gap-3">
{/* Start Game Button (Visible during Lobby) */}
{!gameStarted && !isConcluded && (
<button
onClick={onStartGame}
disabled={playerCount === 0}
className={`text-xs font-bold px-4 py-1.5 rounded-lg flex items-center gap-1.5 shadow-lg transition-all ${
playerCount > 0
? 'bg-gradient-to-r from-emerald-500 to-teal-600 hover:from-emerald-400 hover:to-teal-500 text-white shadow-emerald-500/30 animate-pulse cursor-pointer ring-1 ring-emerald-400'
: 'bg-slate-800 text-slate-500 border border-slate-700 cursor-not-allowed'
}`}
title={playerCount === 0 ? 'Spawn or register bots before starting' : 'Start the game!'}
>
<span></span> Start Game ({playerCount} {playerCount === 1 ? 'Bot' : 'Bots'})
</button>
)}
{isConcluded && onOpenScoreboard && (
<button
onClick={onOpenScoreboard}
className="text-xs font-bold text-amber-950 px-3.5 py-1.5 rounded-lg bg-gradient-to-r from-amber-400 to-yellow-300 hover:from-amber-300 hover:to-yellow-200 shadow-lg shadow-amber-400/30 flex items-center gap-1.5 transition-all"
>
<span>🏆</span> Final Scoreboard
</button>
)}
<a
href="/docs"
target="_blank"
rel="noopener noreferrer"
className="text-xs font-mono text-slate-400 hover:text-sky-400 transition-colors px-2.5 py-1.5 rounded-lg border border-slate-800 hover:border-slate-700 bg-slate-950/40"
title="Open FastAPI Swagger API Docs"
>
API Docs
</a>
<button
onClick={onResetBoard}
className="text-xs font-medium text-slate-400 hover:text-red-400 transition-colors px-3 py-1.5 rounded-lg border border-slate-800 hover:border-red-900/60 bg-slate-950/40"
title="Regenerate map terrain and clear all players"
>
Recreate Layout
</button>
<button
onClick={onQuickSpawn}
className="text-xs font-medium text-slate-200 hover:text-white transition-all px-3.5 py-1.5 rounded-lg bg-slate-800 hover:bg-slate-700 border border-slate-700 shadow flex items-center gap-1.5"
>
<span>🎲</span> Quick Spawn Bot
</button>
<button
onClick={onOpenRegister}
className="text-xs font-semibold text-white transition-all px-4 py-1.5 rounded-lg bg-gradient-to-r from-sky-500 to-indigo-600 hover:from-sky-400 hover:to-indigo-500 shadow-lg shadow-sky-500/25 flex items-center gap-1.5"
>
<span>+</span> Register Player
</button>
</div>
</header>
);
};