-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #81 from ChangePlusPlusVandy/event-application-api
Event application api
- Loading branch information
Showing
5 changed files
with
247 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import dbConnect from '@/lib/dbConnect'; | ||
import { ObjectId } from 'mongodb'; | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
import mongoose from 'mongoose'; | ||
import VolunteerApplications from 'bookem-shared/src/models/VolunteerApplications'; | ||
import { ApplicationResponseData } from 'bookem-shared/src/types/database'; | ||
import ApplicationResponse from 'bookem-shared/src/models/ApplicationResponse'; | ||
import VolunteerEvents from 'bookem-shared/src/models/VolunteerEvents'; | ||
import { authOptions } from '@/pages/api/auth/[...nextauth]'; | ||
import { getServerSession } from 'next-auth'; | ||
import { makeSessionForAPITest } from '@/utils/api-testing'; | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse | ||
) { | ||
// Get session user | ||
const session = | ||
(await getServerSession(req, res, authOptions)) || makeSessionForAPITest(); | ||
|
||
// Get request parameter | ||
const { | ||
query: { id }, | ||
method, | ||
} = req; | ||
|
||
switch (method) { | ||
/** | ||
* @route GET /api/applications | ||
* @desc Get all applications to all applied events for a user | ||
* @req event id, user in session | ||
* @res list of applied events | ||
*/ | ||
case 'GET': | ||
try { | ||
await dbConnect(); | ||
await VolunteerEvents.find({}); | ||
|
||
// query volunteerApplication by event id attributes | ||
const applicationResponses = await ApplicationResponse.find({ | ||
userId: session.user.id, | ||
}).populate('eventId'); | ||
|
||
// get all the events that the user has applied to | ||
const events = applicationResponses.map(response => { | ||
return response.eventId; | ||
}); | ||
|
||
return res.status(200).json({ message: events }); | ||
} catch (error: any) { | ||
console.error(error); | ||
res.status(500).json({ message: error.message }); | ||
} | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import dbConnect from '@/lib/dbConnect'; | ||
import { ObjectId } from 'mongodb'; | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
import mongoose from 'mongoose'; | ||
import VolunteerApplications from 'bookem-shared/src/models/VolunteerApplications'; | ||
import { ApplicationResponseData } from 'bookem-shared/src/types/database'; | ||
import ApplicationResponse from 'bookem-shared/src/models/ApplicationResponse'; | ||
import { authOptions } from '@/pages/api/auth/[...nextauth]'; | ||
import { getServerSession } from 'next-auth'; | ||
import { makeSessionForAPITest } from '@/utils/api-testing'; | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse | ||
) { | ||
// Get session user | ||
let session = | ||
(await getServerSession(req, res, authOptions)) || makeSessionForAPITest(); | ||
|
||
// Get request parameter | ||
const { | ||
query: { id }, | ||
method, | ||
} = req; | ||
|
||
switch (method) { | ||
/** | ||
* @route GET /api/event/[id]/apply | ||
* @desc Return a list of application questions that this event needs | ||
* @req event id, user in session | ||
* @res list of application questions | ||
*/ | ||
case 'GET': | ||
try { | ||
await dbConnect(); | ||
|
||
if (!id) return res.status(400).json({ message: 'Missing id' }); | ||
|
||
// check if id is a valid mongoose id | ||
if (!ObjectId.isValid(id as string)) | ||
return res.status(400).json({ message: 'Invalid id' }); | ||
|
||
// query volunteerApplication by event id attributes | ||
const volunteerApplication = await VolunteerApplications.findOne({ | ||
eventId: id, | ||
}); | ||
|
||
if (!volunteerApplication) { | ||
return res | ||
.status(404) | ||
.json({ message: 'No application for the event found' }); | ||
} | ||
|
||
const questions = volunteerApplication.questions; | ||
|
||
return res.status(200).json({ message: questions }); | ||
} catch (error) { | ||
console.error(error); | ||
res.status(500).json({ message: error }); | ||
} | ||
break; | ||
|
||
/** | ||
* @route POST /api/event/[id]/apply | ||
* @desc Submit the answers to the questions this event needs | ||
* @req event id, user in session | ||
* @res Success message | ||
*/ | ||
case 'POST': | ||
try { | ||
await dbConnect(); | ||
|
||
const response = req.body as ApplicationResponseData; | ||
const { answers } = response; | ||
|
||
// Declare the following ops to be an atomic transaction | ||
const mongoSession = await mongoose.startSession(); | ||
await mongoSession.withTransaction(async () => { | ||
// insert the response to applicationResponses data | ||
const newResponse = new ApplicationResponse({ | ||
userId: session.user.id, | ||
status: 'pending', | ||
eventId: id, | ||
answers, | ||
}); | ||
|
||
await newResponse.save(); | ||
|
||
// use the id of the saved response to update the volunteerApplications data | ||
await VolunteerApplications.updateOne( | ||
{ eventId: id }, | ||
{ | ||
$push: { | ||
responses: newResponse._id, | ||
}, | ||
} | ||
); | ||
}); | ||
|
||
return res.status(200).json('Application Submitted'); | ||
} catch (error: any) { | ||
res.status(500).json({ message: error.message }); | ||
console.error(error); | ||
} | ||
|
||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import dbConnect from '@/lib/dbConnect'; | ||
import { ObjectId } from 'mongodb'; | ||
import type { NextApiRequest, NextApiResponse } from 'next'; | ||
import ApplicationResponse from 'bookem-shared/src/models/ApplicationResponse'; | ||
import { getServerSession } from 'next-auth'; | ||
import { authOptions } from '@/pages/api/auth/[...nextauth]'; | ||
import { makeSessionForAPITest } from '@/utils/api-testing'; | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse | ||
) { | ||
// Get session user | ||
let session = | ||
(await getServerSession(req, res, authOptions)) || makeSessionForAPITest(); | ||
|
||
// Get request parameter | ||
const { | ||
query: { id }, | ||
method, | ||
} = req; | ||
|
||
switch (method) { | ||
/** | ||
* @route GET /api/event/[id]/submitted-application | ||
* @desc Get submitted application | ||
* @req event id, user in session | ||
* @res list of application questions | ||
*/ | ||
case 'GET': | ||
try { | ||
await dbConnect(); | ||
|
||
if (!id) return res.status(400).json({ message: 'Missing id' }); | ||
|
||
// check if id is a valid mongoose id | ||
if (!ObjectId.isValid(id as string)) | ||
return res.status(400).json({ message: 'Invalid id' }); | ||
|
||
// query volunteerApplication by event id attributes | ||
// using findOne - assuming there is only one application per event per user | ||
const volunteerApplication = await ApplicationResponse.findOne({ | ||
userId: session.user.id, | ||
eventId: id, | ||
}); | ||
|
||
// TODO - refactor a common util for when something is not found | ||
if (!volunteerApplication) { | ||
return res | ||
.status(404) | ||
.json({ message: 'No application for the event found' }); | ||
} | ||
|
||
return res.status(200).json({ message: volunteerApplication }); | ||
} catch (error: any) { | ||
console.error(error); | ||
res.status(500).json({ message: error }); | ||
} | ||
break; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// common utils for simple API testing in development phase | ||
|
||
// change this var to true when you are testing the API endpoints without logging in | ||
export const testingAPI = false; | ||
|
||
const fakeUserSession = { | ||
user: { | ||
id: '65ae7bbd24dc37492f2581c0', | ||
}, | ||
}; | ||
|
||
// returns a fake user session when testing the API | ||
export const makeSessionForAPITest = () => { | ||
return testingAPI ? fakeUserSession : null; | ||
}; |