From c9fec37d33e1815ea209711acf0092805a8a123b Mon Sep 17 00:00:00 2001
From: Prateek579
Date: Sat, 18 May 2024 13:05:46 +0530
Subject: [PATCH] enhanced complaint sysytem task completed
---
model/query.js | 6 +
routers/NgoRoutes.js | 39 ++--
routers/adminRoutes.js | 125 ++++++-----
routers/userRoutes.js | 63 +++++-
views/Admin_Dashboard.ejs | 14 +-
views/UserDashBoard.ejs | 444 ++++++++++++++++++++++++--------------
6 files changed, 433 insertions(+), 258 deletions(-)
diff --git a/model/query.js b/model/query.js
index 9fa0ab9..1d80237 100644
--- a/model/query.js
+++ b/model/query.js
@@ -7,6 +7,12 @@ const querySchema = new mongoose.Schema(
subject: String,
message: String,
approved: { type: Boolean, default: false },
+ // adding models for storing ANSWERE ans USER_ID
+ answere: String,
+ user_id: {
+ type: mongoose.Schema.Types.ObjectId,
+ ref: "User",
+ },
},
{ timestamps: true }
);
diff --git a/routers/NgoRoutes.js b/routers/NgoRoutes.js
index 8f7d274..e8eb5ce 100644
--- a/routers/NgoRoutes.js
+++ b/routers/NgoRoutes.js
@@ -1,8 +1,8 @@
const express = require("express");
const router = new express.Router();
const fs = require("fs");
-const path = require('path');
-const Handlebars = require('handlebars');
+const path = require("path");
+const Handlebars = require("handlebars");
const bcrypt = require("bcrypt");
const saltRounds = 10;
@@ -19,6 +19,11 @@ router.post("/NGO-login", async (req, res) => {
const username = req.body.username;
const password = req.body.password;
const ngo = await NGO.findOne({ username: username, password: password });
+
+ //checking NGO is APPROVED or NOT
+ if (ngo.approved == false) {
+ res.status(500).json({ messaage: "NGO is send for approval" });
+ }
try {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
@@ -61,24 +66,28 @@ router.post("/NGO-Registarion", async (req, res) => {
// Save the new NGO to the database
await newNGO.save();
- const templatePath = path.join(__dirname, '../views', 'Email.template.handlebars');
- const templateContent = fs.readFileSync(templatePath, 'utf8');
-
-// Compile the Handlebars template with the provided context data
-const compiledHtml = Handlebars.compile(templateContent)({
- user: {
- _id: newNGO.NgoID, // Example ID
- username: newNGO.NGOName, // Example username
- email: newNGO.username, // Example email
- fname: newNGO.NGOName // Example first name
- }
- });
+ const templatePath = path.join(
+ __dirname,
+ "../views",
+ "Email.template.handlebars"
+ );
+ const templateContent = fs.readFileSync(templatePath, "utf8");
+
+ // Compile the Handlebars template with the provided context data
+ const compiledHtml = Handlebars.compile(templateContent)({
+ user: {
+ _id: newNGO.NgoID, // Example ID
+ username: newNGO.NGOName, // Example username
+ email: newNGO.username, // Example email
+ fname: newNGO.NGOName, // Example first name
+ },
+ });
// Send an email to the admin for approval
const mailOptions = {
to: newNGO.username, // Admin's email address
subject: "New NGO Registration",
text: "A new NGO registration is pending approval. Login to the admin panel to review and approve.",
- html: compiledHtml
+ html: compiledHtml,
// Include any necessary information in the email body
};
transporter.transporter.sendMail(mailOptions, function (error, info) {
diff --git a/routers/adminRoutes.js b/routers/adminRoutes.js
index f801a5f..78c533f 100644
--- a/routers/adminRoutes.js
+++ b/routers/adminRoutes.js
@@ -33,7 +33,7 @@ router.post("/admin-login", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -119,7 +119,7 @@ router.post("/approve-ngo/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -156,7 +156,7 @@ router.post("/decline-ngo/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -193,7 +193,7 @@ router.post("/decline-donor/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -231,7 +231,7 @@ router.post("/accept-donor/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -267,7 +267,7 @@ router.post("/delete-complain/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -303,7 +303,7 @@ router.post("/accept-complain/:id/:userId", async (req, res) => {
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
@@ -321,71 +321,78 @@ router.post("/accept-complain/:id/:userId", async (req, res) => {
});
//making a POST method for RESPONDE to email
-router.post("/complains-response/:email/:userId", async (req, res) => {
+router.post("/complains-response/:email/:userId/:id", async (req, res) => {
const email = req.params.email;
const answere = req.body.answere;
const userId = req.params.userId;
- console.log(email, answere, userId);
+ const compId = req.params.id;
- //sending email to the COMPLAIN email
try {
- const transporter = nodemailer.createTransport({
- service: "gmail",
- host: "smtp.gmail.com",
- port: 465,
- secure: true,
- auth: {
- user: process.env.mail_id,
- pass: process.env.pass_id,
- },
- });
-
- let MailGenerator = new Mailgen({
- theme: "default",
- product: {
- name: "PETARI",
- link: "https://mailgen.js",
- },
- });
-
- let response = {
- body: {
- name: "",
- intro: "Welcome to PETARI! We're very excited to have you on board.",
- action: {
- instructions: answere,
- button: {
- color: "#22BC66", // Optional action button color
- text: "Have a good day",
- link: "",
+ //checking user EXIST or NOT
+ const userExist = await User.findOne({ email });
+ if (userExist) {
+ const complaint = await Query.findByIdAndUpdate(compId, {
+ answere,
+ });
+ } else {
+ //sending email to the COMPLAIN email
+ const transporter = nodemailer.createTransport({
+ service: "gmail",
+ host: "smtp.gmail.com",
+ port: 465,
+ secure: true,
+ auth: {
+ user: process.env.mail_id,
+ pass: process.env.pass_id,
+ },
+ });
+ let MailGenerator = new Mailgen({
+ theme: "default",
+ product: {
+ name: "PETARI",
+ link: "https://mailgen.js",
+ },
+ });
+ let response = {
+ body: {
+ name: "",
+ intro: "Welcome to PETARI! We're very excited to have you on board.",
+ action: {
+ instructions: answere,
+ button: {
+ color: "#22BC66", // Optional action button color
+ text: "Have a good day",
+ link: "",
+ },
},
+ outro: "Thankyou for a part of PETARI",
},
- outro: "Thankyou for a part of PETARI",
- },
- };
-
- let mail = MailGenerator.generate(response);
-
- let message = {
- to: email,
- subject: "Petari Support team",
- html: mail,
- };
+ };
+ let mail = MailGenerator.generate(response);
+ let message = {
+ to: email,
+ subject: "Petari Support team",
+ html: mail,
+ };
+ transporter
+ .sendMail(message)
+ .then(() => {
+ console.log("email is send successfully");
+ })
+ .catch((error) => {
+ console.log("Email is not send", error);
+ });
+
+ //DELETING complain after response because user does not exist
+ await Query.findByIdAndDelete(compId);
+ }
- transporter
- .sendMail(message)
- .then(() => {
- console.log("email is send successfully");
- })
- .catch((error) => {
- console.log("Email is not send", error);
- });
const admin = await Admin.findById(userId);
console.log("admin details in approve-ngo", admin);
const dooner = await User.find(); // Assuming User is your Mongoose model for users
const ngo = await NGO.find();
- const query1 = await problem.find();
+ const query1 = await problem.find({ answere: { $exists: false } });
res.render("Admin_Dashboard", {
name: admin.fullName,
email: admin.fullName,
diff --git a/routers/userRoutes.js b/routers/userRoutes.js
index 673704c..f11168f 100644
--- a/routers/userRoutes.js
+++ b/routers/userRoutes.js
@@ -36,18 +36,34 @@ router.get("/success", function (req, res) {
});
router.post("/", async function (req, res) {
+ const email = req.body.Email;
try {
- const newQuery = new Query({
- name: req.body.Fname,
- email: req.body.Email,
- subject: req.body.sub,
- message: req.body.sms,
- });
+ //finding the user EXIST or NOT in DATABASE
+ const userExist = await User.findOne({ email });
+ if (userExist) {
+ const newQuery = new Query({
+ name: req.body.Fname,
+ email: req.body.Email,
+ subject: req.body.sub,
+ message: req.body.sms,
+ user_id: userExist._id,
+ });
+
+ await newQuery.save();
+ console.log(newQuery);
+ } else {
+ const newQuery = new Query({
+ name: req.body.Fname,
+ email: req.body.Email,
+ subject: req.body.sub,
+ message: req.body.sms,
+ });
- await newQuery.save();
+ await newQuery.save();
+ console.log(newQuery);
+ }
res.status(200).send("Successfully Received Message... Thank You!");
- console.log(newQuery);
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
@@ -57,22 +73,23 @@ router.post("/", async function (req, res) {
// user login (seems to be something wrong here - user cant login even if he gives correct credentials)
router.post("/login", async function (req, res) {
const { username, password } = req.body;
-
+ console.log("user credentials", username, password);
try {
const foundUser = await User.findOne({ email: username });
-
+ console.log("user find in database", foundUser);
if (!foundUser) {
return res.render("loginError", { message: "User not found" });
}
const result = await bcrypt.compare(password, foundUser.password);
-
+ const userQuerys = await Query.find({ user_id: foundUser._id });
if (result) {
return res.render("UserDashBoard", {
fullName: foundUser.fullName,
email: foundUser.email,
phoneNo: foundUser.Mobile,
address: foundUser.address,
+ complain: userQuerys,
});
} else {
return res.render("loginError", { message: "Incorrect password" });
@@ -414,4 +431,28 @@ router.post(async (req, res) => {
}
});
+//making a POST method for DELETING the COMPLAINt
+router.post("/delete-query/:id/:email", async (req, res) => {
+ const compId = req.params.id;
+ const email = req.params.email;
+ try {
+ const dele = await Query.findByIdAndDelete(compId);
+
+ //rendering USER DASHBOARD
+ const foundUser = await User.findOne({ email });
+ const userQuerys = await Query.find({ user_id: foundUser._id });
+
+ return res.render("UserDashBoard", {
+ fullName: foundUser.fullName,
+ email: foundUser.email,
+ phoneNo: foundUser.Mobile,
+ address: foundUser.address,
+ complain: userQuerys,
+ });
+ } catch (error) {
+ console.error(error);
+ res.status(500).send("Internal Server Error");
+ }
+});
+
module.exports = router;
diff --git a/views/Admin_Dashboard.ejs b/views/Admin_Dashboard.ejs
index 48b34ae..12ca23c 100644
--- a/views/Admin_Dashboard.ejs
+++ b/views/Admin_Dashboard.ejs
@@ -670,7 +670,8 @@
-
-
-
-
<% } %>
<% }); %>
@@ -809,8 +805,10 @@
const textarea = document.getElementById('myTextarea');
textarea.addEventListener('input', function () {
- this.style.height = 'auto';
- this.style.height = (this.scrollHeight) + 'px';
+ if (this.style.height < "65px") {
+ this.style.height = 'auto';
+ this.style.height = (this.scrollHeight) + 'px';
+ }
});
diff --git a/views/UserDashBoard.ejs b/views/UserDashBoard.ejs
index 88d4b38..4303fd7 100644
--- a/views/UserDashBoard.ejs
+++ b/views/UserDashBoard.ejs
@@ -62,7 +62,7 @@
}
.top-border {
-
+
border-style: double;
border-color: #F07070;
}
@@ -112,76 +112,94 @@
cursor: pointer;
z-index: 2;
}
- .dash{
+
+ .dash {
position: absolute;
left: 35px;
}
+
body.dark .top {
background-color: #333;
color: #FFF;
}
- .donation{
+
+ .donation {
display: none;
}
.container {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- }
- .form-container {
- border: 1px solid #ddd;
- padding: 20px;
- width: 400px;
- margin-bottom: 20px;
- }
- label {
- display: block;
- margin-bottom: 8px;
- }
- input[type="text"], input[type="number"], input[type="email"], select {
- width: 100%;
- padding: 8px;
- border: 1px solid #ccc;
- border-radius: 4px;
- box-sizing: border-box;
- margin-bottom: 10px;
- }
- select {
- margin-bottom: 10px;
- }
- table {
- border-collapse: collapse;
- width: 100%;
- margin-bottom: 20px;
- font-family: Arial, sans-serif;
- }
- th, td {
- padding: 8px;
- text-align: left;
- border-bottom: 1px solid #ddd;
- }
-
- th:last-child, td:last-child {
- text-align: center;
- }
- .button {
- background-color: #4CAF50; /* Green */
- border: none;
- color: white;
- padding: 8px 16px;
- text-align: center;
- text-decoration: none;
- display: inline-block;
- font-size: 16px;
- margin: 4px 2px;
- cursor: pointer;
- border-radius: 7%;
- }
- .button:hover {
- background-color: #3e8e41; /* Green hover */
- }
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20px;
+ }
+
+ .form-container {
+ border: 1px solid #ddd;
+ padding: 20px;
+ width: 400px;
+ margin-bottom: 20px;
+ }
+
+ label {
+ display: block;
+ margin-bottom: 8px;
+ }
+
+ input[type="text"],
+ input[type="number"],
+ input[type="email"],
+ select {
+ width: 100%;
+ padding: 8px;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ box-sizing: border-box;
+ margin-bottom: 10px;
+ }
+
+ select {
+ margin-bottom: 10px;
+ }
+
+ table {
+ border-collapse: collapse;
+ width: 100%;
+ margin-bottom: 20px;
+ font-family: Arial, sans-serif;
+ }
+
+ th,
+ td {
+ padding: 8px;
+ text-align: left;
+ border-bottom: 1px solid #ddd;
+ }
+
+ th:last-child,
+ td:last-child {
+ text-align: center;
+ }
+
+ .button {
+ background-color: #4CAF50;
+ /* Green */
+ border: none;
+ color: white;
+ padding: 8px 16px;
+ text-align: center;
+ text-decoration: none;
+ display: inline-block;
+ font-size: 16px;
+ margin: 4px 2px;
+ cursor: pointer;
+ border-radius: 7%;
+ }
+
+ .button:hover {
+ background-color: #3e8e41;
+ /* Green hover */
+ }
/* aditya End */
/* colors */
@@ -326,6 +344,56 @@
background-color: #333;
color: #FFF;
}
+
+ .query-container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin: 2rem;
+ }
+
+ .query-list {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+ }
+
+ .query-item {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ background-color: #f9f9f9;
+ border-radius: 8px;
+ padding: 1rem;
+ margin-bottom: 1rem;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+
+ .query-details {
+ display: flex;
+ flex-direction: column;
+ }
+
+ .query-ques {
+ font-weight: bold;
+ margin-bottom: 0.5rem;
+ }
+
+ .query-ans {
+ color: #666;
+ margin-bottom: 0.5rem;
+ }
+
+ .btn-decline {
+ padding: 5px 10px;
+ border: none;
+ border-radius: 3px;
+ background-color: #4CAF50;
+ color: white;
+ cursor: pointer;
+ margin-right: 5px;
+ }
@@ -344,17 +412,21 @@
DashBoard
Welcome, <%= fullName %>!
-
+