Implement API integration for statistics, recent chat messages, and top players; remove mock data
This commit is contained in:
220
src/App.tsx
220
src/App.tsx
@@ -1,47 +1,126 @@
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
|
import { useState, useEffect } from 'react'
|
||||||
import Layout from './components/Layout'
|
import Layout from './components/Layout'
|
||||||
import './App.css'
|
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() {
|
function App() {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
// Mock data - in real app, this would come from API
|
const [stats, setStats] = useState<Stats>({
|
||||||
// API endpoints: /api/server/statistics/*
|
totalPlayers: 0,
|
||||||
// To integrate real API, replace mock data with:
|
totalConnects: 0,
|
||||||
//
|
totalPlayTime: 0,
|
||||||
// const [stats, setStats] = useState({ totalPlayers: 0, totalConnects: 0, totalPlayTime: 0, totalKills: 0 })
|
totalKills: 0
|
||||||
//
|
})
|
||||||
// useEffect(() => {
|
const [recentChats, setRecentChats] = useState<ChatMessage[]>([])
|
||||||
// const timeRangeEnd = Date.now()
|
const [topPlayers, setTopPlayers] = useState<TopPlayer[]>([])
|
||||||
// const timeRangeStart = 0 // or specific start time
|
|
||||||
// const requestBody = { timeRangeStart, timeRangeEnd, playerFilter: [] }
|
// Fetch statistics data from API
|
||||||
//
|
useEffect(() => {
|
||||||
// Promise.all([
|
const timeRangeEnd = Date.now()
|
||||||
// fetch('/api/server/statistics/total-player-count', { method: 'POST', body: JSON.stringify(requestBody) }),
|
const timeRangeStart = 0 // all time
|
||||||
// fetch('/api/server/statistics/total-connect-count', { method: 'POST', body: JSON.stringify(requestBody) }),
|
const requestBody = { timeRangeStart, timeRangeEnd }
|
||||||
// fetch('/api/server/statistics/total-play-time', { method: 'POST', body: JSON.stringify(requestBody) }),
|
|
||||||
// fetch('/api/server/statistics/total-kill-count', {
|
Promise.all([
|
||||||
// method: 'POST',
|
fetch('/api/server/statistics/total-player-count', {
|
||||||
// body: JSON.stringify({ ...requestBody, headshotOnly: false, weaponFilter: [] })
|
method: 'POST',
|
||||||
// })
|
headers: { 'Content-Type': 'application/json' },
|
||||||
// ]).then(responses => Promise.all(responses.map(r => r.json())))
|
body: JSON.stringify(requestBody)
|
||||||
// .then(([players, connects, playTime, kills]) => {
|
}),
|
||||||
// setStats({
|
fetch('/api/server/statistics/total-connect-count', {
|
||||||
// totalPlayers: players.count,
|
method: 'POST',
|
||||||
// totalConnects: connects.totalConnectCount,
|
headers: { 'Content-Type': 'application/json' },
|
||||||
// totalPlayTime: playTime.totalPlayTime,
|
body: JSON.stringify(requestBody)
|
||||||
// totalKills: kills.totalKillCount
|
}),
|
||||||
// })
|
fetch('/api/server/statistics/total-play-time', {
|
||||||
// })
|
method: 'POST',
|
||||||
// }, [])
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(requestBody)
|
||||||
const stats = {
|
}),
|
||||||
totalPlayers: 1247, // from /api/server/statistics/total-player-count
|
fetch('/api/server/statistics/total-kill-count', {
|
||||||
totalConnects: 3456, // from /api/server/statistics/total-connect-count
|
method: 'POST',
|
||||||
totalPlayTime: 8640000, // from /api/server/statistics/total-play-time (in seconds)
|
headers: { 'Content-Type': 'application/json' },
|
||||||
totalKills: 15420 // from /api/server/statistics/total-kill-count
|
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
|
// Format playtime from seconds to hours
|
||||||
const formatPlayTime = (seconds: number) => {
|
const formatPlayTime = (seconds: number) => {
|
||||||
@@ -54,75 +133,6 @@ function App() {
|
|||||||
return hours.toLocaleString()
|
return hours.toLocaleString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mock recent chat messages - from /api/server/statistics/recent-chat-message
|
|
||||||
// Response format: { messages: [{ steamID64, userName, message, timeStamp }] }
|
|
||||||
// To integrate real API:
|
|
||||||
// const [recentChats, setRecentChats] = useState([])
|
|
||||||
// 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 => setRecentChats(data.messages))
|
|
||||||
// }, [])
|
|
||||||
const recentChats = [
|
|
||||||
{
|
|
||||||
steamID64: '76561198281616762',
|
|
||||||
userName: 'ProGamer99',
|
|
||||||
message: 'GG everyone! Great match!',
|
|
||||||
timeStamp: Date.now() - 120000 // 2 minutes ago
|
|
||||||
},
|
|
||||||
{
|
|
||||||
steamID64: '76561198281616763',
|
|
||||||
userName: 'SniperElite',
|
|
||||||
message: 'Anyone up for a quick match?',
|
|
||||||
timeStamp: Date.now() - 300000 // 5 minutes ago
|
|
||||||
},
|
|
||||||
{
|
|
||||||
steamID64: '76561198281616764',
|
|
||||||
userName: 'HeadshotKing',
|
|
||||||
message: 'New server just went live!',
|
|
||||||
timeStamp: Date.now() - 480000 // 8 minutes ago
|
|
||||||
},
|
|
||||||
{
|
|
||||||
steamID64: '76561198281616765',
|
|
||||||
userName: 'TacticalNuke',
|
|
||||||
message: 'Looking for team players',
|
|
||||||
timeStamp: Date.now() - 720000 // 12 minutes ago
|
|
||||||
},
|
|
||||||
{
|
|
||||||
steamID64: '76561198281616766',
|
|
||||||
userName: 'FragMaster',
|
|
||||||
message: 'Server maintenance complete',
|
|
||||||
timeStamp: Date.now() - 900000 // 15 minutes ago
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
// Mock top players - from /api/server/statistics/top-play-time
|
|
||||||
// Response format: { players: [{ steamID64, userName, playTime }] }
|
|
||||||
// To integrate real API:
|
|
||||||
// const [topPlayers, setTopPlayers] = useState([])
|
|
||||||
// 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 => setTopPlayers(data.players.slice(0, 3))) // top 3
|
|
||||||
// }, [])
|
|
||||||
const topPlayers = [
|
|
||||||
{ steamID64: '76561198281616762', userName: 'ProGamer99', playTime: 882000 }, // 245 hours
|
|
||||||
{ steamID64: '76561198281616763', userName: 'SniperElite', playTime: 784800 }, // 218 hours
|
|
||||||
{ steamID64: '76561198281616764', userName: 'HeadshotKing', playTime: 702000 } // 195 hours
|
|
||||||
]
|
|
||||||
|
|
||||||
// Format time ago from timestamp
|
// Format time ago from timestamp
|
||||||
const formatTimeAgo = (timestamp: number) => {
|
const formatTimeAgo = (timestamp: number) => {
|
||||||
const seconds = Math.floor((Date.now() - timestamp) / 1000)
|
const seconds = Math.floor((Date.now() - timestamp) / 1000)
|
||||||
|
|||||||
Reference in New Issue
Block a user