From c4fa85015eba54029a4413bd47cdb3ebe1723b4c Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Wed, 31 Jan 2024 19:53:26 -0800 Subject: [PATCH 01/19] First iteration of teammate adding route --- backend/index.ts | 3 +- backend/routes/team_info.ts | 110 +++++++++++++++++++++++++++++++++++- 2 files changed, 111 insertions(+), 2 deletions(-) diff --git a/backend/index.ts b/backend/index.ts index 5b51c9eb..8d18ba56 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -29,7 +29,7 @@ import { import { getMeetInfo, setMeetInfo } from "./routes/meet_info"; import { getUsedMeals, setUsedMeals } from "./routes/used_meals"; import { getCheckIn, setCheckIn } from "./routes/check_in"; -import { getTeamInfo, setTeamInfo } from "./routes/team_info"; +import { addTeammate, getTeamInfo, setTeamInfo } from "./routes/team_info"; import { getSubmitInfo, setSubmitInfo } from "./routes/submit_info"; import { getUserDetail } from "./routes/user_detail"; import { getUserList, getUserStats, getMeetList } from "./routes/user_list"; @@ -185,6 +185,7 @@ authenticatedRoute.get("/users/:userId/forms/submit_info", getSubmitInfo); authenticatedRoute.put("/users/:userId/forms/submit_info", setSubmitInfo); authenticatedRoute.get("/users/:userId/forms/team_info", getTeamInfo); authenticatedRoute.put("/users/:userId/forms/team_info", setTeamInfo); +authenticatedRoute.put("/users/:userId/forms/add_teammate", addTeammate); // What permission should this one be? authenticatedRoute.get("/users/:userId/status", getApplicationStatus); diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 0c1913da..d5b20c7f 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -1,6 +1,9 @@ import { Request, Response } from 'express'; import { getApplicationAttribute, setApplicationAttribute } from "./common"; import { IApplication } from '../models/Application.d'; +import Application from 'backend/models/Application'; +import { HACKATHON_YEAR } from 'backend/constants'; +import { mergeWith, pickBy } from "lodash"; export function getTeamInfo(req: Request, res: Response) { return getApplicationAttribute(req, res, (e: IApplication) => { @@ -15,4 +18,109 @@ export function setTeamInfo(req: Request, res: Response) { }, e => e.forms.team_info ); -} \ No newline at end of file +} + +// parse existing teammate list, or create one with only user if doesn't exist +function parseList(list: string | null, email: string): Record { + try { + return JSON.parse(list); + } catch (_) { + return { [email]: 1 }; + } +} + +// filter out pending teammates from team list +function filterPending(list: Record) { + return pickBy(list, value => value !== 0); +} + +// combine team lists, preferring a confirmed teammate (a number 1) over a pending teammate (a number 0) +function combineLists(one: Record, two: Record): Record { + return mergeWith(one, two, (oneValue, twoValue) => oneValue || twoValue); +} + +function applicationByEmail(email: string): PromiseLike { + return Application.findOne( + { "user.email": email, year: HACKATHON_YEAR }, + { __v: 0, reviews: 0 } + ); +} + +// add each teammate from `two` to the teamList of each user in `one` +async function combineTeams(one: Record, two: Record) { + for (const email of Object.keys(one)) { + const teammate = await applicationByEmail(email); + + if (!teammate) { + throw new Error("Teammate not found"); + } + + const teammateList = parseList(teammate.forms.team_info.teamList.toString(), email); + const newTeam = combineLists(teammateList, two); + + teammate.forms.team_info.teamList = JSON.stringify(newTeam); + await teammate.save(); + } +} + +export async function addTeammate(req: Request, res: Response) { + // find request user's application + const user: IApplication | null = await Application.findOne( + { "user.id": req.params.userId }, + { __v: 0, reviews: 0 } + ); + + if (!user) { + res.status(404).send("User application not found."); + return; + } + + // find requested teammate user's application + const teammate = await applicationByEmail(req.body.email); + + if (!teammate) { + res.status(404).send("Teammate application not found."); + return; + } + + // filter out user's pending teammates + const userList = parseList(user.forms.team_info.teamList.toString(), user.user.email); + const userConfirmed = filterPending(userList); + + // filter out teammate's pending teammates + const teammateList = parseList(teammate.forms.team_info.teamList.toString(), teammate.user.email); + const teammateConfirmed = filterPending(teammateList); + + // requested teammate hasn't added user + if (!Object.hasOwn(teammateList, user.user.email)) { + userList[teammate.user.email] = 0; + user.forms.team_info.teamList = JSON.stringify(userList); + + await user.save(); + return; + } + + // check combined teams at most four people + const combinedConfirmed = combineLists(userConfirmed, teammateConfirmed); + if (Object.keys(combinedConfirmed).length > 4) { + res.status(400).send("Too many combined teammates"); + } + + // for each of user's current teammate, combine with requested teammate + try { + await combineTeams(userConfirmed, teammateConfirmed); + } catch (e) { + res.status(404).send(e); + return; + } + + // for each of requeste teammates's current teammate, combine with user + try { + await combineTeams(teammateConfirmed, userConfirmed); + } catch (e) { + res.status(404).send(e); + return; + } + + res.status(200).send(); +} From 67ed958f68975dbe0eaed363844e61e374eb6051 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Wed, 31 Jan 2024 20:02:06 -0800 Subject: [PATCH 02/19] Fix object `hasOwn` missing method --- backend/routes/team_info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index d5b20c7f..ffaa54a5 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -92,7 +92,7 @@ export async function addTeammate(req: Request, res: Response) { const teammateConfirmed = filterPending(teammateList); // requested teammate hasn't added user - if (!Object.hasOwn(teammateList, user.user.email)) { + if (!teammateList.hasOwnProperty(user.user.email)) { userList[teammate.user.email] = 0; user.forms.team_info.teamList = JSON.stringify(userList); From 6dd1ec477e8071a0723744d9002edc582b7200a6 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Wed, 31 Jan 2024 20:19:12 -0800 Subject: [PATCH 03/19] Fix absolute imports --- backend/routes/team_info.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index ffaa54a5..74ef2dc0 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -1,8 +1,8 @@ import { Request, Response } from 'express'; import { getApplicationAttribute, setApplicationAttribute } from "./common"; import { IApplication } from '../models/Application.d'; -import Application from 'backend/models/Application'; -import { HACKATHON_YEAR } from 'backend/constants'; +import Application from '../models/Application'; +import { HACKATHON_YEAR } from '../constants'; import { mergeWith, pickBy } from "lodash"; export function getTeamInfo(req: Request, res: Response) { From 91f2ba353a42f297eb2cdc8b4deb1b9893acae54 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Wed, 31 Jan 2024 20:42:21 -0800 Subject: [PATCH 04/19] Send response after adding teammate --- backend/routes/team_info.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 74ef2dc0..e1652a6d 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -97,6 +97,7 @@ export async function addTeammate(req: Request, res: Response) { user.forms.team_info.teamList = JSON.stringify(userList); await user.save(); + res.status(200).send(); return; } From 03012e6959f68b0750c20a4701d4c0c733344dfd Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Wed, 31 Jan 2024 20:51:35 -0800 Subject: [PATCH 05/19] Send `team_info` on successful request --- backend/routes/team_info.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index e1652a6d..8cdf99c3 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -97,7 +97,7 @@ export async function addTeammate(req: Request, res: Response) { user.forms.team_info.teamList = JSON.stringify(userList); await user.save(); - res.status(200).send(); + res.status(200).send(user.forms.team_info); return; } @@ -123,5 +123,5 @@ export async function addTeammate(req: Request, res: Response) { return; } - res.status(200).send(); + res.status(200).send(user.forms.team_info); } From 10bbd1284d4ed1e2b08723435fdc5417289b350f Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Thu, 1 Feb 2024 15:26:12 -0800 Subject: [PATCH 06/19] Add teammate removal method --- backend/index.ts | 3 +- backend/routes/team_info.ts | 84 +++++++++++++++++++++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/backend/index.ts b/backend/index.ts index 8d18ba56..4310dc72 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -29,7 +29,7 @@ import { import { getMeetInfo, setMeetInfo } from "./routes/meet_info"; import { getUsedMeals, setUsedMeals } from "./routes/used_meals"; import { getCheckIn, setCheckIn } from "./routes/check_in"; -import { addTeammate, getTeamInfo, setTeamInfo } from "./routes/team_info"; +import { addTeammate, getTeamInfo, removeTeammate, setTeamInfo } from "./routes/team_info"; import { getSubmitInfo, setSubmitInfo } from "./routes/submit_info"; import { getUserDetail } from "./routes/user_detail"; import { getUserList, getUserStats, getMeetList } from "./routes/user_list"; @@ -186,6 +186,7 @@ authenticatedRoute.put("/users/:userId/forms/submit_info", setSubmitInfo); authenticatedRoute.get("/users/:userId/forms/team_info", getTeamInfo); authenticatedRoute.put("/users/:userId/forms/team_info", setTeamInfo); authenticatedRoute.put("/users/:userId/forms/add_teammate", addTeammate); +authenticatedRoute.put("/users/:userId/forms/remove_teammate", removeTeammate); // What permission should this one be? authenticatedRoute.get("/users/:userId/status", getApplicationStatus); diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 8cdf99c3..eb454e8b 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -3,7 +3,7 @@ import { getApplicationAttribute, setApplicationAttribute } from "./common"; import { IApplication } from '../models/Application.d'; import Application from '../models/Application'; import { HACKATHON_YEAR } from '../constants'; -import { mergeWith, pickBy } from "lodash"; +import { mergeWith, pickBy, without } from "lodash"; export function getTeamInfo(req: Request, res: Response) { return getApplicationAttribute(req, res, (e: IApplication) => { @@ -52,7 +52,7 @@ async function combineTeams(one: Record, two: Record 4) { - res.status(400).send("Too many combined teammates"); + res.status(400).send("Too many combined teammates."); } // for each of user's current teammate, combine with requested teammate @@ -125,3 +125,81 @@ export async function addTeammate(req: Request, res: Response) { res.status(200).send(user.forms.team_info); } + +// remove an email `removed` from each confirmed teammate in `team` +async function removeTeammateFromAll(team: Record, removed: string) { + for (const email of without(Object.keys(team), removed)) { + const teammate = await applicationByEmail(email); + + if (!teammate) { + throw new Error("Teammate not found."); + } + + const teammateList = parseList(teammate.forms.team_info.teamList.toString(), email); + delete teammateList[removed]; + + teammate.forms.team_info.teamList = JSON.stringify(teammateList); + await teammate.save(); + } +} + +export async function removeTeammate(req: Request, res: Response) { + // find request user's application + const user: IApplication | null = await Application.findOne( + { "user.id": req.params.userId }, + { __v: 0, reviews: 0 } + ); + + if (!user) { + res.status(404).send("User application not found."); + return; + } + + // find removed teammate user's application + const teammate = await applicationByEmail(req.body.email); + + if (!teammate) { + res.status(404).send("Teammate application not found."); + return; + } + + // filter out user's pending teammates + const userList = parseList(user.forms.team_info.teamList.toString(), user.user.email); + const userConfirmed = filterPending(userList); + + // ensure email exists in team + if (!userList.hasOwnProperty(teammate.user.email)) { + res.status(400).send("Removed teammate is not in user's team list."); + return; + } + + // if pending, only remove from user's team list + if (!userConfirmed.hasOwnProperty(teammate.user.email)) { + delete userList[teammate.user.email]; + user.forms.team_info.teamList = JSON.stringify(userList); + await user.save() + + res.status(200).send(user.forms.team_info); + return; + } + + // delete all emails except self in deleted user's team list + const teammateList = parseList(teammate.forms.team_info.teamList.toString(), teammate.user.email); + for (const email of without(Object.keys(teammateList), teammate.user.email)) { + delete teammateList[email]; + } + + teammate.forms.team_info.teamList = JSON.stringify(teammateList); + await teammate.save(); + + // for each user in the team except the deleted user, + // remove the deleted user's email + try { + await removeTeammateFromAll(userConfirmed, teammate.user.email); + } catch (e) { + res.status(404).send(e); + return; + } + + res.status(200).send(user.forms.team_info); +} From ca23fe2e486db773abd356a5f68d461b3a008f97 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Thu, 1 Feb 2024 16:48:34 -0800 Subject: [PATCH 07/19] Prevent clearing a removed teammates team list --- backend/routes/team_info.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index eb454e8b..596d9bb7 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -183,10 +183,12 @@ export async function removeTeammate(req: Request, res: Response) { return; } - // delete all emails except self in deleted user's team list + // delete all emails except self and pending teammates in deleted user's team list const teammateList = parseList(teammate.forms.team_info.teamList.toString(), teammate.user.email); for (const email of without(Object.keys(teammateList), teammate.user.email)) { - delete teammateList[email]; + if (teammateList[email] === 1) { + delete teammateList[email]; + } } teammate.forms.team_info.teamList = JSON.stringify(teammateList); From 36e7bef0fb15fbd964d193b028646ab893f1d334 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Thu, 1 Feb 2024 20:17:24 -0800 Subject: [PATCH 08/19] Send JSON from teammate add/remove routes --- backend/routes/team_info.ts | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 596d9bb7..a4bd1fc2 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -71,7 +71,7 @@ export async function addTeammate(req: Request, res: Response) { ); if (!user) { - res.status(404).send("User application not found."); + res.status(404).json({message: "User application not found."}); return; } @@ -79,7 +79,7 @@ export async function addTeammate(req: Request, res: Response) { const teammate = await applicationByEmail(req.body.email); if (!teammate) { - res.status(404).send("Teammate application not found."); + res.status(404).json({message: "Teammate application not found."}); return; } @@ -97,33 +97,33 @@ export async function addTeammate(req: Request, res: Response) { user.forms.team_info.teamList = JSON.stringify(userList); await user.save(); - res.status(200).send(user.forms.team_info); + res.status(200).json(user.forms.team_info); return; } // check combined teams at most four people const combinedConfirmed = combineLists(userConfirmed, teammateConfirmed); if (Object.keys(combinedConfirmed).length > 4) { - res.status(400).send("Too many combined teammates."); + res.status(400).json({message: "Too many combined teammates."}); } // for each of user's current teammate, combine with requested teammate try { await combineTeams(userConfirmed, teammateConfirmed); - } catch (e) { - res.status(404).send(e); + } catch (e: any) { + res.status(404).json({message: e.message}); return; } // for each of requeste teammates's current teammate, combine with user try { await combineTeams(teammateConfirmed, userConfirmed); - } catch (e) { - res.status(404).send(e); + } catch (e: any) { + res.status(404).json({message: e.message}); return; } - res.status(200).send(user.forms.team_info); + res.status(200).json(user.forms.team_info); } // remove an email `removed` from each confirmed teammate in `team` @@ -151,7 +151,7 @@ export async function removeTeammate(req: Request, res: Response) { ); if (!user) { - res.status(404).send("User application not found."); + res.status(404).json({message: "User application not found."}); return; } @@ -159,7 +159,7 @@ export async function removeTeammate(req: Request, res: Response) { const teammate = await applicationByEmail(req.body.email); if (!teammate) { - res.status(404).send("Teammate application not found."); + res.status(404).json({message: "Teammate application not found."}); return; } @@ -169,7 +169,7 @@ export async function removeTeammate(req: Request, res: Response) { // ensure email exists in team if (!userList.hasOwnProperty(teammate.user.email)) { - res.status(400).send("Removed teammate is not in user's team list."); + res.status(400).json({message: "Removed teammate is not in user's team list."}); return; } @@ -179,7 +179,7 @@ export async function removeTeammate(req: Request, res: Response) { user.forms.team_info.teamList = JSON.stringify(userList); await user.save() - res.status(200).send(user.forms.team_info); + res.status(200).json(user.forms.team_info); return; } @@ -198,10 +198,10 @@ export async function removeTeammate(req: Request, res: Response) { // remove the deleted user's email try { await removeTeammateFromAll(userConfirmed, teammate.user.email); - } catch (e) { - res.status(404).send(e); + } catch (e: any) { + res.status(404).json({message: e.message}); return; } - res.status(200).send(user.forms.team_info); + res.status(200).json(user.forms.team_info); } From 3cd50b05e127e4f679e6150b7f9f349763483a30 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Thu, 1 Feb 2024 20:20:21 -0800 Subject: [PATCH 09/19] Check error type when catching team add/remove --- backend/routes/team_info.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index a4bd1fc2..2bd3157a 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -110,17 +110,21 @@ export async function addTeammate(req: Request, res: Response) { // for each of user's current teammate, combine with requested teammate try { await combineTeams(userConfirmed, teammateConfirmed); - } catch (e: any) { - res.status(404).json({message: e.message}); - return; + } catch (e) { + if (e instanceof Error) { + res.status(404).json({message: e.message}); + return; + } } // for each of requeste teammates's current teammate, combine with user try { await combineTeams(teammateConfirmed, userConfirmed); - } catch (e: any) { - res.status(404).json({message: e.message}); - return; + } catch (e) { + if (e instanceof Error) { + res.status(404).json({message: e.message}); + return; + } } res.status(200).json(user.forms.team_info); @@ -198,9 +202,11 @@ export async function removeTeammate(req: Request, res: Response) { // remove the deleted user's email try { await removeTeammateFromAll(userConfirmed, teammate.user.email); - } catch (e: any) { - res.status(404).json({message: e.message}); - return; + } catch (e) { + if (e instanceof Error) { + res.status(404).json({message: e.message}); + return; + } } res.status(200).json(user.forms.team_info); From cc085838af88795e7c837be4a046ab53bf7ed407 Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Fri, 9 Feb 2024 18:17:51 -0800 Subject: [PATCH 10/19] Add missing return when combined team too large --- backend/routes/team_info.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 2bd3157a..008a18b9 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -105,6 +105,7 @@ export async function addTeammate(req: Request, res: Response) { const combinedConfirmed = combineLists(userConfirmed, teammateConfirmed); if (Object.keys(combinedConfirmed).length > 4) { res.status(400).json({message: "Too many combined teammates."}); + return; } // for each of user's current teammate, combine with requested teammate From b1d3beefed1588ccaa546ebd8fdf5fafcba198de Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Fri, 9 Feb 2024 18:28:27 -0800 Subject: [PATCH 11/19] Limit number of pending teammates --- backend/routes/team_info.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/backend/routes/team_info.ts b/backend/routes/team_info.ts index 008a18b9..8e2a08ba 100644 --- a/backend/routes/team_info.ts +++ b/backend/routes/team_info.ts @@ -34,6 +34,11 @@ function filterPending(list: Record) { return pickBy(list, value => value !== 0); } +// filter out approved teammates from team list +function filterApproved(list: Record) { + return pickBy(list, value => value !== 1); +} + // combine team lists, preferring a confirmed teammate (a number 1) over a pending teammate (a number 0) function combineLists(one: Record, two: Record): Record { return mergeWith(one, two, (oneValue, twoValue) => oneValue || twoValue); @@ -93,6 +98,12 @@ export async function addTeammate(req: Request, res: Response) { // requested teammate hasn't added user if (!teammateList.hasOwnProperty(user.user.email)) { + // don't allow user to have more than 8 pending teammates + if (Object.keys(filterApproved(userList)).length > 8) { + res.status(400).json({message: "Too many pending teammates."}); + return; + } + userList[teammate.user.email] = 0; user.forms.team_info.teamList = JSON.stringify(userList); From 502a77152f6abd60996cddc247df9173c0dc675d Mon Sep 17 00:00:00 2001 From: Connor Fogarty Date: Fri, 9 Feb 2024 18:35:55 -0800 Subject: [PATCH 12/19] Add team list to `users_meet` route --- backend/routes/user_list.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/routes/user_list.ts b/backend/routes/user_list.ts index b419b900..ce0e6fff 100644 --- a/backend/routes/user_list.ts +++ b/backend/routes/user_list.ts @@ -23,6 +23,7 @@ export async function getMeetList(req: Request, res: Response) { "forms.meet_info": 1, "forms.application_info.first_name": 1, "forms.application_info.last_name": 1, + "forms.team_info.teamList": 1, } ); From f8096c2c88ed076cad7ea9678beb59706e0a93d3 Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Thu, 15 Feb 2024 15:49:42 -0800 Subject: [PATCH 13/19] change stanford due --- backend/routes/common.ts | 2 +- src/themes/timber_pine.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/routes/common.ts b/backend/routes/common.ts index 89540941..1fa61640 100644 --- a/backend/routes/common.ts +++ b/backend/routes/common.ts @@ -14,7 +14,7 @@ export function getDeadline(type) { case "is": return new Date("2023-12-13:45:00.000Z"); case "stanford": - return new Date("2024-02-15T07:59:00.000Z"); + return new Date("2024-02-18T07:59:00.000Z"); case "oos": default: return new Date("2023-12-13:45:00.000Z"); diff --git a/src/themes/timber_pine.ts b/src/themes/timber_pine.ts index 8212cb0f..0665ba5e 100644 --- a/src/themes/timber_pine.ts +++ b/src/themes/timber_pine.ts @@ -75,8 +75,8 @@ export default { { key: "stanford", label: "Stanford student", - date: "2024-02-15T07:59:00.000Z", - display_date: "February 15th, 2024", + date: "2024-02-18T07:59:00.000Z", + display_date: "February 18th, 2024", }, ], logo: require("./assets/logo.svg"), From 016c4b7aa1aa8c56fed4c11d179904dfceed1c3e Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Thu, 15 Feb 2024 21:35:27 -0800 Subject: [PATCH 14/19] adding workshops field --- backend/index.ts | 2 ++ backend/models/Application.d.ts | 5 +++++ backend/models/ApplicationAnyYear.ts | 2 ++ backend/models/workshopInfoSchema.ts | 8 ++++++++ backend/routes/workshop_info.ts | 18 ++++++++++++++++++ 5 files changed, 35 insertions(+) create mode 100644 backend/models/workshopInfoSchema.ts create mode 100644 backend/routes/workshop_info.ts diff --git a/backend/index.ts b/backend/index.ts index 4310dc72..e9a181fb 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -185,6 +185,8 @@ authenticatedRoute.get("/users/:userId/forms/submit_info", getSubmitInfo); authenticatedRoute.put("/users/:userId/forms/submit_info", setSubmitInfo); authenticatedRoute.get("/users/:userId/forms/team_info", getTeamInfo); authenticatedRoute.put("/users/:userId/forms/team_info", setTeamInfo); +authenticatedRoute.get("/users/:userId/forms/team_info", getWorkshopList); +authenticatedRoute.put("/users/:userId/forms/team_info", setWorkshopList); authenticatedRoute.put("/users/:userId/forms/add_teammate", addTeammate); authenticatedRoute.put("/users/:userId/forms/remove_teammate", removeTeammate); diff --git a/backend/models/Application.d.ts b/backend/models/Application.d.ts index b1e0acad..4b6c48bd 100644 --- a/backend/models/Application.d.ts +++ b/backend/models/Application.d.ts @@ -58,6 +58,10 @@ export interface ITeamInfo { teamList?: String; } +export interface IWorkshopInfo { + workshopList?: String; +} + export interface ICheckIn { checkInStatus?: Boolean; } @@ -101,6 +105,7 @@ export interface IApplication extends Document { used_meals: IUsedMeals; check_in: ICheckIn; team_info: ITeamInfo; + workshop_info: IWorkshopInfo; // we can conceivably add additional forms here. }; admin_info: { diff --git a/backend/models/ApplicationAnyYear.ts b/backend/models/ApplicationAnyYear.ts index 3d25c577..b29851d6 100644 --- a/backend/models/ApplicationAnyYear.ts +++ b/backend/models/ApplicationAnyYear.ts @@ -7,6 +7,7 @@ import meetInfoSchema from "./meetInfoSchema"; import usedMealsSchema from "./usedMealsSchema"; import checkInSchema from "./checkInSchema"; import teamInfoSchema from "./teamInfoSchema"; +import workshopInfoSchema from "./workshopInfoSchema"; import submitInfoSchema from "./submitInfoSchema"; import reviewSchema from "./reviewSchema"; import { STATUS, TRANSPORTATION_STATUS } from "../constants"; @@ -22,6 +23,7 @@ export const applicationSchema: Schema = new mongoose.Schema({ "used_meals": usedMealsSchema, "check_in": checkInSchema, "team_info": teamInfoSchema, + "workshop_info": workshopInfoSchema, "submit_info": submitInfoSchema }, "admin_info": adminInfoSchema, // Only editable by admin. diff --git a/backend/models/workshopInfoSchema.ts b/backend/models/workshopInfoSchema.ts new file mode 100644 index 00000000..5b404e54 --- /dev/null +++ b/backend/models/workshopInfoSchema.ts @@ -0,0 +1,8 @@ +import mongoose from "mongoose"; +import { Schema } from "mongoose"; + +const workshopInfoSchema: Schema = new mongoose.Schema({ + workshopList: String, +}, { _id: false }); + +export default workshopInfoSchema; \ No newline at end of file diff --git a/backend/routes/workshop_info.ts b/backend/routes/workshop_info.ts new file mode 100644 index 00000000..7f69a358 --- /dev/null +++ b/backend/routes/workshop_info.ts @@ -0,0 +1,18 @@ +import { Request, Response } from 'express'; +import { getApplicationAttribute, setApplicationAttribute } from "./common"; +import { IApplication } from '../models/Application.d'; + +export function getWorkshopList(req: Request, res: Response) { + return getApplicationAttribute(req, res, (e: IApplication) => { + return e.forms.workshop_info || {}; + }, true); +} + +export function setWorkshopList(req: Request, res: Response) { + return setApplicationAttribute(req, res, + (e: IApplication) => { + e.forms.workshop_info = req.body; + }, + e => e.forms.workshop_info + ); +} \ No newline at end of file From 797fc32899479f291ae3df875a765c24ba97fd05 Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Fri, 16 Feb 2024 00:52:10 -0800 Subject: [PATCH 15/19] fix workshops --- backend/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/index.ts b/backend/index.ts index e9a181fb..938742cd 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -28,6 +28,7 @@ import { } from "./routes/application_info"; import { getMeetInfo, setMeetInfo } from "./routes/meet_info"; import { getUsedMeals, setUsedMeals } from "./routes/used_meals"; +import { getUsedMeals, setUsedMeals } from "./routes/workshop_info"; import { getCheckIn, setCheckIn } from "./routes/check_in"; import { addTeammate, getTeamInfo, removeTeammate, setTeamInfo } from "./routes/team_info"; import { getSubmitInfo, setSubmitInfo } from "./routes/submit_info"; From b0cf7757b3ac55636be81f013736cffbf7f4d1ef Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Fri, 16 Feb 2024 00:57:16 -0800 Subject: [PATCH 16/19] workshop fix --- backend/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/index.ts b/backend/index.ts index 938742cd..adb1fc47 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -28,7 +28,7 @@ import { } from "./routes/application_info"; import { getMeetInfo, setMeetInfo } from "./routes/meet_info"; import { getUsedMeals, setUsedMeals } from "./routes/used_meals"; -import { getUsedMeals, setUsedMeals } from "./routes/workshop_info"; +import { getWorkshopList, setWorkshopList } from "./routes/workshop_info"; import { getCheckIn, setCheckIn } from "./routes/check_in"; import { addTeammate, getTeamInfo, removeTeammate, setTeamInfo } from "./routes/team_info"; import { getSubmitInfo, setSubmitInfo } from "./routes/submit_info"; From 234f8e90bf6534400aa4171695cc8ab4d9613a6c Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Fri, 16 Feb 2024 01:21:54 -0800 Subject: [PATCH 17/19] fix workshops --- backend/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/index.ts b/backend/index.ts index adb1fc47..388c0e42 100644 --- a/backend/index.ts +++ b/backend/index.ts @@ -186,8 +186,8 @@ authenticatedRoute.get("/users/:userId/forms/submit_info", getSubmitInfo); authenticatedRoute.put("/users/:userId/forms/submit_info", setSubmitInfo); authenticatedRoute.get("/users/:userId/forms/team_info", getTeamInfo); authenticatedRoute.put("/users/:userId/forms/team_info", setTeamInfo); -authenticatedRoute.get("/users/:userId/forms/team_info", getWorkshopList); -authenticatedRoute.put("/users/:userId/forms/team_info", setWorkshopList); +authenticatedRoute.get("/users/:userId/forms/workshop_info", getWorkshopList); +authenticatedRoute.put("/users/:userId/forms/workshop_info", setWorkshopList); authenticatedRoute.put("/users/:userId/forms/add_teammate", addTeammate); authenticatedRoute.put("/users/:userId/forms/remove_teammate", removeTeammate); From 549dffce290b7e284b556bd7e96bd637f0881cfb Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:41:17 -0800 Subject: [PATCH 18/19] change sue timber_pine.ts --- src/themes/timber_pine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/themes/timber_pine.ts b/src/themes/timber_pine.ts index 0665ba5e..005ea9b7 100644 --- a/src/themes/timber_pine.ts +++ b/src/themes/timber_pine.ts @@ -63,13 +63,13 @@ export default { { key: "oos", label: "out-of-state", - date: "2023-12-12T07:59:00.000Z", + date: "2024-02-20T07:59:00.000Z", display_date: "December 11th, 2023", }, { key: "is", label: "in-state", - date: "2023-12-12T07:59:00.000Z", + date: "2024-02-20T07:59:00.000Z", display_date: "December 11th, 2023", }, { From 99b103cec54e4e2c031b18caa384a72aa1f94650 Mon Sep 17 00:00:00 2001 From: Ananya Gupta <93958307+guananya@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:42:25 -0800 Subject: [PATCH 19/19] change due common.ts --- backend/routes/common.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/routes/common.ts b/backend/routes/common.ts index 1fa61640..09e70b85 100644 --- a/backend/routes/common.ts +++ b/backend/routes/common.ts @@ -12,12 +12,12 @@ import { prepopulateMeetInfo } from "./meet_info"; export function getDeadline(type) { switch (type) { case "is": - return new Date("2023-12-13:45:00.000Z"); + return new Date("2024-02-18:45:00.000Z"); case "stanford": return new Date("2024-02-18T07:59:00.000Z"); case "oos": default: - return new Date("2023-12-13:45:00.000Z"); + return new Date("2024-02-18:45:00.000Z"); } }