Anmeldung mit ADMIN_PASSWORD (12 h, Sitzung nur im Speicher, Sperre nach 5 Fehlversuchen pro Minute). Alle Matches mit Codes, Servern, Spielern, Veto und Verlauf. Aktionen: Veto starten bzw. Schritte für beide Teams, Warmup beenden, nächste Map, Server stoppen/neu starten, abschließen, abbrechen, Spieler entfernen, Codes erneuern, Match löschen. Ohne ADMIN_PASSWORD ist der Admin-Modus komplett aus.
65 lines
2.7 KiB
React
65 lines
2.7 KiB
React
import { useEffect, useState } from 'react';
|
||
import { Link, Route, Routes } from 'react-router-dom';
|
||
import { api } from './lib/api.js';
|
||
import Overview from './pages/Overview.jsx';
|
||
import CreateMatch from './pages/CreateMatch.jsx';
|
||
import MatchPage from './pages/MatchPage.jsx';
|
||
import StreamPage from './pages/StreamPage.jsx';
|
||
import StreamOverviewPage from './pages/StreamOverviewPage.jsx';
|
||
import AdminPage from './pages/AdminPage.jsx';
|
||
import { JoinPage, WatchPage } from './pages/AccessPages.jsx';
|
||
|
||
export default function App() {
|
||
return (
|
||
<Routes>
|
||
{/* Stream-Übersicht ohne Kopfzeile, als Vollbild bzw. OBS-Browserquelle */}
|
||
<Route path="/stream/:code" element={<StreamPage />} />
|
||
<Route path="/stream" element={<StreamOverviewPage />} />
|
||
<Route path="*" element={<MainLayout />} />
|
||
</Routes>
|
||
);
|
||
}
|
||
|
||
function MainLayout() {
|
||
const [config, setConfig] = useState(null);
|
||
const [configError, setConfigError] = useState(null);
|
||
|
||
useEffect(() => {
|
||
api('/config').then(setConfig).catch((e) => setConfigError(e.message));
|
||
}, []);
|
||
|
||
return (
|
||
<div className="app">
|
||
<header className="topbar">
|
||
<Link to="/" className="brand" aria-label="MaxLAN e.V. CS2 Mapveto – zur Übersicht">
|
||
<img src="/brand/maxlan-logo.webp" alt="MaxLAN e.V." className="brand-logo" width="743" height="174" />
|
||
<span className="brand-app">CS2 Mapveto</span>
|
||
</Link>
|
||
{config?.server.simulated && (
|
||
<span className="demo-flag" title="SERVER_ADAPTER=demo – es werden keine echten CS2-Server gestartet">
|
||
Demo-Modus: keine echten Server
|
||
</span>
|
||
)}
|
||
<nav>
|
||
<Link to="/" className="nav-link">Übersicht</Link>
|
||
<a href="/stream" target="_blank" rel="noreferrer" className="nav-link">Stream-Übersicht</a>
|
||
<Link to="/admin" className="nav-link">Admin</Link>
|
||
<Link to="/neu" className="btn btn-primary btn-sm">Match erstellen</Link>
|
||
</nav>
|
||
</header>
|
||
<main className="content">
|
||
{configError && <div className="alert alert-error">Backend nicht erreichbar: {configError}</div>}
|
||
<Routes>
|
||
<Route path="/" element={<Overview />} />
|
||
<Route path="/neu" element={<CreateMatch config={config} />} />
|
||
<Route path="/admin" element={<AdminPage />} />
|
||
<Route path="/m/:id" element={<MatchPage />} />
|
||
<Route path="/join/:code" element={<JoinPage config={config} />} />
|
||
<Route path="/watch/:code" element={<WatchPage />} />
|
||
<Route path="*" element={<div className="empty"><h2>Seite nicht gefunden</h2><Link to="/">Zur Übersicht</Link></div>} />
|
||
</Routes>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|