diff --git a/.env b/.env index ed782b0..e09ecfa 100644 --- a/.env +++ b/.env @@ -1,6 +1,7 @@ DB_URL="mongodb+srv://smellica:Anjefef23dnsfjne@cluster0.c5gfqzm.mongodb.net/" +# DB_URL="mongodb://localhost:27017/smellica" PORT = 5000 JWT_SECRET = jdvnvjwrniwj4562ddsjn6@1xsbfeh@wre4Njdf; diff --git a/app.js b/app.js index e10bf7d..701ad0d 100644 --- a/app.js +++ b/app.js @@ -165,7 +165,8 @@ import AffiliateRoute from "./resources/Affiliate&Coupon/Affiliate/AffiliateRout import CouponRoute from "./resources/Affiliate&Coupon/Coupon/CouponRoute.js"; //short urls // import ShortUrlRouter from "./resources/Businesses/Short_Urls/ShortUrlRoute.js"; - +//support Ticket +import SupportRouter from "./resources/Supports/supportRoute.js"; app.use("/api/v1/", user); //Product @@ -225,5 +226,6 @@ app.use("/api/v1/coupon", CouponRoute); // app.use("/api/appointment", AppointmentRouter); //short urls // app.use("/api/shorturl", ShortUrlRouter); - +//Support +app.use("/api", SupportRouter); export default app; diff --git a/resources/Supports/supportController.js b/resources/Supports/supportController.js new file mode 100644 index 0000000..d25f406 --- /dev/null +++ b/resources/Supports/supportController.js @@ -0,0 +1,292 @@ +import { Support } from "./supportModel.js"; +import cloudinary from "../../Utils/cloudinary.js"; + +export const createSupport = async (req, res) => { + // console.log(req.body); + // console.log(req.files.image); + try { + // const { ticketId, createdOn, subject, description } = req.body; + if(req.files && req.files.image){ + let images = []; + let Allfiles = req.files.image; + if (typeof Allfiles.tempFilePath === "string") { + let filepath = Allfiles.tempFilePath; + + images.push(filepath); + } else { + Allfiles.map((item) => { + images.push(item.tempFilePath); + }); + } + + const imagesLinks = []; + for (let i = 0; i < images.length; i++) { + const result = await cloudinary.v2.uploader.upload(images[i], { + folder: "smellica/CustomerSupport", + }); + + imagesLinks.push({ + public_id: result.public_id, + url: result.secure_url, + }); + } + req.body.image = imagesLinks; + } + req.body.addedBy = req.user._id; + // Check if any required field is missing + // if (!ticketId || !createdOn || !subject || !description) { + // return res.status(400).json({ + // success: false, + // msg: "All fields are required.", + // }); + // } + + // Create the support ticket + // const support = await Support.create({ + // ticketId, + // createdOn, + // subject, + // description, + // addedBy: req.user._id, + // image: imagesLinks, + // }); + const support = await Support.create({ ...req.body }); + // Return the created support ticket + res.status(201).json({ + success: true, + data: support, + msg: "Support ticket created successfully.", + }); + } catch (error) { + console.error(error); + // Handle errors + res.status(500).json({ + success: false, + msg: error.message, + }); + } +}; +// **************************** + +export const getAllSupportTicket = async (req, res) => { + try { + // Use the find method to retrieve all support tickets + const support = await Support.find().sort({ createdAt: -1 }); + + // Check if support tickets were found + if (support) { + return res.status(200).json({ + success: true, + support, + }); + } + } catch (error) { + // Handle errors + // console.error(error); + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; +export const getOneSupportTicket = async (req, res) => { + try { + // console.log(req.params.id); + const support = await Support.findOne({ ticketId: req.params.id }); + if (support) { + return res.status(200).json({ + success: true, + support, + }); + } else { + return res.status(404).json({ + success: false, + msg: "Support ticket not found", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; + +// ************************8 + +export const getAllSupportTicketofuser = async (req, res) => { + try { + // Retrieve the user ID from the request + const userId = req.user._id; + + // Use the find method to retrieve all support tickets created by the user + const support = await Support.find({ addedBy: userId }).sort({ + createdAt: -1, + }); + + // Check if support tickets were found + if (support) { + return res.status(200).json({ + success: true, + support, + }); + } else { + return res.status(404).json({ + success: false, + msg: "No support tickets found for the user.", + }); + } + } catch (error) { + // Handle errors + // console.error(error); + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; + +// ************************8 + +export const deleteSupport = async (req, res) => { + try { + if (!req.params.id) { + return res.status(400).json({ + success: false, + msg: "Please Provide Support ID!", + }); + } + // console.log(req.params.id); + const getSupport = await Support.findById(req.params.id); + if (!getSupport) { + return res.status(404).json({ + success: false, + msg: "Support not Found!", + }); + } + // Deleting Images From Cloudinary + for (let i = 0; i < getSupport.image.length; i++) { + await cloudinary.v2.uploader.destroy(getSupport.image[i].public_id); + } + + //-------------------------// + const supportticket = await Support.findByIdAndDelete(req.params.id); + if (!supportticket) { + return res.status(404).json({ message: "Support Not Found" }); + } + await supportticket.remove(); + res.status(200).json({ + success: true, + msg: "Support Deleted Successfully!!", + }); + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; + +export const updateSupport = async (req, res) => { + try { + const { status, message } = req.body; + // console.log(req.params.id); + // Prepare an array for the images + // const jsonArray = JSON.parse(image); + // const AllImages = jsonArray.map(({ public_id, url }) => ({ + // public_id, + // url, + // })); + + // if (req.files && req.files.newImages) { + // const newuploadImages = Array.isArray(req.files.newImages) + // ? req.files.newImages + // : [req.files.newImages]; + + // const imagesLinks = []; + + // for (let i = 0; i < newuploadImages.length; i++) { + // const result = await cloudinary.v2.uploader.upload( + // newuploadImages[i].tempFilePath, + // { + // folder: "smellica/product", + // } + // ); + + // imagesLinks.push({ + // public_id: result.public_id, + // url: result.secure_url, + // }); + // } + + // Combine the existing images and the newly uploaded images + // const updatedImages = [...AllImages, ...imagesLinks]; + + // Perform the product update + // Find the support ticket by ID + const supportTicket = await Support.findOne({ ticketId: req.params.id }); + // Check if the support ticket exists + if (!supportTicket) { + return res.status(404).json({ + success: false, + msg: "Support ticket not found", + }); + } + + // Update the support ticket fields + if (status) { + supportTicket.status = status; + } + if (message) { + const newMessage = { + message: message.message, + user: message.user, + replyDate: message.replyDate, // Add a timestamp to the message object + }; + supportTicket.message.push(newMessage); + // Update the last reply to the timestamp of the new message if the user is admin + if (message.user === "admin") { + supportTicket.lastreply = newMessage.replyDate; + } + } + + // Save the updated support ticket + const updatedSupportTicket = await supportTicket.save(); + + return res.status(200).json({ + success: true, + updatedSupportTicket, + }); + } catch (error) { + // Handle errors + // console.error(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: "CustomerSupport Deleted Successfully!!", + }); + } + } catch (error) { + res.status(500).json({ + success: false, + msg: error.message ? error.message : "Something went wrong!", + }); + } +}; \ No newline at end of file diff --git a/resources/Supports/supportModel.js b/resources/Supports/supportModel.js new file mode 100644 index 0000000..25892b0 --- /dev/null +++ b/resources/Supports/supportModel.js @@ -0,0 +1,67 @@ +import mongoose from "mongoose"; +const { Schema, model } = mongoose; +const supportSchema = new Schema( + { + ticketId: { + type: String, + required: true, + unique: true, + }, + addedBy: { + type: Schema.Types.ObjectId, + ref: "User", + required: true, + }, + subject: { + type: String, + required: true, + }, + description: { + type: String, + maxLength: [100, "description cannot exceed 100 characters"], + required: [true, "Please Enter product Description"], + }, + createdOn: { + type: String, + }, + lastreply: { + type: String, + }, + status: { + type: String, + enum: ["Open", "Close"], + default: "Open", + }, + image: [ + { + public_id: { + type: String, + // required: true, + }, + url: { + type: String, + // required: true, + }, + }, + ], + message: [ + { + message: { + type: String, + default: "", + }, + user: { + type: String, + enum: ["admin", "user"], + default: "user", + }, + replyDate: { + type: String, + }, + }, + ], + }, + { timestamps: true, versionKey: false } +); + +export const Support = model("Support", supportSchema); diff --git a/resources/Supports/supportRoute.js b/resources/Supports/supportRoute.js new file mode 100644 index 0000000..dcc3c18 --- /dev/null +++ b/resources/Supports/supportRoute.js @@ -0,0 +1,32 @@ +import bodyParser from "body-parser"; +import { createSupport, deleteImageFromCloudinary, deleteSupport, getAllSupportTicket, getAllSupportTicketofuser, getOneSupportTicket, updateSupport } from "./supportController.js"; +import { isAuthenticatedUser, authorizeRoles } from "../../middlewares/auth.js"; +import express from "express"; + +const app = express(); + +// Configure bodyParser to parse the raw request body as a buffer +app.use(bodyParser.raw({ type: "application/json" })); + +const router = express.Router(); +//checkout Routes-------------------------// +router.route("/support/create/").post(isAuthenticatedUser,createSupport); +router.route("/support/getAll/").get(getAllSupportTicket); +router.route("/support/userticket/").get(isAuthenticatedUser,getAllSupportTicketofuser); +router + .route("/support/delete/:id") + .delete( deleteSupport); + router.route("/support/getOne/:id").get(getOneSupportTicket); + router + .route("/support/update/:id") + .patch(updateSupport); + router + .route("/support/deleteImage/jatinMor/CustomerSupport/:public_id") + .delete( + isAuthenticatedUser, + authorizeRoles("admin"), + deleteImageFromCloudinary + ); +// --------------------------------------------------------- + +export default router;