Skip to content

Commit

Permalink
feature/lisasiliu/edit-programs-form-backend-route (#68)
Browse files Browse the repository at this point in the history
* edit branch commit

* changed createForm to createProgram, updateForm to updateProgram, and removed _id field in update

* finished v2 edit changes

* fixed lint
  • Loading branch information
lisasiliu authored Apr 15, 2024
1 parent b6d90d7 commit bf35387
Show file tree
Hide file tree
Showing 7 changed files with 708 additions and 536 deletions.
644 changes: 322 additions & 322 deletions backend/package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"firebase-admin": "^12.0.0",
"firebase-functions": "^4.7.0",
"mongodb": "^6.3.0",
"mongoose": "^8.0.3",
"mongoose": "^8.3.1",
"tsc-alias": "^1.8.8"
},
"devDependencies": {
Expand Down
30 changes: 29 additions & 1 deletion backend/src/controllers/program.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { RequestHandler } from "express";
import { validationResult } from "express-validator";
//import { error } from "firebase-functions/logger";

import ProgramModel from "../models/program";
import validationErrorParser from "../util/validationErrorParser";

export type Program = {
_id: string;
name: string;
abbreviation: string;
type: string;
daysOfWeek: string[];
startDate: string;
endDate: string;
color: string; //colorValueHex;
studentUIDs: string[];
renewalDate: string;
hourlyPay: string;
sessions: [string[]];
};

export const createForm: RequestHandler = async (req, res, next) => {
export const createProgram: RequestHandler = async (req, res, next) => {
const errors = validationResult(req);

try {
Expand All @@ -29,6 +35,28 @@ export const createForm: RequestHandler = async (req, res, next) => {
}
};

export const updateProgram: RequestHandler = async (req, res, next) => {
const errors = validationResult(req);
try {
validationErrorParser(errors);

const programId = req.params.id;
const programData = req.body as Program;

const editedProgram = await ProgramModel.findOneAndUpdate({ _id: programId }, programData, {
new: true,
});

if (!editedProgram) {
return res.status(404).json({ message: "No object in database with provided ID" });
}

res.status(200).json(editedProgram);
} catch (error) {
next(error);
}
};

export const getAllPrograms: RequestHandler = async (req, res, next) => {
try {
const programs = await ProgramModel.find();
Expand Down
6 changes: 5 additions & 1 deletion backend/src/models/program-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ const programSchema = new Schema({
daysOfWeek: { type: [String], required: true }, // M, T, W, TH, F
startDate: { type: Date, required: true },
endDate: { type: Date, required: true },
color: { type: String, required: true }, // options: 1 (teal, #4FA197), 2 (yellow, #FFB800), 3 (pink, #FF7A5E), 4 (olive, #B6BF0E)
color: { type: String, required: true },
studentUIDs: { type: [String], required: true },
renewalDate: { type: Date, required: true },
hourlyPay: { type: Number, required: true },
sessions: { type: [[String]], required: true },
});

type ProgramForm = InferSchemaType<typeof programSchema>;
Expand Down
4 changes: 3 additions & 1 deletion backend/src/routes/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import * as ProgramValidator from "../validators/program";

const router = express.Router();

router.post("/create", ProgramValidator.createForm, ProgramController.createForm);
router.post("/", ProgramValidator.createProgram, ProgramController.createProgram);
router.patch("/:id", ProgramValidator.updateProgram, ProgramController.updateProgram);
router.post("/create", ProgramValidator.createProgram, ProgramController.createProgram);
router.get("/all", ProgramController.getAllPrograms);

export default router;
92 changes: 84 additions & 8 deletions backend/src/validators/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ const makeColorValidator = () =>
}
return true;
});
// check for first chara being # and others being 1-F

// verify student ids passed in, if any, are valid
const makeStudentsValidator = () =>
body("students")
.optional()
const makeStudentUIDsValidator = () =>
// mongoID
body("studentUIDs")
.exists()
.withMessage("student UIDs list needed")
.bail()
.isArray()
.bail()
.withMessage("students must be an array")
Expand All @@ -125,14 +125,90 @@ const makeStudentsValidator = () =>
})
.bail()
.withMessage("students must be valid student ids");
const makeRenewalDateValidator = () =>
body("renewalDate")
.exists()
.withMessage("renewal date needed")
.bail()
.isISO8601()
.withMessage("renewal date must be a valid date-time string");
const makeHourlyPayValidator = () =>
body("hourlyPay")
.exists()
.withMessage("hourly pay needed")
.bail()
.isNumeric()
.withMessage("hourly pay must be a valid number");
const makeSessionsValidator = () =>
body("sessions")
.exists()
.withMessage("sessions list needed")
.bail()
.isArray()
.withMessage("sessions list must be an array")
.custom((value: [string[]]) => {
for (const arr of value) {
// each time interval must be array
if (!Array.isArray(arr)) throw new Error("each session must be formatted as an array");
// array: [10:00, 13:00]
for (let j = 0; j <= 1; j++) {
if (arr[j].length !== 5) throw new Error("times should be 5 characters, in XX:XX format");
if (arr[j][2] !== ":") throw new Error("middle character should be :");
// first character is 0 or 1
if (arr[j].charCodeAt(0) === 48 || arr[j].charCodeAt(0) === 49) {
if (!(arr[j].charCodeAt(1) > 47 && arr[j].charCodeAt(1) < 58))
throw new Error("second number should be 0-9");
}
// first character is 2
else if (arr[j].charCodeAt(0) === 50) {
if (!(arr[j].charCodeAt(1) > 47 && arr[j].charCodeAt(1) < 52))
throw new Error("second number should be 0-3");
} else {
throw new Error("first number should be 0, 1, or 2");
}
// third character is 0 - 5
if (!(arr[j].charCodeAt(3) > 47 && arr[j].charCodeAt(3) < 54))
throw new Error("third number should be 0-5");
// fourth character is 0 - 9
if (!(arr[j].charCodeAt(4) > 47 && arr[j].charCodeAt(4) < 58))
throw new Error("fourth number should be 0-9");
for (let i = 0; i <= 4; i++) {
if (i === 2) continue;
const code = arr[j].charCodeAt(i);
if (!(code > 47 && code < 58)) {
// numeric (0-9)
throw new Error("color hex must be a hex string, with characters 0-9 or A-F");
}
}
}
}
return true;
});

export const createProgram = [
makeNameValidator(),
makeAbbreviationValidator(),
makeTypeValidator(),
makeDaysOfWeekValidator(),
makeStartDateValidator(),
makeEndDateValidator(),
makeColorValidator(),
makeStudentUIDsValidator(),
makeRenewalDateValidator(),
makeHourlyPayValidator(),
makeSessionsValidator(),
];

export const createForm = [
export const updateProgram = [
makeNameValidator(),
makeAbbreviationValidator(),
makeTypeValidator(),
makeDaysOfWeekValidator(),
makeStartDateValidator(),
makeEndDateValidator(),
makeColorValidator(),
makeStudentsValidator(),
makeStudentUIDsValidator(),
makeRenewalDateValidator(),
makeHourlyPayValidator(),
makeSessionsValidator(),
];
Loading

0 comments on commit bf35387

Please sign in to comment.