From 012c609d89fb6baa59eba1807b3678ca9e18904f Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Fri, 1 Nov 2024 02:19:42 -0400 Subject: [PATCH 1/9] post meeting --- src/controllers/meetingController.js | 72 +++++++++++++++++++++++ src/models/meeting.js | 14 +++++ src/routes/meetingRouter.js | 14 +++++ src/startup/routes.js | 3 + src/utilities/createInitialPermissions.js | 6 ++ 5 files changed, 109 insertions(+) create mode 100644 src/controllers/meetingController.js create mode 100644 src/models/meeting.js create mode 100644 src/routes/meetingRouter.js diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js new file mode 100644 index 000000000..311240696 --- /dev/null +++ b/src/controllers/meetingController.js @@ -0,0 +1,72 @@ +const moment = require('moment-timezone'); +const mongoose = require('mongoose'); +const logger = require('../startup/logger'); + +const UserProfile = require('../models/userProfile'); + +const meetingController = function (Meeting) { + + const postMeeting = async function (req, res){ + // res.status(400).send({error:''}); + + const isInvalid = + (!req.body.dateOfMeeting || !moment(req.body.dateOfMeeting).isValid()) || + !req.body.startHour || + !req.body.startMinute || + (!req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod)) || + !req.body.duration || + (!req.body.participantList || req.body.participantList.length < 2) || + (req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location)); + + if (isInvalid){ + return res.status(400).send({error:'Bad request'}); + } + + try { + await Promise.all(req.body.participantList.map(async (userProfileId) => { + if (!mongoose.Types.ObjectId.isValid(userProfileId)) { + throw new Error('Invalid participant ID'); + } + const userProfileExists = await UserProfile.exists({ _id: userProfileId }); + if (!userProfileExists) { + throw new Error('Participant ID does not exist'); + } + })); + + // Continue with other operations if all IDs are valid + } catch (error) { + return res.status(400).send({ error: `Bad request: ${error.message}` }); + } + + const session = await mongoose.startSession(); + session.startTransaction(); + try{ + const meeting = new Meeting(); + meeting.dateOfMeeting = moment(req.body.dateOfMeeting).format('YYYY-MM-DD'); + meeting.startHour = req.body.startHour; + meeting.startMinute = req.body.startMinute; + meeting.startTimePeriod = req.body.startTimePeriod; + meeting.duration = req.body.duration; + meeting.participantList = req.body.participantList; + meeting.location = req.body.location; + meeting.notes = req.body.notes; + + await meeting.save({ session }); + await session.commitTransaction(); + session.endSession(); + res.status(201).json({ message: 'Meeting saved successfully' }); + } catch (err) { + await session.abortTransaction(); + logger.logException(err); + return res.status(500).send({ error: err.toString() }); + } finally { + session.endSession(); + } + }; + + return { + postMeeting + }; +}; + +module.exports = meetingController; \ No newline at end of file diff --git a/src/models/meeting.js b/src/models/meeting.js new file mode 100644 index 000000000..0a5f827b0 --- /dev/null +++ b/src/models/meeting.js @@ -0,0 +1,14 @@ +const mongoose = require('mongoose'); + +const meetingSchema = new mongoose.Schema({ + dateOfMeeting: { type: Date, required: true }, + startHour: { type: Number, required: true }, + startMinute: { type: Number, required: true }, + startTimePeriod: { type: String, required: true }, + duration: { type: Number, required: true }, + participantList: [{ type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }], + location: { type: String}, + notes: { type: String }, +}); + +module.exports = mongoose.model('Meeting', meetingSchema); \ No newline at end of file diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js new file mode 100644 index 000000000..22e753888 --- /dev/null +++ b/src/routes/meetingRouter.js @@ -0,0 +1,14 @@ +const express = require('express'); + +const routes = function (Meeting) { + const MeetingRouter = express.Router(); + + const controller = require('../controllers/meetingController')(Meeting); + + MeetingRouter.route('/meeting/new').post(controller.postMeeting); + + + return MeetingRouter; +} + +module.exports = routes; \ No newline at end of file diff --git a/src/startup/routes.js b/src/startup/routes.js index 82a4155a8..77f03811c 100644 --- a/src/startup/routes.js +++ b/src/startup/routes.js @@ -46,6 +46,7 @@ const { } = require('../models/bmdashboard/buildingInventoryItem'); const timeOffRequest = require('../models/timeOffRequest'); const followUp = require('../models/followUp'); +const meeting = require('../models/meeting'); const userProfileRouter = require('../routes/userProfileRouter')(userProfile, project); const warningRouter = require('../routes/warningRouter')(userProfile); @@ -96,6 +97,7 @@ const timeOffRequestRouter = require('../routes/timeOffRequestRouter')( userProfile, ); const followUpRouter = require('../routes/followUpRouter')(followUp); +const meetingRouter = require('../routes/meetingRouter')(meeting); // bm dashboard const bmLoginRouter = require('../routes/bmdashboard/bmLoginRouter')(); @@ -162,6 +164,7 @@ module.exports = function (app) { app.use('/api', timeOffRequestRouter); app.use('/api', followUpRouter); app.use('/api', blueSquareEmailAssignmentRouter); + app.use('/api', meetingRouter); // bm dashboard app.use('/api/bm', bmLoginRouter); app.use('/api/bm', bmMaterialsRouter); diff --git a/src/utilities/createInitialPermissions.js b/src/utilities/createInitialPermissions.js index 3a214bbec..177193661 100644 --- a/src/utilities/createInitialPermissions.js +++ b/src/utilities/createInitialPermissions.js @@ -90,6 +90,8 @@ const permissionsRoles = [ 'seeUsersInDashboard', 'editTeamCode', + // Meeting + 'scheduleMeetings', ], }, { @@ -120,6 +122,7 @@ const permissionsRoles = [ 'getTimeZoneAPIKey', 'checkLeadTeamOfXplus', 'seeUsersInDashboard', + 'scheduleMeetings', ], }, { @@ -146,6 +149,7 @@ const permissionsRoles = [ 'postInvType', 'getTimeZoneAPIKey', 'checkLeadTeamOfXplus', + 'scheduleMeetings', ], }, { @@ -169,6 +173,7 @@ const permissionsRoles = [ 'postInvType', 'getTimeZoneAPIKey', 'checkLeadTeamOfXplus', + 'scheduleMeetings', ], }, { @@ -247,6 +252,7 @@ const permissionsRoles = [ 'checkLeadTeamOfXplus', 'editTeamCode', 'totalValidWeeklySummaries', + 'scheduleMeetings', // Title 'seeQSC', From 1cd81d3bbd0d33fd43928297584c9bbfbf7884ce Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Fri, 1 Nov 2024 21:22:08 -0400 Subject: [PATCH 2/9] fix bug --- src/controllers/meetingController.js | 59 +++++++++++++++++----------- src/routes/meetingRouter.js | 7 ++-- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index 311240696..c34aa3fe7 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -5,34 +5,44 @@ const logger = require('../startup/logger'); const UserProfile = require('../models/userProfile'); const meetingController = function (Meeting) { + const postMeeting = async function (req, res) { + // console.log((!req.body.dateOfMeeting || !moment(req.body.dateOfMeeting).isValid())); + // console.log(req.body.startHour == null); + // console.log(req.body.startMinute == null); + // console.log((!req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod))); + // console.log(!req.body.duration); + // console.log((!req.body.participantList || req.body.participantList.length < 2)); + // console.log((req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location))); - const postMeeting = async function (req, res){ - // res.status(400).send({error:''}); - - const isInvalid = - (!req.body.dateOfMeeting || !moment(req.body.dateOfMeeting).isValid()) || - !req.body.startHour || - !req.body.startMinute || - (!req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod)) || + const isInvalid = + !req.body.dateOfMeeting || + !moment(req.body.dateOfMeeting).isValid() || + req.body.startHour == null || + req.body.startMinute == null || + !req.body.startTimePeriod || + !['AM', 'PM'].includes(req.body.startTimePeriod) || !req.body.duration || - (!req.body.participantList || req.body.participantList.length < 2) || + !req.body.participantList || + req.body.participantList.length < 2 || (req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location)); - if (isInvalid){ - return res.status(400).send({error:'Bad request'}); + if (isInvalid) { + return res.status(400).send({ error: 'Bad request: Invalid form values' }); } try { - await Promise.all(req.body.participantList.map(async (userProfileId) => { - if (!mongoose.Types.ObjectId.isValid(userProfileId)) { - throw new Error('Invalid participant ID'); - } - const userProfileExists = await UserProfile.exists({ _id: userProfileId }); - if (!userProfileExists) { - throw new Error('Participant ID does not exist'); - } - })); - + await Promise.all( + req.body.participantList.map(async (userProfileId) => { + if (!mongoose.Types.ObjectId.isValid(userProfileId)) { + throw new Error('Invalid participant ID'); + } + const userProfileExists = await UserProfile.exists({ _id: userProfileId }); + if (!userProfileExists) { + throw new Error('Participant ID does not exist'); + } + }), + ); + // Continue with other operations if all IDs are valid } catch (error) { return res.status(400).send({ error: `Bad request: ${error.message}` }); @@ -40,9 +50,10 @@ const meetingController = function (Meeting) { const session = await mongoose.startSession(); session.startTransaction(); - try{ + try { const meeting = new Meeting(); meeting.dateOfMeeting = moment(req.body.dateOfMeeting).format('YYYY-MM-DD'); + console.log(meeting.dateOfMeeting); meeting.startHour = req.body.startHour; meeting.startMinute = req.body.startMinute; meeting.startTimePeriod = req.body.startTimePeriod; @@ -65,8 +76,8 @@ const meetingController = function (Meeting) { }; return { - postMeeting + postMeeting, }; }; -module.exports = meetingController; \ No newline at end of file +module.exports = meetingController; diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js index 22e753888..ea23a3a21 100644 --- a/src/routes/meetingRouter.js +++ b/src/routes/meetingRouter.js @@ -5,10 +5,9 @@ const routes = function (Meeting) { const controller = require('../controllers/meetingController')(Meeting); - MeetingRouter.route('/meeting/new').post(controller.postMeeting); - + MeetingRouter.route('/meetings/new').post(controller.postMeeting); return MeetingRouter; -} +}; -module.exports = routes; \ No newline at end of file +module.exports = routes; From 354e843091a4d68f97f381aa32f0f814c1ddca64 Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sun, 3 Nov 2024 01:35:48 -0500 Subject: [PATCH 3/9] implement controllers for meetings --- src/controllers/meetingController.js | 63 ++++++++++++++++++++++++---- src/models/meeting.js | 6 +-- src/routes/meetingRouter.js | 1 + 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index c34aa3fe7..55021f791 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -11,7 +11,7 @@ const meetingController = function (Meeting) { // console.log(req.body.startMinute == null); // console.log((!req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod))); // console.log(!req.body.duration); - // console.log((!req.body.participantList || req.body.participantList.length < 2)); + // console.log(!req.body.participantList || req.body.participantList.length === 0); // console.log((req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location))); const isInvalid = @@ -22,8 +22,9 @@ const meetingController = function (Meeting) { !req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod) || !req.body.duration || + !req.body.organizer || !req.body.participantList || - req.body.participantList.length < 2 || + req.body.participantList.length === 0 || (req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location)); if (isInvalid) { @@ -42,8 +43,13 @@ const meetingController = function (Meeting) { } }), ); - - // Continue with other operations if all IDs are valid + if (!mongoose.Types.ObjectId.isValid(req.body.organizer)) { + throw new Error('Invalid organizer ID'); + } + const organizerExists = await UserProfile.exists({ _id: req.body.organizer }); + if (!organizerExists) { + throw new Error('Organizer ID does not exist'); + } } catch (error) { return res.status(400).send({ error: `Bad request: ${error.message}` }); } @@ -51,13 +57,13 @@ const meetingController = function (Meeting) { const session = await mongoose.startSession(); session.startTransaction(); try { + const dateTimeString = `${req.body.dateOfMeeting} ${req.body.startHour}:${req.body.startMinute} ${req.body.startTimePeriod}`; + const dateTimeISO = moment(dateTimeString, 'YYYY-MM-DD hh:mm A').toISOString(); + const meeting = new Meeting(); - meeting.dateOfMeeting = moment(req.body.dateOfMeeting).format('YYYY-MM-DD'); - console.log(meeting.dateOfMeeting); - meeting.startHour = req.body.startHour; - meeting.startMinute = req.body.startMinute; - meeting.startTimePeriod = req.body.startTimePeriod; + meeting.dateTime = dateTimeISO; meeting.duration = req.body.duration; + meeting.organizer = req.body.organizer; meeting.participantList = req.body.participantList; meeting.location = req.body.location; meeting.notes = req.body.notes; @@ -75,8 +81,47 @@ const meetingController = function (Meeting) { } }; + const getMeetings = async function (req, res){ + try { + const {startTime, endTime } = req.query; + const decodedStartTime = decodeURIComponent(startTime); + const decodedEndTime = decodeURIComponent(endTime); + console.log('decodedStartTime', decodedStartTime); + console.log('decodedEndTime', decodedEndTime); + + const meetings = await Meeting.aggregate([ + { + $match: { + dateTime: { + $gte: new Date(decodedStartTime), + $lte: new Date(decodedEndTime), + }, + }, + }, + { $unwind: "$participantList" }, + { + $project: { + _id: 1, + dateTime: 1, + duration: 1, + location: 1, + notes: 1, + organizer: 1, + recipient: "$participantList", + }, + }, + ]); + console.log('meetings', meetings); + res.status(200).json(meetings); + } catch (error) { + console.error('Error fetching meetings:', error); + res.status(500).json({ error: 'Failed to fetch meetings' }); + } + } + return { postMeeting, + getMeetings, }; }; diff --git a/src/models/meeting.js b/src/models/meeting.js index 0a5f827b0..4bfb1decb 100644 --- a/src/models/meeting.js +++ b/src/models/meeting.js @@ -1,11 +1,9 @@ const mongoose = require('mongoose'); const meetingSchema = new mongoose.Schema({ - dateOfMeeting: { type: Date, required: true }, - startHour: { type: Number, required: true }, - startMinute: { type: Number, required: true }, - startTimePeriod: { type: String, required: true }, + dateTime: { type: Date, required: true }, duration: { type: Number, required: true }, + organizer: { type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }, participantList: [{ type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }], location: { type: String}, notes: { type: String }, diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js index ea23a3a21..36da452ac 100644 --- a/src/routes/meetingRouter.js +++ b/src/routes/meetingRouter.js @@ -6,6 +6,7 @@ const routes = function (Meeting) { const controller = require('../controllers/meetingController')(Meeting); MeetingRouter.route('/meetings/new').post(controller.postMeeting); + MeetingRouter.route('/meetings').get(controller.getMeetings); return MeetingRouter; }; From a125f4dd9d514c61f9c94d33b5cf1123016c735f Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sun, 10 Nov 2024 03:23:49 -0500 Subject: [PATCH 4/9] update: mark as read --- src/controllers/meetingController.js | 28 ++++++++++++++++++++++------ src/models/meeting.js | 5 +++-- src/routes/meetingRouter.js | 1 + 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index 55021f791..8990391b3 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -81,9 +81,9 @@ const meetingController = function (Meeting) { } }; - const getMeetings = async function (req, res){ + const getMeetings = async function (req, res) { try { - const {startTime, endTime } = req.query; + const { startTime, endTime } = req.query; const decodedStartTime = decodeURIComponent(startTime); const decodedEndTime = decodeURIComponent(endTime); console.log('decodedStartTime', decodedStartTime); @@ -92,13 +92,13 @@ const meetingController = function (Meeting) { const meetings = await Meeting.aggregate([ { $match: { - dateTime: { + dateTime: { $gte: new Date(decodedStartTime), $lte: new Date(decodedEndTime), }, }, }, - { $unwind: "$participantList" }, + { $unwind: '$participantList' }, { $project: { _id: 1, @@ -107,7 +107,7 @@ const meetingController = function (Meeting) { location: 1, notes: 1, organizer: 1, - recipient: "$participantList", + recipient: '$participantList', }, }, ]); @@ -117,11 +117,27 @@ const meetingController = function (Meeting) { console.error('Error fetching meetings:', error); res.status(500).json({ error: 'Failed to fetch meetings' }); } - } + }; + + const markMeetingAsRead = async function (req, res) { + try { + const { meetingId } = req.params; + const result = await Meeting.updateOne({ _id: meetingId }, { $set: { isRead: true } }); + console.log(result); + if (result.nModified === 0) { + return res.status(404).json({ error: 'Meeting not found or already marked as read' }); + } + res.status(200).json({ message: 'Meeting marked as read successfully' }); + } catch (error) { + console.error('Error marking meeting as read:', error); + res.status(500).json({ error: 'Failed to mark meeting as read' }); + } + }; return { postMeeting, getMeetings, + markMeetingAsRead, }; }; diff --git a/src/models/meeting.js b/src/models/meeting.js index 4bfb1decb..0343013eb 100644 --- a/src/models/meeting.js +++ b/src/models/meeting.js @@ -5,8 +5,9 @@ const meetingSchema = new mongoose.Schema({ duration: { type: Number, required: true }, organizer: { type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }, participantList: [{ type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }], - location: { type: String}, + location: { type: String }, notes: { type: String }, + isRead: { type: Boolean, default: false }, }); -module.exports = mongoose.model('Meeting', meetingSchema); \ No newline at end of file +module.exports = mongoose.model('Meeting', meetingSchema); diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js index 36da452ac..5eff9adc9 100644 --- a/src/routes/meetingRouter.js +++ b/src/routes/meetingRouter.js @@ -7,6 +7,7 @@ const routes = function (Meeting) { MeetingRouter.route('/meetings/new').post(controller.postMeeting); MeetingRouter.route('/meetings').get(controller.getMeetings); + MeetingRouter.route('/meetings/markRead/:meetingId').post(controller.markMeetingAsRead); return MeetingRouter; }; From be9ce5173323bba05c9195398f85a5f4d5fbf663 Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sat, 16 Nov 2024 18:34:03 -0500 Subject: [PATCH 5/9] fix: modify schema --- src/controllers/meetingController.js | 18 +++++++++++++----- src/models/meeting.js | 8 ++++++-- src/routes/meetingRouter.js | 4 +++- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index 8990391b3..13484f41a 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -64,7 +64,10 @@ const meetingController = function (Meeting) { meeting.dateTime = dateTimeISO; meeting.duration = req.body.duration; meeting.organizer = req.body.organizer; - meeting.participantList = req.body.participantList; + meeting.participantList = req.body.participantList.map((participant) => ({ + participant, + notificationIsRead: false, + })); meeting.location = req.body.location; meeting.notes = req.body.notes; @@ -104,10 +107,11 @@ const meetingController = function (Meeting) { _id: 1, dateTime: 1, duration: 1, + organizer: 1, location: 1, notes: 1, - organizer: 1, - recipient: '$participantList', + recipient: '$participantList.participant', + isRead: '$participantList.notificationIsRead', }, }, ]); @@ -121,8 +125,12 @@ const meetingController = function (Meeting) { const markMeetingAsRead = async function (req, res) { try { - const { meetingId } = req.params; - const result = await Meeting.updateOne({ _id: meetingId }, { $set: { isRead: true } }); + const { meetingId, recipient } = req.params; + console.log('req.params', meetingId, recipient); + const result = await Meeting.updateOne( + { _id: meetingId, 'participantList.participant': recipient }, + { $set: { 'participantList.$.notificationIsRead': true } }, + ); console.log(result); if (result.nModified === 0) { return res.status(404).json({ error: 'Meeting not found or already marked as read' }); diff --git a/src/models/meeting.js b/src/models/meeting.js index 0343013eb..a55ff5911 100644 --- a/src/models/meeting.js +++ b/src/models/meeting.js @@ -4,10 +4,14 @@ const meetingSchema = new mongoose.Schema({ dateTime: { type: Date, required: true }, duration: { type: Number, required: true }, organizer: { type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }, - participantList: [{ type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }], + participantList: [ + { + participant: { type: mongoose.Schema.Types.ObjectId, ref: 'userProfile', required: true }, + notificationIsRead: { type: Boolean, default: false }, + }, + ], location: { type: String }, notes: { type: String }, - isRead: { type: Boolean, default: false }, }); module.exports = mongoose.model('Meeting', meetingSchema); diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js index 5eff9adc9..84fef15b2 100644 --- a/src/routes/meetingRouter.js +++ b/src/routes/meetingRouter.js @@ -7,7 +7,9 @@ const routes = function (Meeting) { MeetingRouter.route('/meetings/new').post(controller.postMeeting); MeetingRouter.route('/meetings').get(controller.getMeetings); - MeetingRouter.route('/meetings/markRead/:meetingId').post(controller.markMeetingAsRead); + MeetingRouter.route('/meetings/markRead/:meetingId/:recipient').post( + controller.markMeetingAsRead, + ); return MeetingRouter; }; From 5c185329db79dfdef1d2b25b0881ea7db2115490 Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sun, 17 Nov 2024 01:14:34 -0500 Subject: [PATCH 6/9] fix: update --- src/controllers/meetingController.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index 13484f41a..d949b980e 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -6,14 +6,6 @@ const UserProfile = require('../models/userProfile'); const meetingController = function (Meeting) { const postMeeting = async function (req, res) { - // console.log((!req.body.dateOfMeeting || !moment(req.body.dateOfMeeting).isValid())); - // console.log(req.body.startHour == null); - // console.log(req.body.startMinute == null); - // console.log((!req.body.startTimePeriod || !['AM', 'PM'].includes(req.body.startTimePeriod))); - // console.log(!req.body.duration); - // console.log(!req.body.participantList || req.body.participantList.length === 0); - // console.log((req.body.location && !['Zoom', 'Phone call', 'On-site'].includes(req.body.location))); - const isInvalid = !req.body.dateOfMeeting || !moment(req.body.dateOfMeeting).isValid() || From 06cce67854f52143bf457a52bbf123daa9ff888e Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sun, 17 Nov 2024 03:19:43 -0500 Subject: [PATCH 7/9] fix: permission updates --- src/utilities/createInitialPermissions.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/utilities/createInitialPermissions.js b/src/utilities/createInitialPermissions.js index 177193661..825772a54 100644 --- a/src/utilities/createInitialPermissions.js +++ b/src/utilities/createInitialPermissions.js @@ -122,7 +122,6 @@ const permissionsRoles = [ 'getTimeZoneAPIKey', 'checkLeadTeamOfXplus', 'seeUsersInDashboard', - 'scheduleMeetings', ], }, { @@ -173,7 +172,6 @@ const permissionsRoles = [ 'postInvType', 'getTimeZoneAPIKey', 'checkLeadTeamOfXplus', - 'scheduleMeetings', ], }, { From 49552365c0e5b3edd3d1fc97e72c6422a0258d01 Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Thu, 21 Nov 2024 02:46:42 -0500 Subject: [PATCH 8/9] add new api --- src/controllers/meetingController.js | 40 ++++++++++++++++++++++++++++ src/routes/meetingRouter.js | 1 + 2 files changed, 41 insertions(+) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index d949b980e..a74b4574b 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -134,10 +134,50 @@ const meetingController = function (Meeting) { } }; + const getAllMeetingsByOrganizer = async function (req, res) { + try { + const { organizerId } = req.query; + if (!mongoose.Types.ObjectId.isValid(organizerId)) { + return res.status(400).json({ error: 'Invalid organizer userId' }); + } + const userProfileExists = await UserProfile.exists({ _id: organizerId }); + if (!userProfileExists) { + throw new Error('Organizer ID does not exist'); + } + + const currentTime = new Date(); + const meetings = await Meeting.aggregate([ + { + $match: { + dateTime: { $gt: currentTime }, + organizer: mongoose.Types.ObjectId(organizerId), + }, + }, + { + $project: { + _id: 1, + dateTime: 1, + duration: 1, + organizer: 1, + location: 1, + notes: 1, + participantList: 1, + }, + }, + ]); + + res.status(200).json(meetings); + } catch (error) { + console.error('Error fetching all upcoming meetings:', error); + res.status(500).json({ error: 'Failed to fetch all upcoming meetings' }); + } + }; + return { postMeeting, getMeetings, markMeetingAsRead, + getAllMeetingsByOrganizer, }; }; diff --git a/src/routes/meetingRouter.js b/src/routes/meetingRouter.js index 84fef15b2..048ebf5e7 100644 --- a/src/routes/meetingRouter.js +++ b/src/routes/meetingRouter.js @@ -10,6 +10,7 @@ const routes = function (Meeting) { MeetingRouter.route('/meetings/markRead/:meetingId/:recipient').post( controller.markMeetingAsRead, ); + MeetingRouter.route('/meetings/upcoming/:organizerId').get(controller.getAllMeetingsByOrganizer); return MeetingRouter; }; From 4b06f068390f5829cb79d475d8704774dd051d9a Mon Sep 17 00:00:00 2001 From: huijieliu8 <91745551+metaphor987@users.noreply.github.com> Date: Sat, 30 Nov 2024 21:42:45 -0800 Subject: [PATCH 9/9] clean up --- src/controllers/meetingController.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/controllers/meetingController.js b/src/controllers/meetingController.js index a74b4574b..20af2ed7c 100644 --- a/src/controllers/meetingController.js +++ b/src/controllers/meetingController.js @@ -81,8 +81,6 @@ const meetingController = function (Meeting) { const { startTime, endTime } = req.query; const decodedStartTime = decodeURIComponent(startTime); const decodedEndTime = decodeURIComponent(endTime); - console.log('decodedStartTime', decodedStartTime); - console.log('decodedEndTime', decodedEndTime); const meetings = await Meeting.aggregate([ { @@ -107,7 +105,6 @@ const meetingController = function (Meeting) { }, }, ]); - console.log('meetings', meetings); res.status(200).json(meetings); } catch (error) { console.error('Error fetching meetings:', error); @@ -118,12 +115,10 @@ const meetingController = function (Meeting) { const markMeetingAsRead = async function (req, res) { try { const { meetingId, recipient } = req.params; - console.log('req.params', meetingId, recipient); const result = await Meeting.updateOne( { _id: meetingId, 'participantList.participant': recipient }, { $set: { 'participantList.$.notificationIsRead': true } }, ); - console.log(result); if (result.nModified === 0) { return res.status(404).json({ error: 'Meeting not found or already marked as read' }); }