├── server ├── config │ ├── keys.js │ ├── db.js │ ├── uploadFolderCreateScript.js │ └── function.js ├── routes │ ├── braintree.js │ ├── auth.js │ ├── orders.js │ ├── users.js │ ├── customize.js │ ├── categories.js │ └── products.js ├── models │ ├── customize.js │ ├── categories.js │ ├── users.js │ ├── orders.js │ └── products.js ├── package.json ├── middleware │ └── auth.js ├── controller │ ├── braintree.js │ ├── customize.js │ ├── orders.js │ ├── categories.js │ ├── users.js │ ├── auth.js │ └── products.js └── server.js ├── Data Privacy.pdf ├── Screenshots ├── 1.jpeg ├── 2.jpeg ├── 3.jpeg ├── 4.jpeg ├── 5.jpeg └── 6.jpeg ├── vercel.json ├── LICENSE └── README.md /server/config/keys.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | JWT_SECRET: "SecretKey", 3 | }; 4 | -------------------------------------------------------------------------------- /Data Privacy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Data Privacy.pdf -------------------------------------------------------------------------------- /Screenshots/1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/1.jpeg -------------------------------------------------------------------------------- /Screenshots/2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/2.jpeg -------------------------------------------------------------------------------- /Screenshots/3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/3.jpeg -------------------------------------------------------------------------------- /Screenshots/4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/4.jpeg -------------------------------------------------------------------------------- /Screenshots/5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/5.jpeg -------------------------------------------------------------------------------- /Screenshots/6.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hindhuja-V/Organease/HEAD/Screenshots/6.jpeg -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | {"builds":[ 2 | { 3 | "src": "./client/src/App.js", 4 | "use": "@vercel/node" 5 | } 6 | ], 7 | "routes":[ 8 | { 9 | "src":"/.*", 10 | "dest":"app.js" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /server/routes/braintree.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const brainTreeController = require("../controller/braintree"); 4 | 5 | router.post("/braintree/get-token", brainTreeController.ganerateToken); 6 | router.post("/braintree/payment", brainTreeController.paymentProcess); 7 | 8 | module.exports = router; 9 | -------------------------------------------------------------------------------- /server/config/db.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | try { 3 | mongoose.connect("mongodb://localhost:27017/Ecommerce", { 4 | useNewUrlParser: true, 5 | useUnifiedTopology: true, 6 | useCreateIndex: true, 7 | }); 8 | console.log("Database Connected Successfully"); 9 | } catch (err) { 10 | console.log("Database Not Connected"); 11 | } 12 | -------------------------------------------------------------------------------- /server/models/customize.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const customizeSchema = new mongoose.Schema( 4 | { 5 | slideImage: { 6 | type: String, 7 | }, 8 | firstShow: { 9 | type: Number, 10 | default: 0, 11 | }, 12 | }, 13 | { timestamps: true } 14 | ); 15 | 16 | const customizeModel = mongoose.model("customizes", customizeSchema); 17 | module.exports = customizeModel; 18 | -------------------------------------------------------------------------------- /server/routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const authController = require("../controller/auth"); 4 | const { loginCheck, isAuth, isAdmin } = require("../middleware/auth"); 5 | 6 | router.post("/isadmin", authController.isAdmin); 7 | router.post("/signup", authController.postSignup); 8 | router.post("/signin", authController.postSignin); 9 | router.post("/user", loginCheck, isAuth, isAdmin, authController.allUser); 10 | 11 | module.exports = router; 12 | -------------------------------------------------------------------------------- /server/routes/orders.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const ordersController = require("../controller/orders"); 4 | 5 | router.get("/get-all-orders", ordersController.getAllOrders); 6 | router.post("/order-by-user", ordersController.getOrderByUser); 7 | 8 | router.post("/create-order", ordersController.postCreateOrder); 9 | router.post("/update-order", ordersController.postUpdateOrder); 10 | router.post("/delete-order", ordersController.postDeleteOrder); 11 | 12 | module.exports = router; 13 | -------------------------------------------------------------------------------- /server/routes/users.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const usersController = require("../controller/users"); 4 | 5 | router.get("/all-user", usersController.getAllUser); 6 | router.post("/signle-user", usersController.getSingleUser); 7 | 8 | router.post("/add-user", usersController.postAddUser); 9 | router.post("/edit-user", usersController.postEditUser); 10 | router.post("/delete-user", usersController.getDeleteUser); 11 | 12 | router.post("/change-password", usersController.changePassword); 13 | 14 | module.exports = router; 15 | -------------------------------------------------------------------------------- /server/models/categories.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const categorySchema = new mongoose.Schema( 4 | { 5 | cName: { 6 | type: String, 7 | required: true, 8 | }, 9 | cDescription: { 10 | type: String, 11 | required: true, 12 | }, 13 | cImage: { 14 | type: String, 15 | }, 16 | cStatus: { 17 | type: String, 18 | required: true, 19 | }, 20 | }, 21 | { timestamps: true } 22 | ); 23 | 24 | const categoryModel = mongoose.model("categories", categorySchema); 25 | module.exports = categoryModel; 26 | -------------------------------------------------------------------------------- /server/config/uploadFolderCreateScript.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | const categoriesFolder = "./public/uploads/categories"; 4 | const customizeFolder = "./public/uploads/customize"; 5 | const productsFolder = "./public/uploads/products"; 6 | 7 | const CreateAllFolder = () => { 8 | if (!fs.existsSync(categoriesFolder)) { 9 | fs.mkdirSync(categoriesFolder, { 10 | recursive: true, 11 | }); 12 | } 13 | 14 | if (!fs.existsSync(customizeFolder)) { 15 | fs.mkdirSync(customizeFolder, { 16 | recursive: true, 17 | }); 18 | } 19 | 20 | if (!fs.existsSync(productsFolder)) { 21 | fs.mkdirSync(productsFolder, { 22 | recursive: true, 23 | }); 24 | } 25 | }; 26 | 27 | module.exports = CreateAllFolder; 28 | -------------------------------------------------------------------------------- /server/routes/customize.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const customizeController = require("../controller/customize"); 4 | const multer = require("multer"); 5 | 6 | var storage = multer.diskStorage({ 7 | destination: function (req, file, cb) { 8 | cb(null, "public/uploads/customize"); 9 | }, 10 | filename: function (req, file, cb) { 11 | cb(null, Date.now() + "_" + file.originalname); 12 | }, 13 | }); 14 | 15 | const upload = multer({ storage: storage }); 16 | 17 | router.get("/get-slide-image", customizeController.getImages); 18 | router.post("/delete-slide-image", customizeController.deleteSlideImage); 19 | router.post( 20 | "/upload-slide-image", 21 | upload.single("image"), 22 | customizeController.uploadSlideImage 23 | ); 24 | router.post("/dashboard-data", customizeController.getAllData); 25 | 26 | module.exports = router; 27 | -------------------------------------------------------------------------------- /server/routes/categories.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const categoryController = require("../controller/categories"); 4 | const multer = require("multer"); 5 | const { loginCheck } = require("../middleware/auth"); 6 | 7 | // Image Upload setting 8 | var storage = multer.diskStorage({ 9 | destination: function (req, file, cb) { 10 | cb(null, "./public/uploads/categories"); 11 | }, 12 | filename: function (req, file, cb) { 13 | cb(null, Date.now() + "_" + file.originalname); 14 | }, 15 | }); 16 | 17 | const upload = multer({ storage: storage }); 18 | 19 | router.get("/all-category", categoryController.getAllCategory); 20 | router.post( 21 | "/add-category", 22 | loginCheck, 23 | upload.single("cImage"), 24 | categoryController.postAddCategory 25 | ); 26 | router.post("/edit-category", loginCheck, categoryController.postEditCategory); 27 | router.post( 28 | "/delete-category", 29 | loginCheck, 30 | categoryController.getDeleteCategory 31 | ); 32 | 33 | module.exports = router; 34 | -------------------------------------------------------------------------------- /server/config/function.js: -------------------------------------------------------------------------------- 1 | /* This all of are helper function */ 2 | const userModel = require("../models/users"); 3 | 4 | exports.toTitleCase = function (str) { 5 | return str.replace(/\w\S*/g, function (txt) { 6 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 7 | }); 8 | }; 9 | 10 | exports.validateEmail = function (mail) { 11 | if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail)) { 12 | return true; 13 | } else { 14 | return false; 15 | } 16 | }; 17 | 18 | exports.emailCheckInDatabase = async function (email) { 19 | let user = await userModel.findOne({ email: email }); 20 | user.exec((err, data) => { 21 | if (!data) { 22 | return false; 23 | } else { 24 | return true; 25 | } 26 | }); 27 | }; 28 | 29 | exports.phoneNumberCheckInDatabase = async function (phoneNumber) { 30 | let user = await userModel.findOne({ phoneNumber: phoneNumber }); 31 | user.exec((err, data) => { 32 | if (data) { 33 | return true; 34 | } else { 35 | return false; 36 | } 37 | }); 38 | }; 39 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OrganEase", 3 | "version": "Mark 1", 4 | "description": "Organ Tranfer WEbApp", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start:dev": "nodemon app.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/hasan-py/MERN_Stack_Project_Hayroo_Ecommerce" 13 | }, 14 | "author": "Hasan | https://hasan-py.github.io", 15 | "license": "ISC", 16 | "bugs": { 17 | "url": "https://github.com/hasan-py/MERN_Stack_Project_Hayroo_Ecommerce/issues" 18 | }, 19 | "homepage": "https://github.com/hasan-py/MERN_Stack_Project_Hayroo_Ecommerce#readme", 20 | "dependencies": { 21 | "bcryptjs": "^2.4.3", 22 | "braintree": "^3.0.0", 23 | "cookie-parser": "^1.4.5", 24 | "cors": "^2.8.5", 25 | "dotenv": "^8.2.0", 26 | "express": "^4.18.2", 27 | "i": "^0.3.6", 28 | "jsonwebtoken": "^8.5.1", 29 | "mongoose": "^5.9.27", 30 | "morgan": "^1.10.0", 31 | "multer": "^1.4.2", 32 | "nodemon": "^2.0.4", 33 | "npm": "^6.14.8" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /server/models/users.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const userSchema = new mongoose.Schema( 4 | { 5 | name: { 6 | type: String, 7 | required: true, 8 | maxlength: 32, 9 | }, 10 | email: { 11 | type: String, 12 | required: true, 13 | trim: true, 14 | index: { unique: true }, 15 | match: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/, 16 | }, 17 | password: { 18 | type: String, 19 | required: true, 20 | }, 21 | userRole: { 22 | type: Number, 23 | required: true, 24 | }, 25 | phoneNumber: { 26 | type: Number, 27 | }, 28 | userImage: { 29 | type: String, 30 | default: "user.png", 31 | }, 32 | verified: { 33 | type: String, 34 | default: false, 35 | }, 36 | secretKey: { 37 | type: String, 38 | default: null, 39 | }, 40 | history: { 41 | type: Array, 42 | default: [], 43 | }, 44 | }, 45 | { timestamps: true } 46 | ); 47 | 48 | const userModel = mongoose.model("users", userSchema); 49 | module.exports = userModel; 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Kartik Banshi Katkar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /server/models/orders.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const { ObjectId } = mongoose.Schema.Types; 3 | 4 | const orderSchema = new mongoose.Schema( 5 | { 6 | allProduct: [ 7 | { 8 | id: { type: ObjectId, ref: "products" }, 9 | quantitiy: Number, 10 | }, 11 | ], 12 | user: { 13 | type: ObjectId, 14 | ref: "users", 15 | required: true, 16 | }, 17 | amount: { 18 | type: Number, 19 | required: true, 20 | }, 21 | transactionId: { 22 | type: String, 23 | required: true, 24 | }, 25 | address: { 26 | type: String, 27 | required: true, 28 | }, 29 | phone: { 30 | type: Number, 31 | required: true, 32 | }, 33 | status: { 34 | type: String, 35 | default: "Not processed", 36 | enum: [ 37 | "Not processed", 38 | "Under Scrutiny", 39 | "Request Accepted", 40 | "Expired", 41 | "Cancelled", 42 | ], 43 | }, 44 | }, 45 | { timestamps: true } 46 | ); 47 | 48 | const orderModel = mongoose.model("orders", orderSchema); 49 | module.exports = orderModel; 50 | -------------------------------------------------------------------------------- /server/middleware/auth.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const { JWT_SECRET } = require("../config/keys"); 3 | const userModel = require("../models/users"); 4 | 5 | exports.loginCheck = (req, res, next) => { 6 | try { 7 | let token = req.headers.token; 8 | token = token.replace("Bearer ", ""); 9 | decode = jwt.verify(token, JWT_SECRET); 10 | req.userDetails = decode; 11 | next(); 12 | } catch (err) { 13 | res.json({ 14 | error: "You must be logged in", 15 | }); 16 | } 17 | }; 18 | 19 | exports.isAuth = (req, res, next) => { 20 | let { loggedInUserId } = req.body; 21 | if ( 22 | !loggedInUserId || 23 | !req.userDetails._id || 24 | loggedInUserId != req.userDetails._id 25 | ) { 26 | res.status(403).json({ error: "You are not authenticate" }); 27 | } 28 | next(); 29 | }; 30 | 31 | exports.isAdmin = async (req, res, next) => { 32 | try { 33 | let reqUser = await userModel.findById(req.body.loggedInUserId); 34 | // If user role 0 that's mean not admin it's customer 35 | if (reqUser.userRole === 0) { 36 | res.status(403).json({ error: "Access denied" }); 37 | } 38 | next(); 39 | } catch { 40 | res.status(404); 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /server/models/products.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | const { ObjectId } = mongoose.Schema.Types; 3 | 4 | const productSchema = new mongoose.Schema( 5 | { 6 | pName: { 7 | type: Number, 8 | required: true, 9 | }, 10 | pDescription: { 11 | type: String, 12 | required: true, 13 | }, 14 | pPrice: { 15 | type: Number, 16 | required: true, 17 | }, 18 | pSold: { 19 | type: Number, 20 | default: 0, 21 | }, 22 | pQuantity: { 23 | type: Number, 24 | default: 0, 25 | }, 26 | pCategory: { 27 | type: ObjectId, 28 | ref: "categories", 29 | }, 30 | pImages: { 31 | type: Array, 32 | required: true, 33 | }, 34 | pOffer: { 35 | type: String, 36 | default: null, 37 | }, 38 | pRatingsReviews: [ 39 | { 40 | review: String, 41 | user: { type: ObjectId, ref: "users" }, 42 | rating: String, 43 | createdAt: { 44 | type: Date, 45 | default: Date.now(), 46 | }, 47 | }, 48 | ], 49 | pStatus: { 50 | type: String, 51 | required: true, 52 | }, 53 | }, 54 | { timestamps: true } 55 | ); 56 | 57 | const productModel = mongoose.model("products", productSchema); 58 | module.exports = productModel; 59 | -------------------------------------------------------------------------------- /server/routes/products.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const productController = require("../controller/products"); 4 | const multer = require("multer"); 5 | 6 | var storage = multer.diskStorage({ 7 | destination: function (req, file, cb) { 8 | cb(null, "public/uploads/products"); 9 | }, 10 | filename: function (req, file, cb) { 11 | cb(null, Date.now() + "_" + file.originalname); 12 | }, 13 | }); 14 | 15 | const upload = multer({ storage: storage }); 16 | 17 | router.get("/all-product", productController.getAllProduct); 18 | router.post("/product-by-category", productController.getProductByCategory); 19 | router.post("/product-by-price", productController.getProductByPrice); 20 | router.post("/wish-product", productController.getWishProduct); 21 | router.post("/cart-product", productController.getCartProduct); 22 | 23 | router.post("/add-product", upload.any(), productController.postAddProduct); 24 | router.post("/edit-product", upload.any(), productController.postEditProduct); 25 | router.post("/delete-product", productController.getDeleteProduct); 26 | router.post("/single-product", productController.getSingleProduct); 27 | 28 | router.post("/add-review", productController.postAddReview); 29 | router.post("/delete-review", productController.deleteReview); 30 | 31 | module.exports = router; 32 | -------------------------------------------------------------------------------- /server/controller/braintree.js: -------------------------------------------------------------------------------- 1 | var braintree = require("braintree"); 2 | require("dotenv").config(); 3 | 4 | var gateway = new braintree.BraintreeGateway({ 5 | environment: braintree.Environment.Sandbox, 6 | merchantId: process.env.BRAINTREE_MERCHANT_ID, 7 | publicKey: process.env.BRAINTREE_PUBLIC_KEY, 8 | privateKey: process.env.BRAINTREE_PRIVATE_KEY, 9 | }); 10 | 11 | class brainTree { 12 | ganerateToken(req, res) { 13 | gateway.clientToken.generate({}, (err, response) => { 14 | if (err) { 15 | return res.json(err); 16 | } 17 | return res.json(response); 18 | }); 19 | } 20 | 21 | paymentProcess(req, res) { 22 | let { amountTotal, paymentMethod } = req.body; 23 | gateway.transaction.sale( 24 | { 25 | amount: amountTotal, 26 | paymentMethodNonce: paymentMethod, 27 | options: { 28 | submitForSettlement: true, 29 | }, 30 | }, 31 | (err, result) => { 32 | if (err) { 33 | console.error(err); 34 | return res.json(err); 35 | } 36 | 37 | if (result.success) { 38 | console.log("Transaction ID: " + result.transaction.id); 39 | return res.json(result); 40 | } else { 41 | console.error(result.message); 42 | } 43 | } 44 | ); 45 | } 46 | } 47 | 48 | const brainTreeController = new brainTree(); 49 | module.exports = brainTreeController; 50 | -------------------------------------------------------------------------------- /server/server.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const express = require("express"); 4 | const app = express(); 5 | require("dotenv").config(); 6 | const mongoose = require("mongoose"); 7 | const morgan = require("morgan"); 8 | const cookieParser = require("cookie-parser"); 9 | const cors = require("cors"); 10 | 11 | // Import Router 12 | const authRouter = require("./routes/auth"); 13 | const categoryRouter = require("./routes/categories"); 14 | const productRouter = require("./routes/products"); 15 | const brainTreeRouter = require("./routes/braintree"); 16 | const orderRouter = require("./routes/orders"); 17 | const usersRouter = require("./routes/users"); 18 | const customizeRouter = require("./routes/customize"); 19 | // Import Auth middleware for check user login or not~ 20 | const { loginCheck } = require("./middleware/auth"); 21 | const CreateAllFolder = require("./config/uploadFolderCreateScript"); 22 | 23 | /* Create All Uploads Folder if not exists | For Uploading Images */ 24 | CreateAllFolder(); 25 | 26 | // Database Connection 27 | mongoose 28 | .connect(process.env.DATABASE, { 29 | useNewUrlParser: true, 30 | useUnifiedTopology: true, 31 | useCreateIndex: true, 32 | }) 33 | .then(() => 34 | console.log( 35 | "==============Mongodb Database Connected Successfully==============" 36 | ) 37 | ) 38 | .catch((err) => console.log("Database Not Connected !!!")); 39 | 40 | // Middleware 41 | app.use(morgan("dev")); 42 | app.use(cookieParser()); 43 | app.use(cors()); 44 | app.use(express.static("public")); 45 | app.use(express.urlencoded({ extended: false })); 46 | app.use(express.json()); 47 | 48 | // Routes 49 | app.use("/api", authRouter); 50 | app.use("/api/user", usersRouter); 51 | app.use("/api/category", categoryRouter); 52 | app.use("/api/product", productRouter); 53 | app.use("/api", brainTreeRouter); 54 | app.use("/api/order", orderRouter); 55 | app.use("/api/customize", customizeRouter); 56 | 57 | // Run Server 58 | const PORT = process.env.PORT || 8000; 59 | app.listen(PORT, () => { 60 | console.log("Server is running on ", PORT); 61 | }); 62 | -------------------------------------------------------------------------------- /server/controller/customize.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const categoryModel = require("../models/categories"); 3 | const productModel = require("../models/products"); 4 | const orderModel = require("../models/orders"); 5 | const userModel = require("../models/users"); 6 | const customizeModel = require("../models/customize"); 7 | 8 | class Customize { 9 | async getImages(req, res) { 10 | try { 11 | let Images = await customizeModel.find({}); 12 | if (Images) { 13 | return res.json({ Images }); 14 | } 15 | } catch (err) { 16 | console.log(err); 17 | } 18 | } 19 | 20 | async uploadSlideImage(req, res) { 21 | let image = req.file.filename; 22 | if (!image) { 23 | return res.json({ error: "All field required" }); 24 | } 25 | try { 26 | let newCustomzie = new customizeModel({ 27 | slideImage: image, 28 | }); 29 | let save = await newCustomzie.save(); 30 | if (save) { 31 | return res.json({ success: "Image upload successfully" }); 32 | } 33 | } catch (err) { 34 | console.log(err); 35 | } 36 | } 37 | 38 | async deleteSlideImage(req, res) { 39 | let { id } = req.body; 40 | if (!id) { 41 | return res.json({ error: "All field required" }); 42 | } else { 43 | try { 44 | let deletedSlideImage = await customizeModel.findById(id); 45 | const filePath = `../server/public/uploads/customize/${deletedSlideImage.slideImage}`; 46 | 47 | let deleteImage = await customizeModel.findByIdAndDelete(id); 48 | if (deleteImage) { 49 | // Delete Image from uploads -> customizes folder 50 | fs.unlink(filePath, (err) => { 51 | if (err) { 52 | console.log(err); 53 | } 54 | return res.json({ success: "Image deleted successfully" }); 55 | }); 56 | } 57 | } catch (err) { 58 | console.log(err); 59 | } 60 | } 61 | } 62 | 63 | async getAllData(req, res) { 64 | try { 65 | let Categories = await categoryModel.find({}).count(); 66 | let Products = await productModel.find({}).count(); 67 | let Orders = await orderModel.find({}).count(); 68 | let Users = await userModel.find({}).count(); 69 | if (Categories && Products && Orders) { 70 | return res.json({ Categories, Products, Orders, Users }); 71 | } 72 | } catch (err) { 73 | console.log(err); 74 | } 75 | } 76 | } 77 | 78 | const customizeController = new Customize(); 79 | module.exports = customizeController; 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ## Getting Started 3 | 4 | These instructions will get you a copy of the project up and running on your local machine for development and testing purpose. 5 | 6 | ### Prerequisites 7 | 8 | NPM and Node.js should be installed 9 | 10 | ### Installing 11 | 12 | Installing NPM modules on both client and server folders 13 | 14 | Execute these commands from the project directory 15 | 16 | ``` 17 | cd client && npm install 18 | ``` 19 | 20 | ``` 21 | cd server && npm install 22 | ``` 23 | 24 | ### Running the app 25 | 26 | Open a terminal on server directory 27 | 28 | ``` 29 | npm start:dev 30 | ``` 31 | 32 | and open another terminal on client directory 33 | ``` 34 | npm start 35 | ``` 36 | 37 | 38 | ### Access the web app at http://localhost:3000/ 39 | 40 |
41 | 42 | ### Screenshots 43 | 44 |

45 | image 46 |

47 | 48 |

49 | image 50 |

51 | 52 |

53 | image 54 |

55 | 56 |

57 | image 58 |

59 | 60 |

61 | image 62 |

63 | 64 |

65 | image 66 |

67 | 68 |
69 | 70 | As organs are needed ASAP for operations, time is the most crucial aspect. However, the existing method to request organs from procurement centre/ transplant centres is completely manual (manual data entry, manual communication via faxes, mails, phone calls) and thus is obviously error prone and time consuming. Therefore to solve this grave issue, 'OrganEase' is proposed. 71 | 72 | The website makes the tedious manual task of categorizing different organs and making entries for each, mere clicks away. In a particular region, say n number of procurement centres and/or transplant centres exist. All of them can display the organs stored in their hypothermic storages along with their details at one time (this completely solvesthe time-consuming problem of individually calling of procurement centres one by one which is done presently). 73 | 74 | Hospitals can request organs of suitable compatibility (Blood Group, etc) via the portal itself and make a payment which serves as a token of confirmation for the transfer procedure. Thereafter, the procurement confirms the request from their side. 75 | 76 | Due to the intricate nature of organ transplantation, a manual override feature is available to modify the organ status in case of unexpected circumstances. 77 | 78 | -------------------------------------------------------------------------------- /server/controller/orders.js: -------------------------------------------------------------------------------- 1 | const orderModel = require("../models/orders"); 2 | 3 | class Order { 4 | async getAllOrders(req, res) { 5 | try { 6 | let Orders = await orderModel 7 | .find({}) 8 | .populate("allProduct.id", "pName pImages pPrice") 9 | .populate("user", "name email") 10 | .sort({ _id: -1 }); 11 | if (Orders) { 12 | return res.json({ Orders }); 13 | } 14 | } catch (err) { 15 | console.log(err); 16 | } 17 | } 18 | 19 | async getOrderByUser(req, res) { 20 | let { uId } = req.body; 21 | if (!uId) { 22 | return res.json({ message: "All filled must be required" }); 23 | } else { 24 | try { 25 | let Order = await orderModel 26 | .find({ user: uId }) 27 | .populate("allProduct.id", "pName pImages pPrice") 28 | .populate("user", "name email") 29 | .sort({ _id: -1 }); 30 | if (Order) { 31 | return res.json({ Order }); 32 | } 33 | } catch (err) { 34 | console.log(err); 35 | } 36 | } 37 | } 38 | 39 | async postCreateOrder(req, res) { 40 | let { allProduct, user, amount, transactionId, address, phone } = req.body; 41 | if ( 42 | !allProduct || 43 | !user || 44 | !amount || 45 | !transactionId || 46 | !address || 47 | !phone 48 | ) { 49 | return res.json({ message: "All filled must be required" }); 50 | } else { 51 | try { 52 | let newOrder = new orderModel({ 53 | allProduct, 54 | user, 55 | amount, 56 | transactionId, 57 | address, 58 | phone, 59 | }); 60 | let save = await newOrder.save(); 61 | if (save) { 62 | return res.json({ success: "Order created successfully" }); 63 | } 64 | } catch (err) { 65 | return res.json({ error: error }); 66 | } 67 | } 68 | } 69 | 70 | async postUpdateOrder(req, res) { 71 | let { oId, status } = req.body; 72 | if (!oId || !status) { 73 | return res.json({ message: "All filled must be required" }); 74 | } else { 75 | let currentOrder = orderModel.findByIdAndUpdate(oId, { 76 | status: status, 77 | updatedAt: Date.now(), 78 | }); 79 | currentOrder.exec((err, result) => { 80 | if (err) console.log(err); 81 | return res.json({ success: "Order updated successfully" }); 82 | }); 83 | } 84 | } 85 | 86 | async postDeleteOrder(req, res) { 87 | let { oId } = req.body; 88 | if (!oId) { 89 | return res.json({ error: "All filled must be required" }); 90 | } else { 91 | try { 92 | let deleteOrder = await orderModel.findByIdAndDelete(oId); 93 | if (deleteOrder) { 94 | return res.json({ success: "Order deleted successfully" }); 95 | } 96 | } catch (error) { 97 | console.log(error); 98 | } 99 | } 100 | } 101 | } 102 | 103 | const ordersController = new Order(); 104 | module.exports = ordersController; 105 | -------------------------------------------------------------------------------- /server/controller/categories.js: -------------------------------------------------------------------------------- 1 | const { toTitleCase } = require("../config/function"); 2 | const categoryModel = require("../models/categories"); 3 | const fs = require("fs"); 4 | 5 | class Category { 6 | async getAllCategory(req, res) { 7 | try { 8 | let Categories = await categoryModel.find({}).sort({ _id: -1 }); 9 | if (Categories) { 10 | return res.json({ Categories }); 11 | } 12 | } catch (err) { 13 | console.log(err); 14 | } 15 | } 16 | 17 | async postAddCategory(req, res) { 18 | let { cName, cDescription, cStatus } = req.body; 19 | let cImage = req.file.filename; 20 | const filePath = `../server/public/uploads/categories/${cImage}`; 21 | 22 | if (!cName || !cDescription || !cStatus || !cImage) { 23 | fs.unlink(filePath, (err) => { 24 | if (err) { 25 | console.log(err); 26 | } 27 | return res.json({ error: "All filled must be required" }); 28 | }); 29 | } else { 30 | cName = toTitleCase(cName); 31 | try { 32 | let checkCategoryExists = await categoryModel.findOne({ cName: cName }); 33 | if (checkCategoryExists) { 34 | fs.unlink(filePath, (err) => { 35 | if (err) { 36 | console.log(err); 37 | } 38 | return res.json({ error: "Category already exists" }); 39 | }); 40 | } else { 41 | let newCategory = new categoryModel({ 42 | cName, 43 | cDescription, 44 | cStatus, 45 | cImage, 46 | }); 47 | await newCategory.save((err) => { 48 | if (!err) { 49 | return res.json({ success: "Category created successfully" }); 50 | } 51 | }); 52 | } 53 | } catch (err) { 54 | console.log(err); 55 | } 56 | } 57 | } 58 | 59 | async postEditCategory(req, res) { 60 | let { cId, cDescription, cStatus } = req.body; 61 | if (!cId || !cDescription || !cStatus) { 62 | return res.json({ error: "All filled must be required" }); 63 | } 64 | try { 65 | let editCategory = categoryModel.findByIdAndUpdate(cId, { 66 | cDescription, 67 | cStatus, 68 | updatedAt: Date.now(), 69 | }); 70 | let edit = await editCategory.exec(); 71 | if (edit) { 72 | return res.json({ success: "Category edit successfully" }); 73 | } 74 | } catch (err) { 75 | console.log(err); 76 | } 77 | } 78 | 79 | async getDeleteCategory(req, res) { 80 | let { cId } = req.body; 81 | if (!cId) { 82 | return res.json({ error: "All filled must be required" }); 83 | } else { 84 | try { 85 | let deletedCategoryFile = await categoryModel.findById(cId); 86 | const filePath = `../server/public/uploads/categories/${deletedCategoryFile.cImage}`; 87 | 88 | let deleteCategory = await categoryModel.findByIdAndDelete(cId); 89 | if (deleteCategory) { 90 | // Delete Image from uploads -> categories folder 91 | fs.unlink(filePath, (err) => { 92 | if (err) { 93 | console.log(err); 94 | } 95 | return res.json({ success: "Category deleted successfully" }); 96 | }); 97 | } 98 | } catch (err) { 99 | console.log(err); 100 | } 101 | } 102 | } 103 | } 104 | 105 | const categoryController = new Category(); 106 | module.exports = categoryController; 107 | -------------------------------------------------------------------------------- /server/controller/users.js: -------------------------------------------------------------------------------- 1 | const userModel = require("../models/users"); 2 | const bcrypt = require("bcryptjs"); 3 | 4 | class User { 5 | async getAllUser(req, res) { 6 | try { 7 | let Users = await userModel 8 | .find({}) 9 | .populate("allProduct.id", "pName pImages pPrice") 10 | .populate("user", "name email") 11 | .sort({ _id: -1 }); 12 | if (Users) { 13 | return res.json({ Users }); 14 | } 15 | } catch (err) { 16 | console.log(err); 17 | } 18 | } 19 | 20 | async getSingleUser(req, res) { 21 | let { uId } = req.body; 22 | if (!uId) { 23 | return res.json({ error: "All filled must be required" }); 24 | } else { 25 | try { 26 | let User = await userModel 27 | .findById(uId) 28 | .select("name email phoneNumber userImage updatedAt createdAt"); 29 | if (User) { 30 | return res.json({ User }); 31 | } 32 | } catch (err) { 33 | console.log(err); 34 | } 35 | } 36 | } 37 | 38 | async postAddUser(req, res) { 39 | let { allProduct, user, amount, transactionId, address, phone } = req.body; 40 | if ( 41 | !allProduct || 42 | !user || 43 | !amount || 44 | !transactionId || 45 | !address || 46 | !phone 47 | ) { 48 | return res.json({ message: "All filled must be required" }); 49 | } else { 50 | try { 51 | let newUser = new userModel({ 52 | allProduct, 53 | user, 54 | amount, 55 | transactionId, 56 | address, 57 | phone, 58 | }); 59 | let save = await newUser.save(); 60 | if (save) { 61 | return res.json({ success: "User created successfully" }); 62 | } 63 | } catch (err) { 64 | return res.json({ error: error }); 65 | } 66 | } 67 | } 68 | 69 | async postEditUser(req, res) { 70 | let { uId, name, phoneNumber } = req.body; 71 | if (!uId || !name || !phoneNumber) { 72 | return res.json({ message: "All filled must be required" }); 73 | } else { 74 | let currentUser = userModel.findByIdAndUpdate(uId, { 75 | name: name, 76 | phoneNumber: phoneNumber, 77 | updatedAt: Date.now(), 78 | }); 79 | currentUser.exec((err, result) => { 80 | if (err) console.log(err); 81 | return res.json({ success: "User updated successfully" }); 82 | }); 83 | } 84 | } 85 | 86 | async getDeleteUser(req, res) { 87 | let { oId, status } = req.body; 88 | if (!oId || !status) { 89 | return res.json({ message: "All filled must be required" }); 90 | } else { 91 | let currentUser = userModel.findByIdAndUpdate(oId, { 92 | status: status, 93 | updatedAt: Date.now(), 94 | }); 95 | currentUser.exec((err, result) => { 96 | if (err) console.log(err); 97 | return res.json({ success: "User updated successfully" }); 98 | }); 99 | } 100 | } 101 | 102 | async changePassword(req, res) { 103 | let { uId, oldPassword, newPassword } = req.body; 104 | if (!uId || !oldPassword || !newPassword) { 105 | return res.json({ message: "All filled must be required" }); 106 | } else { 107 | const data = await userModel.findOne({ _id: uId }); 108 | if (!data) { 109 | return res.json({ 110 | error: "Invalid user", 111 | }); 112 | } else { 113 | const oldPassCheck = await bcrypt.compare(oldPassword, data.password); 114 | if (oldPassCheck) { 115 | newPassword = bcrypt.hashSync(newPassword, 10); 116 | let passChange = userModel.findByIdAndUpdate(uId, { 117 | password: newPassword, 118 | }); 119 | passChange.exec((err, result) => { 120 | if (err) console.log(err); 121 | return res.json({ success: "Password updated successfully" }); 122 | }); 123 | } else { 124 | return res.json({ 125 | error: "Your old password is wrong!!", 126 | }); 127 | } 128 | } 129 | } 130 | } 131 | } 132 | 133 | const ordersController = new User(); 134 | module.exports = ordersController; 135 | -------------------------------------------------------------------------------- /server/controller/auth.js: -------------------------------------------------------------------------------- 1 | const { toTitleCase, validateEmail } = require("../config/function"); 2 | const bcrypt = require("bcryptjs"); 3 | const userModel = require("../models/users"); 4 | const jwt = require("jsonwebtoken"); 5 | const { JWT_SECRET } = require("../config/keys"); 6 | 7 | class Auth { 8 | async isAdmin(req, res) { 9 | let { loggedInUserId } = req.body; 10 | try { 11 | let loggedInUserRole = await userModel.findById(loggedInUserId); 12 | res.json({ role: loggedInUserRole.userRole }); 13 | } catch { 14 | res.status(404); 15 | } 16 | } 17 | 18 | async allUser(req, res) { 19 | try { 20 | let allUser = await userModel.find({}); 21 | res.json({ users: allUser }); 22 | } catch { 23 | res.status(404); 24 | } 25 | } 26 | 27 | /* User Registration/Signup controller */ 28 | async postSignup(req, res) { 29 | let { name, email, password, cPassword } = req.body; 30 | let error = {}; 31 | if (!name || !email || !password || !cPassword) { 32 | error = { 33 | ...error, 34 | name: "Filed must not be empty", 35 | email: "Filed must not be empty", 36 | password: "Filed must not be empty", 37 | cPassword: "Filed must not be empty", 38 | }; 39 | return res.json({ error }); 40 | } 41 | if (name.length < 3 || name.length > 25) { 42 | error = { ...error, name: "Name must be 3-25 charecter" }; 43 | return res.json({ error }); 44 | } else { 45 | if (validateEmail(email)) { 46 | name = toTitleCase(name); 47 | if ((password.length > 255) | (password.length < 8)) { 48 | error = { 49 | ...error, 50 | password: "Password must be 8 charecter", 51 | name: "", 52 | email: "", 53 | }; 54 | return res.json({ error }); 55 | } else { 56 | // If Email & Number exists in Database then: 57 | try { 58 | password = bcrypt.hashSync(password, 10); 59 | const data = await userModel.findOne({ email: email }); 60 | if (data) { 61 | error = { 62 | ...error, 63 | password: "", 64 | name: "", 65 | email: "Email already exists", 66 | }; 67 | return res.json({ error }); 68 | } else { 69 | let newUser = new userModel({ 70 | name, 71 | email, 72 | password, 73 | // ========= Here role 1 for Procurement signup role 0 for Hospital signup ========= 74 | userRole: 1, // Field Name change to userRole from role 75 | }); 76 | newUser 77 | .save() 78 | .then((data) => { 79 | return res.json({ 80 | success: "Account create successfully. Please login", 81 | }); 82 | }) 83 | .catch((err) => { 84 | console.log(err); 85 | }); 86 | } 87 | } catch (err) { 88 | console.log(err); 89 | } 90 | } 91 | } else { 92 | error = { 93 | ...error, 94 | password: "", 95 | name: "", 96 | email: "Email is not valid", 97 | }; 98 | return res.json({ error }); 99 | } 100 | } 101 | } 102 | 103 | /* User Login/Signin controller */ 104 | async postSignin(req, res) { 105 | let { email, password } = req.body; 106 | if (!email || !password) { 107 | return res.json({ 108 | error: "Fields must not be empty", 109 | }); 110 | } 111 | try { 112 | const data = await userModel.findOne({ email: email }); 113 | if (!data) { 114 | return res.json({ 115 | error: "Invalid email or password", 116 | }); 117 | } else { 118 | const login = await bcrypt.compare(password, data.password); 119 | if (login) { 120 | const token = jwt.sign( 121 | { _id: data._id, role: data.userRole }, 122 | JWT_SECRET 123 | ); 124 | const encode = jwt.verify(token, JWT_SECRET); 125 | return res.json({ 126 | token: token, 127 | user: encode, 128 | }); 129 | } else { 130 | return res.json({ 131 | error: "Invalid email or password", 132 | }); 133 | } 134 | } 135 | } catch (err) { 136 | console.log(err); 137 | } 138 | } 139 | } 140 | 141 | const authController = new Auth(); 142 | module.exports = authController; 143 | -------------------------------------------------------------------------------- /server/controller/products.js: -------------------------------------------------------------------------------- 1 | const productModel = require("../models/products"); 2 | const fs = require("fs"); 3 | const path = require("path"); 4 | 5 | class Product { 6 | // Delete Image from uploads -> products folder 7 | static deleteImages(images, mode) { 8 | var basePath = 9 | path.resolve(__dirname + "../../") + "/public/uploads/products/"; 10 | console.log(basePath); 11 | for (var i = 0; i < images.length; i++) { 12 | let filePath = ""; 13 | if (mode == "file") { 14 | filePath = basePath + `${images[i].filename}`; 15 | } else { 16 | filePath = basePath + `${images[i]}`; 17 | } 18 | console.log(filePath); 19 | if (fs.existsSync(filePath)) { 20 | console.log("Exists image"); 21 | } 22 | fs.unlink(filePath, (err) => { 23 | if (err) { 24 | return err; 25 | } 26 | }); 27 | } 28 | } 29 | 30 | async getAllProduct(req, res) { 31 | try { 32 | let Products = await productModel 33 | .find({}) 34 | .populate("pCategory", "_id cName") 35 | .sort({ _id: -1 }); 36 | if (Products) { 37 | return res.json({ Products }); 38 | } 39 | } catch (err) { 40 | console.log(err); 41 | } 42 | } 43 | 44 | async postAddProduct(req, res) { 45 | let { pName, pDescription, pPrice, pQuantity, pCategory, pOffer, pStatus } = 46 | req.body; 47 | let images = req.files; 48 | // Validation 49 | if ( 50 | !pName | 51 | !pDescription | 52 | !pPrice | 53 | !pQuantity | 54 | !pCategory | 55 | !pOffer | 56 | !pStatus 57 | ) { 58 | Product.deleteImages(images, "file"); 59 | return res.json({ error: "All filled must be required" }); 60 | } 61 | // Validate Name and description 62 | else if (pName.length > 255 || pDescription.length > 3000) { 63 | Product.deleteImages(images, "file"); 64 | return res.json({ 65 | error: "Name 255 & Description must not be 3000 charecter long", 66 | }); 67 | } 68 | // Validate Images 69 | else if (images.length !== 2) { 70 | Product.deleteImages(images, "file"); 71 | return res.json({ error: "Must need to provide 2 images" }); 72 | } else { 73 | try { 74 | let allImages = []; 75 | for (const img of images) { 76 | allImages.push(img.filename); 77 | } 78 | let newProduct = new productModel({ 79 | pImages: allImages, 80 | pName, 81 | pDescription, 82 | pPrice, 83 | pQuantity, 84 | pCategory, 85 | pOffer, 86 | pStatus, 87 | }); 88 | let save = await newProduct.save(); 89 | if (save) { 90 | return res.json({ success: "Product created successfully" }); 91 | } 92 | } catch (err) { 93 | console.log(err); 94 | } 95 | } 96 | } 97 | 98 | async postEditProduct(req, res) { 99 | let { 100 | pId, 101 | pName, 102 | pDescription, 103 | pPrice, 104 | pQuantity, 105 | pCategory, 106 | pOffer, 107 | pStatus, 108 | pImages, 109 | } = req.body; 110 | let editImages = req.files; 111 | 112 | // Validate other fileds 113 | if ( 114 | !pId | 115 | !pName | 116 | !pDescription | 117 | !pPrice | 118 | !pQuantity | 119 | !pCategory | 120 | !pOffer | 121 | !pStatus 122 | ) { 123 | return res.json({ error: "All filled must be required" }); 124 | } 125 | // Validate Name and description 126 | else if (pName.length > 255 || pDescription.length > 3000) { 127 | return res.json({ 128 | error: "Name 255 & Description must not be 3000 charecter long", 129 | }); 130 | } 131 | // Validate Update Images 132 | else if (editImages && editImages.length == 1) { 133 | Product.deleteImages(editImages, "file"); 134 | return res.json({ error: "Must need to provide 2 images" }); 135 | } else { 136 | let editData = { 137 | pName, 138 | pDescription, 139 | pPrice, 140 | pQuantity, 141 | pCategory, 142 | pOffer, 143 | pStatus, 144 | }; 145 | if (editImages.length == 2) { 146 | let allEditImages = []; 147 | for (const img of editImages) { 148 | allEditImages.push(img.filename); 149 | } 150 | editData = { ...editData, pImages: allEditImages }; 151 | Product.deleteImages(pImages.split(","), "string"); 152 | } 153 | try { 154 | let editProduct = productModel.findByIdAndUpdate(pId, editData); 155 | editProduct.exec((err) => { 156 | if (err) console.log(err); 157 | return res.json({ success: "Product edit successfully" }); 158 | }); 159 | } catch (err) { 160 | console.log(err); 161 | } 162 | } 163 | } 164 | 165 | async getDeleteProduct(req, res) { 166 | let { pId } = req.body; 167 | if (!pId) { 168 | return res.json({ error: "All filled must be required" }); 169 | } else { 170 | try { 171 | let deleteProductObj = await productModel.findById(pId); 172 | let deleteProduct = await productModel.findByIdAndDelete(pId); 173 | if (deleteProduct) { 174 | // Delete Image from uploads -> products folder 175 | Product.deleteImages(deleteProductObj.pImages, "string"); 176 | return res.json({ success: "Product deleted successfully" }); 177 | } 178 | } catch (err) { 179 | console.log(err); 180 | } 181 | } 182 | } 183 | 184 | async getSingleProduct(req, res) { 185 | let { pId } = req.body; 186 | if (!pId) { 187 | return res.json({ error: "All filled must be required" }); 188 | } else { 189 | try { 190 | let singleProduct = await productModel 191 | .findById(pId) 192 | .populate("pCategory", "cName") 193 | .populate("pRatingsReviews.user", "name email userImage"); 194 | if (singleProduct) { 195 | return res.json({ Product: singleProduct }); 196 | } 197 | } catch (err) { 198 | console.log(err); 199 | } 200 | } 201 | } 202 | 203 | async getProductByCategory(req, res) { 204 | let { catId } = req.body; 205 | if (!catId) { 206 | return res.json({ error: "All filled must be required" }); 207 | } else { 208 | try { 209 | let products = await productModel 210 | .find({ pCategory: catId }) 211 | .populate("pCategory", "cName"); 212 | if (products) { 213 | return res.json({ Products: products }); 214 | } 215 | } catch (err) { 216 | return res.json({ error: "Search product wrong" }); 217 | } 218 | } 219 | } 220 | 221 | async getProductByPrice(req, res) { 222 | let { price } = req.body; 223 | if (!price) { 224 | return res.json({ error: "All filled must be required" }); 225 | } else { 226 | try { 227 | let products = await productModel 228 | .find({ pPrice: { $lt: price } }) 229 | .populate("pCategory", "cName") 230 | .sort({ pPrice: -1 }); 231 | if (products) { 232 | return res.json({ Products: products }); 233 | } 234 | } catch (err) { 235 | return res.json({ error: "Filter product wrong" }); 236 | } 237 | } 238 | } 239 | 240 | async getWishProduct(req, res) { 241 | let { productArray } = req.body; 242 | if (!productArray) { 243 | return res.json({ error: "All filled must be required" }); 244 | } else { 245 | try { 246 | let wishProducts = await productModel.find({ 247 | _id: { $in: productArray }, 248 | }); 249 | if (wishProducts) { 250 | return res.json({ Products: wishProducts }); 251 | } 252 | } catch (err) { 253 | return res.json({ error: "Filter product wrong" }); 254 | } 255 | } 256 | } 257 | 258 | async getCartProduct(req, res) { 259 | let { productArray } = req.body; 260 | if (!productArray) { 261 | return res.json({ error: "All filled must be required" }); 262 | } else { 263 | try { 264 | let cartProducts = await productModel.find({ 265 | _id: { $in: productArray }, 266 | }); 267 | if (cartProducts) { 268 | return res.json({ Products: cartProducts }); 269 | } 270 | } catch (err) { 271 | return res.json({ error: "Cart product wrong" }); 272 | } 273 | } 274 | } 275 | 276 | async postAddReview(req, res) { 277 | let { pId, uId, rating, review } = req.body; 278 | if (!pId || !rating || !review || !uId) { 279 | return res.json({ error: "All filled must be required" }); 280 | } else { 281 | let checkReviewRatingExists = await productModel.findOne({ _id: pId }); 282 | if (checkReviewRatingExists.pRatingsReviews.length > 0) { 283 | checkReviewRatingExists.pRatingsReviews.map((item) => { 284 | if (item.user === uId) { 285 | return res.json({ error: "Your already reviewd the product" }); 286 | } else { 287 | try { 288 | let newRatingReview = productModel.findByIdAndUpdate(pId, { 289 | $push: { 290 | pRatingsReviews: { 291 | review: review, 292 | user: uId, 293 | rating: rating, 294 | }, 295 | }, 296 | }); 297 | newRatingReview.exec((err, result) => { 298 | if (err) { 299 | console.log(err); 300 | } 301 | return res.json({ success: "Thanks for your review" }); 302 | }); 303 | } catch (err) { 304 | return res.json({ error: "Cart product wrong" }); 305 | } 306 | } 307 | }); 308 | } else { 309 | try { 310 | let newRatingReview = productModel.findByIdAndUpdate(pId, { 311 | $push: { 312 | pRatingsReviews: { review: review, user: uId, rating: rating }, 313 | }, 314 | }); 315 | newRatingReview.exec((err, result) => { 316 | if (err) { 317 | console.log(err); 318 | } 319 | return res.json({ success: "Thanks for your review" }); 320 | }); 321 | } catch (err) { 322 | return res.json({ error: "Cart product wrong" }); 323 | } 324 | } 325 | } 326 | } 327 | 328 | async deleteReview(req, res) { 329 | let { rId, pId } = req.body; 330 | if (!rId) { 331 | return res.json({ message: "All filled must be required" }); 332 | } else { 333 | try { 334 | let reviewDelete = productModel.findByIdAndUpdate(pId, { 335 | $pull: { pRatingsReviews: { _id: rId } }, 336 | }); 337 | reviewDelete.exec((err, result) => { 338 | if (err) { 339 | console.log(err); 340 | } 341 | return res.json({ success: "Your review is deleted" }); 342 | }); 343 | } catch (err) { 344 | console.log(err); 345 | } 346 | } 347 | } 348 | } 349 | 350 | const productController = new Product(); 351 | module.exports = productController; 352 | --------------------------------------------------------------------------------