Files
Cs2-Mapveto/client/src/App.jsx
T
mregosar dc601a32fe Beamer-Diashow der laufenden Matches unter /beamer
Ein Match pro Folie, groß und aus der Ferne lesbar: Teams, Serienstand, aktuelle Map mit Rundenstand und Seiten, Maps der Serie, im Veto wer dran ist. Zum Schluss eine Folie mit Lobbys und Ergebnissen. Schaltet automatisch weiter (?sekunden=), Vollbild per Klick oder F, Pfeiltasten und Leertaste. In der Kopfzeile verlinkt.
2026-11-01 19:00:59 +01:00

70 lines
3.0 KiB
React
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 BeamerPage from './pages/BeamerPage.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/match/:matchId" element={<StreamOverviewPage />} />
<Route path="/stream" element={<StreamOverviewPage />} />
{/* Diashow der laufenden Matches für den Beamer, ein Match pro Folie */}
<Route path="/beamer" element={<BeamerPage />} />
<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>
<a href="/beamer" target="_blank" rel="noreferrer" className="nav-link">Beamer</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>
);
}