Commit
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user