From 1006d28b71e2f47f05f7b8e1bbb29a9d86999ecc Mon Sep 17 00:00:00 2001 From: ak Date: Sat, 9 Sep 2023 18:47:17 -0700 Subject: [PATCH] all CRUD operations functional --- app.js | 13 ------ controllers/category.js | 57 +++++++++++++++++++++++-- controllers/item.js | 94 ++++++++++++++++++++++++++++++++++------- views/category.ejs | 8 ++++ views/editcategory.ejs | 48 +++++++++++++++++++++ views/edititem.ejs | 84 ++++++++++++++++++++++++++++++++++++ views/error.ejs | 3 -- 7 files changed, 272 insertions(+), 35 deletions(-) create mode 100644 views/editcategory.ejs create mode 100644 views/edititem.ejs delete mode 100644 views/error.ejs diff --git a/app.js b/app.js index dac9445..a283018 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,3 @@ -const createError = require("http-errors"); const express = require("express"); const path = require("path"); const cookieParser = require("cookie-parser"); @@ -36,16 +35,4 @@ const router = require("./routes/index"); app.use("/", router); -// catch 404 and forward to error handler -app.use(function (req, res, next) { - next(createError(404)); -}); - -// error handler -app.use(function (err, req, res, next) { - // render the error page - res.status(err.status || 500); - res.render("error"); -}); - module.exports = app; diff --git a/controllers/category.js b/controllers/category.js index 42fbdc7..aafb05f 100644 --- a/controllers/category.js +++ b/controllers/category.js @@ -111,9 +111,58 @@ exports.category_delete_get = asyncHandler(async (req, res, next) => { }); exports.category_update_get = asyncHandler(async (req, res, next) => { - res.send("ligma"); + // get current category from URL + const category = await Category.findOne({ + simpleName: req.params.category, + }) + .lean() + .exec(); + res.render("editcategory", { category: category }); }); -exports.category_update_post = asyncHandler(async (req, res, next) => { - res.send("ligma"); -}); +exports.category_update_post = [ + // Validate and sanitize name + body("name", "Category must have a name!") + .trim() + .isLength({ min: 1 }) + .escape(), + + // Validate and sanitize description + body("description", "Category must have a description!") + .trim() + .isLength({ min: 1 }) + .escape(), + + // Process request after validation and sanitization. + asyncHandler(async (req, res, next) => { + // Extract the validation errors from a request. + const errors = validationResult(req); + + // find existing category in database + const dbCat = await Category.findOne({ simpleName: req.params.category }) + .lean() + .exec(); + + // Create a new category with escaped and trimmed data. + const category = new Category({ + name: req.body.name, + simpleName: req.body.name.toLowerCase().replace(" ", ""), + description: req.body.description, + _id: dbCat._id, // copy original category ID to prevent overwrite errors + }); + + // if there are validation errors + if (!errors.isEmpty()) { + // Render the creation form again with sanitized values/error messages. + res.render("editcategory", { + category: dbCat, + }); + return; + } + // Data from form is valid. + else { + await Category.findByIdAndUpdate(dbCat._id, category, {}); + res.redirect(`/${category.simpleName}`); + } + }), +]; diff --git a/controllers/item.js b/controllers/item.js index 14df402..5ef482b 100644 --- a/controllers/item.js +++ b/controllers/item.js @@ -57,7 +57,7 @@ exports.item_create_post = [ .isLength({ min: 2, max: 2 }) .escape(), - // Validate and sanitize price (formatting has already been taken care of) + // Validate and sanitize quantity body("quantity", "Item must have a quantity!") .trim() .isLength({ min: 1 }) @@ -75,15 +75,6 @@ exports.item_create_post = [ .lean() .exec(); - console.log([ - req.body.name, - category._id, - req.body.description, - req.body.dollars, - req.body.cents, - req.body.quantity, - ]); - // Create a new Item with escaped and trimmed data. const item = new Item({ name: req.body.name, @@ -96,8 +87,9 @@ exports.item_create_post = [ // if there are validation errors if (!errors.isEmpty()) { // Render the creation form again with sanitized values/error messages. - res.render("createcategory", { + res.render("createitem", { errors: errors.array(), + category: category, }); return; } @@ -144,9 +136,81 @@ exports.item_delete_get = asyncHandler(async (req, res, next) => { }); exports.item_update_get = asyncHandler(async (req, res, next) => { - res.send("ligma"); + // get current category from URL + const category = await Category.findOne({ + simpleName: req.params.category, + }) + .lean() + .exec(); + const item = await Item.findOne({ _id: req.params.item }); + res.render("edititem", { category: category, item: item }); }); -exports.item_update_post = asyncHandler(async (req, res, next) => { - res.send("ligma"); -}); +exports.item_update_post = [ + // Validate and sanitize name + body("name", "Item must have a name!").trim().isLength({ min: 1 }).escape(), + + // Validate and sanitize description + body("description", "Item must have a description!") + .trim() + .isLength({ min: 1 }) + .escape(), + + // Validate and sanitize price (formatting has already been taken care of) + body("dollars", "Item must have a dollar amount!") + .trim() + .isLength({ min: 1 }) + .escape(), + body("cents", "Item must have a cent amount!") + .trim() + .isLength({ min: 2, max: 2 }) + .escape(), + + // Validate and sanitize quantity + body("quantity", "Item must have a quantity!") + .trim() + .isLength({ min: 1 }) + .escape(), + + // Process request after validation and sanitization. + asyncHandler(async (req, res, next) => { + // Extract the validation errors from a request. + const errors = validationResult(req); + + // get current category from URL + const category = await Category.findOne({ + simpleName: req.params.category, + }) + .lean() + .exec(); + + // get item in db + const dbItem = await Item.findOne({ _id: req.params.item }); + + // Create a new Item with escaped and trimmed data. + const item = new Item({ + name: req.body.name, + category: category._id, + description: req.body.description, + price: Number(`${req.body.dollars}.${req.body.cents}`), + quantity: req.body.quantity, + _id: dbItem._id, + }); + + // if there are validation errors + if (!errors.isEmpty()) { + // Render the creation form again with sanitized values/error messages. + res.render("edititem", { + errors: errors.array(), + category: category, + item: dbItem, + }); + return; + } + // Data from form is valid. + else { + await Item.findByIdAndUpdate(dbItem._id, item, {}); + res.redirect(`/${req.params.category}/${req.params.item}`); + } + }), +]; diff --git a/views/category.ejs b/views/category.ejs index 088bd75..b1dcce3 100644 --- a/views/category.ejs +++ b/views/category.ejs @@ -27,6 +27,14 @@ + Create new item
+ + Edit this category + +
+ + + Good Pickin's - Editing <%= category.name %> + + + +
+

Editing <%= category.name %>

+
+
+ Category Name: + +
+
+ + Category Description: + + +
+ +
+
+
+ + diff --git a/views/edititem.ejs b/views/edititem.ejs new file mode 100644 index 0000000..c05b5b3 --- /dev/null +++ b/views/edititem.ejs @@ -0,0 +1,84 @@ + + + + + Good Pickin's - <%= category.name %> - Editing <%= item.name %> + + + + +
+

Editing <%= item.name %>

+
+
+ Item Name: + +
+
+ + Item Description: + + +
+
+ Item Price: + + . + +
+
+ Item Quantity: + +
+ +
+
+ + + diff --git a/views/error.ejs b/views/error.ejs deleted file mode 100644 index d721023..0000000 --- a/views/error.ejs +++ /dev/null @@ -1,3 +0,0 @@ -

<%= message = 'Error!' %>

-

<%= error.status %>

-
<%= error.stack %>