From d1035379c5c739a6c984bfdd9a4eb2c87d70fd3d Mon Sep 17 00:00:00 2001 From: sjohn198 Date: Wed, 15 May 2024 09:55:05 -0700 Subject: [PATCH 01/39] fixed delete --- packages/react-frontend/src/Components/OrderTable.jsx | 7 ++++++- packages/react-frontend/src/Views/AddOrders.jsx | 11 ++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/react-frontend/src/Components/OrderTable.jsx b/packages/react-frontend/src/Components/OrderTable.jsx index 8ed6a28..c597d19 100644 --- a/packages/react-frontend/src/Components/OrderTable.jsx +++ b/packages/react-frontend/src/Components/OrderTable.jsx @@ -39,8 +39,13 @@ function convertToDict(order_str){ function TableBody(props) { const rows = props.orderData.map((order, index) => { let arr_order = Array(order); + let count = 0; if (order != undefined){ let each_item = arr_order.map(item => { + console.log(item); + let item_arr = JSON.stringify(item).split(","); + let item_id = item_arr[0].slice(item_arr[0].indexOf("\"_id\":")+7, item_arr[0].length - 1);; + console.log(item_id); item = convertToDict(JSON.stringify(item)); const item_count = item[0]["item_count"]; let each_product = item.slice(1).map((product, index) => { @@ -50,7 +55,7 @@ function TableBody(props) { {product["product"]} {product["quantity"]} - diff --git a/packages/react-frontend/src/Views/AddOrders.jsx b/packages/react-frontend/src/Views/AddOrders.jsx index 7b7455a..e14dae6 100644 --- a/packages/react-frontend/src/Views/AddOrders.jsx +++ b/packages/react-frontend/src/Views/AddOrders.jsx @@ -15,13 +15,10 @@ function AddOrders() { }); }, []); - function removeOneOrder(index) { - let order_id = -1; - const updated = orders.filter((order, i) => { - if (i === index) { - order_id = order["_id"]; - } - return i !== index; + function removeOneOrder(order_id) { + console.log(orders[0]["_id"]); + const updated = orders.filter((order) => { + return order["_id"] !== order_id; }); deleteOrder(order_id) .then((res) => res.status) From a4a35d60de5bee895d9371c6282cbd2e1aa4be8e Mon Sep 17 00:00:00 2001 From: sjohn198 Date: Fri, 17 May 2024 09:17:05 -0700 Subject: [PATCH 02/39] prettier applied --- .prettierrc | 8 +- README.md | 9 +- eslint.config.mjs | 10 +- packages/express-backend/backend.js | 430 +++++++++--------- packages/express-backend/models/order.js | 24 +- packages/express-backend/models/product.js | 54 +-- .../express-backend/models/profile-picture.js | 36 +- packages/express-backend/models/user.js | 90 ++-- packages/express-backend/package.json | 1 + .../express-backend/services/order-service.js | 8 +- .../services/product-service.js | 128 +++--- .../express-backend/services/user-service.js | 372 ++++++++------- packages/react-frontend/package.json | 4 +- .../react-frontend/src/Components/Auth.jsx | 8 +- .../react-frontend/src/Components/Form.jsx | 19 +- .../react-frontend/src/Components/Navbar.jsx | 198 ++++---- .../src/Components/OrderForm.jsx | 30 +- .../src/Components/OrderTable.jsx | 145 +++--- .../react-frontend/src/Components/Table.jsx | 108 ++--- .../react-frontend/src/Components/helpers.js | 22 +- packages/react-frontend/src/MyApp.jsx | 6 +- packages/react-frontend/src/Styles/Navbar.css | 290 ++++++------ .../react-frontend/src/Styles/Profile.css | 124 ++--- packages/react-frontend/src/Styles/main.css | 208 +++++++-- .../react-frontend/src/Views/AddOrders.jsx | 240 +++++----- .../react-frontend/src/Views/Inventory.jsx | 229 +++++----- .../react-frontend/src/Views/LoginPage.jsx | 95 ++-- .../react-frontend/src/Views/ManageOrders.jsx | 207 ++++----- .../src/Views/OrderStatistics.jsx | 207 ++++----- packages/react-frontend/src/Views/Profile.jsx | 221 +++++---- .../react-frontend/src/Views/SignUpPage.jsx | 91 ++-- packages/react-frontend/src/main.jsx | 3 +- packages/react-frontend/vite.config.js | 8 +- 33 files changed, 1845 insertions(+), 1788 deletions(-) diff --git a/.prettierrc b/.prettierrc index a918c9a..accbc2f 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,6 +1,6 @@ { - "trailingComma": "none", - "semi": true, - "singleQuote": false, - "printWidth": 100 + "trailingComma": "none", + "semi": true, + "singleQuote": false, + "printWidth": 100 } diff --git a/README.md b/README.md index 6ab3d66..9a6fd2e 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,20 @@ To run from the repository's root folder, install concurrently with: + ``` npm install concurrently ``` + Then simply run with: + ``` npm start ``` + or run the development mode with + ``` npm run dev ``` -Also, make sure to create a .env file in express-backend and add -```MONGODB_URI = "your_connection_string"``` +Also, make sure to create a .env file in express-backend and add +`MONGODB_URI = "your_connection_string"` diff --git a/eslint.config.mjs b/eslint.config.mjs index ab8edeb..bf8de3e 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,12 +3,16 @@ import pluginJs from "@eslint/js"; import pluginReactConfig from "eslint-plugin-react/configs/recommended.js"; const customRules = { - "no-undef": "warn", + "no-undef": "warn" // feel free to add more rules }; export default [ { languageOptions: { globals: globals.browser } }, - { ...pluginJs.configs.recommended, rules: { ...pluginJs.configs.recommended.rules, ...customRules }, settings: { react: { version: "detect"}}}, - pluginReactConfig, + { + ...pluginJs.configs.recommended, + rules: { ...pluginJs.configs.recommended.rules, ...customRules }, + settings: { react: { version: "detect" } } + }, + pluginReactConfig ]; diff --git a/packages/express-backend/backend.js b/packages/express-backend/backend.js index dc94cf7..50c207b 100644 --- a/packages/express-backend/backend.js +++ b/packages/express-backend/backend.js @@ -1,212 +1,218 @@ -import cors from "cors"; -import orderService from "./services/order-service.js" -import productService from "./services/product-service.js"; -import userService from "./services/user-service.js"; -import express from "express"; -import multer from "multer"; - -const app = express(); -const port = 8000; - -app.use(cors()); -app.use(express.json()); - -// Routes -const upload = multer({ dest: "uploads/" }); -app.use('/uploads', express.static('uploads')) - -app.post("/profile-picture", upload.single("profilePicture"), userService.authenticateUser, async (req, res) => { - const file = req.file; - if (!file) { - res.status(400).send("No file uploaded"); - return; - } - - try { - const result = await userService.uploadProfilePicture(file); - const user = await userService.getUsers(req.body.username, undefined, undefined); - - const pfp = { profilePicture : result._id } - - fetch(`http://localhost:8000/users/${user[0]._id}`, { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(pfp), - }); - res.status(201).send(result._id.toString()); - } catch (error) { - res.status(500).send(error.name); - } -}); - -app.patch("/users/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - userService.changeUserProfilePicture(id, req.body.profilePicture) - .then((result) => { - if (result) { - res.send(result); - } - else { - res.status(404).send(`Not found: ${id}`); - } - }) - .catch((error) => { - console.log(error); - res.status(500).send(error); - }); -}); - -app.get("/profile-picture/:id", (req, res) => { - const id = req.params["id"]; - userService.findProfilePictureById(id) - .then((result) => { - if (result) { - res.contentType(result.contentType) - res.send(result.data); - } - else { - res.status(404).send(`Not found: ${id}`); - } - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.post("/users", (req, res) => { - userService.signupUser(req, res); -}); - -app.get("/users/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - userService.findUserById(id) - .then((result) => { - if (result) { - res.send(result); - } - else { - res.status(404).send(`Not found: ${id}`); - } - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.post("/login", (req, res) => { - userService.loginUser(req, res); -}); - -app.delete("/products/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - productService.removeProduct(id) - .then((result) => { - res.status(204).send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.post("/products", userService.authenticateUser, (req, res) => { - const productToAdd = req.body; - productService.addProduct(productToAdd) - .then((result) => { - - res.status(201).send(result); - }) - .catch((error) => { - console.log(error); - res.status(500).send(error.name); - }); -}); - -app.get("/products/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - productService.findProductById(id) - .then((result) => { - if (result) { - res.send(result); - } - else { - res.status(404).send(`Not found: ${id}`); - } - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.get("/products", userService.authenticateUser, (req, res) => { - const product = req.query.product; - const quantity = req.query.quantity; - productService.getProducts(product, quantity) - .then((result) => { - res.send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.get("/", (req, res) => { - res.send("Hello World!"); -}); - -//add_orders routes -app.get("/orders", userService.authenticateUser, (req, res) => { - const id = req.query.id; - const product = req.query.product; - const quantity = req.query.quantity; - orderService.getOrder(id, product, quantity) - .then((result) => { - res.send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - - - -app.get("/orders/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - orderService.findOrderById(id) - .then((result) => { - res.send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.post("/orders", userService.authenticateUser, (req, res) => { - const orderToAdd = req.body; - orderService.addOrder(orderToAdd) - .then((result) => { - res.status(201).send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.delete("/orders/:id", userService.authenticateUser, (req, res) => { - const id = req.params["id"]; - orderService.removeOrder(id) - .then((result) => { - res.status(204).send(result); - }) - .catch((error) => { - res.status(500).send(error.name); - }); -}); - -app.listen(port, () => { - console.log( - `Example app listening at http://localhost:${port}` - ); -}); - +import cors from "cors"; +import orderService from "./services/order-service.js"; +import productService from "./services/product-service.js"; +import userService from "./services/user-service.js"; +import express from "express"; +import multer from "multer"; + +const app = express(); +const port = 8000; + +app.use(cors()); +app.use(express.json()); + +// Routes +const upload = multer({ dest: "uploads/" }); +app.use("/uploads", express.static("uploads")); + +app.post( + "/profile-picture", + upload.single("profilePicture"), + userService.authenticateUser, + async (req, res) => { + const file = req.file; + if (!file) { + res.status(400).send("No file uploaded"); + return; + } + + try { + const result = await userService.uploadProfilePicture(file); + const user = await userService.getUsers(req.body.username, undefined, undefined); + + const pfp = { profilePicture: result._id }; + + fetch(`http://localhost:8000/users/${user[0]._id}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify(pfp) + }); + res.status(201).send(result._id.toString()); + } catch (error) { + res.status(500).send(error.name); + } + } +); + +app.patch("/users/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + userService + .changeUserProfilePicture(id, req.body.profilePicture) + .then((result) => { + if (result) { + res.send(result); + } else { + res.status(404).send(`Not found: ${id}`); + } + }) + .catch((error) => { + console.log(error); + res.status(500).send(error); + }); +}); + +app.get("/profile-picture/:id", (req, res) => { + const id = req.params["id"]; + userService + .findProfilePictureById(id) + .then((result) => { + if (result) { + res.contentType(result.contentType); + res.send(result.data); + } else { + res.status(404).send(`Not found: ${id}`); + } + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.post("/users", (req, res) => { + userService.signupUser(req, res); +}); + +app.get("/users/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + userService + .findUserById(id) + .then((result) => { + if (result) { + res.send(result); + } else { + res.status(404).send(`Not found: ${id}`); + } + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.post("/login", (req, res) => { + userService.loginUser(req, res); +}); + +app.delete("/products/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + productService + .removeProduct(id) + .then((result) => { + res.status(204).send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.post("/products", userService.authenticateUser, (req, res) => { + const productToAdd = req.body; + productService + .addProduct(productToAdd) + .then((result) => { + res.status(201).send(result); + }) + .catch((error) => { + console.log(error); + res.status(500).send(error.name); + }); +}); + +app.get("/products/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + productService + .findProductById(id) + .then((result) => { + if (result) { + res.send(result); + } else { + res.status(404).send(`Not found: ${id}`); + } + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.get("/products", userService.authenticateUser, (req, res) => { + const product = req.query.product; + const quantity = req.query.quantity; + productService + .getProducts(product, quantity) + .then((result) => { + res.send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.get("/", (req, res) => { + res.send("Hello World!"); +}); + +//add_orders routes +app.get("/orders", userService.authenticateUser, (req, res) => { + const id = req.query.id; + const product = req.query.product; + const quantity = req.query.quantity; + orderService + .getOrder(id, product, quantity) + .then((result) => { + res.send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.get("/orders/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + orderService + .findOrderById(id) + .then((result) => { + res.send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.post("/orders", userService.authenticateUser, (req, res) => { + const orderToAdd = req.body; + orderService + .addOrder(orderToAdd) + .then((result) => { + res.status(201).send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.delete("/orders/:id", userService.authenticateUser, (req, res) => { + const id = req.params["id"]; + orderService + .removeOrder(id) + .then((result) => { + res.status(204).send(result); + }) + .catch((error) => { + res.status(500).send(error.name); + }); +}); + +app.listen(port, () => { + console.log(`Example app listening at http://localhost:${port}`); +}); diff --git a/packages/express-backend/models/order.js b/packages/express-backend/models/order.js index a38b585..85d25ff 100644 --- a/packages/express-backend/models/order.js +++ b/packages/express-backend/models/order.js @@ -1,7 +1,8 @@ import mongoose from "mongoose"; const OrderSchema = new mongoose.Schema({ - items: [{ + items: [ + { product: { type: String, required: true @@ -10,16 +11,17 @@ const OrderSchema = new mongoose.Schema({ type: Number, required: true } - }], - item_count: { - type: Number, - required: true - }, - total_profit: { - type: Number, - required: false } - }); + ], + item_count: { + type: Number, + required: true + }, + total_profit: { + type: Number, + required: false + } +}); const Order = mongoose.model("Order", OrderSchema); -export default Order; \ No newline at end of file +export default Order; diff --git a/packages/express-backend/models/product.js b/packages/express-backend/models/product.js index 7bf8b2b..8a32df7 100644 --- a/packages/express-backend/models/product.js +++ b/packages/express-backend/models/product.js @@ -1,27 +1,27 @@ -import mongoose from 'mongoose' - -const ProductSchema = new mongoose.Schema( - { - product: { - type: String, - unique: true, - required: true, - trim: true, - }, - quantity: { - type: Number, - required: true, - trim: true, - }, - price: { - type: Number, - required: true, - trim: true, - } - }, - { collection: 'products' } // Specify collection name -) - -const Product = mongoose.model('Product', ProductSchema) - -export default Product +import mongoose from "mongoose"; + +const ProductSchema = new mongoose.Schema( + { + product: { + type: String, + unique: true, + required: true, + trim: true + }, + quantity: { + type: Number, + required: true, + trim: true + }, + price: { + type: Number, + required: true, + trim: true + } + }, + { collection: "products" } // Specify collection name +); + +const Product = mongoose.model("Product", ProductSchema); + +export default Product; diff --git a/packages/express-backend/models/profile-picture.js b/packages/express-backend/models/profile-picture.js index c573ae0..41ddbcd 100644 --- a/packages/express-backend/models/profile-picture.js +++ b/packages/express-backend/models/profile-picture.js @@ -1,18 +1,18 @@ -import mongoose from "mongoose"; - -const profilePictureSchema = new mongoose.Schema({ - data: { - type: Buffer, - required: true, - trim: true - }, - contentType: { - type: String, - required: true, - trim : true - } -}); - -const ProfilePicture = mongoose.model("ProfilePicture", profilePictureSchema); - -export default ProfilePicture; +import mongoose from "mongoose"; + +const profilePictureSchema = new mongoose.Schema({ + data: { + type: Buffer, + required: true, + trim: true + }, + contentType: { + type: String, + required: true, + trim: true + } +}); + +const ProfilePicture = mongoose.model("ProfilePicture", profilePictureSchema); + +export default ProfilePicture; diff --git a/packages/express-backend/models/user.js b/packages/express-backend/models/user.js index 7279f31..5fabe1c 100644 --- a/packages/express-backend/models/user.js +++ b/packages/express-backend/models/user.js @@ -1,45 +1,45 @@ -import mongoose from "mongoose"; - -const UserSchema = new mongoose.Schema( - { - username: { - type: String, - required: true, - trim: true, - }, - password: { - type: String, - required: true, - trim: true, - }, - name: { - type: String, - required: false, - trim: true, - }, - location: { - type: String, - required: false, - trim: true, - }, - bio: { - type: String, - required: false, - trim: true, - }, - skills: { - type: [String], - required: false, - trim: true, - }, - profilePicture: { - type: mongoose.Schema.Types.ObjectId, - ref: 'ProfilePicture', - }, - }, - { collection: "users" } -); - -const Users = mongoose.model("User", UserSchema); - -export default Users; +import mongoose from "mongoose"; + +const UserSchema = new mongoose.Schema( + { + username: { + type: String, + required: true, + trim: true + }, + password: { + type: String, + required: true, + trim: true + }, + name: { + type: String, + required: false, + trim: true + }, + location: { + type: String, + required: false, + trim: true + }, + bio: { + type: String, + required: false, + trim: true + }, + skills: { + type: [String], + required: false, + trim: true + }, + profilePicture: { + type: mongoose.Schema.Types.ObjectId, + ref: "ProfilePicture" + } + }, + { collection: "users" } +); + +const Users = mongoose.model("User", UserSchema); + +export default Users; diff --git a/packages/express-backend/package.json b/packages/express-backend/package.json index 42d0222..18ae3aa 100644 --- a/packages/express-backend/package.json +++ b/packages/express-backend/package.json @@ -7,6 +7,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "dev": "npx nodemon backend.js", + "lint": "npx eslint .", "start": "node backend.js" }, "author": "", diff --git a/packages/express-backend/services/order-service.js b/packages/express-backend/services/order-service.js index c612088..03acb63 100644 --- a/packages/express-backend/services/order-service.js +++ b/packages/express-backend/services/order-service.js @@ -6,9 +6,7 @@ const uri = process.env.MONGODB_URI; mongoose.set("debug", true); -mongoose - .connect(uri) - .catch((error) => console.log(error)); +mongoose.connect(uri).catch((error) => console.log(error)); function getOrder(id, product, quantity) { let promise; @@ -37,7 +35,7 @@ function addOrder(order) { } function findOrderByProductAndQuantity(product, quantity) { - return OrderModel.find({ product: product, quantity: quantity }); + return OrderModel.find({ product: product, quantity: quantity }); } export default { @@ -46,4 +44,4 @@ export default { getOrder, findOrderById, findOrderByProductAndQuantity -}; \ No newline at end of file +}; diff --git a/packages/express-backend/services/product-service.js b/packages/express-backend/services/product-service.js index 9bb83b2..6945262 100644 --- a/packages/express-backend/services/product-service.js +++ b/packages/express-backend/services/product-service.js @@ -1,65 +1,63 @@ -import mongoose from 'mongoose' -import ProductModel from '../models/product.js' -import dotenv from 'dotenv' -dotenv.config() -const uri = process.env.MONGODB_URI - -mongoose.set('debug', true) - -mongoose - .connect(uri) - .catch((error) => console.log(error)); - -function getProducts(product, quantity) { - let promise - if (product === undefined && quantity === undefined) { - promise = ProductModel.find() - } else if (product && !quantity) { - promise = findProductByProduct(product) - } else if (quantity && !product) { - promise = findProductByQuantity(quantity) - } else if (product && quantity) { - promise = findProductByProductAndQuantity(product, quantity) - } - return promise -} - -function findProductById(id) { - return ProductModel.findById(id) -} - -function removeProduct(id) { - return ProductModel.findByIdAndDelete(id) -} - -function addProduct(product) { - console.log(product); - console.log("hi"); - return ProductModel.findOneAndUpdate( - { product: product.product }, - { $inc: { quantity: product.quantity, price: product.price } }, - { upsert: true, new: true } - ) -} - -function findProductByProduct(product) { - return ProductModel.find({ product: product }) -} - -function findProductByQuantity(quantity) { - return ProductModel.find({ quantity: quantity }) -} - -function findProductByProductAndQuantity(product, quantity) { - return ProductModel.find({ product: product, quantity: quantity }) -} - -export default { - addProduct, - removeProduct, - getProducts, - findProductById, - findProductByProduct, - findProductByQuantity, - findProductByProductAndQuantity, -} +import mongoose from "mongoose"; +import ProductModel from "../models/product.js"; +import dotenv from "dotenv"; +dotenv.config(); +const uri = process.env.MONGODB_URI; + +mongoose.set("debug", true); + +mongoose.connect(uri).catch((error) => console.log(error)); + +function getProducts(product, quantity) { + let promise; + if (product === undefined && quantity === undefined) { + promise = ProductModel.find(); + } else if (product && !quantity) { + promise = findProductByProduct(product); + } else if (quantity && !product) { + promise = findProductByQuantity(quantity); + } else if (product && quantity) { + promise = findProductByProductAndQuantity(product, quantity); + } + return promise; +} + +function findProductById(id) { + return ProductModel.findById(id); +} + +function removeProduct(id) { + return ProductModel.findByIdAndDelete(id); +} + +function addProduct(product) { + console.log(product); + console.log("hi"); + return ProductModel.findOneAndUpdate( + { product: product.product }, + { $inc: { quantity: product.quantity, price: product.price } }, + { upsert: true, new: true } + ); +} + +function findProductByProduct(product) { + return ProductModel.find({ product: product }); +} + +function findProductByQuantity(quantity) { + return ProductModel.find({ quantity: quantity }); +} + +function findProductByProductAndQuantity(product, quantity) { + return ProductModel.find({ product: product, quantity: quantity }); +} + +export default { + addProduct, + removeProduct, + getProducts, + findProductById, + findProductByProduct, + findProductByQuantity, + findProductByProductAndQuantity +}; diff --git a/packages/express-backend/services/user-service.js b/packages/express-backend/services/user-service.js index 5885824..43dc01f 100644 --- a/packages/express-backend/services/user-service.js +++ b/packages/express-backend/services/user-service.js @@ -1,193 +1,179 @@ -import mongoose from "mongoose"; -import UserModel from "../models/user.js"; -import ProfilePictureModel from "../models/profile-picture.js"; -import fs from "fs"; -import dotenv from "dotenv"; -dotenv.config(); -const uri = process.env.MONGODB_URI; -import jwt from "jsonwebtoken"; -import bcrypt from "bcrypt"; - - - -mongoose.set("debug", true); - -mongoose - .connect(uri) - .catch((error) => console.log(error)); - - -const uploadProfilePicture = async (file) => { - try { - if (!file) { - throw new Error("No file uploaded"); - } - - const data = fs.readFileSync(file.path); - const profilePicture = new ProfilePictureModel({ - data: data, - contentType: file.mimetype, - }); - - return await profilePicture.save(); - } catch (error) { - console.error(error); - throw error; - } -} - -function getUsers(username, name, profilePicture) { - let query = {}; - if (username) { - query.username = username; - } - if (name) { - query.name = name; - } - if (profilePicture) { - query.profilePicture = profilePicture; - } - return UserModel.find(query); -} - -function getPassword(username) { //same as get Users but uses findOne - let query = {}; - query.username = username; - return UserModel.findOne(query, {password: 1}); -} - -function getUsername(username) { //same as get Users but uses findOne - let query = {}; - query.username = username; - return UserModel.findOne(query, {username: 1}); -} - -function generateAccessToken(username) { - return new Promise((resolve, reject) => { - jwt.sign( - { username: username }, - process.env.TOKEN_SECRET, - { expiresIn: "1d" }, - (error, token) => { - if (error) reject(error); - else resolve(token); - } - ); - }); -} -function loginUser(req, res) -{ - console.log(req.body) - const salt = "$2b$10$5u3nVKlTV5RPpREyblmGqe"; - const {username, password} = req.body; - bcrypt.hash(password, salt) - .then((hashedPassword) => { - getPassword(username) - .then((result) => { - if (result !== null && result.password === hashedPassword) { - generateAccessToken(username) - .then((token) => { - res.status(200).send(token); - }) - .catch((error) => { - res.status(500).send(error); - }); - } - else { - res.status(401).send("Invalid Username or Password"); - } - }) - }) - .catch((error) => { - res.status(500).send(error); - }); -} -function signupUser(req, res) -{ - const salt = "$2b$10$5u3nVKlTV5RPpREyblmGqe"; //pregenerated salt - const { username, password } = req.body; // from form - if (!username || !password) { - res.status(400).send("Bad request: Invalid input data."); - } else { - getUsername(username) - .then((result) => { - if (result !== null && result.username === username) { - res.status(409).send("Username already taken"); - } - else { - bcrypt.hash(password, salt) - .then((hashedPassword) => { - generateAccessToken(username).then((token) => { - console.log("Token:", token); - res.status(201).send(token); - addUser({username: username, password: hashedPassword}); - }); - }); - } - }); - } - } - -function authenticateUser(req, res, next) { - const authHeader = req.headers["authorization"]; - //Getting the 2nd part of the auth header (the token) - const token = authHeader && authHeader.split(" ")[1]; - - if (!token) { - console.log("No token received"); - res.status(401).end(); - } else { - jwt.verify( - token, - process.env.TOKEN_SECRET, - (error, decoded) => { - if (decoded) { - next(); - } else { - console.log("JWT error:", error); - res.status(401).end(); - } - } - ); - } -} - -function changeUserProfilePicture(id, profilePictureId) { - return UserModel.findByIdAndUpdate( - id, - { profilePicture: profilePictureId }, - { new: true } - ).exec();} - - -function findUserById(id) { - return UserModel.findById(id); -} - -function findProfilePictureById(id) { - return ProfilePictureModel.findById(id); -} - -function removeUser(id) { - return UserModel.findByIdAndDelete(id); -} - -function addUser(user) { - const userToAdd = new UserModel(user); - let promise = userToAdd.save(); - return promise; -} - - -export default { - addUser, - removeUser, - getUsers, - loginUser, - signupUser, - authenticateUser, - findUserById, - findProfilePictureById, - uploadProfilePicture, - changeUserProfilePicture, -}; +import mongoose from "mongoose"; +import UserModel from "../models/user.js"; +import ProfilePictureModel from "../models/profile-picture.js"; +import fs from "fs"; +import dotenv from "dotenv"; +dotenv.config(); +const uri = process.env.MONGODB_URI; +import jwt from "jsonwebtoken"; +import bcrypt from "bcrypt"; + +mongoose.set("debug", true); + +mongoose.connect(uri).catch((error) => console.log(error)); + +const uploadProfilePicture = async (file) => { + try { + if (!file) { + throw new Error("No file uploaded"); + } + + const data = fs.readFileSync(file.path); + const profilePicture = new ProfilePictureModel({ + data: data, + contentType: file.mimetype + }); + + return await profilePicture.save(); + } catch (error) { + console.error(error); + throw error; + } +}; + +function getUsers(username, name, profilePicture) { + let query = {}; + if (username) { + query.username = username; + } + if (name) { + query.name = name; + } + if (profilePicture) { + query.profilePicture = profilePicture; + } + return UserModel.find(query); +} + +function getPassword(username) { + //same as get Users but uses findOne + let query = {}; + query.username = username; + return UserModel.findOne(query, { password: 1 }); +} + +function getUsername(username) { + //same as get Users but uses findOne + let query = {}; + query.username = username; + return UserModel.findOne(query, { username: 1 }); +} + +function generateAccessToken(username) { + return new Promise((resolve, reject) => { + jwt.sign( + { username: username }, + process.env.TOKEN_SECRET, + { expiresIn: "1d" }, + (error, token) => { + if (error) reject(error); + else resolve(token); + } + ); + }); +} +function loginUser(req, res) { + console.log(req.body); + const salt = "$2b$10$5u3nVKlTV5RPpREyblmGqe"; + const { username, password } = req.body; + bcrypt + .hash(password, salt) + .then((hashedPassword) => { + getPassword(username).then((result) => { + if (result !== null && result.password === hashedPassword) { + generateAccessToken(username) + .then((token) => { + res.status(200).send(token); + }) + .catch((error) => { + res.status(500).send(error); + }); + } else { + res.status(401).send("Invalid Username or Password"); + } + }); + }) + .catch((error) => { + res.status(500).send(error); + }); +} +function signupUser(req, res) { + const salt = "$2b$10$5u3nVKlTV5RPpREyblmGqe"; //pregenerated salt + const { username, password } = req.body; // from form + if (!username || !password) { + res.status(400).send("Bad request: Invalid input data."); + } else { + getUsername(username).then((result) => { + if (result !== null && result.username === username) { + res.status(409).send("Username already taken"); + } else { + bcrypt.hash(password, salt).then((hashedPassword) => { + generateAccessToken(username).then((token) => { + console.log("Token:", token); + res.status(201).send(token); + addUser({ username: username, password: hashedPassword }); + }); + }); + } + }); + } +} + +function authenticateUser(req, res, next) { + const authHeader = req.headers["authorization"]; + //Getting the 2nd part of the auth header (the token) + const token = authHeader && authHeader.split(" ")[1]; + + if (!token) { + console.log("No token received"); + res.status(401).end(); + } else { + jwt.verify(token, process.env.TOKEN_SECRET, (error, decoded) => { + if (decoded) { + next(); + } else { + console.log("JWT error:", error); + res.status(401).end(); + } + }); + } +} + +function changeUserProfilePicture(id, profilePictureId) { + return UserModel.findByIdAndUpdate( + id, + { profilePicture: profilePictureId }, + { new: true } + ).exec(); +} + +function findUserById(id) { + return UserModel.findById(id); +} + +function findProfilePictureById(id) { + return ProfilePictureModel.findById(id); +} + +function removeUser(id) { + return UserModel.findByIdAndDelete(id); +} + +function addUser(user) { + const userToAdd = new UserModel(user); + let promise = userToAdd.save(); + return promise; +} + +export default { + addUser, + removeUser, + getUsers, + loginUser, + signupUser, + authenticateUser, + findUserById, + findProfilePictureById, + uploadProfilePicture, + changeUserProfilePicture +}; diff --git a/packages/react-frontend/package.json b/packages/react-frontend/package.json index 2b477e2..0b32495 100644 --- a/packages/react-frontend/package.json +++ b/packages/react-frontend/package.json @@ -7,7 +7,7 @@ "dev": "vite", "start": "vite --host", "build": "vite build", - "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "lint": "npx eslint .", "preview": "vite preview" }, "dependencies": { @@ -24,4 +24,4 @@ "eslint-plugin-react-refresh": "^0.4.6", "vite": "^5.2.0" } -} \ No newline at end of file +} diff --git a/packages/react-frontend/src/Components/Auth.jsx b/packages/react-frontend/src/Components/Auth.jsx index 98d640d..8b35090 100644 --- a/packages/react-frontend/src/Components/Auth.jsx +++ b/packages/react-frontend/src/Components/Auth.jsx @@ -10,8 +10,7 @@ function Auth(props) { const { name, value } = event.target; if (name === "password") { setLogin({ username: userAuth["username"], password: value }); - } - else setLogin({ username: value, password: userAuth["password"] }); + } else setLogin({ username: value, password: userAuth["password"] }); } function submitForm() { @@ -39,8 +38,7 @@ function Auth(props) { /> - - ) + ); } -export default Auth; \ No newline at end of file +export default Auth; diff --git a/packages/react-frontend/src/Components/Form.jsx b/packages/react-frontend/src/Components/Form.jsx index 9cf401e..6e6c249 100644 --- a/packages/react-frontend/src/Components/Form.jsx +++ b/packages/react-frontend/src/Components/Form.jsx @@ -10,9 +10,9 @@ function Form(props) { const { name, value } = event.target; if (name === "quantity") { setOrder({ product: order["product"], quantity: value }); - } + } if (name === "product") { - setOrder({ product: value, quantity: order["quantity"], price: order["price"] }); + setOrder({ product: value, quantity: order["quantity"], price: order["price"] }); } if (name === "price") { setOrder({ product: order["product"], quantity: order["quantity"], price: value }); @@ -21,7 +21,7 @@ function Form(props) { function submitForm() { props.handleSubmit(order); - setOrder({ product: "", quantity: "", price: ""}); + setOrder({ product: "", quantity: "", price: "" }); } return ( @@ -43,17 +43,10 @@ function Form(props) { onChange={handleChange} /> - + - - ) + ); } -export default Form; \ No newline at end of file +export default Form; diff --git a/packages/react-frontend/src/Components/Navbar.jsx b/packages/react-frontend/src/Components/Navbar.jsx index 3329e56..8066afc 100644 --- a/packages/react-frontend/src/Components/Navbar.jsx +++ b/packages/react-frontend/src/Components/Navbar.jsx @@ -1,99 +1,99 @@ -import React from "react"; -import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom"; -import Inventory from "../Views/Inventory"; -import LoginPage from "../Views/LoginPage"; -import SignUpPage from "../Views/SignUpPage"; -import ManageOrders from "../Views/ManageOrders"; -import AddOrders from "../Views/AddOrders"; -import OrderStatistics from "../Views/OrderStatistics"; -import ProfilePage from "../Views/Profile"; -import "../Styles/Navbar.css"; - -function App() { - const user = { - id: "663340b898b86ea44965feb0" - }; - return ( - - - - } /> - } /> - } /> - } /> - } /> - } /> - } /> - } /> - -