From 6fdb7451a6b6290b4885d1999441a991f6080b0b Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Mon, 1 Apr 2024 16:10:46 +0530 Subject: [PATCH 1/6] Blog Create,update,delete,read and readAll controller Done --- resources/Blog/BlogController.js | 212 ++++++++++++++++++++++++++----- resources/Blog/BlogModel.js | 7 +- resources/Blog/BlogRoute.js | 27 +++- resources/Blog/dummy.json | 5 - 4 files changed, 206 insertions(+), 45 deletions(-) delete mode 100644 resources/Blog/dummy.json diff --git a/resources/Blog/BlogController.js b/resources/Blog/BlogController.js index 79abfd3..07f49bf 100644 --- a/resources/Blog/BlogController.js +++ b/resources/Blog/BlogController.js @@ -1,59 +1,64 @@ import Blog from "./BlogModel.js"; +import cloudinary from "../../Utils/cloudinary.js"; export const createBlog = async (req, res) => { - const { title, tags, image, blog_content } = req.body; - console.log(req.body); - - // Checking Fields - if (!title || !tags || !image || !blog_content) { - return res.status(400).json({ - success: false, - message: "All fields are mandatory", - }); - } + const { title, tags, blog_content } = req.body; try { - let images = []; - let Allfiles = req.files.image; - console.log(Allfiles); - // if (!Array.isArray(Allfiles)) { - // Allfiles = [Allfiles]; // Convert to array if it's not already - // } + let image; // To store Cloudinary image details - // Allfiles.forEach((file) => { - // if (typeof file.tempFilePath === "string") { - // let filepath = file.tempFilePath; - // images.push(filepath); - // } - // }); + if (req.files && req.files.image) { + const imageFile = req.files.image; + const result = await cloudinary.v2.uploader.upload( + imageFile.tempFilePath, + { + folder: "smellica/Blog", + } + ); - // const newBlog = await Blog.create({ - // title, - // tags, - // image: images, // Assign the array of image file paths - // blog_content, - // }); + image = { + public_id: result.public_id, + url: result.secure_url, + }; + } + + // Create the blog post + const blog = await Blog.create({ + title, + tags: tags.split(/\s*,\s*|\s+/) + .filter(tag => tag.trim() !== ''), // Splitting tags string into array + image, + blog_content, + }); res.status(201).json({ success: true, + blog, message: "Blog created successfully", - data: images, }); } catch (error) { console.error("Error creating blog:", error); res.status(500).json({ success: false, - message: error.message ? error.message : "Internal server error", + message: error.message || "Internal server error", }); } }; export const getAllBlog = async (req, res) => { try { - const saveData = await Blog.find(); - res.status(200).json({ - success: true, - message: saveData, - }); + const BlogData = await Blog.find().sort({ createdAt: -1 }); + if (BlogData) { + return res.status(200).json({ + success: true, + BlogData, + message: "Fetched All Blog", + }); + } else { + return res.status(404).json({ + success: true, + message: "No Blog till Now", + }); + } } catch { res.status(500).json({ success: false, @@ -61,3 +66,140 @@ export const getAllBlog = async (req, res) => { }); } }; +//get single Blog +export const getOneBlog = async (req, res) => { + try { + // console.log(req.params.id); + const blog = await Blog.findById(req.params.id); + if (blog) { + return res.status(200).json({ + success: true, + blog, + }); + } else { + return res.status(404).json({ + success: false, + msg: "Blog not found", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; + +export const deleteImageFromCloudinary = async (req, res) => { + const { public_id } = req.params; + + try { + if (!public_id) { + return res.status(400).json({ + success: false, + msg: "Please Provide Product ID!", + }); + } + const response = await cloudinary.v2.uploader.destroy(public_id); + if (response) { + res.status(200).json({ + success: true, + msg: "Blog Deleted Successfully!!", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; +//delete one Product +export const deleteBlog = async (req, res) => { + try { + if (!req?.user) return res.status(400).json({ message: "please login !" }); + // console.log(req?.user) + if (!req.params.id) + return res.status(400).json({ message: "please give Blog ID !" }); + // console.log(req.params.id) + const getblog = await Blog.findById(req.params.id); + // console.log(getblog) + if (!getblog) { + return res + .status(404) + .json({ success: false, msg: "Testimonial not Found!" }); + } + // Deleting Images From Cloudinary + await cloudinary.v2.uploader.destroy(getblog.image.public_id); + + //-------------------------// + const blog = await Blog.findByIdAndDelete(req.params.id); + if (!blog) { + return res.status(404).json({ message: "blog Not Found" }); + } + await blog.remove(); + res.status(200).json({ success: true, msg: "blog Deleted Successfully!!" }); + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; + +//update blog +export const updateBlog = async (req, res) => { + try { + // Check if the user is authenticated + if (!req.user) { + return res.status(400).json({ message: "Please login!" }); + } + + // Destructure request body + const { title, tags, blog_content } = req.body; + + // Prepare an object for the updated testimonial data + const updatedBlogData = { + title, + tags: tags.split(/\s*,\s*|\s+/) + .filter(tag => tag.trim() !== ''), // Splitting tags string into array + blog_content, + }; + + // Check if files are uploaded + if (req.files && req.files.image) { + // If image file is uploaded, upload it to cloudinary + const uploadedImage = req.files.image; + const result = await cloudinary.v2.uploader.upload( + uploadedImage.tempFilePath, + { + folder: "smellica/Blog", + } + ); + + // Prepare the image object with public_id and url + const image = { + public_id: result.public_id, + url: result.secure_url, + }; + + // Assign the uploaded image to the Blog's image field + updatedBlogData.image = image; + } + const modifiedBlog = await Blog.findOneAndUpdate( + { _id: req.params.id }, + { $set: updatedBlogData }, + { new: true } + ); + + return res.status(200).json({ + success: true, + ModifyBlog: modifiedBlog, + }); + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; diff --git a/resources/Blog/BlogModel.js b/resources/Blog/BlogModel.js index 1b3a65b..b57a523 100644 --- a/resources/Blog/BlogModel.js +++ b/resources/Blog/BlogModel.js @@ -13,7 +13,12 @@ const blogSchema = new Schema( required: [true, "Tags are required"], }, image: { - type: String, + public_id: { + type: String, + }, + url: { + type: String, + }, }, blog_content: { type: Object, diff --git a/resources/Blog/BlogRoute.js b/resources/Blog/BlogRoute.js index 772b7b6..9efaddc 100644 --- a/resources/Blog/BlogRoute.js +++ b/resources/Blog/BlogRoute.js @@ -1,11 +1,30 @@ import express from "express"; -import { createBlog, getAllBlog } from "./BlogController.js"; +import { createBlog, getAllBlog, getOneBlog, deleteBlog, deleteImageFromCloudinary, updateBlog } from "./BlogController.js"; import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; const router = express.Router(); -router.post("/create", createBlog); -router.get("/getallblog", getAllBlog); - +router + .route("/create") + .post(isAuthenticatedUser, authorizeRoles("admin"), createBlog); +router + .route("/getallblog") + .get(getAllBlog); +router + .route("/getoneblog/:id") + .get(getOneBlog); +router + .route("/deleteblog/:id") + .delete(isAuthenticatedUser, authorizeRoles("admin"), deleteBlog); +router + .route("/deleteImage/jatinMor/Blog/:public_id") + .delete( + isAuthenticatedUser, + authorizeRoles("admin"), + deleteImageFromCloudinary + ); + router + .route("/updateblog/:id") + .patch(isAuthenticatedUser, authorizeRoles("admin"), updateBlog); export default router; diff --git a/resources/Blog/dummy.json b/resources/Blog/dummy.json deleted file mode 100644 index 90dfec3..0000000 --- a/resources/Blog/dummy.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - { - "title": "String0" - } -] From 61d3835cc9a84dc86c8fa122c8c9834e86db7bdf Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Mon, 1 Apr 2024 16:36:21 +0530 Subject: [PATCH 2/6] package-lock.json install from privious commit and push in GIT --- package-lock.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bafc1a..a1f5970 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5417,7 +5417,8 @@ "cloudinary-core": { "version": "2.12.3", "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz", - "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==" + "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==", + "requires": {} }, "color-convert": { "version": "2.0.1", @@ -6660,7 +6661,8 @@ "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==" + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "requires": {} }, "mute-stream": { "version": "0.0.8", @@ -7893,7 +7895,8 @@ "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} }, "xregexp": { "version": "2.0.0", From e1cbd1a30b658db1fe072141398ae1ed80e3829f Mon Sep 17 00:00:00 2001 From: roshangarg28 Date: Tue, 2 Apr 2024 14:31:55 +0530 Subject: [PATCH 3/6] api for getting the order of each user and latest purchase --- resources/Orders/orderController.js | 1 + resources/user/userController.js | 45 ++++++++++++++++++++++++++++- resources/user/userRoute.js | 42 ++++++++++++++------------- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/resources/Orders/orderController.js b/resources/Orders/orderController.js index 77dd538..096a0d3 100644 --- a/resources/Orders/orderController.js +++ b/resources/Orders/orderController.js @@ -89,6 +89,7 @@ export const getUserSelf = async (req, res) => { }); } }; + export const deleteOneOrder = async (req, res) => { try { if (!req?.user) return res.status(400).json({ message: "please login !" }); diff --git a/resources/user/userController.js b/resources/user/userController.js index 334b267..60161d4 100644 --- a/resources/user/userController.js +++ b/resources/user/userController.js @@ -6,6 +6,7 @@ import sendEmail from "../../Utils/sendEmail.js"; import crypto from "crypto"; import cloudinary from "cloudinary"; import password from "secure-random-password"; +import { Order } from "../Orders/orderModel.js"; // 1.Register a User export const registerUser = async (req, res) => { try { @@ -200,6 +201,24 @@ export const getUserDetails = catchAsyncErrors(async (req, res, next) => { user, }); }); +export const getAllUsers = catchAsyncErrors(async (req, res, next) => { + const users = await User.find().populate("orders"); // Assuming orders are stored in a separate collection and populated in the User model + + // Process user data to calculate last purchase date and order count + const usersWithInfo = users.map((user) => { + const lastPurchase = + user.orders.length > 0 + ? user.orders[user.orders.length - 1].createdAt + : null; + const orderCount = user.orders.length; + return { ...user.toJSON(), lastPurchase, orderCount }; + }); + + res.status(200).json({ + success: true, + users: usersWithInfo, + }); +}); // 7.Get single user (admin) export const getSingleUser = catchAsyncErrors(async (req, res, next) => { @@ -219,6 +238,29 @@ export const getSingleUser = catchAsyncErrors(async (req, res, next) => { user, }); }); +export const getUserOrderForAdmin = async (req, res) => { + const id = req.params.id; + // console.log(id); + try { + const order = await Order.find({ + user: id, + payment_status: "success", + }).sort({ createdAt: -1 }); + + if (order) { + return res.status(200).json({ + success: true, + order, + message: "self Order fetched", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; // 8.update User password export const updatePassword = catchAsyncErrors(async (req, res, next) => { const user = await User.findById(req.user.id).select("+password"); @@ -284,7 +326,8 @@ export const updateProfile = catchAsyncErrors(async (req, res, next) => { // 9.Get all users(admin) export const getAllUser = catchAsyncErrors(async (req, res, next) => { - const users = await User.find(); //.select('-role'); + // Assuming your User model is imported as 'User' + const users = await User.find({ role: "user" }); res.status(200).json({ success: true, diff --git a/resources/user/userRoute.js b/resources/user/userRoute.js index 841ee68..78c4c2b 100644 --- a/resources/user/userRoute.js +++ b/resources/user/userRoute.js @@ -1,17 +1,18 @@ -import express from "express" +import express from "express"; import { - registerUser, - loginUser, - logout, - forgotPassword, - resetPassword, - getUserDetails, - updatePassword, - updateProfile, - getSingleUser, - getAllUser -} from "./userController.js" -import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js" + registerUser, + loginUser, + logout, + forgotPassword, + resetPassword, + getUserDetails, + updatePassword, + updateProfile, + getSingleUser, + getAllUser, + getUserOrderForAdmin, +} from "./userController.js"; +import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; const router = express.Router(); @@ -27,17 +28,18 @@ router.route("/user/logout").get(logout); router.route("/user/details").get(isAuthenticatedUser, getUserDetails); router - .route("/admin/users") - .get(isAuthenticatedUser, authorizeRoles("admin"), getAllUser); + .route("/admin/users") + .get(isAuthenticatedUser, authorizeRoles("admin"), getAllUser); router - .route("/admin/user/:id") - .get(isAuthenticatedUser, authorizeRoles("admin"), getSingleUser); - + .route("/admin/users/orders/:id") + .get(isAuthenticatedUser, authorizeRoles("admin"), getUserOrderForAdmin); +router + .route("/admin/user/:id") + .get(isAuthenticatedUser, authorizeRoles("admin"), getSingleUser); router.route("/user/password/update").put(isAuthenticatedUser, updatePassword); router.route("/user/update/profile").put(isAuthenticatedUser, updateProfile); - -export default router; \ No newline at end of file +export default router; From e7d068798dc763c5307935431eb8da3fb71d2d40 Mon Sep 17 00:00:00 2001 From: roshangarg28 Date: Tue, 2 Apr 2024 14:36:04 +0530 Subject: [PATCH 4/6] installed rozarpay package --- package-lock.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1f5970..9bafc1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5417,8 +5417,7 @@ "cloudinary-core": { "version": "2.12.3", "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz", - "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==", - "requires": {} + "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==" }, "color-convert": { "version": "2.0.1", @@ -6661,8 +6660,7 @@ "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==", - "requires": {} + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==" }, "mute-stream": { "version": "0.0.8", @@ -7895,8 +7893,7 @@ "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", - "requires": {} + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" }, "xregexp": { "version": "2.0.0", From 8218f2447dd850477f0d433900db0574314f731b Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Tue, 2 Apr 2024 14:59:19 +0530 Subject: [PATCH 5/6] get All Order Api Developed for Deshboard --- resources/Orders/orderController.js | 28 +++++++++++++++++++++++++++- resources/Orders/orderRoute.js | 4 ++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/resources/Orders/orderController.js b/resources/Orders/orderController.js index 77dd538..9444e68 100644 --- a/resources/Orders/orderController.js +++ b/resources/Orders/orderController.js @@ -36,7 +36,33 @@ export const getAllOrder = async (req, res) => { }); } }; - +export const getOrders = async (req, res) => { + try { + const order = await Order.find({ + payment_status: "success", + }) + .populate({ + path: "user", + select: "name -_id", + }) + .populate({ + path: "shippingInfo.addressId", + }) + .sort({ updatedAt: -1 }); + if (order) { + res.status(201).json({ + success: true, + order, + message: "All Order Fetched", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + message: error.message ? error.message : "Something went Wrong", + }); + } +}; export const getSingleOrder = async (req, res) => { try { if (!req.params.id) diff --git a/resources/Orders/orderRoute.js b/resources/Orders/orderRoute.js index 32cd99a..89721b8 100644 --- a/resources/Orders/orderRoute.js +++ b/resources/Orders/orderRoute.js @@ -2,6 +2,7 @@ import bodyParser from "body-parser"; import { deleteOneOrder, getAllOrder, + getOrders, getSingleOrder, getUserSelf, updateOrderStatusById, @@ -46,6 +47,9 @@ router.route("/user/self").get(isAuthenticatedUser, getUserSelf); router .route("/getAll/:status") .get(isAuthenticatedUser, authorizeRoles("admin"), getAllOrder); + router + .route("/getAll/") + .get(isAuthenticatedUser, authorizeRoles("admin"), getOrders); router.route("/getOne/:id").get(isAuthenticatedUser, getSingleOrder); router.route("/change/status/:id").patch(updateOrderStatusById); From 076958eba6830f04b300f2636b16306cabd620fa Mon Sep 17 00:00:00 2001 From: Sibunnayak Date: Tue, 2 Apr 2024 15:03:34 +0530 Subject: [PATCH 6/6] updated package-lock.json from privious commit --- package-lock.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bafc1a..a1f5970 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5417,7 +5417,8 @@ "cloudinary-core": { "version": "2.12.3", "resolved": "https://registry.npmjs.org/cloudinary-core/-/cloudinary-core-2.12.3.tgz", - "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==" + "integrity": "sha512-Ll4eDzcrIVn4zCttMh3Mdi+KNz07p5EEjBT2PQSRx8Eok1lKPt3uBBenOk/w88RKK3B8SFIWcEe/mN4BHQ0p8A==", + "requires": {} }, "color-convert": { "version": "2.0.1", @@ -6660,7 +6661,8 @@ "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==" + "integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==", + "requires": {} }, "mute-stream": { "version": "0.0.8", @@ -7893,7 +7895,8 @@ "ws": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==" + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} }, "xregexp": { "version": "2.0.0",