diff --git a/backend/services/matchService.js b/backend/services/matchService.js index 24640896..14bafd50 100755 --- a/backend/services/matchService.js +++ b/backend/services/matchService.js @@ -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) }; } diff --git a/frontend/src/i18n/locales/de.json b/frontend/src/i18n/locales/de.json index e6af68f8..454ade09 100755 --- a/frontend/src/i18n/locales/de.json +++ b/frontend/src/i18n/locales/de.json @@ -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.", diff --git a/frontend/src/i18n/locales/en-AU.json b/frontend/src/i18n/locales/en-AU.json index 038e28ea..9866d46e 100755 --- a/frontend/src/i18n/locales/en-AU.json +++ b/frontend/src/i18n/locales/en-AU.json @@ -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", diff --git a/frontend/src/i18n/locales/en-GB.json b/frontend/src/i18n/locales/en-GB.json index 77e8146e..1e121e16 100755 --- a/frontend/src/i18n/locales/en-GB.json +++ b/frontend/src/i18n/locales/en-GB.json @@ -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", diff --git a/frontend/src/i18n/locales/en-US.json b/frontend/src/i18n/locales/en-US.json index c5a38e23..4f7c87ca 100755 --- a/frontend/src/i18n/locales/en-US.json +++ b/frontend/src/i18n/locales/en-US.json @@ -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.", diff --git a/frontend/src/views/ScheduleView.vue b/frontend/src/views/ScheduleView.vue index 3b69e7e2..88bd9d0f 100755 --- a/frontend/src/views/ScheduleView.vue +++ b/frontend/src/views/ScheduleView.vue @@ -294,6 +294,14 @@
{{ $t('schedule.location') }}
+
+ {{ $t('schedule.matchCredentials') }} +
+ + + +
+
@@ -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; }