feat(match-report): enhance score input with additional buttons and auto-completion logic

- Added extra buttons for appending ':' and '-' to score inputs in the MatchReportApiDialog component, improving user interaction.
- Implemented a method to automatically complete matches when a player wins 3 sets, enhancing match management.
- Updated styles for input elements and buttons to improve layout and usability in the ScheduleView component.
This commit is contained in:
Torsten Schulz (local)
2026-02-26 16:11:33 +01:00
parent e22e3257ef
commit f031485bd4
2 changed files with 98 additions and 15 deletions

View File

@@ -383,17 +383,31 @@
<td>{{ m.homeName }}</td>
<td>{{ m.guestName }}</td>
<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="isSetInputDisabled(idx, sIdx)"
inputmode="numeric"
pattern="[0-9:\-]*"
@keyup.enter="processScoreInput(idx, sIdx)"
@blur="processScoreInput(idx, sIdx)"
/>
<div class="set-input-wrapper">
<input
class="set-input"
:class="{ 'gap-warning': shouldHighlightSetInput(idx, sIdx) }"
v-model="m.sets[sIdx]"
placeholder=":"
:disabled="isSetInputDisabled(idx, sIdx)"
inputmode="numeric"
pattern="[0-9:\-]*"
@keyup.enter="processScoreInput(idx, sIdx)"
@blur="processScoreInput(idx, sIdx)"
/>
<div class="set-extra-buttons">
<button
type="button"
class="set-extra-btn"
@click="appendToSet(idx, sIdx, ':')"
>:</button>
<button
type="button"
class="set-extra-btn"
@click="appendToSet(idx, sIdx, '-')"
>-</button>
</div>
</div>
</td>
<td class="state-cell">
<div class="state-content">
@@ -2119,6 +2133,17 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
// Synchronisiere zurück ins Match-Objekt
this.syncResultsToMatch();
},
appendToSet(matchIndex, setIndex, char) {
if (!this.results || !this.results[matchIndex]) return;
const sets = this.results[matchIndex].sets || [];
const current = sets[setIndex] || '';
// Einfache Längenbegrenzung, damit die Eingabe übersichtlich bleibt
if (current.length >= 5) {
return;
}
this.results[matchIndex].sets[setIndex] = current + char;
},
reopenMatch(idx) {
const m = this.results[idx];
m.completed = false;
@@ -2216,6 +2241,17 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
// Verarbeite die Eingabe nach den Regeln
this.parseAndValidateScore(inputValue, matchIndex, setIndex);
// Nach der Verarbeitung: automatisch abschließen, wenn ein Spieler 3 Sätze gewonnen hat
const updatedMatch = this.results[matchIndex];
if (updatedMatch && !updatedMatch.completed) {
const homeWins = this.getPlayerSetWins(updatedMatch, 'home');
const guestWins = this.getPlayerSetWins(updatedMatch, 'guest');
if (homeWins >= 3 || guestWins >= 3) {
this.completeMatch(matchIndex);
}
}
// Aktualisiere die Anzeige
this.$forceUpdate();
},
@@ -3681,6 +3717,11 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
.result-table { width: 100%; border-collapse: collapse; background: #fff; border: 1px solid #e0e0e0; border-radius: 8px; overflow: hidden; }
.result-table th, .result-table td { border-bottom: 1px solid #eee; padding: 8px; text-align: left; }
.result-table thead th { background: #f8f9fa; }
.set-input-wrapper {
display: flex;
align-items: center;
gap: 4px;
}
.set-input {
width: 56px;
text-align: center;
@@ -3703,6 +3744,24 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
cursor: not-allowed;
}
.set-extra-buttons {
display: none;
}
.set-extra-btn {
border: 1px solid #ccc;
border-radius: 4px;
background-color: #fff;
padding: 2px 4px;
font-size: 0.75rem;
cursor: pointer;
line-height: 1;
}
.set-extra-btn:active {
background-color: #f0f0f0;
}
/* Mobile-spezifische Optimierungen */
@media (max-width: 768px) {
.set-input {
@@ -3713,9 +3772,10 @@ Wir wünschen den Spielen einen schönen, spannenden und fairen Verlauf und begr
border-radius: 6px;
}
.set-input[inputmode="numeric"] {
/* Erzwingt numerische Tastatur auf mobilen Geräten */
-webkit-text-security: none;
.set-extra-buttons {
display: flex;
flex-direction: column;
gap: 2px;
}
}
.state-cell { text-align: center; }

View File

@@ -94,7 +94,7 @@
<td
v-if="selectedLeague === $t('schedule.overallSchedule') || selectedLeague === $t('schedule.adultSchedule')">
{{ match.leagueDetails?.name || 'N/A' }}</td>
<td class="code-cell">
<td class="code-cell match-report-cell" @click.stop="openMatchReport(match)">
<span v-if="match.code && selectedLeague && selectedLeague !== ''">
<button @click.stop="openMatchReport(match)" class="nuscore-link"
:title="$t('schedule.openMatchReport')">📊</button>
@@ -974,6 +974,9 @@ export default {
},
openMatchReport(match) {
if (!match || !match.code) {
return;
}
const title = `${match.homeTeam?.name || 'N/A'} vs ${match.guestTeam?.name || 'N/A'} - ${this.selectedLeague}`;
this.openDialog({
title,
@@ -1210,6 +1213,10 @@ li {
min-width: 80px;
}
.match-report-cell {
cursor: pointer;
}
.code-value {
background: #e3f2fd;
color: #1976d2;
@@ -1241,12 +1248,28 @@ li {
cursor: pointer;
padding: 0;
color: inherit;
display: inline-flex;
align-items: center;
justify-content: center;
width: 2.25rem;
height: 2.25rem;
border-radius: 999px;
background-color: #e3f2fd;
border: 1px solid #bbdefb;
}
.nuscore-link:hover {
transform: scale(1.2);
}
@media (pointer: coarse), (max-width: 900px) {
.nuscore-link {
width: 2.75rem;
height: 2.75rem;
font-size: 1.4rem;
}
}
.pin-value {
background: #fff3e0;
color: #f57c00;