- Stream-Übersicht unter /stream/<Zuschauercode> (1920x1080, Lobby, Veto, Spielstand) - Live-Stand, Rundenverlauf und Serienstand auf Match-Seite und Übersicht - Parser mit echten AMP-Logs geprüft: Game Over mit leerer Map-Gruppe, Match_Start vor der Aufwärmphase, veraltete Seitenzuordnung nach der Halbzeit - Nach Map-Ende automatisch nächste Map bzw. Abschluss der entschiedenen Serie - LOG_DEBUG zur Fehlersuche, README und .env.example ergänzt Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
44 lines
2.0 KiB
React
44 lines
2.0 KiB
React
import CopyField from './CopyField.jsx';
|
||
|
||
export default function OrganizerPanel({ state, act, busy, matchId, token }) {
|
||
const { codes, links } = state.organizer;
|
||
const open = !['finished', 'cancelled'].includes(state.status);
|
||
const orgLink = `${window.location.origin}/m/${matchId}#org=${token}`;
|
||
|
||
const regen = (target, label) =>
|
||
window.confirm(`Neuen Code für ${label} erzeugen? Der alte Link funktioniert dann nicht mehr. Bereits beigetretene Spieler bleiben im Team.`) &&
|
||
act('codes/regenerate', { target }, `Neuer Code für ${label}`);
|
||
|
||
return (
|
||
<section className="panel organizer-panel">
|
||
<h2>Einladungen</h2>
|
||
<p className="small muted">Jeder Link führt nur in das jeweilige Team. Gib ihn ausschließlich an dieses Team weiter.</p>
|
||
{[
|
||
['A', state.teams.A.name, 'team-A'],
|
||
['B', state.teams.B.name, 'team-B'],
|
||
['spectator', 'Zuschauer (Stream, Kommentatoren)', 'spectator'],
|
||
].map(([key, label, cls]) => (
|
||
<div key={key} className={`invite ${cls}`}>
|
||
<div className="invite-head">
|
||
<strong>{label}</strong>
|
||
<span className="invite-code">{codes[key]}</span>
|
||
{open && <button className="link-btn" disabled={!!busy} onClick={() => regen(key, label)}>Neuer Code</button>}
|
||
</div>
|
||
<CopyField value={links[key]} />
|
||
{key === 'spectator' && (
|
||
<div className="stream-link">
|
||
<CopyField label="Stream-Übersicht (als Browserquelle in OBS, 1920×1080)" value={links.stream} />
|
||
<a className="btn btn-sm" href={links.stream} target="_blank" rel="noreferrer">Stream-Ansicht öffnen</a>
|
||
</div>
|
||
)}
|
||
</div>
|
||
))}
|
||
<details className="org-link">
|
||
<summary>Organisator-Zugang auf einem anderen Gerät öffnen</summary>
|
||
<p className="small muted">Dieser Link gibt volle Kontrolle über das Match. Nicht weitergeben.</p>
|
||
<CopyField value={orgLink} secret />
|
||
</details>
|
||
</section>
|
||
);
|
||
}
|