- 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
60 lines
2.7 KiB
React
60 lines
2.7 KiB
React
import MapImage from './MapImage.jsx';
|
|
import SideIcon from './SideIcon.jsx';
|
|
import RoundStrip from './RoundStrip.jsx';
|
|
|
|
const STATUS = { pending: 'Ausstehend', next: 'Wird eingerichtet', live: 'Aktuell', done: 'Gespielt' };
|
|
|
|
export default function SeriesList({ state }) {
|
|
const { teams } = state;
|
|
return (
|
|
<div className="series">
|
|
<h2>Map-Reihenfolge</h2>
|
|
<ol className="series-list">
|
|
{state.series.map((s) => {
|
|
const map = state.maps.find((m) => m.id === s.map);
|
|
const ct = s.ctTeam ? teams[s.ctTeam].name : null;
|
|
const t = s.ctTeam ? teams[s.ctTeam === 'A' ? 'B' : 'A'].name : null;
|
|
const isLive = s.live?.status === 'live' && s.status !== 'done';
|
|
const hasScore = s.live && (s.live.rounds.length > 0 || s.status === 'done');
|
|
return (
|
|
<li key={s.number} className={`series-item is-${s.status} ${isLive ? 'is-playing' : ''}`} style={{ '--map': map?.color ?? '#556' }}>
|
|
<MapImage map={map} className="series-art" />
|
|
<span className="series-no">Map {s.number}</span>
|
|
<strong className="series-map">{s.mapName}</strong>
|
|
<span className="series-status">
|
|
{isLive ? <span className="live-badge">Live</span> : STATUS[s.status]}
|
|
</span>
|
|
{hasScore && (
|
|
<span className="series-score" aria-label={`${teams.A.name} ${s.score.A} zu ${s.score.B} ${teams.B.name}`}>
|
|
<span className={`team-a ${s.winner === 'A' ? 'is-winner' : ''}`}>{s.score.A}</span>
|
|
<span className="colon">:</span>
|
|
<span className={`team-b ${s.winner === 'B' ? 'is-winner' : ''}`}>{s.score.B}</span>
|
|
{s.status === 'done' && (
|
|
<small>{s.winner ? `${teams[s.winner].name} gewinnt` : 'Unentschieden'}</small>
|
|
)}
|
|
</span>
|
|
)}
|
|
<span className="series-origin">
|
|
{s.pickedBy ? `Pick von ${teams[s.pickedBy].name}` : 'Entscheidungsmap'}
|
|
</span>
|
|
<span className="series-sides">
|
|
{ct ? (
|
|
<>
|
|
<span className="side-ct"><SideIcon side="CT" size={18} /> {ct}</span>
|
|
<span className="side-t"><SideIcon side="T" size={18} /> {t}</span>
|
|
</>
|
|
) : 'Seiten im Spiel festlegen'}
|
|
</span>
|
|
{hasScore && (
|
|
<div className="series-rounds">
|
|
<RoundStrip rounds={s.live.rounds} maxRounds={state.maxRounds} teams={teams} size="sm" />
|
|
</div>
|
|
)}
|
|
</li>
|
|
);
|
|
})}
|
|
</ol>
|
|
</div>
|
|
);
|
|
}
|