⚠️ Dieser Spielbericht wurde bereits abgesendet. Keine weiteren Änderungen möglich.
+
+
+
+
+ ❌ Der Spielbericht kann nicht abgesendet werden. Es müssen alle Spiele abgeschlossen sein.
+ Bitte schließen Sie alle {{ results.filter(match => !match.completed).length }} offenen Spiele ab!
+
+
+ ❌ Der Spielbericht kann nicht abgesendet werden. Es gibt noch Fehler in den Match-Ergebnissen.
+ Bitte überprüfen Sie die Ergebniserfassung!
+
+
+
+
+
+ ❌ Der Spielbericht kann nicht abgesendet werden. Start- oder Endzeit sind nicht festgelegt.
+ Bitte legen Sie beide Zeiten fest!
+
@@ -642,10 +662,21 @@ export default {
'werner-scheffler-system': [
'DA1 – DB1', 'DA2 – DB2', 'A1 – B2', 'A2 – B1', 'A3 – B4', 'A4 – B3', 'A1 – B1', 'A2 – B2', 'A3 – B3', 'A4 – B4', 'A3 – B1', 'A1 – B3', 'A2 – B4', 'A4 – B2'
],
- 'braunschweiger system': [
- // Vierer–Vierer (häufigster Pfad)
- 'DA1 – DB1', 'DA2 – DB2', 'A1 – B1', 'A2 – B2', 'A3 – B3', 'A4 – B4', 'A1 – B2', 'A2 – B1', 'A3 – B4', 'A4 – B3'
- ],
+ 'braunschweiger system': {
+ // Dynamische Auswahl je nach Spielerzahlen
+ matrices: {
+ // 4 vs 4 Spieler
+ '4-4': ['DA1 – DB1', 'DA2 – DB2', 'A1 – B1', 'A2 – B2', 'A3 – B3', 'A4 – B4', 'A1 – B2', 'A2 – B1', 'A3 – B4', 'A4 – B3'],
+ // 4 vs 3 Spieler
+ '4-3': ['DA1 – DB1', 'A3 – B3', 'A1 – B2', 'A2 – B1', 'A4 – B2', 'A1 – B1', 'A4 – B3', 'A2 – B2', 'A1 – B3', 'A3 – B1'],
+ // 3 vs 4 Spieler
+ '3-4': ['DA1 – DB1', 'A3 – B3', 'A2 – B1', 'A1 – B2', 'A2 – B4', 'A1 – B1', 'A3 – B4', 'A2 – B2', 'A3 – B1', 'A1 – B3'],
+ // 3 vs 3 Spieler
+ '3-3': ['DA1 – DB1', 'A1 – B2', 'A2 – B1', 'A3 – B2', 'A2 – B3', 'A1 – B1', 'A3 – B3', 'A2 – B2', 'A3 – B1', 'A1 – B3']
+ },
+ // Fallback für unbekannte Kombination
+ default: ['DA1 – DB1', 'DA2 – DB2', 'A1 – B1', 'A2 – B2', 'A3 – B3', 'A4 – B4', 'A1 – B2', 'A2 – B1', 'A3 – B4', 'A4 – B3']
+ },
'modifiziertes swaythling-cup-system': [
'A1 – B2', 'A2 – B1', 'A3 – B3', 'DA1 – DB1', 'A1 – B1', 'A3 – B2', 'A2 – B3'
],
@@ -700,8 +731,29 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
},
currentPlayModeMatrix() {
const key = (this.currentPlayMode || '').toLowerCase();
- return this.playModeMatrices[key] || [];
- }
+ const matrixConfig = this.playModeMatrices[key];
+
+ // Spezielle Behandlung für Braunschweiger System
+ if (matrixConfig && typeof matrixConfig === 'object' && matrixConfig.matrices) {
+ const homePlayerCount = this.getSelectedPlayerCount('home');
+ const guestPlayerCount = this.getSelectedPlayerCount('guest');
+
+ // Erstelle Key basierend auf Spielerzahlen (z.B. "3-4", "4-4")
+ const playerCountKey = `${homePlayerCount}-${guestPlayerCount}`;
+
+ console.log(`🎯 Braunschweiger System: ${homePlayerCount} vs ${guestPlayerCount} → Key: ${playerCountKey}`);
+
+ // Verwende spezifische Matrix oder Fallback
+ return matrixConfig.matrices[playerCountKey] || matrixConfig.default || [];
+ }
+
+ // Standard-Verhalten für andere Systeme
+ return matrixConfig || [];
+ },
+ // Prüfe ob das Match bereits abgeschlossen ist
+ isMatchCompleted() {
+ return this.match && this.match.isCompleted === true;
+ },
},
async mounted() {
await this.loadData();
@@ -845,10 +897,151 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
this.finalGuestPin = this.match.guestPin || '';
},
+ // Text für den Absenden-Button basierend auf Zustand
+ getSubmitButtonText() {
+ if (this.isMatchCompleted) {
+ return '✅ Spielbericht bereits abgesendet';
+ } else if (!this.areAllMatchResultsValid()) {
+ const playThrough = this.getPlayThrough();
+ if (playThrough && playThrough.toUpperCase().includes('ALLGAMES')) {
+ const unfinishedMatches = this.results.filter(match => !match.completed);
+ return `❌ Spielbericht absenden (${unfinishedMatches.length} Spiel/e noch offen)`;
+ }
+ return '❌ Spielbericht absenden (Ergebnisse fehlerhaft)';
+ } else if (!this.areStartAndEndTimesValid()) {
+ return '❌ Spielbericht absenden (Zeiten fehlerhaft)';
+ } else {
+ return '📝 Spielbericht absenden';
+ }
+ },
+
+ // Prüfe ob Start- und Endzeiten korrekt festgelegt sind
+ areStartAndEndTimesValid() {
+ // Prüfe ob Startzeit festgelegt wurde
+ if (!this.match.startDate) {
+ console.log('❌ Startzeit ist nicht festgelegt');
+ return false;
+ }
+
+ // Prüfe ob Endzeit festgelegt wurde
+ if (!this.match.endDate) {
+ console.log('❌ Endzeit ist nicht festgelegt');
+ return false;
+ }
+
+ // Prüfe ob Endzeit nach Startzeit liegt
+ const startTime = new Date(this.match.startDate).getTime();
+ const endTime = new Date(this.match.endDate).getTime();
+
+ if (endTime <= startTime) {
+ console.log('⚠️ Endzeit liegt vor/vor Startzeit - korrigiere auf nächsten Tag...');
+ // Setze Endzeit auf nächsten Tag um dieselbe Uhrzeit
+ const nextDay = new Date(endTime);
+ nextDay.setDate(nextDay.getDate() + 1);
+ this.match.endDate = nextDay;
+ console.log('✅ Endzeit wurde auf nächsten Tag verschoben:', nextDay.toISOString());
+ }
+
+ console.log('✅ Start- und Endzeiten sind korrekt');
+ return true;
+ },
+
+ // Prüfe ob alle Matchergebnisse korrekt sind (für Spielbericht-Absendung)
+ areAllMatchResultsValid() {
+ if (!this.results || this.results.length === 0) {
+ return false;
+ }
+
+ // Spezielle Regel für ALLGAMES Spielmodus
+ const playThrough = this.getPlayThrough();
+ if (playThrough && playThrough.toUpperCase().includes('ALLGAMES')) {
+ // Alle Spiele müssen abgeschlossen sein
+ const unfinishedMatches = this.results.filter(match => !match.completed);
+ if (unfinishedMatches.length > 0) {
+ console.log(`❌ ALLGAMES Modus: ${unfinishedMatches.length} Spiel(e) noch nicht abgeschlossen`);
+ return false;
+ }
+ console.log('✅ ALLGAMES Modus: Alle Spiele sind abgeschlossen');
+ }
+
+ for (let i = 0; i < this.results.length; i++) {
+ const match = this.results[i];
+
+ // Prüfe auf Lücken in der Sätze-Reihenfolge
+ const gapIndices = this.hasGapInSets(match);
+ if (gapIndices !== false && Array.isArray(gapIndices) && gapIndices.length > 0) {
+ console.log(`❌ Match ${i + 1}: Lücken gefunden bei Satz ${gapIndices.map(idx => idx + 1).join(', ')}`);
+ return false;
+ }
+
+ // Prüfe jeden Satz auf Validität (nur ausgefüllte Sätze)
+ for (let j = 0; j < match.sets.length; j++) {
+ const set = match.sets[j];
+ if (set && set.trim().length > 0 && set.includes(':')) {
+ // Parse die Satzergebnisse
+ const [homeScoreStr, guestScoreStr] = set.split(':');
+ const homeScore = parseInt(homeScoreStr) || 0;
+ const guestScore = parseInt(guestScoreStr) || 0;
+
+ const validationResult = this.validateSetScore(homeScore, guestScore, set);
+ if (!validationResult.isValid) {
+ console.log(`❌ Match ${i + 1}, Satz ${j + 1}: ${validationResult.error}`);
+ return false;
+ }
+ }
+ }
+
+ // Prüfe Match-Abschluss-Regeln wenn Match als abgeschlossen markiert ist
+ if (match.completed) {
+ const completionValidation = this.validateMatchCompletion(i);
+ if (!completionValidation.isValid) {
+ console.log(`❌ Match ${i + 1}: ${completionValidation.error}`);
+ return false;
+ }
+ }
+ }
+
+ console.log('✅ Alle Match-Ergebnisse sind korrekt');
+ return true;
+ },
+
async submitMatchReport() {
try {
console.log('🚀 Starte Spielbericht-Absendung...');
+ // Validiere zuerst alle Match-Ergebnisse
+ if (!this.areAllMatchResultsValid()) {
+ const playThrough = this.getPlayThrough();
+ if (playThrough && playThrough.toUpperCase().includes('ALLGAMES')) {
+ const unfinishedMatches = this.results.filter(match => !match.completed);
+ alert(`❌ Der Spielbericht kann nicht abgesendet werden. Es müssen alle Spiele abgeschlossen sein.\n\n` +
+ `📊 Aktueller Status:\n` +
+ `• ${this.results.length} Spiele insgesamt\n` +
+ `• ${this.results.length - unfinishedMatches.length} Spiele abgeschlossen\n` +
+ `• ${unfinishedMatches.length} Spiele noch offen\n\n` +
+ `Bitte schließen Sie alle offenen Spiele ab, bevor Sie den Spielbericht absenden.`);
+ return;
+ } else {
+ alert('❌ Der Spielbericht kann nicht abgesendet werden, da noch Fehler in den Match-Ergebnissen vorhanden sind. Bitte korrigieren Sie:\n\n' +
+ '• Lücken in der Satze-Reihenfolge\n' +
+ '• Ungültige Satzergebnisse\n' +
+ '• Ungenerische Match-Abschlüsse\n\n' +
+ 'Überprüfen Sie die Ergebniserfassung.');
+ return;
+ }
+ }
+
+ console.log('✅ Alle Match-Ergebnisse sind gültig - fahre fort...');
+
+ // Validiere Start- und Endzeiten
+ if (!this.areStartAndEndTimesValid()) {
+ alert('❌ Der Spielbericht kann nicht abgesendet werden, da Start- oder Endzeit nicht festgelegt wurden.\n\n' +
+ 'Bitte legen Sie sowohl Startzeit als auch Endzeit fest.');
+ return;
+ }
+
+ console.log('✅ Alle Zeiten sind gültig - fahre fort...');
+
// Validiere PINs (für Test: Gast-PIN "1234" akzeptieren)
if (!this.finalHomePin || this.finalHomePin.trim() === '') {
alert('Bitte geben Sie die PIN des Heimvereins ein.');
@@ -1163,10 +1356,6 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
console.log('✅ Player-Positionen aktualisiert');
},
- // Prüfe ob das Match bereits abgeschlossen ist
- get isMatchCompleted() {
- return this.match && this.match.isCompleted === true;
- },
// Zähle die ausgewählten Spieler für ein Team
getSelectedPlayerCount(team) {
@@ -1874,6 +2063,21 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
const now = new Date();
const timeString = now.toTimeString().slice(0, 5); // HH:MM format
this.match.endDate = this.createDateTimeFromTimeString(timeString);
+
+ // Prüfe ob Endzeit vor Startzeit liegt und korrigiere automatisch
+ if (this.match.startDate && this.match.endDate) {
+ const startTime = new Date(this.match.startDate).getTime();
+ const endTime = new Date(this.match.endDate).getTime();
+
+ if (endTime <= startTime) {
+ console.log('⚠️ Endzeit liegt vor/auf Startzeit - korrigiere auf nächsten Tag...');
+ // Setze Endzeit auf nächsten Tag um dieselbe Uhrzeit
+ const nextDay = new Date(endTime);
+ nextDay.setDate(nextDay.getDate() + 1);
+ this.match.endDate = nextDay;
+ console.log('✅ Endzeit wurde auf nächsten Tag verschoben:', nextDay.toISOString());
+ }
+ }
},
setStartTime(timeString) {
@@ -1882,6 +2086,21 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
setEndTime(timeString) {
this.match.endDate = this.createDateTimeFromTimeString(timeString);
+
+ // Prüfe ob Endzeit vor Startzeit liegt und korrigiere automatisch
+ if (this.match.startDate && this.match.endDate) {
+ const startTime = new Date(this.match.startDate).getTime();
+ const endTime = new Date(this.match.endDate).getTime();
+
+ if (endTime <= startTime) {
+ console.log('⚠️ Endzeit liegt vor/auf Startzeit - korrigiere auf nächsten Tag...');
+ // Setze Endzeit auf nächsten Tag um dieselbe Uhrzeit
+ const nextDay = new Date(endTime);
+ nextDay.setDate(nextDay.getDate() + 1);
+ this.match.endDate = nextDay;
+ console.log('✅ Endzeit wurde auf nächsten Tag verschoben:', nextDay.toISOString());
+ }
+ }
},
getFormattedTime(dateValue) {
@@ -2494,16 +2713,50 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
},
- // Hole aktuellen Spielmodus
+ // Hole aktuellen Spielmodus (für Validierungen)
+ getPlayThrough() {
+ // Suche nach playThrough für ALLGAMES-Validierung
+ const meetingPlayThrough = this.meetingDetails && this.meetingDetails.playThrough;
+ const dataPlayThrough = this.meetingData && this.meetingData.playThrough;
+
+ const playThrough = meetingPlayThrough || dataPlayThrough || '';
+ console.log(`🔍 getPlayThrough: meetingPlayThrough=${meetingPlayThrough}, dataPlayThrough=${dataPlayThrough}, result=${playThrough}`);
+ return playThrough;
+ },
+
+ // Hole aktuellen Spielmodus (für matrix/logic)
getPlayMode() {
- return (this.meetingDetails && this.meetingDetails.playMode) ||
- (this.meetingData && (this.meetingData.playMode || this.meetingData.matchSystem || this.meetingData.system)) ||
- '';
+ const meetingPlayModeObj = this.meetingDetails && this.meetingDetails.playMode;
+ const dataMode = this.meetingData && (this.meetingData.playMode || this.meetingData.matchSystem || this.meetingData.system);
+
+ // Falls meetingPlayMode ein Objekt ist, extrahiere die richtige Eigenschaft
+ let meetingPlayMode = '';
+ if (meetingPlayModeObj) {
+ if (typeof meetingPlayModeObj === 'string') {
+ meetingPlayMode = meetingPlayModeObj;
+ } else if (meetingPlayModeObj.name) {
+ meetingPlayMode = meetingPlayModeObj.name;
+ } else if (meetingPlayModeObj.playMode) {
+ meetingPlayMode = meetingPlayModeObj.playMode;
+ } else {
+ // Debug: Objekt-Struktur analysieren
+ console.log('🔍 meetingPlayMode Objekt-Struktur:', Object.keys(meetingPlayModeObj));
+ meetingPlayMode = meetingPlayModeObj.toString();
+ }
+ }
+
+ const playMode = meetingPlayMode || dataMode || '';
+ console.log(`🔍 getPlayMode: meetingPlayModeObj=${meetingPlayModeObj}, extracted=${meetingPlayMode}, dataMode=${dataMode}, result=${playMode}`);
+ return playMode;
},
// Bestimme erforderliche Mindestspielerzahl für Spielmodus
getRequiredPlayerCount(playMode) {
- const mode = (playMode || '').toLowerCase();
+ if (!playMode) {
+ console.log('⚠️ getRequiredPlayerCount: playMode ist undefined oder leer');
+ return 3; // Fallback-Wert
+ }
+ const mode = playMode.toLowerCase();
// 6er System: 4 Spieler erforderlich
if (mode.includes('6')) {
@@ -3897,6 +4150,22 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
text-align: center;
}
+.validation-notice {
+ margin-top: 8px;
+ padding: 8px 12px;
+ background-color: #f8d7da;
+ border: 1px solid #f5c6cb;
+ border-radius: 4px;
+ color: #721c24;
+ font-size: 12px;
+ text-align: center;
+ font-weight: 500;
+}
+
+.validation-notice strong {
+ color: #721c24;
+}
+
.time-input:disabled,
.protest-input:disabled,
.pin-input:disabled {