Frontend, README und Konfigurationsvorlage

React-Oberfläche mit Übersicht, Match-Erstellung, Beitritt über Team- und
Zuschauercodes, Teamkarten, visuellem Map-Veto, Serie und Serverpanel.
README beschreibt Einrichtung, Umgebungsvariablen, Rollen, Veto-Abläufe,
Serveradapter und CSTV-Zuschauerzugang.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SPP UserandClaude Opus 5.5 committed 2026-10-25 17:02:18 +01:00
1 parent 104aa1a67b
commit 568ccf9b09
24 files changed
+1938 -1

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
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 { JoinPage, WatchPage } from './pages/AccessPages.jsx';
export default function App() {
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="Zur Übersicht">
<svg viewBox="0 0 32 32" width="26" height="26" aria-hidden="true">
<path d="M4 4h24l-4 24H8z" fill="var(--ct)" />
<path d="M10 10l12 12M22 10L10 22" stroke="var(--bg)" strokeWidth="3" />
</svg>
<span>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>
<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="/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>
);
}