Erweitert den MatchReportApiDialog um neue Validierungsfunktionen zur Überprüfung von Satz-Inputs und zur Handhabung von Lücken in der Eingabe. Implementiert Methoden zur Berechnung gewonnener Sätze und zur Deaktivierung von Eingabefeldern, wenn ein Spieler bereits 3 Sätze gewonnen hat. Fügt visuelle Warnungen für problematische Eingaben hinzu und verbessert die Benutzeroberfläche mit neuen CSS-Stilen für Eingabefelder.

This commit is contained in:
Torsten Schulz (local)
2025-10-03 23:11:18 +02:00
parent c6bb534a0d
commit 049ee56571

View File

@@ -354,9 +354,10 @@
<td v-for="(s, sIdx) in m.sets" :key="sIdx" class="set-cell">
<input
class="set-input"
:class="{ 'gap-warning': shouldHighlightSetInput(idx, sIdx) }"
v-model="m.sets[sIdx]"
placeholder=":"
:disabled="m.completed"
:disabled="isSetInputDisabled(idx, sIdx)"
inputmode="numeric"
pattern="[0-9:\-]*"
@keyup.enter="processScoreInput(idx, sIdx)"
@@ -1542,12 +1543,126 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
this.$forceUpdate();
},
// Berechne gewonnene Sätze für einen Spieler in einem Match
getPlayerSetWins(match, player) {
let wins = 0;
match.sets.forEach(set => {
if (set && set.includes(':')) {
const [home, guest] = set.split(':').map(s => parseInt(s) || 0);
if (player === 'home' && home > guest) {
wins++;
} else if (player === 'guest' && guest > home) {
wins++;
}
}
});
return wins;
},
// Prüfe ob ein Satz-Input-Feld deaktiviert werden sollte
isSetInputDisabled(matchIndex, setIndex) {
const match = this.results[matchIndex];
// Wenn Match bereits abgeschlossen, alle Felder deaktiviert
if (match.completed) {
return true;
}
// Berechne aktuelle Gewinne ohne das zu prüfende Feld
let homeWins = 0;
let guestWins = 0;
match.sets.forEach((set, index) => {
// Überspringe das aktuell zu prüfende Feld
if (index === setIndex) {
return;
}
if (set && set.includes(':')) {
const [home, guest] = set.split(':').map(s => parseInt(s) || 0);
if (home > guest) {
homeWins++;
} else if (guest > home) {
guestWins++;
}
}
});
// Prüfe ob das aktuelle Feld bereits ausgefüllt ist
const currentSet = match.sets[setIndex];
const currentFieldHasValue = currentSet && currentSet.trim() !== '' && currentSet.includes(':');
// Wenn ein Spieler bereits 3 Sätze gewonnen hat UND das aktuelle Feld leer ist,
// dann dieses Feld deaktivieren (bereits ausgefüllte Felder bleiben aktiv)
if ((homeWins >= 3 || guestWins >= 3) && !currentFieldHasValue) {
return true;
}
return false;
},
// Prüfe ob es leere Input-Felder gibt, die nicht am Ende stehen
hasGapInSets(match) {
const problematicGaps = [];
for (let i = 0; i < match.sets.length; i++) {
const hasCurrentValue = match.sets[i] && match.sets[i].trim() !== '' && match.sets[i].includes(':');
// Wenn dieses Feld leer ist, prüfe ob es ein Problem darstellt
if (!hasCurrentValue) {
// Prüfe ob es ausgefüllte Felder nach diesem gibt
const hasFilledAfter = match.sets.slice(i + 1).some(set =>
set && set.trim() !== '' && set.includes(':')
);
if (hasFilledAfter) {
problematicGaps.push(i);
}
}
}
return problematicGaps.length > 0 ? problematicGaps : false;
},
// Prüfe ob ein Satz-Input rot umrandet werden sollte
shouldHighlightSetInput(matchIndex, setIndex) {
const match = this.results[matchIndex];
// Wenn Match schon abgeschlossen, keine Hervorhebung
if (match.completed) {
return false;
}
// Hole alle Lücken-Indizes
const gapIndices = this.hasGapInSets(match);
if (gapIndices === false) {
return false;
}
// Prüfe ob dieses Feld eine der problematischen Lücken ist
if (Array.isArray(gapIndices) && gapIndices.includes(setIndex)) {
const currentSet = match.sets[setIndex];
return !currentSet || currentSet.trim() === '' || !currentSet.includes(':');
}
return false;
},
parseAndValidateScore(inputValue, matchIndex, setIndex) {
const match = this.results[matchIndex];
// Entferne Leerzeichen
const cleanedValue = inputValue.trim();
// Prüfe ob das Feld überhaupt bearbeitet werden darf
if (this.isSetInputDisabled(matchIndex, setIndex)) {
// Wenn das Feld deaktiviert werden soll, Eingabe ignorieren
return;
}
// Verschiedene Eingabeformate unterstützen:
// "3:1", "3-1", "3 1", "3:1 ", "3", "-3"
let homeScore, guestScore;
@@ -1657,6 +1772,17 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
validateMatchCompletion(matchIndex) {
const match = this.results[matchIndex];
// Prüfe auf Lücken in der Sätze-Reihenfolge
const gapIndices = this.hasGapInSets(match);
if (gapIndices !== false && Array.isArray(gapIndices) && gapIndices.length > 0) {
const gapNumbers = gapIndices.map(idx => idx + 1).join(', ');
return {
isValid: false,
error: `Satz ${gapNumbers} muss ausgefüllt werden, bevor weitere Sätze eingegeben werden können.`
};
}
let homeWins = 0;
let guestWins = 0;
@@ -3510,6 +3636,25 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
gap: 6px;
}
/* Satz-Input Warnung für Lücken */
.set-input.gap-warning {
border: 2px solid #dc3545 !important;
background-color: #fef5f5 !important;
box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25) !important;
}
.set-input.gap-warning:focus {
border: 2px solid #dc3545 !important;
box-shadow: 0 0 0 0.3rem rgba(220, 53, 69, 0.25) !important;
}
.set-input:disabled {
opacity: 0.6 !important;
cursor: not-allowed !important;
background-color: #f8f9fa !important;
border-color: #dee2e6 !important;
}
/* Zertifizierung-Styles */
.section-btn.certified {
background-color: #d4edda;