feat(AutoFetchMatchResultsService, ScheduleView): enhance date and time parsing for match results

- Implemented a new method in AutoFetchMatchResultsService to parse match date and time from various formats, improving robustness in handling date inputs.
- Updated storeMatchResult method to utilize the new date parsing logic, ensuring accurate match date handling.
- Enhanced ScheduleView to maintain consistent display of match dates and times, improving user experience in the schedule table.
This commit is contained in:
Torsten Schulz (local)
2026-03-26 19:34:46 +01:00
parent c7d51efb5d
commit 32ba433008
2 changed files with 177 additions and 107 deletions

View File

@@ -80,84 +80,86 @@
</div>
</div>
<div v-if="matches.length > 0">
<table id="schedule-table">
<thead>
<tr>
<th>{{ $t('schedule.locationInfo') }}</th>
<th>{{ $t('schedule.date') }}</th>
<th>{{ $t('schedule.time') }}</th>
<th>{{ $t('schedule.homeTeam') }}</th>
<th>{{ $t('schedule.guestTeam') }}</th>
<th>{{ $t('schedule.result') }}</th>
<th
v-if="selectedLeague === $t('schedule.overallSchedule') || selectedLeague === $t('schedule.adultSchedule')">
{{ $t('schedule.ageClass') }}</th>
<th>{{ $t('schedule.code') }}</th>
<th>{{ $t('schedule.homePin') }}</th>
<th>{{ $t('schedule.guestPin') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="match in matches" :key="match.id"
@click="openPlayerSelectionDialog(match)"
:class="getRowClass(match.date)"
style="cursor: pointer;">
<td class="location-info-cell">
<button
v-if="match.location"
type="button"
class="location-info-button"
:title="$t('schedule.showLocation')"
@click.stop="openLocationDialog(match)"
>
📍
</button>
<span v-else class="no-data">-</span>
</td>
<td>{{ formatDate(match.date) }}</td>
<td>{{ match.time ? match.time.toString().slice(0, 5) + ' ' + $t('common.time') : 'N/A' }}</td>
<td :class="{ 'highlighted-club': isClubHighlighted(match.homeTeam?.name) }">
{{ match.homeTeam?.name || 'N/A' }}
</td>
<td :class="{ 'highlighted-club': isClubHighlighted(match.guestTeam?.name) }">
{{ match.guestTeam?.name || 'N/A' }}
</td>
<td class="result-cell" :class="getResultClass(match)">
<span v-if="match.isCompleted" class="result-score">
{{ match.homeMatchPoints }}:{{ match.guestMatchPoints }}
</span>
<span v-else class="result-pending"></span>
</td>
<td
v-if="selectedLeague === $t('schedule.overallSchedule') || selectedLeague === $t('schedule.adultSchedule')">
{{ match.leagueDetails?.name || 'N/A' }}</td>
<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>
<span class="code-value clickable" @click.stop="copyToClipboard(match.code, $t('schedule.code'), $event)"
<div class="schedule-table-wrapper">
<table id="schedule-table">
<thead>
<tr>
<th>{{ $t('schedule.locationInfo') }}</th>
<th>{{ $t('schedule.date') }}</th>
<th>{{ $t('schedule.time') }}</th>
<th>{{ $t('schedule.homeTeam') }}</th>
<th>{{ $t('schedule.guestTeam') }}</th>
<th>{{ $t('schedule.result') }}</th>
<th
v-if="selectedLeague === $t('schedule.overallSchedule') || selectedLeague === $t('schedule.adultSchedule')">
{{ $t('schedule.ageClass') }}</th>
<th>{{ $t('schedule.code') }}</th>
<th>{{ $t('schedule.homePin') }}</th>
<th>{{ $t('schedule.guestPin') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="match in matches" :key="match.id"
@click="openPlayerSelectionDialog(match)"
:class="getRowClass(match.date)"
style="cursor: pointer;">
<td class="location-info-cell">
<button
v-if="match.location"
type="button"
class="location-info-button"
:title="$t('schedule.showLocation')"
@click.stop="openLocationDialog(match)"
>
📍
</button>
<span v-else class="no-data">-</span>
</td>
<td>{{ formatDate(match.date) }}</td>
<td>{{ match.time ? match.time.toString().slice(0, 5) + ' ' + $t('common.time') : 'N/A' }}</td>
<td :class="{ 'highlighted-club': isClubHighlighted(match.homeTeam?.name) }">
{{ match.homeTeam?.name || 'N/A' }}
</td>
<td :class="{ 'highlighted-club': isClubHighlighted(match.guestTeam?.name) }">
{{ match.guestTeam?.name || 'N/A' }}
</td>
<td class="result-cell" :class="getResultClass(match)">
<span v-if="match.isCompleted" class="result-score">
{{ match.homeMatchPoints }}:{{ match.guestMatchPoints }}
</span>
<span v-else class="result-pending"></span>
</td>
<td
v-if="selectedLeague === $t('schedule.overallSchedule') || selectedLeague === $t('schedule.adultSchedule')">
{{ match.leagueDetails?.name || 'N/A' }}</td>
<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>
<span class="code-value clickable" @click.stop="copyToClipboard(match.code, $t('schedule.code'), $event)"
:title="$t('schedule.copyCode') + ': ' + match.code">{{ match.code }}</span>
</span>
<span v-else-if="match.code" class="code-value clickable"
@click.stop="copyToClipboard(match.code, $t('schedule.code'), $event)"
:title="$t('schedule.copyCode') + ': ' + match.code">{{ match.code }}</span>
</span>
<span v-else-if="match.code" class="code-value clickable"
@click.stop="copyToClipboard(match.code, $t('schedule.code'), $event)"
:title="$t('schedule.copyCode') + ': ' + match.code">{{ match.code }}</span>
<span v-else class="no-data">-</span>
</td>
<td class="pin-cell">
<span v-if="match.homePin" class="pin-value clickable"
@click.stop="copyToClipboard(match.homePin, $t('schedule.homePin'), $event)"
:title="$t('schedule.copyHomePin') + ': ' + match.homePin">{{ match.homePin }}</span>
<span v-else class="no-data">-</span>
</td>
<td class="pin-cell">
<span v-if="match.guestPin" class="pin-value clickable"
@click.stop="copyToClipboard(match.guestPin, $t('schedule.guestPin'), $event)"
:title="$t('schedule.copyGuestPin') + ': ' + match.guestPin">{{ match.guestPin }}</span>
<span v-else class="no-data">-</span>
</td>
</tr>
</tbody>
</table>
<span v-else class="no-data">-</span>
</td>
<td class="pin-cell">
<span v-if="match.homePin" class="pin-value clickable"
@click.stop="copyToClipboard(match.homePin, $t('schedule.homePin'), $event)"
:title="$t('schedule.copyHomePin') + ': ' + match.homePin">{{ match.homePin }}</span>
<span v-else class="no-data">-</span>
</td>
<td class="pin-cell">
<span v-if="match.guestPin" class="pin-value clickable"
@click.stop="copyToClipboard(match.guestPin, $t('schedule.guestPin'), $event)"
:title="$t('schedule.copyGuestPin') + ': ' + match.guestPin">{{ match.guestPin }}</span>
<span v-else class="no-data">-</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-else>
<p>{{ $t('schedule.noGames') }}</p>
@@ -169,28 +171,30 @@
<h3>{{ $t('schedule.leagueTable') }}</h3>
</div>
<div v-if="leagueTable.length > 0">
<table id="league-table">
<thead>
<tr>
<th>{{ $t('schedule.position') }}</th>
<th>{{ $t('schedule.team') }}</th>
<th>{{ $t('schedule.matches') }}</th>
<th>{{ $t('schedule.sets') }}</th>
<th>{{ $t('schedule.points') }}</th>
<th>{{ $t('schedule.balls') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(team, index) in leagueTable" :key="team.teamId" :class="{ 'our-team': isOurTeam(team.teamName) }">
<td>{{ index + 1 }}</td>
<td>{{ team.teamName }}</td>
<td>{{ team.matchPoints }}</td>
<td>{{ team.setsWon }}:{{ team.setsLost }}</td>
<td>{{ team.tablePoints }}</td>
<td>{{ team.pointRatio }}</td>
</tr>
</tbody>
</table>
<div class="schedule-table-wrapper">
<table id="league-table">
<thead>
<tr>
<th>{{ $t('schedule.position') }}</th>
<th>{{ $t('schedule.team') }}</th>
<th>{{ $t('schedule.matches') }}</th>
<th>{{ $t('schedule.sets') }}</th>
<th>{{ $t('schedule.points') }}</th>
<th>{{ $t('schedule.balls') }}</th>
</tr>
</thead>
<tbody>
<tr v-for="(team, index) in leagueTable" :key="team.teamId" :class="{ 'our-team': isOurTeam(team.teamName) }">
<td>{{ index + 1 }}</td>
<td>{{ team.teamName }}</td>
<td>{{ team.matchPoints }}</td>
<td>{{ team.setsWon }}:{{ team.setsLost }}</td>
<td>{{ team.tablePoints }}</td>
<td>{{ team.pointRatio }}</td>
</tr>
</tbody>
</table>
</div>
</div>
<div v-else>
<p>{{ $t('schedule.noTableData') }}</p>
@@ -1728,6 +1732,36 @@ li {
margin: 0;
}
.schedule-table-wrapper {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
overscroll-behavior-x: contain;
}
#schedule-table {
width: 100%;
min-width: 980px;
border-collapse: collapse;
}
#schedule-table th,
#schedule-table td {
padding: 12px 8px;
text-align: left;
border: 1px solid #ddd;
white-space: nowrap;
}
#schedule-table th {
background-color: #f8f9fa;
font-weight: 600;
}
#schedule-table tr:hover {
background-color: #f5f5f5;
}
.fetch-table-btn {
background: linear-gradient(135deg, var(--primary-color), var(--primary-hover));
color: var(--text-on-primary);
@@ -1752,6 +1786,7 @@ li {
#league-table {
width: 100%;
min-width: 640px;
border-collapse: collapse;
}