This commit is contained in:
Joan
2025-11-27 16:27:01 +01:00
parent 33cc9586c2
commit 81f8912059
304 changed files with 56149 additions and 10122 deletions

View File

@@ -1,5 +1,8 @@
import { useState, useEffect } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import { useAuth } from '../hooks/useAuth'
import { useGameWebSocket } from '../hooks/useGameWebSocket'
import api from '../services/api'
import './Game.css'
interface GameHeaderProps {
@@ -9,37 +12,82 @@ interface GameHeaderProps {
export default function GameHeader({ className = '' }: GameHeaderProps) {
const navigate = useNavigate()
const location = useLocation()
const { user, logout } = useAuth()
const { currentCharacter, logout } = useAuth()
const [playerCount, setPlayerCount] = useState<number>(0)
// Fetch initial player count
useEffect(() => {
const fetchPlayerCount = async () => {
try {
const response = await api.get('/api/statistics/online-players')
if (response.data && typeof response.data.count === 'number') {
setPlayerCount(response.data.count)
}
} catch (error) {
console.error('Failed to fetch player count:', error)
}
}
fetchPlayerCount()
}, [])
// Connect to WebSocket for player count updates
// We use a separate connection here to ensure the header always has live data
// regardless of which page is active (Game, Leaderboards, Profile)
const token = localStorage.getItem('token')
useGameWebSocket({
token,
enabled: !!token,
onMessage: (message) => {
if (message.type === 'player_count_update' && message.data?.count !== undefined) {
//console.log('🔢 GameHeader received count update:', message.data.count)
setPlayerCount(message.data.count)
}
}
})
const isActive = (path: string) => {
return location.pathname === path || location.pathname.startsWith(path)
}
const isOnOwnProfile = location.pathname === `/profile/${user?.id}`
const isOnOwnProfile = location.pathname === `/profile/${currentCharacter?.id}`
return (
<header className={`game-header ${className}`}>
<h1>Echoes of the Ash</h1>
<div className="header-left">
<h1>Echoes of the Ash</h1>
</div>
<nav className="nav-links">
<button
onClick={() => navigate('/game')}
<button
onClick={() => navigate('/game')}
className={`nav-link ${isActive('/game') ? 'active' : ''}`}
>
🎮 Game
</button>
<button
onClick={() => navigate('/leaderboards')}
<button
onClick={() => navigate('/leaderboards')}
className={`nav-link ${isActive('/leaderboards') ? 'active' : ''}`}
>
🏆 Leaderboards
</button>
</nav>
<div className="user-info">
<button
onClick={() => navigate(`/profile/${user?.id}`)}
<div className="player-count-badge" title="Online Players">
<span className="status-dot"></span>
<span className="count-text">{playerCount} Online</span>
</div>
<button
onClick={() => navigate(`/profile/${currentCharacter?.id}`)}
className={`username-link ${isOnOwnProfile ? 'active' : ''}`}
>
{user?.username}
{currentCharacter?.name}
</button>
<button
onClick={() => navigate('/account')}
className="button-secondary"
>
Account
</button>
<button onClick={logout} className="button-secondary">Logout</button>
</div>