Implement external participant management and tournament class features
This commit enhances the tournament management system by introducing functionality for handling external participants and tournament classes. New methods are added to the `tournamentController` and `tournamentService` for adding, retrieving, updating, and removing external participants, as well as managing tournament classes. The backend models are updated to support these features, including new relationships and attributes. The frontend is also updated to allow users to manage external participants and classes, improving the overall user experience and interactivity in tournament management.
This commit is contained in:
89
backend/models/ExternalTournamentParticipant.js
Normal file
89
backend/models/ExternalTournamentParticipant.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import { encryptData, decryptData } from '../utils/encrypt.js';
|
||||
|
||||
const ExternalTournamentParticipant = sequelize.define('ExternalTournamentParticipant', {
|
||||
tournamentId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
groupId: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: false,
|
||||
allowNull: true
|
||||
},
|
||||
firstName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
set(value) {
|
||||
const encryptedValue = encryptData(value);
|
||||
this.setDataValue('firstName', encryptedValue);
|
||||
},
|
||||
get() {
|
||||
const encryptedValue = this.getDataValue('firstName');
|
||||
return decryptData(encryptedValue);
|
||||
}
|
||||
},
|
||||
lastName: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
set(value) {
|
||||
const encryptedValue = encryptData(value);
|
||||
this.setDataValue('lastName', encryptedValue);
|
||||
},
|
||||
get() {
|
||||
const encryptedValue = this.getDataValue('lastName');
|
||||
return decryptData(encryptedValue);
|
||||
}
|
||||
},
|
||||
club: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
set(value) {
|
||||
if (!value) {
|
||||
this.setDataValue('club', null);
|
||||
return;
|
||||
}
|
||||
const encryptedValue = encryptData(value);
|
||||
this.setDataValue('club', encryptedValue);
|
||||
},
|
||||
get() {
|
||||
const encryptedValue = this.getDataValue('club');
|
||||
if (!encryptedValue) return null;
|
||||
return decryptData(encryptedValue);
|
||||
}
|
||||
},
|
||||
birthDate: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
set(value) {
|
||||
if (!value) {
|
||||
this.setDataValue('birthDate', null);
|
||||
return;
|
||||
}
|
||||
const encryptedValue = encryptData(value || '');
|
||||
this.setDataValue('birthDate', encryptedValue);
|
||||
},
|
||||
get() {
|
||||
const encryptedValue = this.getDataValue('birthDate');
|
||||
if (!encryptedValue) return null;
|
||||
return decryptData(encryptedValue);
|
||||
}
|
||||
},
|
||||
seeded: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
},
|
||||
classId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true
|
||||
}
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'external_tournament_participant',
|
||||
timestamps: true,
|
||||
});
|
||||
|
||||
export default ExternalTournamentParticipant;
|
||||
|
||||
@@ -34,6 +34,11 @@ const Tournament = sequelize.define('Tournament', {
|
||||
allowNull: false,
|
||||
defaultValue: 3,
|
||||
},
|
||||
allowsExternal: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false,
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'tournament',
|
||||
|
||||
38
backend/models/TournamentClass.js
Normal file
38
backend/models/TournamentClass.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { DataTypes } from 'sequelize';
|
||||
import sequelize from '../database.js';
|
||||
import Tournament from './Tournament.js';
|
||||
|
||||
const TournamentClass = sequelize.define('TournamentClass', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
allowNull: false
|
||||
},
|
||||
tournamentId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
references: {
|
||||
model: Tournament,
|
||||
key: 'id'
|
||||
},
|
||||
onDelete: 'CASCADE',
|
||||
onUpdate: 'CASCADE'
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
sortOrder: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
defaultValue: 0
|
||||
}
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'tournament_class',
|
||||
timestamps: true
|
||||
});
|
||||
|
||||
export default TournamentClass;
|
||||
|
||||
@@ -12,6 +12,10 @@ const TournamentGroup = sequelize.define('TournamentGroup', {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false
|
||||
},
|
||||
classId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true
|
||||
},
|
||||
}, {
|
||||
underscored: true,
|
||||
tableName: 'tournament_group',
|
||||
|
||||
@@ -25,6 +25,10 @@ const TournamentMatch = sequelize.define('TournamentMatch', {
|
||||
onDelete: 'SET NULL',
|
||||
onUpdate: 'CASCADE'
|
||||
},
|
||||
classId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
groupRound: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
|
||||
@@ -21,6 +21,10 @@ const TournamentMember = sequelize.define('TournamentMember', {
|
||||
type: DataTypes.BOOLEAN,
|
||||
allowNull: false,
|
||||
defaultValue: false
|
||||
},
|
||||
classId: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true
|
||||
}
|
||||
}, {
|
||||
underscored: true,
|
||||
|
||||
@@ -27,9 +27,11 @@ import Group from './Group.js';
|
||||
import GroupActivity from './GroupActivity.js';
|
||||
import Tournament from './Tournament.js';
|
||||
import TournamentGroup from './TournamentGroup.js';
|
||||
import TournamentClass from './TournamentClass.js';
|
||||
import TournamentMember from './TournamentMember.js';
|
||||
import TournamentMatch from './TournamentMatch.js';
|
||||
import TournamentResult from './TournamentResult.js';
|
||||
import ExternalTournamentParticipant from './ExternalTournamentParticipant.js';
|
||||
import Accident from './Accident.js';
|
||||
import UserToken from './UserToken.js';
|
||||
import OfficialTournament from './OfficialTournament.js';
|
||||
@@ -201,6 +203,15 @@ Member.hasMany(TournamentMember, { foreignKey: 'clubMemberId', as: 'tournamentGr
|
||||
|
||||
TournamentMember.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
|
||||
Tournament.hasMany(TournamentMember, { foreignKey: 'tournamentId', as: 'tournamentMembers' });
|
||||
TournamentMember.belongsTo(TournamentClass, {
|
||||
foreignKey: 'classId',
|
||||
as: 'class',
|
||||
constraints: false
|
||||
});
|
||||
TournamentClass.hasMany(TournamentMember, {
|
||||
foreignKey: 'classId',
|
||||
as: 'members'
|
||||
});
|
||||
|
||||
TournamentMatch.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
|
||||
Tournament.hasMany(TournamentMatch, { foreignKey: 'tournamentId', as: 'tournamentMatches' });
|
||||
@@ -227,6 +238,33 @@ TournamentMatch.belongsTo(TournamentMember, { foreignKey: 'player2Id', as: 'play
|
||||
TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player1Id', as: 'player1Matches' });
|
||||
TournamentMember.hasMany(TournamentMatch, { foreignKey: 'player2Id', as: 'player2Matches' });
|
||||
|
||||
// Tournament Classes
|
||||
TournamentClass.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
|
||||
Tournament.hasMany(TournamentClass, { foreignKey: 'tournamentId', as: 'classes' });
|
||||
|
||||
// External Tournament Participants
|
||||
ExternalTournamentParticipant.belongsTo(Tournament, { foreignKey: 'tournamentId', as: 'tournament' });
|
||||
Tournament.hasMany(ExternalTournamentParticipant, { foreignKey: 'tournamentId', as: 'externalParticipants' });
|
||||
ExternalTournamentParticipant.belongsTo(TournamentGroup, {
|
||||
foreignKey: 'groupId',
|
||||
targetKey: 'id',
|
||||
as: 'group',
|
||||
constraints: false
|
||||
});
|
||||
TournamentGroup.hasMany(ExternalTournamentParticipant, {
|
||||
foreignKey: 'groupId',
|
||||
as: 'externalGroupMembers'
|
||||
});
|
||||
ExternalTournamentParticipant.belongsTo(TournamentClass, {
|
||||
foreignKey: 'classId',
|
||||
as: 'class',
|
||||
constraints: false
|
||||
});
|
||||
TournamentClass.hasMany(ExternalTournamentParticipant, {
|
||||
foreignKey: 'classId',
|
||||
as: 'externalParticipants'
|
||||
});
|
||||
|
||||
Accident.belongsTo(Member, { foreignKey: 'memberId', as: 'members' });
|
||||
Member.hasMany(Accident, { foreignKey: 'memberId', as: 'accidents' });
|
||||
|
||||
@@ -283,9 +321,11 @@ export {
|
||||
GroupActivity,
|
||||
Tournament,
|
||||
TournamentGroup,
|
||||
TournamentClass,
|
||||
TournamentMember,
|
||||
TournamentMatch,
|
||||
TournamentResult,
|
||||
ExternalTournamentParticipant,
|
||||
Accident,
|
||||
UserToken,
|
||||
OfficialTournament,
|
||||
|
||||
Reference in New Issue
Block a user