From 673a3afbb55bd0ab63c2fcb98855bcb7cac36208 Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Wed, 4 Feb 2026 11:12:37 +0100 Subject: [PATCH] feat(tournament): enhance external participant management with email and address fields - Added email and address fields to the external participant model, allowing for more comprehensive participant information. - Updated the tournament service and controller to handle the new fields when adding external participants. - Modified frontend components to include input fields for email and address, improving user experience and data collection. - Updated localization strings to support the new fields, ensuring clarity in the user interface. --- backend/controllers/tournamentController.js | 4 +- ..._email_address_to_external_participant.sql | 6 ++ .../models/ExternalTournamentParticipant.js | 34 ++++++++++ backend/services/tournamentService.js | 4 +- .../tournament/PlayerDetailsDialog.vue | 4 +- .../tournament/TournamentParticipantsTab.vue | 62 +++++++++++++++++++ frontend/src/i18n/locales/de.json | 2 + frontend/src/views/TournamentTab.vue | 9 ++- 8 files changed, 119 insertions(+), 6 deletions(-) create mode 100644 backend/migrations/20260130_add_email_address_to_external_participant.sql diff --git a/backend/controllers/tournamentController.js b/backend/controllers/tournamentController.js index a517233..e59a444 100644 --- a/backend/controllers/tournamentController.js +++ b/backend/controllers/tournamentController.js @@ -545,9 +545,9 @@ export const setMatchActive = async (req, res) => { // Externe Teilnehmer hinzufügen export const addExternalParticipant = async (req, res) => { const { authcode: token } = req.headers; - const { clubId, tournamentId, classId, firstName, lastName, club, birthDate, gender } = req.body; + const { clubId, tournamentId, classId, firstName, lastName, club, birthDate, gender, email, address } = req.body; try { - await tournamentService.addExternalParticipant(token, clubId, classId, firstName, lastName, club, birthDate, gender); + await tournamentService.addExternalParticipant(token, clubId, classId, firstName, lastName, club, birthDate, gender, email, address); emitTournamentChanged(clubId, tournamentId); res.status(200).json({ message: 'Externer Teilnehmer hinzugefügt' }); } catch (error) { diff --git a/backend/migrations/20260130_add_email_address_to_external_participant.sql b/backend/migrations/20260130_add_email_address_to_external_participant.sql new file mode 100644 index 0000000..1a52e76 --- /dev/null +++ b/backend/migrations/20260130_add_email_address_to_external_participant.sql @@ -0,0 +1,6 @@ +-- E-Mail und Adresse für externe Teilnehmer (für Weitermeldung) +-- Die Felder werden verschlüsselt gespeichert (siehe Model) + +ALTER TABLE `external_tournament_participant` + ADD COLUMN `email` VARCHAR(500) NULL AFTER `club`, + ADD COLUMN `address` TEXT NULL AFTER `email`; diff --git a/backend/models/ExternalTournamentParticipant.js b/backend/models/ExternalTournamentParticipant.js index f9d66c2..6ebb3b5 100644 --- a/backend/models/ExternalTournamentParticipant.js +++ b/backend/models/ExternalTournamentParticipant.js @@ -53,6 +53,40 @@ const ExternalTournamentParticipant = sequelize.define('ExternalTournamentPartic return decryptData(encryptedValue); } }, + email: { + type: DataTypes.STRING(500), + allowNull: true, + set(value) { + if (!value) { + this.setDataValue('email', null); + return; + } + const encryptedValue = encryptData(value); + this.setDataValue('email', encryptedValue); + }, + get() { + const encryptedValue = this.getDataValue('email'); + if (!encryptedValue) return null; + return decryptData(encryptedValue); + } + }, + address: { + type: DataTypes.TEXT, + allowNull: true, + set(value) { + if (!value) { + this.setDataValue('address', null); + return; + } + const encryptedValue = encryptData(value); + this.setDataValue('address', encryptedValue); + }, + get() { + const encryptedValue = this.getDataValue('address'); + if (!encryptedValue) return null; + return decryptData(encryptedValue); + } + }, birthDate: { type: DataTypes.STRING, allowNull: true, diff --git a/backend/services/tournamentService.js b/backend/services/tournamentService.js index 2822efd..8d27977 100644 --- a/backend/services/tournamentService.js +++ b/backend/services/tournamentService.js @@ -3369,7 +3369,7 @@ Ve // 2. Neues Turnier anlegen } // Externe Teilnehmer hinzufügen - async addExternalParticipant(userToken, clubId, classId, firstName, lastName, club, birthDate, gender) { + async addExternalParticipant(userToken, clubId, classId, firstName, lastName, club, birthDate, gender, email = null, address = null) { await checkAccess(userToken, clubId); if (!classId) { throw new Error('Klasse ist erforderlich'); @@ -3432,6 +3432,8 @@ Ve // 2. Neues Turnier anlegen firstName, lastName, club: club || null, + email: email || null, + address: address || null, birthDate: birthDate || null, gender: participantGender, groupId: null diff --git a/frontend/src/components/tournament/PlayerDetailsDialog.vue b/frontend/src/components/tournament/PlayerDetailsDialog.vue index 8aeea0c..bb06cf2 100644 --- a/frontend/src/components/tournament/PlayerDetailsDialog.vue +++ b/frontend/src/components/tournament/PlayerDetailsDialog.vue @@ -172,9 +172,9 @@ export default { this.playerData = { name: `${externalParticipant.firstName || ''} ${externalParticipant.lastName || ''}`.trim(), birthDate: externalParticipant.birthDate || null, - address: null, // Externe Teilnehmer haben keine Adresse + address: externalParticipant.address || null, gender: externalParticipant.gender || null, - email: null, // Externe Teilnehmer haben keine E-Mail + email: externalParticipant.email || null, phone: null // Externe Teilnehmer haben keine Telefonnummer }; } else { diff --git a/frontend/src/components/tournament/TournamentParticipantsTab.vue b/frontend/src/components/tournament/TournamentParticipantsTab.vue index 55a92c3..eddbe13 100644 --- a/frontend/src/components/tournament/TournamentParticipantsTab.vue +++ b/frontend/src/components/tournament/TournamentParticipantsTab.vue @@ -77,6 +77,22 @@ {{ $t('tournaments.add') }} +
+ + +
@@ -97,6 +113,8 @@ {{ $t('tournaments.name') }} {{ $t('members.gender') }} {{ $t('tournaments.club') }} + {{ $t('tournaments.email') }} + {{ $t('tournaments.address') }} {{ $t('tournaments.group') }} {{ $t('tournaments.action') }} @@ -146,6 +164,14 @@ {{ participant.club || '–' }} + + + + + + + +