From 2dd2a08b516ef815aac311d4ff092058fccd46fc Mon Sep 17 00:00:00 2001 From: pawan-dot <71133473+pawan-dot@users.noreply.github.com> Date: Tue, 24 Jan 2023 09:40:04 +0530 Subject: [PATCH] city state etc --- Utils/cloudinary.js | 42 +- Utils/jwtToken.js | 8 +- Utils/reusableApi.js | 188 ++++++++ app.js | 14 +- middlewares/auth.js | 2 +- package-lock.json | 14 + package.json | 1 + .../setting/Configration/Config_controller.js | 410 ++++++++++++++++++ .../setting/Configration/Config_model.js | 14 + .../setting/Configration/Config_routes.js | 37 ++ .../Configration/config_client_routes.js | 7 + resources/setting/city/city_controller.js | 61 +++ resources/setting/city/city_model.js | 16 + resources/setting/city/city_routes.js | 21 + resources/setting/state/state_controller.js | 47 ++ resources/setting/state/state_model.js | 11 + resources/setting/state/state_routes.js | 19 + .../user}/userController.js | 120 ++--- {models => resources/user}/userModel.js | 4 +- {routes => resources/user}/userRoute.js | 4 +- 20 files changed, 974 insertions(+), 66 deletions(-) create mode 100644 Utils/reusableApi.js create mode 100644 resources/setting/Configration/Config_controller.js create mode 100644 resources/setting/Configration/Config_model.js create mode 100644 resources/setting/Configration/Config_routes.js create mode 100644 resources/setting/Configration/config_client_routes.js create mode 100644 resources/setting/city/city_controller.js create mode 100644 resources/setting/city/city_model.js create mode 100644 resources/setting/city/city_routes.js create mode 100644 resources/setting/state/state_controller.js create mode 100644 resources/setting/state/state_model.js create mode 100644 resources/setting/state/state_routes.js rename {controllers => resources/user}/userController.js (68%) rename {models => resources/user}/userModel.js (93%) rename {routes => resources/user}/userRoute.js (84%) diff --git a/Utils/cloudinary.js b/Utils/cloudinary.js index cc3afae..dc46c05 100644 --- a/Utils/cloudinary.js +++ b/Utils/cloudinary.js @@ -1,7 +1,47 @@ -import cloudinary from "cloudinary" +import cloudinary from "cloudinary"; +import { CloudinaryStorage } from "multer-storage-cloudinary"; +import multer from "multer"; +import path from "path" cloudinary.v2.config({ cloud_name: process.env.CLOUDINARY_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, }); + + + + +const storage = new CloudinaryStorage({ + cloudinary: cloudinary, + params: { + folder: "Atp", + }, +}); + +// export const upload = multer({ +// storage: multer.diskStorage({}), +// fileFilter: (req, file, cb) => { +// let ext = path.extname(file.originalname); +// // if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") { +// // cb(new Error("File type is not supported"), false); +// // return; +// // } +// cb(null, true); +// }, +// }); + + + +export const upload = multer({ + storage: multer.diskStorage({}), + fileFilter: (req, file, cb) => { + let ext = path.extname(file.originalname); + if (ext !== ".jpg" && ext !== ".jpeg" && ext !== ".png") { + cb(new Error("File type not supported!"), false) + return + } + cb(null, true); + } +}); + export default cloudinary; \ No newline at end of file diff --git a/Utils/jwtToken.js b/Utils/jwtToken.js index f0a5a14..3311de3 100644 --- a/Utils/jwtToken.js +++ b/Utils/jwtToken.js @@ -15,10 +15,10 @@ const sendToken = (user, statusCode, res) => { // res.status(statusCode).json({ success: true, - userId: user._id, - userName: user.name, - userEmail: user.email, - userPhone: user.phone, + // userId: user._id, + // userName: user.name, + // userEmail: user.email, + // userPhone: user.phone, token, }); }; diff --git a/Utils/reusableApi.js b/Utils/reusableApi.js new file mode 100644 index 0000000..757b869 --- /dev/null +++ b/Utils/reusableApi.js @@ -0,0 +1,188 @@ +/* Guys Im creating this resuable CRUD funtions so that you no need to write these + things again and again you have to just pass them in arguments + feel free to make any changes here if you want to improve the code + here:- + remember you can import this in controllers ONLY not anywhere else!!! + Entity to pass is Schema Name which you import in controller e.g import { CalendarEvent } from "./calendarEventModel"; so Entity will be CalendarEvent in this case + by default I have kept the boolean arguments as false. you can pass it as true whenever needed. + +*/ +//author: Tazim K Madre + +//imports +import cloudinary from "./cloudinary.js"; + +const getEntities = async ( + req, + res, + Entity, + isUser = false, + criteria = false, + log = false +) => { + //pagination added filter can change so it needs to be dynamic will add it in future + let { page, limit } = req.query; + page = page * 1; + limit = limit * 1; + let limitVal = limit; + let skipeValue = (page - 1) * limitVal; + if (isUser) { + if (!req.user) return res.status(400).json({ message: "User not found." }); + } + try { + if (criteria) { + const entity = await Entity.find({ createdBy: req.user._id }); + return res.status(200).json({ status: "OK", data: entity }); + } + const totalRecords = await Entity.countDocuments({}); + const entity = await Entity.find({}) + .sort({ createdAt: -1 }) + .limit(limitVal) + .skip(skipeValue); + res + .status(200) + .json({ status: "OK", totalRecords: totalRecords, data: entity }); + } catch (err) { + log && console.log(err); + return res.status(500).json({ message: "Unable to fetch." }); + } +}; + +const getEntity = async (req, res, Entity, isUser = false, log = false) => { + if (isUser) { + 1; + if (!req.user) return res.status(400).json({ message: "User not found." }); + } + try { + const entity = await Entity.findById(req.params.id); + if (!entity) { + return res.status(400).json({ message: "Not found" }); + } + res.status(200).json({ status: "OK", data: entity }); + } catch (err) { + log && console.log(err); + return res.status(500).json({ message: "Unable to find" }); + } +}; + +const addEntity = async ( + req, + res, + Entity, + isUser = false, + isSingleImage = false, + isMultipleImages = false, + isCreatedBy = false, + log = false +) => { + if (isUser) { + if (!req.user) return res.status(400).json({ message: "User not found." }); + } + try { + if (isCreatedBy) { + req.body.createdBy = req.user._id; + } + if (isSingleImage) { + if (req.file) { + const result = await cloudinary.v2.uploader.upload(req.file.path); + const image = { url: result.secure_url, public_id: result.public_id }; + req.body.image = image; + } + } + if (isMultipleImages) { + const imageUrlList = []; + for (var i = 0; i < req.files.length; i++) { + const locaFilePath = req.files[i].path; + const result = await cloudinary.v2.uploader.upload(locaFilePath); + imageUrlList.push({ url: result.url, public_id: result.public_id }); + } + req.body.files = imageUrlList; + } + const entity = await Entity.create(req.body); + res.status(200).json({ status: "OK", data: entity }); + } catch (err) { + log && console.log(err); + return res.status(500).json({ message: "Unable to create." }); + } +}; + +const updateEntity = async ( + req, + res, + Entity, + isUser = false, + isSingleImage = false, + isMultipleImages = false, + log = false +) => { + if (isUser) { + if (!req.user) return res.status(400).json({ message: "User not found." }); + } + let entity = await Entity.findById(req.params.id); + if (!entity) { + return res.status(400).json({ message: "Not found" }); + } + try { + if (isSingleImage) { + await cloudinary.v2.uploader.destroy(req.body.public_id); + if (req.file) { + const result = await cloudinary.v2.uploader.upload(req.file.path); + const image = { url: result.url, public_id: result.public_id }; + req.body.image = image; + } + } + if (isMultipleImages) { + for (let i = 0; i < req.body.publicIdArray; i++) { + await cloudinary.v2.uploader.destroy(req.body.publicIdArray[i]); + } + const imageUrlList = []; + for (var i = 0; i < req.files.length; i++) { + const locaFilePath = req.files[i].path; + const result = await cloudinary.v2.uploader.upload(locaFilePath); + imageUrlList.push({ url: result.url, public_id: result.public_id }); + } + req.body.files = imageUrlList; + } + entity = await Entity.findByIdAndUpdate(req.params.id, req.body, { + new: true, + }); + res.status(200).json({ status: "OK", data: entity }); + } catch (err) { + log && console.log(err); + return res.status(500).json({ message: "Unable to update." }); + } +}; + +const deleteEntity = async ( + req, + res, + Entity, + isUser = false, + isSingleImage = false, + isMultipleImages = false, + log = false +) => { + if (isUser) { + if (!req.user) return res.status(400).json({ message: "User not found." }); + } + // if (isSingleImage) { + // req.body.imageUrl = req.file.location; + // } + try { + // if (isSingleImage) { + // await cloudinary.v2.uploader.destroy(entity.image.public_id); + // } + // if (isMultipleImages) { + // for (let i = 0; i < entity.files.length; i++) { + // await cloudinary.v2.uploader.destroy(entity.files[i].public_id); + // } + // } + await Entity.deleteOne({ _id: req.params.id }); + res.status(200).json({ status: "OK", message: "Deleted Successfully" }); + } catch (err) { + log && console.log(err); + return res.status(500).json({ message: "Unable to delete" }); + } +}; + +export { getEntities, getEntity, addEntity, updateEntity, deleteEntity }; diff --git a/app.js b/app.js index 46e57ec..60982d8 100644 --- a/app.js +++ b/app.js @@ -21,7 +21,19 @@ app.use(fileUpload({ })); //auth -import user from "./routes/userRoute.js" +import user from "./resources/user/userRoute.js" app.use("/api/v1/", user); +//state +import StateRouter from "./resources/setting/state/state_routes.js"; +app.use("/api/state", StateRouter); + +//city +import CityRouter from "./resources/setting/city/city_routes.js"; +app.use("/api/city", CityRouter); + +//config +import ConfigRouter from "./resources/setting/Configration/Config_routes.js"; + +app.use("/api/config", ConfigRouter); export default app; \ No newline at end of file diff --git a/middlewares/auth.js b/middlewares/auth.js index ee69600..8376b20 100644 --- a/middlewares/auth.js +++ b/middlewares/auth.js @@ -1,4 +1,4 @@ -import User from "../models/userModel.js"; +import User from "../resources/user/userModel.js"; import jwt from "jsonwebtoken"; import ErrorHander from "../Utils/errorhander.js" diff --git a/package-lock.json b/package-lock.json index 793d7e6..1274ff0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "jsonwebtoken": "^8.5.1", "mongoose": "^6.3.5", "multer": "^1.4.5-lts.1", + "multer-storage-cloudinary": "^4.0.0", "nodemailer": "^6.7.5", "secure-random-password": "^0.2.3", "validator": "^13.7.0" @@ -1313,6 +1314,14 @@ "node": ">= 6.0.0" } }, + "node_modules/multer-storage-cloudinary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "peerDependencies": { + "cloudinary": "^1.21.0" + } + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -2957,6 +2966,11 @@ "xtend": "^4.0.0" } }, + "multer-storage-cloudinary": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multer-storage-cloudinary/-/multer-storage-cloudinary-4.0.0.tgz", + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==" + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", diff --git a/package.json b/package.json index 1546c9e..9ba6e41 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "jsonwebtoken": "^8.5.1", "mongoose": "^6.3.5", "multer": "^1.4.5-lts.1", + "multer-storage-cloudinary": "^4.0.0", "nodemailer": "^6.7.5", "secure-random-password": "^0.2.3", "validator": "^13.7.0" diff --git a/resources/setting/Configration/Config_controller.js b/resources/setting/Configration/Config_controller.js new file mode 100644 index 0000000..0f4c964 --- /dev/null +++ b/resources/setting/Configration/Config_controller.js @@ -0,0 +1,410 @@ +import { Config } from "./Config_model.js"; +import cloudinary from "../../../Utils/cloudinary.js"; +// // Add GST +// const addGST = async (req, res) => { +// const { gst } = req.body; +// try { +// if (!gst) { +// return res.status(400).json({ +// status: "failed", +// message: "Please Provide Valid GST Value", +// }); +// } +// const configuration = await Config.find(); + +// if (configuration.length === 0) { +// const createGst = await Config.create({ +// gst, +// }); + +// if (createGst) { +// return res.status(201).json({ +// status: "success", +// message: "GST Created", +// }); +// } +// } else { +// const updateGst = await Config.updateOne( +// {}, +// { +// $set: { +// gst, +// }, +// } +// ); + +// if (updateGst) { +// return res.status(200).json({ +// status: "success", +// message: "Updated GST Successfully", +// }); +// } +// } +// } catch (error) { +// console.log(error); +// } +// }; + +// Add Social Media + +const addSocialMedia = async (req, res) => { + const { facebook, twitter, instagram, linkedin, mail, youtube, pinterest } = + req.body; + + try { + if (req.body.constructor === Object && Object.keys(req.body).length === 0) { + return res.status(400).json({ + status: "failed", + message: "Please Provide Social Links", + }); + } + + const socialMediaLink = await Config.find(); + if (socialMediaLink.length === 0) { + const createSocialLinks = await Config.create({ + socialMedia: { + facebook, + twitter, + instagram, + linkedin, + youtube, + mail, + pinterest, + }, + }); + + if (createSocialLinks) { + return res.status(201).json({ + status: "success", + message: "Added Social Media Links Successfully", + }); + } + } else { + const updateSocial = await Config.updateOne( + {}, + { + $set: { + socialMedia: { + facebook, + twitter, + instagram, + linkedin, + mail, + youtube, + pinterest, + }, + }, + } + ); + if (updateSocial) { + return res.status(200).json({ + status: "success", + message: "Updated Social Media Links Successfully", + }); + } + } + } catch (error) { + console.log(error); + } +}; + +// add Address + +const addAddress = async (req, res) => { + const { + company, + address, + city, + state, + country, + pincode, + website, + contact, + email, + gstin, + } = req.body; + console.log(req.body); + if ( + !company || + !address || + !city || + !state || + !country || + !pincode || + !contact || + !email || + !gstin + ) { + return res.status(400).json({ + status: "failed", + message: "Please Provide All Fields", + }); + } + try { + const getAddress = await Config.find(); + if (getAddress.length === 0) { + const createAddress = await Config.create({ + address: { + company, + address, + city, + state, + country, + pincode, + website, + contact, + email, + gstin, + }, + }); + + if (createAddress) { + return res.status(201).json({ + status: "success", + message: "created address successfully", + }); + } + } else { + const updateAddress = await Config.updateOne( + {}, + { + $set: { + address: { + company, + address, + city, + state, + country, + pincode, + website, + contact, + email, + gstin, + }, + }, + } + ); + + if (updateAddress) { + return res.status(200).json({ + status: "success", + message: "Updated Address Successfully", + }); + } + } + } catch (error) { + console.log(error); + } +}; + +// get configuration + +const getConfig = async (req, res) => { + try { + const configration = await Config.find({}); + if (configration) { + res.status(200).json({ + status: "success", + result: configration, + }); + } + } catch (error) { + console.log(error); + } +}; + +// add logo +const addLogo = async (req, res) => { + try { + const configuration = await Config.find(); + + // console.log(req.files); + console.log(configuration.length) + // const result1 = await cloudinary.uploader.upload(req.files.Headerlogo[0].path,{folder: 'Vardhaman'}); + // const result2 = await cloudinary.uploader.upload(req.files.Footerlogo[0].path,{folder: 'Vardhaman'}); + // const result3 = await cloudinary.uploader.upload(req.files.Adminlogo[0].path,{folder: 'Vardhaman'}); + + let result1 = req.body.Headerlogo ? req.body.Headerlogo : ""; + let result2 = req.body.Footerlogo ? req.body.Footerlogo : ""; + let result3 = req.body.Adminlogo ? req.body.Adminlogo : ""; + // console.log(req.files.Headerlogo) + if (req.files.Headerlogo) { + console.log(req.files.Headerlogo[0].path) + + const result = await cloudinary.uploader.upload( + req.files.Headerlogo[0].path, + { folder: "ATP/Logo" } + ); + result1 = result.secure_url; + } + if (req.files.Footerlogo) { + const result = await cloudinary.uploader.upload( + req.files.Footerlogo[0].path, + { folder: "ATP/Logo" } + ); + result2 = result.secure_url; + } + if (req.files.Adminlogo) { + console.log(req.files.Adminlogo[0].path) + const result = await cloudinary.uploader.upload( + req.files.Adminlogo[0].path, + { folder: "ATP/Logo" } + ); + result3 = result.secure_url; + } + + console.log(result1); + console.log(result2); + console.log(result3); + + if (configuration.length === 0) { + const createLogo = await Config.create({ + logo: { + Headerlogo: result1, + Footerlogo: result2, + Adminlogo: result3, + }, + }); + + if (createLogo) { + return res.status(200).json({ + status: "success", + message: "Created Logos Successfully", + }); + } + } else { + // const result1 = await cloudinary.uploader.upload(req.files.Headerlogo[0].path,{folder: 'Vardhaman'}); + // const result2 = await cloudinary.uploader.upload(req.files.Footerlogo[0].path,{folder: 'Vardhaman'}); + // const result3 = await cloudinary.uploader.upload(req.files.Adminlogo[0].path,{folder: 'Vardhaman'}); + + const updateLogo = await Config.updateOne( + {}, + { + $set: { + logo: { + Headerlogo: result1, + Footerlogo: result2, + Adminlogo: result3, + }, + }, + } + ); + if (updateLogo) { + return res.status(200).json({ + status: "success", + message: "Updated Logos Successfully", + }); + } + } + } catch (error) { + console.log(error); + } +}; + +// //add scrollText +// const addScrollText = async (req, res) => { +// const { scrollText } = req.body; + +// try { +// if (req.body.constructor === Object && Object.keys(req.body).length === 0) { +// return res.status(400).json({ +// status: "failed", +// message: "Please Provide Scroll Text", +// }); +// } + +// const config = await Config.find(); +// if (config.length === 0) { +// const createScrollText = await Config.create(req.body); + +// if (createScrollText) { +// return res.status(201).json({ +// status: "success", +// message: "Added Scroll Text Successfully", +// }); +// } +// } else { +// const updateScroll = await Config.updateOne( +// {}, +// { +// $set: { +// scrollText: scrollText, +// }, +// } +// ); +// if (updateScroll) { +// return res.status(200).json({ +// status: "success", +// message: "Updated Scroll Text Successfully", +// }); +// } +// } +// } catch (error) { +// console.log(error); +// } +// }; + +//terms of use +const addTermsOfUse = async (req, res) => { + try { + const config = await Config.find(); + if (config.length === 0) { + const createScrollText = await Config.create(req.body); + if (createScrollText) { + return res.status(201).json({ + status: "success", + message: "Added Terms of Use Successfully", + }); + } + } else { + const updateScroll = await Config.updateOne( + {}, + { + $set: { + terms_of_use: req.body?.terms_of_use, + }, + } + ); + if (updateScroll) { + return res.status(200).json({ + status: "success", + message: "Updated Terms of Use Successfully", + }); + } + } + } catch (error) { + console.log(error); + res.status(500).json({ message: "Something went wrong!" }); + } +}; + +const getTermsOfUse = async (req, res) => { + try { + let configration = await Config.findOne({}); + if (!configration) configration = await Config.create({}); + res + .status(200) + .json({ status: "success", data: configration?.terms_of_use || "" }); + } catch (error) { + console.log(error); + res.status(500).json({ message: "Something went wrong!" }); + } +}; + +const deleteConfig = async (req, res) => { + const deleteConfig = await Config.deleteMany({}); + + console.log(deleteConfig); +}; + +export { + // addGST, + addSocialMedia, + addAddress, + getConfig, + addLogo, + deleteConfig, + // addScrollText, + addTermsOfUse, + getTermsOfUse, +}; diff --git a/resources/setting/Configration/Config_model.js b/resources/setting/Configration/Config_model.js new file mode 100644 index 0000000..6ef8a1d --- /dev/null +++ b/resources/setting/Configration/Config_model.js @@ -0,0 +1,14 @@ +import mongoose from "mongoose"; + +const { Schema, model } = mongoose; + +const configSchema = new Schema({ + // gst: { type: Number }, + // scrollText: { type: String }, + socialMedia: { type: Array, default: [] }, + address: { type: Array, default: [] }, + logo: { type: Array, default: [] }, + terms_of_use: { type: String, default: "" }, +}); + +export const Config = model("Config", configSchema); diff --git a/resources/setting/Configration/Config_routes.js b/resources/setting/Configration/Config_routes.js new file mode 100644 index 0000000..d5bf6b4 --- /dev/null +++ b/resources/setting/Configration/Config_routes.js @@ -0,0 +1,37 @@ +import { Router } from "express"; +import { + addAddress, + // addGST, + addLogo, + addSocialMedia, + deleteConfig, + getConfig, + // addScrollText, + addTermsOfUse, + getTermsOfUse, +} from "./Config_controller.js"; +import { upload } from "../../../Utils/cloudinary.js"; + +import { authorizeRoles, isAuthenticatedUser } from "../../../middlewares/auth.js"; + + +const router = Router(); + +let cpUpload = upload.fields([ + { name: "Headerlogo", maxCount: 1 }, + { name: "Footerlogo", maxCount: 1 }, + { name: "Adminlogo", maxCount: 1 }, +]); +console.log(cpUpload) +// router.route("/gst").post(isAuthenticatedUser, authorizeRoles("admin"), addGST); +router.route("/social").post(isAuthenticatedUser, authorizeRoles("admin"), addSocialMedia); +router.route("/address").post(isAuthenticatedUser, authorizeRoles("admin"), addAddress); +// router.route("/scrollText").post(isAuthenticatedUser, authorizeRoles("admin"), addScrollText); +router.route("/logo").post(isAuthenticatedUser, authorizeRoles("admin"), addLogo); +router.route("/").get(getConfig).delete(isAuthenticatedUser, authorizeRoles("admin"), deleteConfig); +router + .route("/termsofuse") + .get(isAuthenticatedUser, authorizeRoles("admin"), getTermsOfUse) + .patch(isAuthenticatedUser, authorizeRoles("admin"), addTermsOfUse); + +export default router; diff --git a/resources/setting/Configration/config_client_routes.js b/resources/setting/Configration/config_client_routes.js new file mode 100644 index 0000000..49efb79 --- /dev/null +++ b/resources/setting/Configration/config_client_routes.js @@ -0,0 +1,7 @@ +import { Router } from "express"; +import { getTermsOfUse } from "./Config_controller.js"; +const router = Router(); + +router.get("/termsofuse", getTermsOfUse); + +export default router; diff --git a/resources/setting/city/city_controller.js b/resources/setting/city/city_controller.js new file mode 100644 index 0000000..9537606 --- /dev/null +++ b/resources/setting/city/city_controller.js @@ -0,0 +1,61 @@ +import mongoose from "mongoose"; +import { City } from "./city_model.js"; +import { + addEntity, + deleteEntity, + getEntity, + updateEntity, +} from "../../../Utils/reusableApi.js"; + +const getNewId = async (req, res) => { + try { + const newId = new mongoose.Types.ObjectId(); + res.status(200).json({ status: "OK", data: { _id: newId } }); + } catch (err) { + return res.status(500).json({ message: "Unable to get ID." }); + } +}; + +const addCity = async (req, res) => { + await addEntity(req, res, City); +}; + +const getCityById = async (req, res) => { + await getEntity(req, res, City); +}; + +const getCityByIdWithState = async (req, res) => { + try { + const city = await City.findById(req.params.id).populate("state"); + res.status(200).json(city); + } catch (e) { + res.status(500).json({ message: "Something went wrong!" }); + } +}; + +const getAllCities = async (req, res) => { + try { + const cities = await City.find({}).populate("state"); + res.status(200).json({ data: cities }); + } catch (e) { + res.status(500).json({ message: "Something went wrong!" }); + } +}; + +const updateCity = async (req, res) => { + await updateEntity(req, res, City); +}; + +const deleteCityById = async (req, res) => { + await deleteEntity(req, res, City); +}; + +export { + getNewId, + addCity, + getAllCities, + getCityById, + updateCity, + deleteCityById, + getCityByIdWithState, +}; diff --git a/resources/setting/city/city_model.js b/resources/setting/city/city_model.js new file mode 100644 index 0000000..b82cfc5 --- /dev/null +++ b/resources/setting/city/city_model.js @@ -0,0 +1,16 @@ +import mongoose from "mongoose"; +const { Schema, model } = mongoose; + +const CitySchema = new Schema( + { + // _id: { type: Schema.Types.ObjectId }, + city_name: { type: String, default: "" }, + state: { type: Schema.Types.ObjectId, ref: "State" }, + // createdAt: { type: Date, default: new Date() }, + }, + // { timestamps: { createdAt: false, updatedAt: true } } + { timestamps: true } + +); + +export const City = model("City", CitySchema); diff --git a/resources/setting/city/city_routes.js b/resources/setting/city/city_routes.js new file mode 100644 index 0000000..ed7cb85 --- /dev/null +++ b/resources/setting/city/city_routes.js @@ -0,0 +1,21 @@ +import { Router } from "express"; +const router = Router(); +import { + getNewId, + addCity, + getAllCities, + getCityById, + updateCity, + deleteCityById, + getCityByIdWithState, +} from "./city_controller.js"; + +router.get("/newid", getNewId); +router.get("/", getAllCities); +router.get("/:id", getCityById); +router.get("/withstate/:id", getCityByIdWithState); +router.post("/", addCity); +router.patch("/:id", updateCity); +router.delete("/:id", deleteCityById); + +export default router; diff --git a/resources/setting/state/state_controller.js b/resources/setting/state/state_controller.js new file mode 100644 index 0000000..9db5ced --- /dev/null +++ b/resources/setting/state/state_controller.js @@ -0,0 +1,47 @@ +import mongoose from "mongoose"; +import { State } from "./state_model.js"; +import { + addEntity, + deleteEntity, + getEntities, + getEntity, + updateEntity, +} from "../../../Utils/reusableApi.js"; + +const getNewId = async (req, res) => { + try { + const newId = new mongoose.Types.ObjectId(); + res.status(200).json({ status: "OK", data: { _id: newId } }); + } catch (err) { + return res.status(500).json({ message: "Unable to get ID." }); + } +}; + +const addState = async (req, res) => { + await addEntity(req, res, State); +}; + +const getStateById = async (req, res) => { + await getEntity(req, res, State); +}; + +const getAllStates = async (req, res) => { + await getEntities(req, res, State); +}; + +const updateState = async (req, res) => { + await updateEntity(req, res, State); +}; + +const deleteStateById = async (req, res) => { + await deleteEntity(req, res, State); +}; + +export { + getNewId, + addState, + getAllStates, + getStateById, + updateState, + deleteStateById, +}; diff --git a/resources/setting/state/state_model.js b/resources/setting/state/state_model.js new file mode 100644 index 0000000..28b3f71 --- /dev/null +++ b/resources/setting/state/state_model.js @@ -0,0 +1,11 @@ +import mongoose from "mongoose"; +const { Schema, model } = mongoose; + +const StateSchema = new Schema( + { + state_name: { type: String, default: "" }, + }, + { timestamps: true } +); + +export const State = model("State", StateSchema); diff --git a/resources/setting/state/state_routes.js b/resources/setting/state/state_routes.js new file mode 100644 index 0000000..4b2d09c --- /dev/null +++ b/resources/setting/state/state_routes.js @@ -0,0 +1,19 @@ +import { Router } from "express"; +const router = Router(); +import { + getNewId, + addState, + getAllStates, + getStateById, + updateState, + deleteStateById, +} from "./state_controller.js"; + +router.get("/newid", getNewId); +router.get("/", getAllStates); +router.get("/:id", getStateById); +router.post("/", addState); +router.patch("/:id", updateState); +router.delete("/:id", deleteStateById); + +export default router; diff --git a/controllers/userController.js b/resources/user/userController.js similarity index 68% rename from controllers/userController.js rename to resources/user/userController.js index cc4e510..bad3ef0 100644 --- a/controllers/userController.js +++ b/resources/user/userController.js @@ -1,14 +1,13 @@ -//require("dotenv").config({ path: "backend/config/config.env" }); -import ErrorHander from "../Utils/errorhander.js" -import catchAsyncErrors from "../middlewares/catchAsyncErrors.js" -import User from "../models/userModel.js" -import sendToken from "../Utils/jwtToken.js" -import sendEmail from "../Utils/sendEmail.js" +import ErrorHander from "../../Utils/errorhander.js" +import catchAsyncErrors from "../../middlewares/catchAsyncErrors.js" +import User from "./userModel.js" +import sendToken from "../../Utils/jwtToken.js" +import sendEmail from "../../Utils/sendEmail.js" import crypto from "crypto" import cloudinary from "cloudinary" import password from 'secure-random-password' // 1.Register a User -export const registerUser = async (req, res, next) => { +export const registerUser = async (req, res) => { try { const { name, email, password, phone } = req.body; let findUser = await User.findOne({ email }) @@ -17,11 +16,14 @@ export const registerUser = async (req, res, next) => { .status(400) .json({ success: false, message: "User already exists" }); } - const files = req.files.avatar; - const myCloud = await cloudinary.uploader.upload(files.tempFilePath, { - folder: "cmp-user/image", - }, - function (error, result) { (result, error) }); + if (req.files) { + const files = req.files.avatar; + const myCloud = await cloudinary.uploader.upload(files.tempFilePath, { + folder: "ATM/user-image", + }, + function (error, result) { (result, error) }); + } + @@ -30,14 +32,14 @@ export const registerUser = async (req, res, next) => { email, password, phone, - avatar: { - public_id: myCloud.public_id, - url: myCloud.secure_url, - }, + // avatar: { + // public_id: myCloud.public_id, + // url: myCloud.secure_url, + // }, }); sendToken(user, 201, res); } catch (e) { - // console.log(e.message); + return res .status(400) .json({ success: false, message: e.message }); @@ -46,30 +48,36 @@ export const registerUser = async (req, res, next) => { }; // 2.Login User -export const loginUser = catchAsyncErrors(async (req, res, next) => { +export const loginUser = async (req, res, next) => { const { email, password } = req.body; - // checking if user has given password and email both - if (!email || !password) { - return next(res.status(400).json({ message: 'Please Enter Email & Password' })); + try { + if (!email || !password) { + return res.status(400).json({ message: 'Please Enter Email & Password' }); + } + + const user = await User.findOne({ email }).select("+password"); + + if (!user) { + return res.status(400).json({ message: 'Invalid Email or Password' }); + } + + + const isPasswordMatched = await user.comparePassword(password); + + if (!isPasswordMatched) { + return res.status(400).json({ message: 'Invalid Email or Password' }); + } + + sendToken(user, 200, res); + } catch (error) { + return res + .status(500) + .json({ message: "Something went wrong!", error: error?.message || "" }); } - const user = await User.findOne({ email }).select("+password"); - - if (!user) { - return res.status(400).json({ message: 'Invalid Email or Password' }); - } - - - const isPasswordMatched = await user.comparePassword(password); - - if (!isPasswordMatched) { - return res.status(400).json({ message: 'Invalid Email or Password' }); - } - - sendToken(user, 200, res); -}); +}; // 3.Logout User @@ -88,25 +96,19 @@ export const logout = catchAsyncErrors(async (req, res, next) => { // 4.Forgot Password -export const forgotPassword = catchAsyncErrors(async (req, res, next) => { +export const forgotPassword = async (req, res, next) => { const user = await User.findOne({ email: req.body.email }); if (!user) { - return next(new ErrorHander("User not found", 404)); + return res.status(404).json({ message: "User not found" }); + } // Get ResetPassword Token const resetToken = user.getResetPasswordToken();//call function //save database reset token await user.save({ validateBeforeSave: false }); - //create link for send mail - // const resetPasswordUrl = `http://localhost:5000/api/v1/user/password/reset/${resetToken}` //send from localhost - //send from anyhost - // const resetPasswordUrl = `${req.protocol}://${req.get( - // "host" - // )}/api/v1/user/password/reset/${resetToken}`; - //const resetPasswordUrl = `${process.env.FRONTEND_URL}:/api/user/password/reset/${resetToken}`; - //const resetPasswordUrl = `${process.env.FRONTEND_URL}/password/reset/${resetToken}`; + const passwords = password.randomPassword({ length: 12, characters: [ @@ -142,9 +144,9 @@ export const forgotPassword = catchAsyncErrors(async (req, res, next) => { await user.save({ validateBeforeSave: false }); - return next(new ErrorHander(error.message, 500)); + return res.status(500).json({ message: "Something went wrong!", error: error?.message || "" }); } -}); +} // 5.Reset Password @@ -242,17 +244,25 @@ export const updateProfile = catchAsyncErrors(async (req, res, next) => { }; if (req.files) { - const files = req.files.avatar; + const userImage = req.files?.avatar; const user = await User.findById(req.user.id); - const imageId = user.avatar.public_id; - await cloudinary.uploader.destroy(imageId) + if (user?.avatar) { + const imageId = user?.avatar?.public_id; + + await cloudinary.uploader.destroy(imageId) + } + + + + const myCloud = await cloudinary.v2.uploader.upload(userImage.tempFilePath, + { + folder: "ATM/user-image", + + }); + - const myCloud = await cloudinary.uploader.upload(files.tempFilePath, { - folder: "image", - }, - function (error, result) { (result, error) }); newUserData.avatar = { public_id: myCloud.public_id, diff --git a/models/userModel.js b/resources/user/userModel.js similarity index 93% rename from models/userModel.js rename to resources/user/userModel.js index e96e1fd..35a3fd9 100644 --- a/models/userModel.js +++ b/resources/user/userModel.js @@ -34,11 +34,11 @@ const userSchema = new mongoose.Schema({ avatar: { public_id: { type: String, - required: true, + // required: true, }, url: { type: String, - required: true, + // required: true, }, }, role: { diff --git a/routes/userRoute.js b/resources/user/userRoute.js similarity index 84% rename from routes/userRoute.js rename to resources/user/userRoute.js index c3b7647..841ee68 100644 --- a/routes/userRoute.js +++ b/resources/user/userRoute.js @@ -10,8 +10,8 @@ import { updateProfile, getSingleUser, getAllUser -} from "../controllers/userController.js" -import { isAuthenticatedUser, authorizeRoles } from "../middlewares/auth.js" +} from "./userController.js" +import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js" const router = express.Router();