From bf438511d6c211df4b3b17d285ddd5e4c18ed0b7 Mon Sep 17 00:00:00 2001 From: MrEgosar Date: Sun, 25 Oct 2026 17:09:31 +0100 Subject: [PATCH] Lobby zeigt konkret, was einem Team zum Veto-Start fehlt --- client/src/pages/MatchPage.jsx | 44 +++++++++++++++++++++++++--------- client/src/styles.css | 5 +++- server/src/matchService.js | 1 + 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/client/src/pages/MatchPage.jsx b/client/src/pages/MatchPage.jsx index 5a3fde2..166c373 100644 --- a/client/src/pages/MatchPage.jsx +++ b/client/src/pages/MatchPage.jsx @@ -126,19 +126,26 @@ function Stage(ctx) { const missing = [A, B].filter((t) => !t.readiness.ready); return (
-

Warten auf beide Teams

-

- {missing.length === 0 - ? 'Beide Teams sind bereit.' - : missing.map((t) => `${t.name}: ${t.readiness.count}/${t.teamSize} Spieler, ${t.readiness.allReady ? 'alle bereit' : 'noch nicht alle bereit'}`).join(' – ')} -

+

{missing.length === 0 ? 'Beide Teams sind bereit' : 'Warten auf beide Teams'}

+ {missing.length > 0 && ( + + )} {isOrg ? ( - + <> + + {!state.canStartVeto &&

Der Knopf wird aktiv, sobald beide Teams bereit sind.

} + ) : ( -

Der Organisator startet das Veto, sobald beide Teams bereit sind.

+

+ {missing.length === 0 + ? 'Der Organisator kann das Veto jetzt starten.' + : 'Sobald beide Teams bereit sind, startet der Organisator das Veto.'} +

)}
@@ -153,6 +160,21 @@ function Stage(ctx) { ); } +/** Sagt konkret, was einem Team noch fehlt, damit es als bereit gilt. */ +function readinessGap(team, requireFull) { + const r = team.readiness; + const gaps = []; + if (!r.enough) { + const need = requireFull ? team.teamSize - r.count : 1; + gaps.push(requireFull + ? `noch ${need} von ${team.teamSize} Spielern fehlen (Team muss vollständig sein)` + : 'mindestens ein Spieler fehlt'); + } + if (r.count > 0 && !r.allReady) gaps.push('noch nicht alle haben „bereit“ geklickt'); + if (r.count > 0 && !r.hasCaptain) gaps.push('kein Captain'); + return gaps.join(', '); +} + function MapPoolPreview({ maps }) { return (
diff --git a/client/src/styles.css b/client/src/styles.css index 5bb1b98..cbe8959 100644 --- a/client/src/styles.css +++ b/client/src/styles.css @@ -173,7 +173,10 @@ input:focus, select:focus { border-color: var(--ct); outline: none; } .match-grid { display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr) minmax(220px, 280px); gap: 20px; align-items: start; } .stage { min-width: 0; } .stage-note { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 24px; } -.stage-note .btn { margin: 8px 0 20px; } +.stage-note .btn { margin: 8px 0 8px; } +.stage-note .pool-preview { margin-top: 16px; } +.missing-list { margin: 0 0 12px; padding-left: 1.1em; color: var(--muted); } +.missing-list li { margin-bottom: 4px; } .pool-preview { display: flex; flex-wrap: wrap; gap: 6px; } .pool-chip { padding: 4px 10px; border-left: 3px solid var(--map); background: var(--surface-2); font-size: .875rem; border-radius: 3px; } diff --git a/server/src/matchService.js b/server/src/matchService.js index c6260fd..a394d5e 100644 --- a/server/src/matchService.js +++ b/server/src/matchService.js @@ -531,6 +531,7 @@ export class MatchService extends EventEmitter { currentMapNumber: match.current_map_number, viewer: { role: viewer.role, playerId: viewer.playerId, team: viewer.team }, canStartVeto: match.status === 'lobby' && readiness.A.ready && readiness.B.ready, + requireFullTeams: this.config.requireFullTeams, maps: pool.maps, veto: publicView ? null