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 @@

-
@@ -678,11 +679,6 @@
-
-
- -
-
<% } %> <% }); %> @@ -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 %>!
- +
-

Full Name: <%= fullName %>

-

Email: <%= email %>

-

Phone No: <%= phoneNo %>

-

Address: <%= address %>

+

Full Name: <%= fullName %> +

+

Email: <%= email %> +

+

Phone No: <%= phoneNo %> +

+

Address: <%= address %> +

@@ -367,8 +439,8 @@
- - + + @@ -408,14 +480,14 @@ - + - +

Food Inventory

- + @@ -439,102 +511,144 @@ - - - - - - + <% }); %> + + + + + + + + + + - + \ No newline at end of file
Food Item Quantity