From d23a9f086c176b9160427d51e195e591d09d7a36 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Fri, 3 Oct 2025 20:13:49 +0200 Subject: [PATCH] =?UTF-8?q?Erweitert=20den=20MatchReportApiDialog=20mit=20?= =?UTF-8?q?neuen=20Funktionen=20zur=20Abschlussbearbeitung.=20F=C3=BCgt=20?= =?UTF-8?q?die=20Anzeige=20von=20Aufstellungen,=20Endergebnis,=20Zeitangab?= =?UTF-8?q?en,=20Protest-Eingabe=20und=20PIN-Eingaben=20hinzu.=20Implement?= =?UTF-8?q?iert=20Methoden=20zur=20Extraktion=20von=20Einzel-=20und=20Dopp?= =?UTF-8?q?elspielern=20sowie=20zur=20Berechnung=20des=20Gesamtergebnisses?= =?UTF-8?q?.=20Optimiert=20die=20Benutzeroberfl=C3=A4che=20mit=20neuen=20C?= =?UTF-8?q?SS-Stilen=20f=C3=BCr=20eine=20verbesserte=20Darstellung.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/MatchReportApiDialog.vue | 451 +++++++++++++++++- 1 file changed, 444 insertions(+), 7 deletions(-) diff --git a/frontend/src/components/MatchReportApiDialog.vue b/frontend/src/components/MatchReportApiDialog.vue index f5bd32d..0b7d163 100644 --- a/frontend/src/components/MatchReportApiDialog.vue +++ b/frontend/src/components/MatchReportApiDialog.vue @@ -67,12 +67,12 @@

{{ meetingData.homeClub }}

-
{{ getOverallScore().split(':')[0] }}
+
{{ getOverallMatchScore().split(':')[0] }}
vs

{{ meetingData.guestClub }}

-
{{ getOverallScore().split(':')[1] }}
+
{{ getOverallMatchScore().split(':')[1] }}
@@ -376,9 +376,115 @@
-

Abschluss

-

Hier können Sie den Abschluss des Spielberichts vornehmen.

- + +
+
+

{{ meetingData.homeTeamname }}

+
+
Einzel
+
+ {{ idx + 1 }}: {{ player }} +
+
+
+
Doppel
+
+ D{{ idx + 1 }}: {{ pair }} +
+
+
+ +
vs
+ +
+

{{ meetingData.guestTeamname }}

+
+
Einzel
+
+ {{ idx + 1 }}: {{ player }} +
+
+
+
Doppel
+
+ D{{ idx + 1 }}: {{ pair }} +
+
+
+
+ + +
+

Endergebnis

