-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/steven+yoto vsr personal info (#24)
* lint fixes * Added route to POST and VSR controller * Added validation functions for form responses * Added validation functions for form responses * Removed numOfBoys, numOfGirls from schema, cleaned up backend, renamed martial to marital * Added tests for validate spouse name * Added tests for validate ethnicity * Basic text field, multiple choice, dropdown, and submit * Fix linting issues and minor edit to gender field validation * app now uses post route * Attempt at linking front end with back end, onbooarding code for front end api requests imported and adjusted * Reworked TextField component to do ref-forwarding, successfully pushed a document to the mongo database * Fixed couple bugs with date verification * Removed forwardRef * Added title and description, required fields, and overall more styling * updated date to use current date, added more fields for the vsr page * Prototype of ethnicity selector * Made options unselectable * Working version of ethnicity form * Prototype of appearing and disappearing children form * Added more styling * Added backend functionality for ages, changed Child #n name to Child #n age * Fixed small bug with ethnicity, added numBoys and spouse to createVSR, and continued styling * fixed issue with ethnicity selection * Changed textbox styling to flex 1 * Fixed issue with null values in age array * Page number component * added girls form * changes with validation * Yet even more lint fixes * Fix CSS styles & clean up code * Update favicon, title, & description, remove unused boilerplate * Remove commented-out code & make ethnicity an array * Fix bugs with entering ages of children * Only require spouse's name for Married marital status * Fix age validation * Fix bugs with VSR age & num children * Address Daniel's review comments --------- Co-authored-by: Yoto Kim <[email protected]> Co-authored-by: Benjamin Johnson <[email protected]>
- Loading branch information
1 parent
c60b6b4
commit 3750b82
Showing
30 changed files
with
1,731 additions
and
278 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,51 @@ | ||
import { RequestHandler } from "express"; | ||
import { validationResult } from "express-validator"; | ||
import VSRModel from "src/models/vsr"; | ||
import validationErrorParser from "src/util/validationErrorParser"; | ||
|
||
export const createVSR: RequestHandler = async (req, res, next) => { | ||
// extract any errors that were found by the validator | ||
const errors = validationResult(req); | ||
const { | ||
name, | ||
gender, | ||
age, | ||
maritalStatus, | ||
spouseName, | ||
agesOfBoys, | ||
agesOfGirls, | ||
ethnicity, | ||
employmentStatus, | ||
incomeLevel, | ||
sizeOfHome, | ||
} = req.body; | ||
|
||
try { | ||
// if there are errors, then this function throws an exception | ||
validationErrorParser(errors); | ||
|
||
// Get the current date as a timestamp for when VSR was submitted | ||
const date = new Date(); | ||
|
||
const vsr = await VSRModel.create({ | ||
name, | ||
date, | ||
gender, | ||
age, | ||
maritalStatus, | ||
spouseName, | ||
agesOfBoys, | ||
agesOfGirls, | ||
ethnicity, | ||
employmentStatus, | ||
incomeLevel, | ||
sizeOfHome, | ||
}); | ||
|
||
// 201 means a new resource has been created successfully | ||
// the newly created VSR is sent back to the user | ||
res.status(201).json(vsr); | ||
} catch (error) { | ||
next(error); | ||
} | ||
}; |
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,20 @@ | ||
import { InferSchemaType, Schema, model } from "mongoose"; | ||
|
||
const vsrSchema = new Schema({ | ||
name: { type: String, required: true }, | ||
date: { type: Date, required: true }, | ||
gender: { type: String, require: true }, | ||
age: { type: Number, require: true }, | ||
maritalStatus: { type: String, required: true }, | ||
spouseName: { type: String }, | ||
agesOfBoys: { type: [Number] }, | ||
agesOfGirls: { type: [Number] }, | ||
ethnicity: { type: [String], require: true }, | ||
employmentStatus: { type: String, require: true }, | ||
incomeLevel: { type: String, require: true }, | ||
sizeOfHome: { type: String, require: true }, | ||
}); | ||
|
||
type VSR = InferSchemaType<typeof vsrSchema>; | ||
|
||
export default model<VSR>("VSR", vsrSchema); |
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,9 @@ | ||
import express from "express"; | ||
import * as VSRController from "src/controllers/vsr"; | ||
import * as VSRValidator from "src/validators/vsr"; | ||
|
||
const router = express.Router(); | ||
|
||
router.post("/", VSRValidator.createVSR, VSRController.createVSR); | ||
|
||
export default router; |
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,25 @@ | ||
import { Result, ValidationError } from "express-validator"; | ||
import createHttpError from "http-errors"; | ||
|
||
/** | ||
* Parses through errors thrown by validator (if any exist). Error messages are | ||
* added to a string and that string is used as the error message for the HTTP | ||
* error. | ||
* | ||
* @param errors the validation result provided by express validator middleware | ||
*/ | ||
const validationErrorParser = (errors: Result<ValidationError>) => { | ||
if (!errors.isEmpty()) { | ||
let errorString = ""; | ||
|
||
// parse through errors returned by the validator and append them to the error string | ||
for (const error of errors.array()) { | ||
errorString += error.msg + " "; | ||
} | ||
|
||
// trim removes the trailing space created in the for loop | ||
throw createHttpError(400, errorString.trim()); | ||
} | ||
}; | ||
|
||
export default validationErrorParser; |
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,97 @@ | ||
import { body } from "express-validator"; | ||
|
||
const makeNameValidator = () => | ||
body("name") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Name is required") | ||
.isString() | ||
.withMessage("Name must be a string"); | ||
|
||
const makeGenderValidator = () => | ||
body("gender") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Gender is required") | ||
.isString() | ||
.withMessage("Gender must be a string"); | ||
|
||
const makeAgeValidator = () => | ||
body("age") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Age is required") | ||
.isInt({ min: 0 }) | ||
.withMessage("Age must be a positive integer"); | ||
|
||
const makeMaritalStatusValidator = () => | ||
body("maritalStatus") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Marital Status is required") | ||
.isString() | ||
.withMessage("Marital Status must be a string"); | ||
|
||
const makeSpouseNameValidator = () => | ||
body("spouseName") | ||
.optional({ checkFalsy: true }) | ||
.isString() | ||
.withMessage("Spouse Name must be a string"); | ||
|
||
const makeAgesOfBoysValidator = () => | ||
body("agesOfBoys") | ||
.exists({ checkFalsy: true }) | ||
.isArray() | ||
.withMessage("Ages of Boys must be an array of numbers") | ||
.custom((ages: number[]) => ages.every((age) => Number.isInteger(age) && age >= 0)) | ||
.withMessage("Each age in Ages of Boys must be a positive integer"); | ||
|
||
const makeAgesOfGirlsValidator = () => | ||
body("agesOfGirls") | ||
.exists({ checkFalsy: true }) | ||
.isArray() | ||
.withMessage("Ages of Girls must be an array of numbers") | ||
.custom((ages: number[]) => ages.every((age) => Number.isInteger(age) && age >= 0)) | ||
.withMessage("Each age in Ages of Girls must be a positive integer"); | ||
|
||
const makeEthnicityValidator = () => | ||
body("ethnicity") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Ethnicity is required") | ||
.isArray() | ||
.withMessage("Ethnicity must be an array") | ||
.custom((ethnicities: string[]) => | ||
ethnicities.every((ethnicity) => typeof ethnicity === "string"), | ||
) | ||
.withMessage("Each ethnicity in Ethnicities must be a positive integer"); | ||
|
||
const makeEmploymentStatusValidator = () => | ||
body("employmentStatus") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Employment Status is required") | ||
.isString() | ||
.withMessage("Employment Status must be a string"); | ||
|
||
const makeIncomeLevelValidator = () => | ||
body("incomeLevel") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Income Level is required") | ||
.isString() | ||
.withMessage("Income Level must be a string"); | ||
|
||
const makeSizeOfHomeValidator = () => | ||
body("sizeOfHome") | ||
.exists({ checkFalsy: true }) | ||
.withMessage("Size of Home is required") | ||
.isString() | ||
.withMessage("Size of Home must be a string"); | ||
|
||
export const createVSR = [ | ||
makeNameValidator(), | ||
makeGenderValidator(), | ||
makeAgeValidator(), | ||
makeMaritalStatusValidator(), | ||
makeSpouseNameValidator(), | ||
makeAgesOfBoysValidator(), | ||
makeAgesOfGirlsValidator(), | ||
makeEthnicityValidator(), | ||
makeEmploymentStatusValidator(), | ||
makeIncomeLevelValidator(), | ||
makeSizeOfHomeValidator(), | ||
]; |
Oops, something went wrong.