Add Servers page with layout, mock data, and routing; update navigation and localization
This commit is contained in:
@@ -18,7 +18,7 @@ function Nav({ currentPage }: NavProps) {
|
|||||||
</div>
|
</div>
|
||||||
<div className="nav-links">
|
<div className="nav-links">
|
||||||
<a href="/" className={currentPage === 'home' ? 'active' : ''}>{t('nav.home')}</a>
|
<a href="/" className={currentPage === 'home' ? 'active' : ''}>{t('nav.home')}</a>
|
||||||
<a href="/#servers" className={currentPage === 'servers' ? 'active' : ''}>{t('nav.servers')}</a>
|
<Link to="/servers" className={currentPage === 'servers' ? 'active' : ''}>{t('nav.servers')}</Link>
|
||||||
<Link to="/blog" className={currentPage === 'blog' ? 'active' : ''}>{t('nav.blog')}</Link>
|
<Link to="/blog" className={currentPage === 'blog' ? 'active' : ''}>{t('nav.blog')}</Link>
|
||||||
<a href="https://git.cialloo.com" className={currentPage === 'git' ? 'active' : ''}>{t('nav.git')}</a>
|
<a href="https://git.cialloo.com" className={currentPage === 'git' ? 'active' : ''}>{t('nav.git')}</a>
|
||||||
<a href="/#forum" className={currentPage === 'forum' ? 'active' : ''}>{t('nav.forum')}</a>
|
<a href="/#forum" className={currentPage === 'forum' ? 'active' : ''}>{t('nav.forum')}</a>
|
||||||
|
|||||||
@@ -73,6 +73,20 @@
|
|||||||
"english": "English",
|
"english": "English",
|
||||||
"chinese": "中文"
|
"chinese": "中文"
|
||||||
},
|
},
|
||||||
|
"servers": {
|
||||||
|
"title": "Game Servers",
|
||||||
|
"subtitle": "Join active Counter-Strike servers and compete with players worldwide",
|
||||||
|
"players": "Players",
|
||||||
|
"ping": "Ping",
|
||||||
|
"joinServer": "Join Server",
|
||||||
|
"maintenance": "Maintenance",
|
||||||
|
"offline": "Offline",
|
||||||
|
"serverStats": "Server Statistics",
|
||||||
|
"onlineServers": "Online Servers",
|
||||||
|
"totalPlayers": "Total Players",
|
||||||
|
"regions": "Regions",
|
||||||
|
"uptime": "Uptime"
|
||||||
|
},
|
||||||
"blog": {
|
"blog": {
|
||||||
"title": "Community Blog",
|
"title": "Community Blog",
|
||||||
"subtitle": "Stay updated with the latest news, tutorials, and insights from the Counter-Strike community",
|
"subtitle": "Stay updated with the latest news, tutorials, and insights from the Counter-Strike community",
|
||||||
|
|||||||
@@ -73,6 +73,20 @@
|
|||||||
"english": "English",
|
"english": "English",
|
||||||
"chinese": "中文"
|
"chinese": "中文"
|
||||||
},
|
},
|
||||||
|
"servers": {
|
||||||
|
"title": "游戏服务器",
|
||||||
|
"subtitle": "加入活跃的反恐精英服务器,与全球玩家竞技",
|
||||||
|
"players": "玩家",
|
||||||
|
"ping": "延迟",
|
||||||
|
"joinServer": "加入服务器",
|
||||||
|
"maintenance": "维护中",
|
||||||
|
"offline": "离线",
|
||||||
|
"serverStats": "服务器统计",
|
||||||
|
"onlineServers": "在线服务器",
|
||||||
|
"totalPlayers": "总玩家数",
|
||||||
|
"regions": "地区",
|
||||||
|
"uptime": "正常运行时间"
|
||||||
|
},
|
||||||
"blog": {
|
"blog": {
|
||||||
"title": "社区博客",
|
"title": "社区博客",
|
||||||
"subtitle": "及时了解反恐精英社区的最新新闻、教程和见解",
|
"subtitle": "及时了解反恐精英社区的最新新闻、教程和见解",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { ThemeProvider } from './contexts/ThemeContext'
|
|||||||
import App from './App.tsx'
|
import App from './App.tsx'
|
||||||
import Friends from './pages/Friends.tsx'
|
import Friends from './pages/Friends.tsx'
|
||||||
import Blog from './pages/Blog.tsx'
|
import Blog from './pages/Blog.tsx'
|
||||||
|
import Servers from './pages/Servers.tsx'
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
@@ -16,6 +17,7 @@ createRoot(document.getElementById('root')!).render(
|
|||||||
<Route path="/" element={<App />} />
|
<Route path="/" element={<App />} />
|
||||||
<Route path="/friends" element={<Friends />} />
|
<Route path="/friends" element={<Friends />} />
|
||||||
<Route path="/blog" element={<Blog />} />
|
<Route path="/blog" element={<Blog />} />
|
||||||
|
<Route path="/servers" element={<Servers />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</Router>
|
||||||
</ThemeProvider>
|
</ThemeProvider>
|
||||||
|
|||||||
497
src/pages/Servers.tsx
Normal file
497
src/pages/Servers.tsx
Normal file
@@ -0,0 +1,497 @@
|
|||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import Layout from '../components/Layout'
|
||||||
|
import '../App.css'
|
||||||
|
|
||||||
|
interface Server {
|
||||||
|
id: number
|
||||||
|
name: string
|
||||||
|
map: string
|
||||||
|
gameMode: string
|
||||||
|
players: number
|
||||||
|
maxPlayers: number
|
||||||
|
ping: number
|
||||||
|
region: string
|
||||||
|
difficulty: 'Easy' | 'Normal' | 'Hard' | 'Expert'
|
||||||
|
status: 'online' | 'offline' | 'maintenance'
|
||||||
|
description: string
|
||||||
|
tags: string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
function Servers() {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
// Mock server data
|
||||||
|
const servers: Server[] = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Dust2 Classic - Competitive",
|
||||||
|
map: "de_dust2",
|
||||||
|
gameMode: "Competitive",
|
||||||
|
players: 8,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 23,
|
||||||
|
region: "Asia-Pacific",
|
||||||
|
difficulty: "Normal",
|
||||||
|
status: "online",
|
||||||
|
description: "Classic Dust2 competitive matches with skilled players",
|
||||||
|
tags: ["Competitive", "Ranked", "Dust2"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Mirage Pro League",
|
||||||
|
map: "de_mirage",
|
||||||
|
gameMode: "Premier",
|
||||||
|
players: 10,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 45,
|
||||||
|
region: "Europe",
|
||||||
|
difficulty: "Hard",
|
||||||
|
status: "online",
|
||||||
|
description: "Professional Mirage matches for experienced players",
|
||||||
|
tags: ["Premier", "Mirage", "Pro"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Inferno Casual",
|
||||||
|
map: "de_inferno",
|
||||||
|
gameMode: "Casual",
|
||||||
|
players: 6,
|
||||||
|
maxPlayers: 12,
|
||||||
|
ping: 67,
|
||||||
|
region: "North America",
|
||||||
|
difficulty: "Easy",
|
||||||
|
status: "online",
|
||||||
|
description: "Relaxed Inferno matches for all skill levels",
|
||||||
|
tags: ["Casual", "Inferno", "Beginner"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
name: "Nuke Tactical",
|
||||||
|
map: "de_nuke",
|
||||||
|
gameMode: "Tactical",
|
||||||
|
players: 9,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 34,
|
||||||
|
region: "Asia-Pacific",
|
||||||
|
difficulty: "Expert",
|
||||||
|
status: "online",
|
||||||
|
description: "Tactical Nuke gameplay with strategic objectives",
|
||||||
|
tags: ["Tactical", "Nuke", "Strategy"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
name: "Vertigo Deathmatch",
|
||||||
|
map: "de_vertigo",
|
||||||
|
gameMode: "Deathmatch",
|
||||||
|
players: 12,
|
||||||
|
maxPlayers: 16,
|
||||||
|
ping: 28,
|
||||||
|
region: "Europe",
|
||||||
|
difficulty: "Normal",
|
||||||
|
status: "online",
|
||||||
|
description: "Fast-paced Vertigo deathmatch action",
|
||||||
|
tags: ["Deathmatch", "Vertigo", "FFA"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
name: "Ancient Wingman",
|
||||||
|
map: "de_ancient",
|
||||||
|
gameMode: "Wingman",
|
||||||
|
players: 2,
|
||||||
|
maxPlayers: 4,
|
||||||
|
ping: 52,
|
||||||
|
region: "North America",
|
||||||
|
difficulty: "Normal",
|
||||||
|
status: "online",
|
||||||
|
description: "2v2 Wingman matches on Ancient",
|
||||||
|
tags: ["Wingman", "Ancient", "2v2"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
name: "Overpass Scrim",
|
||||||
|
map: "de_overpass",
|
||||||
|
gameMode: "Scrimmage",
|
||||||
|
players: 8,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 41,
|
||||||
|
region: "South America",
|
||||||
|
difficulty: "Hard",
|
||||||
|
status: "online",
|
||||||
|
description: "Team scrimmage matches for practice",
|
||||||
|
tags: ["Scrimmage", "Overpass", "Practice"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 8,
|
||||||
|
name: "Cache Community",
|
||||||
|
map: "de_cache",
|
||||||
|
gameMode: "Community",
|
||||||
|
players: 0,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 89,
|
||||||
|
region: "Europe",
|
||||||
|
difficulty: "Easy",
|
||||||
|
status: "maintenance",
|
||||||
|
description: "Community server - currently under maintenance",
|
||||||
|
tags: ["Community", "Cache", "Social"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 9,
|
||||||
|
name: "Train Pro League",
|
||||||
|
map: "de_train",
|
||||||
|
gameMode: "Premier",
|
||||||
|
players: 10,
|
||||||
|
maxPlayers: 10,
|
||||||
|
ping: 31,
|
||||||
|
region: "Asia-Pacific",
|
||||||
|
difficulty: "Expert",
|
||||||
|
status: "online",
|
||||||
|
description: "Elite Train matches for top players",
|
||||||
|
tags: ["Premier", "Train", "Elite"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 10,
|
||||||
|
name: "Cobblestone Casual",
|
||||||
|
map: "de_cbble",
|
||||||
|
gameMode: "Casual",
|
||||||
|
players: 4,
|
||||||
|
maxPlayers: 12,
|
||||||
|
ping: 76,
|
||||||
|
region: "North America",
|
||||||
|
difficulty: "Easy",
|
||||||
|
status: "online",
|
||||||
|
description: "Casual gameplay on the classic Cobblestone",
|
||||||
|
tags: ["Casual", "Cobblestone", "Classic"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
switch (status) {
|
||||||
|
case 'online': return '#10b981'
|
||||||
|
case 'offline': return '#ef4444'
|
||||||
|
case 'maintenance': return '#f59e0b'
|
||||||
|
default: return '#6b7280'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDifficultyColor = (difficulty: string) => {
|
||||||
|
switch (difficulty) {
|
||||||
|
case 'Easy': return '#10b981'
|
||||||
|
case 'Normal': return '#3b82f6'
|
||||||
|
case 'Hard': return '#f59e0b'
|
||||||
|
case 'Expert': return '#ef4444'
|
||||||
|
default: return '#6b7280'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout currentPage="servers">
|
||||||
|
{/* Servers Page Header */}
|
||||||
|
<section className="servers-header" style={{
|
||||||
|
padding: '120px 2rem 60px',
|
||||||
|
background: 'linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%)',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{ maxWidth: '800px', margin: '0 auto' }}>
|
||||||
|
<h1 style={{
|
||||||
|
fontSize: '3rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '1rem',
|
||||||
|
background: 'linear-gradient(45deg, var(--accent-primary), var(--accent-secondary))',
|
||||||
|
WebkitBackgroundClip: 'text',
|
||||||
|
WebkitTextFillColor: 'transparent',
|
||||||
|
backgroundClip: 'text'
|
||||||
|
}}>
|
||||||
|
{t('servers.title')}
|
||||||
|
</h1>
|
||||||
|
<p style={{
|
||||||
|
fontSize: '1.2rem',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
marginBottom: '2rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.subtitle')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Servers Grid */}
|
||||||
|
<section className="servers-grid" style={{
|
||||||
|
padding: '2rem',
|
||||||
|
maxWidth: '1200px',
|
||||||
|
margin: '0 auto'
|
||||||
|
}}>
|
||||||
|
<div style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fit, minmax(350px, 1fr))',
|
||||||
|
gap: '2rem'
|
||||||
|
}}>
|
||||||
|
{servers.map((server) => (
|
||||||
|
<div
|
||||||
|
key={server.id}
|
||||||
|
className="server-card"
|
||||||
|
style={{
|
||||||
|
background: 'var(--bg-secondary)',
|
||||||
|
border: '1px solid var(--border-color)',
|
||||||
|
borderRadius: '12px',
|
||||||
|
padding: '1.5rem',
|
||||||
|
transition: 'all 0.3s ease',
|
||||||
|
cursor: 'pointer',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden'
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'translateY(-5px)'
|
||||||
|
e.currentTarget.style.boxShadow = '0 10px 25px rgba(0,0,0,0.2)'
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'translateY(0)'
|
||||||
|
e.currentTarget.style.boxShadow = 'none'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Status Indicator */}
|
||||||
|
<div style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: '1rem',
|
||||||
|
right: '1rem',
|
||||||
|
width: '12px',
|
||||||
|
height: '12px',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: getStatusColor(server.status)
|
||||||
|
}} />
|
||||||
|
|
||||||
|
{/* Server Header */}
|
||||||
|
<div style={{ marginBottom: '1rem' }}>
|
||||||
|
<h3 style={{
|
||||||
|
fontSize: '1.2rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
{server.name}
|
||||||
|
</h3>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '0.5rem',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
color: 'var(--text-secondary)'
|
||||||
|
}}>
|
||||||
|
<span>🗺️ {server.map}</span>
|
||||||
|
<span>•</span>
|
||||||
|
<span>{server.gameMode}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Server Stats */}
|
||||||
|
<div style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: '1fr 1fr',
|
||||||
|
gap: '1rem',
|
||||||
|
marginBottom: '1rem'
|
||||||
|
}}>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '0.8rem',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
marginBottom: '0.25rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.players')}
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '1.1rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--text-primary)'
|
||||||
|
}}>
|
||||||
|
{server.players}/{server.maxPlayers}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '0.8rem',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
marginBottom: '0.25rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.ping')}
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '1.1rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: server.ping < 50 ? '#10b981' : server.ping < 100 ? '#f59e0b' : '#ef4444'
|
||||||
|
}}>
|
||||||
|
{server.ping}ms
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Server Details */}
|
||||||
|
<div style={{ marginBottom: '1rem' }}>
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
gap: '1rem',
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
<span>🌍 {server.region}</span>
|
||||||
|
<span style={{
|
||||||
|
color: getDifficultyColor(server.difficulty),
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}>
|
||||||
|
{server.difficulty}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<p style={{
|
||||||
|
fontSize: '0.9rem',
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
marginBottom: '1rem'
|
||||||
|
}}>
|
||||||
|
{server.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Tags */}
|
||||||
|
<div style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: '0.5rem',
|
||||||
|
marginBottom: '1rem'
|
||||||
|
}}>
|
||||||
|
{server.tags.map((tag, index) => (
|
||||||
|
<span
|
||||||
|
key={index}
|
||||||
|
style={{
|
||||||
|
background: 'var(--accent-primary)',
|
||||||
|
color: 'white',
|
||||||
|
padding: '0.25rem 0.5rem',
|
||||||
|
borderRadius: '4px',
|
||||||
|
fontSize: '0.8rem',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Join Button */}
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
padding: '0.75rem',
|
||||||
|
background: server.status === 'online' ? 'var(--accent-primary)' : 'var(--text-secondary)',
|
||||||
|
color: 'white',
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: '6px',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
cursor: server.status === 'online' ? 'pointer' : 'not-allowed',
|
||||||
|
transition: 'all 0.3s ease'
|
||||||
|
}}
|
||||||
|
disabled={server.status !== 'online'}
|
||||||
|
onClick={() => {
|
||||||
|
if (server.status === 'online') {
|
||||||
|
// In a real app, this would connect to the server
|
||||||
|
alert(`Connecting to ${server.name}...`)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{server.status === 'online' ? t('servers.joinServer') :
|
||||||
|
server.status === 'maintenance' ? t('servers.maintenance') :
|
||||||
|
t('servers.offline')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Server Stats Summary */}
|
||||||
|
<section className="server-stats" style={{
|
||||||
|
padding: '4rem 2rem',
|
||||||
|
background: 'var(--bg-secondary)',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>
|
||||||
|
<div style={{ maxWidth: '800px', margin: '0 auto' }}>
|
||||||
|
<h2 style={{
|
||||||
|
fontSize: '2rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
marginBottom: '2rem',
|
||||||
|
color: 'var(--text-primary)'
|
||||||
|
}}>
|
||||||
|
{t('servers.serverStats')}
|
||||||
|
</h2>
|
||||||
|
<div style={{
|
||||||
|
display: 'grid',
|
||||||
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
||||||
|
gap: '2rem'
|
||||||
|
}}>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '2.5rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--accent-primary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
{servers.filter(s => s.status === 'online').length}
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
fontSize: '1.1rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.onlineServers')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '2.5rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--accent-primary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
{servers.reduce((sum, s) => sum + s.players, 0)}
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
fontSize: '1.1rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.totalPlayers')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '2.5rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--accent-primary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
4
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
fontSize: '1.1rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.regions')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div style={{
|
||||||
|
fontSize: '2.5rem',
|
||||||
|
fontWeight: 'bold',
|
||||||
|
color: 'var(--accent-primary)',
|
||||||
|
marginBottom: '0.5rem'
|
||||||
|
}}>
|
||||||
|
95%
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
color: 'var(--text-secondary)',
|
||||||
|
fontSize: '1.1rem'
|
||||||
|
}}>
|
||||||
|
{t('servers.uptime')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Servers
|
||||||
Reference in New Issue
Block a user