+
+
+ Spielstand: + {{ getOverallScore() }} +
+
+
+ + +
+
+ + {{ getFormattedTime(match.startDate) || 'nicht gesetzt' }} +
+ +
+ + + +
+
+ + +
+ + +
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+ +
@@ -482,6 +588,10 @@ export default { results: [], // Fehlermeldungen für Satzeingaben errors: [], + // Abschluss-Felder + protestText: '', + finalHomePin: '', + finalGuestPin: '', // Definitionen der Spielsysteme als Matrizen (Reihenfolge der Begegnungen) // A = Heim (A1..), B = Gast (B1..), D = Doppel (DAx, DBx) playModeMatrices: { @@ -556,8 +666,162 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr async mounted() { await this.loadData(); this.initializeResults(); + this.initializeFinalPins(); }, methods: { + // Methoden für Abschluss-Seite + getHomeDoublePairs() { + if (!this.results || this.results.length === 0) return []; + + // Extrahiere Doppelpaare aus den tatsächlichen Match-Ergebnissen + const pairs = []; + + this.results.forEach(match => { + // Doppelpaare enthalten "/" im Namen + if (match.homeName && match.homeName.includes(' / ')) { + if (!pairs.includes(match.homeName)) { + pairs.push(match.homeName); + } + } + }); + + return pairs; + }, + + getHomeSinglePlayers() { + if (!this.results || this.results.length === 0) return []; + + // Extrahiere Einzelspieler in der Reihenfolge ihres Auftretens + const players = []; + const seen = new Set(); + + this.results.forEach(match => { + if (match.homeName && match.homeName !== '' && !match.homeName.includes(' / ')) { + if (!seen.has(match.homeName)) { + seen.add(match.homeName); + players.push(match.homeName); + } + } + }); + + return players; + }, + + getGuestDoublePairs() { + if (!this.results || this.results.length === 0) return []; + + // Extrahiere Doppelpaare aus den tatsächlichen Match-Ergebnissen + const pairs = []; + + this.results.forEach(match => { + // Doppelpaare enthalten "/" im Namen + if (match.guestName && match.guestName.includes(' / ')) { + if (!pairs.includes(match.guestName)) { + pairs.push(match.guestName); + } + } + }); + + return pairs; + }, + + getGuestSinglePlayers() { + if (!this.results || this.results.length === 0) return []; + + // Extrahiere Einzelspieler in der Reihenfolge ihres Auftretens + const players = []; + const seen = new Set(); + + this.results.forEach(match => { + if (match.guestName && match.guestName !== '' && !match.guestName.includes(' / ')) { + if (!seen.has(match.guestName)) { + seen.add(match.guestName); + players.push(match.guestName); + } + } + }); + + return players; + }, + + getOverallMatchScore() { + let homeWins = 0; + let guestWins = 0; + + this.results.forEach(match => { + if (match.completed) { + let matchHomeWins = 0; + let matchGuestWins = 0; + + match.sets.forEach(set => { + if (set && set.includes(':')) { + const [home, guest] = set.split(':').map(s => parseInt(s) || 0); + + if (home > guest) { + matchHomeWins++; + } else if (guest > home) { + matchGuestWins++; + } + } + }); + + if (matchHomeWins > matchGuestWins) { + homeWins++; + } else if (matchGuestWins > matchHomeWins) { + guestWins++; + } + } + }); + + return `${homeWins}:${guestWins}`; + }, + + getOverallSetScore() { + let totalHomeSets = 0; + let totalGuestSets = 0; + + this.results.forEach(match => { + if (match.completed) { + match.sets.forEach(set => { + if (set && set.includes(':')) { + const [home, guest] = set.split(':').map(s => parseInt(s) || 0); + totalHomeSets += home; + totalGuestSets += guest; + } + }); + } + }); + + return `(${totalHomeSets}:${totalGuestSets})`; + }, + + initializeFinalPins() { + // Initialisiere PIN-Felder mit den Werten aus dem Match-Objekt + this.finalHomePin = this.match.homePin || ''; + this.finalGuestPin = this.match.guestPin || ''; + }, + + async submitMatchReport() { + try { + const reportData = { + matchId: this.match.id, + startTime: this.match.startDate, + endTime: this.match.endDate, + protestText: this.protestText, + homePin: this.finalHomePin, + guestPin: this.finalGuestPin, + results: this.results, + finalScore: this.getOverallScore() + }; + + console.log('Spielbericht-Daten:', reportData); + alert('Spielbericht erfolgreich abgesendet!'); + } catch (error) { + console.error('Fehler beim Absenden:', error); + alert('Fehler beim Absenden des Spielberichts'); + } + }, + // Verwende die Matches aus dem Match-Objekt oder erstelle defaults initializeResults() { if (this.match.matches && Array.isArray(this.match.matches)) { @@ -1192,16 +1456,21 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr getOverallScore() { let homeWins = 0; let guestWins = 0; + let totalHomeSets = 0; + let totalGuestSets = 0; this.results.forEach(match => { if (match.completed) { - // Zähle gewonnene Sätze für dieses Match + // Source gewonnene Sätze für dieses Match und Gesamtsätze let matchHomeWins = 0; let matchGuestWins = 0; match.sets.forEach(set => { if (set && set.includes(':')) { const [home, guest] = set.split(':').map(s => parseInt(s) || 0); + totalHomeSets += home; + totalGuestSets += guest; + if (home > guest) { matchHomeWins++; } else if (guest > home) { @@ -1219,7 +1488,7 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr } }); - return `${homeWins}:${guestWins}`; + return `${homeWins}:${guestWins} (${totalHomeSets}:${totalGuestSets} Sätze)`; }, getMatchResult(match) { @@ -2117,6 +2386,174 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr border-color: var(--primary-color); } +/* Abschluss-Seite */ +.lineups-summary { + display: grid; + grid-template-columns: 1fr auto 1fr; + gap: 15px; + margin-bottom: 20px; + padding: 12px; + background: #f8f9fa; + border: 1px solid #dee2e6; + border-radius: 6px; +} + +.lineup-team { + background: #fff; + padding: 10px; + border-radius: 4px; + border: 1px solid #dee2e6; +} + +.lineup-team h4 { + margin: 0 0 8px 0; + color: var(--primary-color); + text-align: center; + font-size: 16px; +} + +.doppel-section, .einzel-section { + margin-bottom: 8px; +} + +.doppel-section h5, .einzel-section h5 { + margin: 0 0 4px 0; + color: #495057; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.3px; +} + +.pair-row, .player-row { + padding: 2px 0; + font-size: 13px; + color: #495057; +} + +.team-divider { + display: flex; + align-items: center; + + justify-content: center; + font-weight: bold; + color: var(--primary-color); + font-size: 16px; +} + +.final-score { + text-align: center; + margin: 16px 0; +} + +.final-score h3 { + margin: 0 0 8px 0; + color: var(--primary-color); + font-size: 18px; +} + +.score-summary.large { + padding: 10px; + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); + border: 2px solid var(--primary-color); + border-radius: 6px; +} + +.score-summary.large .score-value { + font-size: 20px; + font-weight: bold; +} + +.time-summary { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 15px; + margin-bottom: 16px; + padding: 10px; + background: #f8f9fa; + border: 1px solid #dee2e6; + border-radius: 4px; +} + +.time-display { + display: flex; + align-items: center; + gap: 8px; +} + +.time-display label { + font-weight: 500; + color: #495057; +} + +.time-value { + font-family: 'Courier New', monospace; + font-weight: 600; + color: var(--primary-color); +} + +.protest-section { + margin-bottom: 16px; +} + +.protest-section label { + display: block; + margin-bottom: 4px; + font-weight: 500; + color: #495057; + font-size: 14px; +} + +.protest-input { + width: 100%; + min-height: 50px; + padding: 8px; + border: 1px solid #dee2e6; + border-radius: 4px; + font-family: inherit; + font-size: 13px; + resize: vertical; +} + +.protest-input:focus { + outline: none; + border-color: var(--primary-color); + box-shadow: 0 0 0 2px rgba(var(--primary-rgb), 0.2); +} + +.final-pins { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 15px; + margin-bottom: 16px; + padding: 10px; + background: #f8f9fa; + border: 1px solid #dee2e6; + border-radius: 4px; +} + +.pin-group { + display: flex; + flex-direction: column; + gap: 4px; +} + +.pin-group label { + font-weight: 500; + color: #495057; + font-size: 14px; +} + +.submit-section { + text-align: center; + padding: 16px; +} + +.submit-btn { + font-size: 16px; + padding: 12px 24px; + font-weight: 600; +} + /* Fehlermeldungen */ .error-row { background-color: #fff5f5;