import { useTranslation } from 'react-i18next' import { Link } from 'react-router-dom' import { useState, useEffect } from 'react' import Layout from './components/Layout' import './App.css' interface ChatMessage { steamID64: string userName: string message: string timeStamp: number } interface TopPlayer { steamID64: string userName: string playTime: number } interface Stats { totalPlayers: number totalConnects: number totalPlayTime: number totalKills: number } function App() { const { t } = useTranslation() const [stats, setStats] = useState({ totalPlayers: 0, totalConnects: 0, totalPlayTime: 0, totalKills: 0 }) const [recentChats, setRecentChats] = useState([]) const [topPlayers, setTopPlayers] = useState([]) // Fetch statistics data from API useEffect(() => { const timeRangeEnd = Date.now() const timeRangeStart = 0 // all time const requestBody = { timeRangeStart, timeRangeEnd } Promise.all([ fetch('/api/server/statistics/total-player-count', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }), fetch('/api/server/statistics/total-connect-count', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }), fetch('/api/server/statistics/total-play-time', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }), fetch('/api/server/statistics/total-kill-count', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...requestBody, headshotOnly: false, weaponFilter: [], playerFilter: [] }) }) ]) .then(responses => Promise.all(responses.map(r => r.json()))) .then(([players, connects, playTime, kills]) => { setStats({ totalPlayers: players.count || 0, totalConnects: connects.totalConnectCount || 0, totalPlayTime: playTime.totalPlayTime || 0, totalKills: kills.totalKillCount || 0 }) }) .catch(error => console.error('Error fetching stats:', error)) }, []) // Fetch recent chat messages (limit to top 5) useEffect(() => { fetch('/api/server/statistics/recent-chat-message', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ timeRangeStart: Date.now() - 3600000, // last hour timeRangeEnd: Date.now() }) }) .then(r => r.json()) .then(data => { // Limit to top 5 most recent messages const messages = data.messages || [] const top5 = messages .sort((a: ChatMessage, b: ChatMessage) => b.timeStamp - a.timeStamp) .slice(0, 5) setRecentChats(top5) }) .catch(error => console.error('Error fetching chat messages:', error)) }, []) // Fetch top players by playtime useEffect(() => { fetch('/api/server/statistics/top-play-time', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ timeRangeStart: 0, // all time timeRangeEnd: Date.now() }) }) .then(r => r.json()) .then(data => { // Get top 3 players const players = data.players || [] setTopPlayers(players.slice(0, 3)) }) .catch(error => console.error('Error fetching top players:', error)) }, []) // Format playtime from seconds to hours and minutes const formatPlayTime = (seconds: number) => { const hours = Math.floor(seconds / 3600) const minutes = Math.floor((seconds % 3600) / 60) if (hours > 0) { if (minutes > 0) { return `${hours}${t('time.hours')} ${minutes}${t('time.minutes')}` } return `${hours}${t('time.hours')}` } return `${minutes}${t('time.minutes')}` } // Format time ago from timestamp const formatTimeAgo = (timestamp: number) => { const seconds = Math.floor((Date.now() - timestamp) / 1000) if (seconds < 60) return `${seconds}s ago` const minutes = Math.floor(seconds / 60) if (minutes < 60) return `${minutes}m ago` const hours = Math.floor(minutes / 60) if (hours < 24) return `${hours}h ago` const days = Math.floor(hours / 24) return `${days}d ago` } // Format playtime to hours for leaderboard const formatPlayTimeHours = (seconds: number) => { return Math.floor(seconds / 3600) } return ( {/* Hero Section */}

{t('hero.title')}
{t('hero.titleHighlight')} {t('hero.titleEnd')}

{t('hero.subtitle')}

100 HP
30/90
{/* Statistics Section */}
👥
{stats.totalPlayers.toLocaleString()}
{t('stats.totalPlayers')}
{stats.totalConnects.toLocaleString()}
{t('stats.totalConnects')}
⏱️
{formatPlayTime(stats.totalPlayTime)}
{t('stats.totalPlayTime')}
🎯
{stats.totalKills.toLocaleString()}
{t('stats.totalKills')}
{/* Features Section */}

{t('features.title')}

🖥️

{t('features.serverBrowser.title')}

{t('features.serverBrowser.description')}

{t('features.browseServers')}
📝

{t('features.blog.title')}

{t('features.blog.description')}

{t('features.readBlog')}
📦

{t('features.git.title')}

{t('features.git.description')}

{t('features.viewGitHub')}
💬

{t('features.forum.title')}

{t('features.forum.description')}

{t('features.joinForum')}
🔗

{t('features.friends.title')}

{t('features.friends.description')}

{t('features.viewFriends')}
{/* Recent Activity Section */}

{t('activity.title')}

{recentChats.map((chat, index) => (
{chat.userName}:
{chat.message}
{formatTimeAgo(chat.timeStamp)}
))}

{t('activity.topPlayers')}

{topPlayers.map((player, index) => (
{index + 1}. {player.userName} - {formatPlayTimeHours(player.playTime)}h
))}

{t('activity.serverInfo')}

{t('activity.serverStatus')}
{t('activity.currentMap')}
{t('activity.nextRestart')}
) } export default App