feat(matches): add optional match credentials fields to manual match creation and update localization
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 56s
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 56s
This commit is contained in:
@@ -52,6 +52,7 @@ class MatchService {
|
||||
const opponentName = String(payload.opponentName || '').trim();
|
||||
const homeAway = payload.homeAway === 'away' ? 'away' : 'home';
|
||||
const fixtureType = String(payload.fixtureType || 'league').trim();
|
||||
const optionalCredential = (value) => String(value || '').trim().slice(0, 255) || null;
|
||||
if (!['league', 'cup'].includes(fixtureType)) {
|
||||
throw new HttpError('Ungültiger Spieltyp', 400);
|
||||
}
|
||||
@@ -82,7 +83,11 @@ class MatchService {
|
||||
date: new Date(`${date}T${time}:00`), time, clubId: parsedClubId, leagueId: league.id, locationId,
|
||||
homeTeamId: homeAway === 'home' ? ownTeam.id : opponentTeam.id,
|
||||
guestTeamId: homeAway === 'home' ? opponentTeam.id : ownTeam.id,
|
||||
fixtureType, notes: String(payload.notes || '').trim() || null
|
||||
fixtureType,
|
||||
code: optionalCredential(payload.code),
|
||||
homePin: optionalCredential(payload.homePin),
|
||||
guestPin: optionalCredential(payload.guestPin),
|
||||
notes: String(payload.notes || '').trim() || null
|
||||
});
|
||||
return { id: match.id, clubId: match.clubId, match: await this.enrichMatch(match) };
|
||||
}
|
||||
|
||||
@@ -1499,6 +1499,7 @@
|
||||
"zip": "PLZ",
|
||||
"city": "Ort",
|
||||
"location": "Spielort",
|
||||
"matchCredentials": "Spielzugangsdaten (optional)",
|
||||
"notes": "Notizen",
|
||||
"saving": "Speichert…",
|
||||
"manualMatchRequired": "Bitte Mannschaft, Gegner, Datum und Uhrzeit ausfüllen.",
|
||||
|
||||
@@ -1437,6 +1437,7 @@
|
||||
"title": "Schedules",
|
||||
"subtitle": "Select teams, review fixtures and keep league tables in view.",
|
||||
"importSchedule": "Import schedule",
|
||||
"matchCredentials": "Match credentials (optional)",
|
||||
"galleryLoading": "Loading gallery…",
|
||||
"gallery": "Member gallery",
|
||||
"overallSchedule": "Overall schedule",
|
||||
|
||||
@@ -1438,6 +1438,7 @@
|
||||
"title": "Schedules",
|
||||
"subtitle": "Select teams, review fixtures and keep league tables in view.",
|
||||
"importSchedule": "Import schedule",
|
||||
"matchCredentials": "Match credentials (optional)",
|
||||
"galleryLoading": "Loading gallery…",
|
||||
"gallery": "Member gallery",
|
||||
"overallSchedule": "Overall schedule",
|
||||
|
||||
@@ -1476,6 +1476,7 @@
|
||||
"zip": "Postal code",
|
||||
"city": "City",
|
||||
"location": "Location",
|
||||
"matchCredentials": "Match credentials (optional)",
|
||||
"notes": "Notes",
|
||||
"saving": "Saving…",
|
||||
"manualMatchRequired": "Please fill in the team, opponent, date and time.",
|
||||
|
||||
@@ -294,6 +294,14 @@
|
||||
<label><span>{{ $t('schedule.city') }}</span><input v-model.trim="manualMatchDialog.form.locationCity"></label>
|
||||
</div>
|
||||
<fieldset class="manual-match-home-away"><legend>{{ $t('schedule.location') }}</legend><label><input v-model="manualMatchDialog.form.homeAway" type="radio" value="home"> {{ $t('schedule.homeGame') }}</label><label><input v-model="manualMatchDialog.form.homeAway" type="radio" value="away"> {{ $t('schedule.away') }}</label></fieldset>
|
||||
<fieldset v-if="manualMatchDialog.form.fixtureType !== 'friendly'" class="manual-match-credentials">
|
||||
<legend>{{ $t('schedule.matchCredentials') }}</legend>
|
||||
<div class="manual-match-grid">
|
||||
<label><span>{{ $t('schedule.code') }}</span><input v-model.trim="manualMatchDialog.form.code" maxlength="255"></label>
|
||||
<label><span>{{ $t('schedule.homePin') }}</span><input v-model.trim="manualMatchDialog.form.homePin" maxlength="255"></label>
|
||||
<label><span>{{ $t('schedule.guestPin') }}</span><input v-model.trim="manualMatchDialog.form.guestPin" maxlength="255"></label>
|
||||
</div>
|
||||
</fieldset>
|
||||
<label class="manual-match-notes"><span>{{ $t('schedule.notes') }}</span><textarea v-model.trim="manualMatchDialog.form.notes" rows="3"></textarea></label>
|
||||
<div class="dialog-actions"><button type="button" class="btn-cancel" :disabled="manualMatchDialog.saving" @click="closeManualMatchDialog">{{ $t('schedule.cancel') }}</button><button type="submit" class="btn-save" :disabled="manualMatchDialog.saving">{{ manualMatchDialog.saving ? $t('schedule.saving') : $t('schedule.save') }}</button></div>
|
||||
</form>
|
||||
@@ -894,7 +902,7 @@ export default {
|
||||
showImportModal: false,
|
||||
manualMatchDialog: {
|
||||
isOpen: false, saving: false, error: '',
|
||||
form: { fixtureType: 'league', clubTeamId: '', opponentName: '', date: new Date().toISOString().slice(0, 10), time: '', homeAway: 'home', locationName: '', locationAddress: '', locationZip: '', locationCity: '', notes: '' }
|
||||
form: { fixtureType: 'league', clubTeamId: '', opponentName: '', date: new Date().toISOString().slice(0, 10), time: '', homeAway: 'home', locationName: '', locationAddress: '', locationZip: '', locationCity: '', code: '', homePin: '', guestPin: '', notes: '' }
|
||||
},
|
||||
selectedFile: null,
|
||||
teams: [],
|
||||
@@ -990,7 +998,7 @@ export default {
|
||||
return (Array.isArray(matches) ? matches : []).filter((match) => !match?.isFriendly);
|
||||
},
|
||||
resetManualMatchDialogForm() {
|
||||
this.manualMatchDialog.form = { fixtureType: 'league', clubTeamId: this.selectedTeam?.id ? String(this.selectedTeam.id) : '', opponentName: '', date: new Date().toISOString().slice(0, 10), time: '', homeAway: 'home', locationName: '', locationAddress: '', locationZip: '', locationCity: '', notes: '' };
|
||||
this.manualMatchDialog.form = { fixtureType: 'league', clubTeamId: this.selectedTeam?.id ? String(this.selectedTeam.id) : '', opponentName: '', date: new Date().toISOString().slice(0, 10), time: '', homeAway: 'home', locationName: '', locationAddress: '', locationZip: '', locationCity: '', code: '', homePin: '', guestPin: '', notes: '' };
|
||||
this.manualMatchDialog.error = '';
|
||||
},
|
||||
openManualMatchDialog() {
|
||||
@@ -3931,6 +3939,8 @@ li {
|
||||
.manual-match-home-away { display: flex; gap: 1rem; padding: .65rem .8rem; border: 1px solid var(--border-color); border-radius: 4px; }
|
||||
.manual-match-home-away legend { padding: 0 .3rem; font-size: .86rem; font-weight: 600; }
|
||||
.manual-match-home-away label { font-size: .9rem; }
|
||||
.manual-match-credentials { margin: 0; padding: .8rem; border: 1px solid var(--border-color); background: var(--surface-muted, #f5f7f6); }
|
||||
.manual-match-credentials legend { padding: 0 .3rem; color: var(--text-muted, #6c757d); font-size: .86rem; font-weight: 600; }
|
||||
.manual-match-error { margin: 0; padding: .65rem .8rem; color: var(--error-color, #b42318); background: #fff1f0; border-left: 3px solid currentColor; }
|
||||
.manual-match-badge { display: inline-block; margin-left: .35rem; padding: .1rem .35rem; border-radius: 3px; color: var(--primary-strong, #1f5f49); background: rgba(47, 122, 95, .12); font-size: .72rem; font-weight: 700; white-space: nowrap; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user