Skip to content
100 changes: 95 additions & 5 deletions src/controllers/EventParticipantsController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const EventParticipantsRepo = require('../repository/team/EventParticipantRepo');
const TeamRepo = require('../repository/team/TeamRepo')
const EventRepo = require('../repository/event/EventRepo')
const UserRepo = require('../repository/user/UserRepo')

Expand All @@ -10,15 +11,15 @@ class EventParticipantController{
const participants = await EventParticipantsRepo.findUnassignedParticipants(eventId);

const nonBannedParticipants = participants.filter(p =>
p.userDetails && p.userDetails.isBanned !== true && p.userDetails.isBanned !== 1
p.participants && p.participants.isBanned !== true && p.participants.isBanned !== 1
);

const formattedParticipants = nonBannedParticipants.map(p => ({
id: p.userId,
firstName: p.userDetails?.firstName,
lastName: p.userDetails?.lastName,
email: p.userDetails?.email,
checkIn: p.userDetails?.checkIn,
firstName: p.participants?.firstName,
lastName: p.participants?.lastName,
email: p.participants?.email,
checkIn: p.participants?.checkIn,
teamId: p.teamId
}));

Expand Down Expand Up @@ -96,6 +97,35 @@ class EventParticipantController{
return res.status(500).json({ message: 'Server error retrieving team status' });
}
}
async getTeamsByEvent(eventId) {
return await Team.findAll({
where: {
eventId: eventId
},
include: [
{
model: EventParticipant,
as: 'EventParticipants',
attributes: ['userId', 'teamId'],
include: [{
model: User,
as: 'participants',
attributes: ['id', 'firstName', 'lastName'],
required: true
}]
}
],
// Select the specific fields needed for the response mapping
attributes: [
'id',
'teamName',
'presentationLink',
'githubLink',
'projectName',
'projectDescription'
],
});
}
static async addParticipantToEvent(req, res){
const {userId, eventId} = req.body;

Expand Down Expand Up @@ -123,6 +153,66 @@ class EventParticipantController{
});
}
}
static async getTeamsByEvent(req, res) {
try {
// 1. Get eventId from query parameters
let { eventId } = req.query;

if (eventId === 'undefined' || eventId === '') {
const activeEvent = await EventRepo.findActiveEvent();

if (!activeEvent) {
return res.status(404).json({ error: "No eventId provided and no active event found." });
}
eventId = activeEvent.id;
}

if (!eventId) {
return res.status(500).json({ error: "Internal error: Failed to determine event ID." });
}

// 2. Call a new repository function to get teams filtered by event
const teams = await TeamRepo.getTeamsByEvent(eventId);

// 3. Map the data for the response
const teamData = teams.map(team => ({
id: team.id,
teamName: team.teamName,
presentationLink: team.presentationLink || null,
githubLink: team.githubLink || null,
projectName: team.projectName || null,
projectDescription: team.projectDescription || null,

// Map the team members list
participants: team.EventParticipants ?
team.EventParticipants.map(participant => {
const user = participant.participants;

// Safety check remains valid
if (!user) {
console.warn(`Participant record in team ${team.id} is missing User details.`);
return 'Unknown User';
}

return {
id: user.id,
firstName: user.firstName,
lastName: user.lastName
};
})
: []
}));

res.status(200).json({
message: `Successfully fetched teams for event ${eventId}`,
data: teamData
});

} catch (err) {
console.error('Error getting teams by event:', err);
res.status(500).json({ message: 'Error getting teams by event', error: err.message });
}
}
static async getUsersByEvent(req, res){
try {
// 1. Get eventId from query parameters
Expand Down
4 changes: 2 additions & 2 deletions src/controllers/TeamController.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ class TeamController {
const participants = await EventParticipantsRepo.findParticipantsByTeamId(teamId);

const formattedParticipants = participants.map(p => ({
id: p.userDetails.id,
name: `${p.userDetails.firstName} ${p.userDetails.lastName}`
id: p.participants.id,
name: `${p.participants.firstName} ${p.participants.lastName}`
}));

return {
Expand Down
4 changes: 2 additions & 2 deletions src/repository/config/Models.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ HackCategory.belongsTo(Event, {
onDelete: 'CASCADE',
});

Team.hasMany(EventParticipant, { foreignKey: 'teamId' });
Team.hasMany(EventParticipant, { foreignKey: 'teamId', as: 'EventParticipants' });
EventParticipant.belongsTo(Team, { foreignKey: 'teamId', as: 'EventParticipants' });

EventParticipant.belongsTo(User, { foreignKey: 'userId', as: 'userDetails' });
EventParticipant.belongsTo(User, { foreignKey: 'userId', as: 'participants', targetKey: 'id' });
User.hasMany(EventParticipant, { foreignKey: 'userId', as:'participant' });

/* HARDWARE/IMAGE ASSOCIATIONS */
Expand Down
6 changes: 3 additions & 3 deletions src/repository/team/EventParticipantRepo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class EventParticipantRepo {
where: { teamId: teamId },
include: [{
model: User,
as: 'userDetails',
as: 'participants',
attributes: ['id', 'firstName', 'lastName', 'isBanned'],
where: {
isBanned: { [Op.not]: true }
Expand All @@ -22,7 +22,7 @@ class EventParticipantRepo {

include: [{
model: User,
as: 'userDetails',
as: 'participants',
attributes: [],
where: {
isBanned: { [Op.not]: true }
Expand Down Expand Up @@ -69,7 +69,7 @@ class EventParticipantRepo {
},
include: [{
model: User,
as: 'userDetails',
as: 'participants',
attributes: ['id', 'firstName', 'lastName', 'email', 'checkIn', 'isBanned'] ,
where: {
checkIn: 1,
Expand Down
33 changes: 31 additions & 2 deletions src/repository/team/TeamRepo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { Team } = require('../config/Models');
const { EventParticipant, User, Team } = require('../config/Models');

const TeamRepo = {
// Method to create a new Team
Expand Down Expand Up @@ -32,7 +32,7 @@ const TeamRepo = {
return rowsUpdated;
},
async delete(teamId){
return Team.destroy({where: {id: teamId}});
return Team.destroy({where: {id: teamId}});
},
async findProjectDetailsById(teamId) {
try {
Expand Down Expand Up @@ -73,6 +73,35 @@ const TeamRepo = {
console.error('Repo error updating project details:', error);
throw error;
}
},
async getTeamsByEvent(eventId) {
return await Team.findAll({
where: {
eventId: eventId
},
include: [
{
model: EventParticipant,
as: 'EventParticipants',
attributes: ['userId', 'teamId'],
include: [{
model: User,
as: 'participants',
attributes: ['id', 'firstName', 'lastName'],
required: true
}]
}
],
// Select the specific fields needed for the response mapping
attributes: [
'id',
'teamName',
'presentationLink',
'githubLink',
'projectName',
'projectDescription'
],
});
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/routes/TeamRoutes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const TeamController = require('../controllers/TeamController');
const EventParticipantController = require('../controllers/EventParticipantsController');

router.post('/create', TeamController.createTeam);
router.get('/all', TeamController.getAllTeams);
router.get('/all', EventParticipantController.getTeamsByEvent);
router.get('/unassignedParticipants', EventParticipantController.getUnassignedParticipants);
router.put('/unassign', EventParticipantController.unassignParticipant);
router.put('/:id', TeamController.updateTeam);
Expand Down
10 changes: 5 additions & 5 deletions src/tests/team.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ const mockEventParticipantsData = [
{
userId: MOCK_USER_ID_1,
teamId: MOCK_TEAM_ID,
userDetails: mockParticipant1,
participants: mockParticipant1,
},
{
userId: MOCK_USER_ID_2,
teamId: MOCK_TEAM_ID,
userDetails: mockParticipant2,
participants: mockParticipant2,
},
];

Expand Down Expand Up @@ -417,9 +417,9 @@ describe('EventParticipantController', () => {
// --------------------------------------------------------------------------
describe('GET /teams/unassignedParticipants', () => {
const mockUnassigned = [
{ userId: 301, teamId: null, eventId: 1, userDetails: { id: 301, firstName: 'A', lastName: 'Unassigned', email: 'a@example.com', checkIn: true, isBanned: false } },
{ userId: 302, teamId: null, eventId: 1, userDetails: { id: 302, firstName: 'B', lastName: 'Unassigned', email: 'b@example.com', checkIn: false, isBanned: 0 } },
{ userId: 303, teamId: null, eventId: 1, userDetails: { id: 303, firstName: 'C', lastName: 'Banned', email: 'c@example.com', checkIn: true, isBanned: true } }, // Should be filtered out
{ userId: 301, teamId: null, eventId: 1, participants: { id: 301, firstName: 'A', lastName: 'Unassigned', email: 'a@example.com', checkIn: true, isBanned: false } },
{ userId: 302, teamId: null, eventId: 1, participants: { id: 302, firstName: 'B', lastName: 'Unassigned', email: 'b@example.com', checkIn: false, isBanned: 0 } },
{ userId: 303, teamId: null, eventId: 1, participants: { id: 303, firstName: 'C', lastName: 'Banned', email: 'c@example.com', checkIn: true, isBanned: true } }, // Should be filtered out
];
const expectedFormatted = [
{ id: 301, firstName: 'A', lastName: 'Unassigned', email: 'a@example.com', checkIn: true, teamId: null },
Expand Down