diff --git a/model/query.js b/model/query.js index d6deb68..9fa0ab9 100644 --- a/model/query.js +++ b/model/query.js @@ -1,12 +1,16 @@ -const mongoose = require('mongoose'); +const mongoose = require("mongoose"); -const querySchema = new mongoose.Schema({ +const querySchema = new mongoose.Schema( + { name: String, email: String, subject: String, - message: String -}, { timestamps: true }); + message: String, + approved: { type: Boolean, default: false }, + }, + { timestamps: true } +); -const Query = mongoose.model('Query', querySchema); +const Query = mongoose.model("Query", querySchema); module.exports = Query; diff --git a/model/user.js b/model/user.js index 0a136b2..01c6015 100644 --- a/model/user.js +++ b/model/user.js @@ -1,38 +1,37 @@ -const mongoose = require('mongoose'); - +const mongoose = require("mongoose"); const userSchema = new mongoose.Schema({ - // username: { - // type: String, - // unique: true, - // required: true, - // }, - email: String, - password: String, - fullName: String, - address: String, - Mobile: Number, - dob: String, - gender: { - type: String, - enum: ['male', 'female', 'other'], + // username: { + // type: String, + // unique: true, + // required: true, + // }, + email: String, + password: String, + fullName: String, + address: String, + Mobile: Number, + dob: String, + gender: { + type: String, + enum: ["male", "female", "other"], + }, + flatNo: { type: String }, + addressLine1: { type: String }, + addressLine2: { type: String }, + city: { type: String }, + state: { type: String }, + zip: { type: String }, + foodInventory: [ + { + foodItem: { type: String }, + quantity: { type: Number }, }, - flatNo: { type: String }, - addressLine1: { type: String }, - addressLine2: { type: String }, - city: { type: String }, - state: { type: String }, - zip: { type: String }, - foodInventory: [ - { - foodItem: { type: String }, - quantity: { type: Number } - } - ] - // googleId: String, - // profile: String, + ], + approved: { type: Boolean, default: false }, + // googleId: String, + // profile: String, }); - const User = new mongoose.model("User", userSchema); -module.exports=User +module.exports = User; diff --git a/package-lock.json b/package-lock.json index 2f924d0..6f34f69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1992,16 +1992,104 @@ "@redis/client": "^1.0.0" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "peer": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "peer": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz", + "integrity": "sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ==", + "peer": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "peer": true + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==" }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "peer": true + }, "node_modules/@types/node": { "version": "18.15.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" }, + "node_modules/@types/qs": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", + "peer": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "peer": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "peer": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "peer": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/triple-beam": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", diff --git a/routers/NgoRoutes.js b/routers/NgoRoutes.js index 0053d28..daa98aa 100644 --- a/routers/NgoRoutes.js +++ b/routers/NgoRoutes.js @@ -1,87 +1,87 @@ -const express = require("express") -const router = new express.Router() +const express = require("express"); +const router = new express.Router(); -const bcrypt=require("bcrypt") +const bcrypt = require("bcrypt"); const saltRounds = 10; const jwt = require("jsonwebtoken"); -const User=require("../model/user") -const Admin=require("../model/admin") -const NGO=require("../model/ngo") -const Query = require("../model/query"); // Adjust the path based on your project structure +const transporter = require("../helpers/emailHelpers"); +const User = require("../model/user"); +const Admin = require("../model/admin"); +const NGO = require("../model/ngo"); +const Query = require("../model/query"); // Adjust the path based on your project structure -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 }); - try { - const dooner = await User.find(); // Assuming User is your Mongoose model for users - - - - res.render("NGO-Dashboard", { - fullName: ngo.NGOName, - email: ngo.username, - id: ngo.NGOID, - phoneNo:ngo.Mobile, - address :ngo.NGOLocation, - Donation : dooner, - Pickup : dooner, - complain: "" - }); - } catch (err) { - console.error(err); - res.status(500).send("An internal server error occurred."); - } - }) - - router.post("/NGO-Registarion", async (req, res) => { - // Check if the NGO already exists - const existingNGO = await NGO.findOne({ username: req.body.username }); - if (existingNGO) { - return res.status(400).json({ error: 'NGO already exists' }); - } - - // Create a new NGO registration - const newNGO = new NGO({ - username: req.body.username, - password: req.body.password, - NGOName: req.body.NGOName, - Mobile: req.body.Mobile, - NGOID: req.body.NGOID, - NGOLocation: req.body.NGOLocation, - approved: false +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 }); + try { + const dooner = await User.find(); // Assuming User is your Mongoose model for users + + res.render("NGO-Dashboard", { + fullName: ngo.NGOName, + email: ngo.username, + id: ngo.NGOID, + phoneNo: ngo.Mobile, + address: ngo.NGOLocation, + Donation: dooner, + Pickup: dooner, + complain: "", }); + } catch (err) { + console.error(err); + res.status(500).send("An internal server error occurred."); + } +}); +router.post("/NGO-Registarion", async (req, res) => { + // Check if the NGO already exists + const existingNGO = await NGO.findOne({ username: req.body.username }); + if (existingNGO) { + return res.status(400).json({ error: "NGO already exists" }); + } + + // Create a new NGO registration + const newNGO = new NGO({ + username: req.body.username, + password: req.body.password, + NGOName: req.body.NgoName, + Mobile: req.body.Mobile, + NgoID: req.body.NgoID, + NgoLocation: req.body.NgoLocation, + approved: false, + }); + // Save the new NGO to the database + + try { // Save the new NGO to the database + await newNGO.save(); + + // Send an email to the admin for approval + let 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.", + // Include any necessary information in the email body + }; + transporter.sendMail(mailOptions, function (error, info) { + if (error) { + console.log(error); + } else { + console.log("Email sent: " + info.response); + } + }); - try { - // Save the new NGO to the database - await newNGO.save(); - - // Send an email to the admin for approval - let 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.', - // Include any necessary information in the email body - }; - transporter.sendMail(mailOptions, function (error, info) { - if (error) { - console.log(error); - } else { - console.log('Email sent: ' + info.response); - } - }); - - console.log('NGO registration request sent for approval'); - res.status(200).json({ message: 'NGO registration request sent for approval' }); + console.log("NGO registration request sent for approval"); + res + .status(200) + .json({ message: "NGO registration request sent for approval" }); } catch (err) { - console.error('Error creating NGO:', err); - res.status(500).json({ error: 'Internal server error' }); + console.error("Error creating NGO:", err); + res.status(500).json({ error: "Internal server error" }); } - // try { + // try { // await newNGO.save(); // let mailOptions = { @@ -117,48 +117,44 @@ router.post("/NGO-login",async(req,res)=>{ // console.error('Error creating NGO:', err); // res.status(500).json({ error: 'Internal server error' }); // } - // newNGO.save() - // .then((ngo) => { - // let mailOptions = { - // to: ngo.username, - // subject: 'Welcome To Petari', - // template: 'Email.template', - // context: { - // ngo: { - // ngoName: ngo.name, - // _id: ngo._id, - // username: ngo.password, - - // }, - - // year: new Date().getFullYear() - // }, - // attachments: [{ - // filename: 'logo.png', - // path: path.join(__dirname, 'public', 'img', 'logo.png'), - // cid: 'logo' - // }] - // }; - // transporter.sendMail(mailOptions, function(error, info){ - // if (error) { - // console.log(error); - // } else { - // console.log('Email sent: ' + info.response); - // } - // }); - - // console.log('NGO registered successfully'); - // res.status(200).json({ message: 'NGO registered successfully' }); - - // }) - // .catch((err) => { - // console.error('Error creating NGO:', err); - // res.status(500).json({ error: 'Internal server error' }); - // }); -}); + // newNGO.save() + // .then((ngo) => { + // let mailOptions = { + // to: ngo.username, + // subject: 'Welcome To Petari', + // template: 'Email.template', + // context: { + // ngo: { + // ngoName: ngo.name, + // _id: ngo._id, + // username: ngo.password, + // }, + // year: new Date().getFullYear() + // }, + // attachments: [{ + // filename: 'logo.png', + // path: path.join(__dirname, 'public', 'img', 'logo.png'), + // cid: 'logo' + // }] + // }; + // transporter.sendMail(mailOptions, function(error, info){ + // if (error) { + // console.log(error); + // } else { + // console.log('Email sent: ' + info.response); + // } + // }); + // console.log('NGO registered successfully'); + // res.status(200).json({ message: 'NGO registered successfully' }); + // }) + // .catch((err) => { + // console.error('Error creating NGO:', err); + // res.status(500).json({ error: 'Internal server error' }); + // }); +}); -module.exports = router \ No newline at end of file +module.exports = router; diff --git a/routers/adminRoutes.js b/routers/adminRoutes.js index 4f5782f..cbd6110 100644 --- a/routers/adminRoutes.js +++ b/routers/adminRoutes.js @@ -1,113 +1,309 @@ -const express = require("express") -const router = new express.Router() +const express = require("express"); +const router = new express.Router(); -const bcrypt=require("bcrypt") +const bcrypt = require("bcrypt"); const saltRounds = 10; const jwt = require("jsonwebtoken"); -const User=require("../model/user") -const Admin=require("../model/admin") -const NGO=require("../model/ngo") +const User = require("../model/user"); +const Admin = require("../model/admin"); +const NGO = require("../model/ngo"); const Query = require("../model/query"); // Adjust the path based on your project structure -const problem=require("../model/query") - - -const {transporter}=require("../helpers/emailHelpers") +const problem = require("../model/query"); +const { transporter } = require("../helpers/emailHelpers"); +const ad = Admin({ + username: "sahilkaitha@gmail.com", + password: "123", + fullName: "Sahil Hossain", + Mobile: "9635955320", +}); +ad.save(); -const ad = Admin({email:"sahilkaitha@gmail.com",password:"123",fullName:"Sahil Hossain",Mobile:"9635955320"}) -ad.save() +router.post("/admin-login", async (req, res) => { + const username = req.body.username; + const password = req.body.password; + const admin = await Admin.findOne({ username: username, password: password }); + console.log(admin); + try { + const dooner = await User.find(); // Assuming User is your Mongoose model for users + const ngo = await NGO.find(); -router.post("/admin-login", async (req, res) => { - const email = req.body.email; - const password = req.body.password; - - - const admin = await Admin.findOne({ email , password }); - console.log(admin); - try { - const dooner = await User.find(); // Assuming User is your Mongoose model for users - const ngo=await NGO.find() - - const query1 = await problem.find(); - res.render("Admin_Dashboard", { - name: admin.fullName, - email: admin.fullName, - mobile:admin.Mobile, - username:admin.username, - id: admin._id, - NGOname: ngo, - Donername: dooner, - UserName: "sahil114", - complain:query1 - }); - } catch (err) { - console.error(err); - res.status(500).send("An internal server error occurred."); - } + const query1 = await problem.find(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (err) { + console.error(err); + res.status(500).send("An internal server error occurred."); + } }); - router.get("/admin-logout", function (req, res) { - - return res.redirect("/"); - }); - + return res.redirect("/"); +}); -router.get("/Ngo-Registration",async(req,res)=>{ - res.render("NGO-Registration") - }); +router.get("/Ngo-Registration", async (req, res) => { + res.render("NGO-Registration"); +}); // Assume you have a route for rendering the admin dashboard // Assuming `pendingNGOs` is an array of pending NGOs router.get("/admin-dashboard", async function (req, res) { - try { - const pendingNGOs = await NGO.find({ status: 'pending' }); - res.render("admin_dashboard", { pendingNGOs }); - } catch (error) { - console.error(error); - res.status(500).send("Internal Server Error"); + try { + const pendingNGOs = await NGO.find({ status: "pending" }); + res.render("admin_dashboard", { pendingNGOs }); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } +}); + +router.post("/approve-ngo/:id/:userId", async (req, res) => { + console.log("approve ngo call"); + const ngoId = req.params.id; + const userId = req.params.userId; + try { + const ngo1 = await NGO.findById(ngoId); + if (!ngo1) { + return res.status(404).json({ error: "NGO not found" }); + } + + // Update the NGO's approval status + + ngo1.approved = true; + await ngo1.save(); + + // Send an email to the NGO with the approved details + // let mailOptions = { + // to: ngo.username, + // subject: "NGO Registration Approved", + // text: "Your NGO registration has been approved. You can now login to your account.", + // // Include any necessary information in the email body + // }; + // transporter.sendMail(mailOptions, function (error, info) { + // if (error) { + // console.log(error); + // } else { + // console.log("Email sent: " + info.response); + // } + // }); + + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (error) { + console.error("Error approving NGO:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + +//making POST request for decline ngo +router.post("/decline-ngo/:id/:userId", async (req, res) => { + const ngoId = req.params.id; + const userId = req.params.userId; + try { + const ngo1 = await NGO.findById(ngoId); + if (!ngo1) { + return res.status(404).json({ error: "NGO not found" }); + } + + //DELETING NGO from database + await NGO.findByIdAndDelete(ngoId); + + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (error) { + console.error("Error declining NGO:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + +// making POST method for declining the DONOR request +router.post("/decline-donor/:id/:userId", async (req, res) => { + const donorId = req.params.id; + const userId = req.params.userId; + try { + const donor = await User.findById(donorId); + if (!donor) { + return res.status(404).json({ error: "Donor not found" }); + } + + //DELETING donor request from data base + await User.findByIdAndDelete(donorId); + + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (error) { + console.error("Error declining doner:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + +// making POST method for acceptiog the DONOR request +router.post("/accept-donor/:id/:userId", async (req, res) => { + const donorId = req.params.id; + const userId = req.params.userId; + try { + const donor = await User.findById(donorId); + if (!donor) { + return res.status(404).json({ error: "Donor not found" }); } - }); - - router.post('/approve-ngo/:id', async (req, res)=> { - const ngoId = req.params.id; - - try { - - const ngo = await NGO.findById(ngoId); - if (!ngo) { - return res.status(404).json({ error: "NGO not found" }); - } - - // Update the NGO's approval status - - ngo.approved = true; - await ngo.save(); - - // Send an email to the NGO with the approved details - let mailOptions = { - to: ngo.username, - subject: 'NGO Registration Approved', - text: 'Your NGO registration has been approved. You can now login to your account.', - // Include any necessary information in the email body - }; - transporter.sendMail(mailOptions, function (error, info) { - if (error) { - console.log(error); - } else { - console.log('Email sent: ' + info.response); - } - }); - - res.status(200).json({ message: "NGO approved successfully" }); - } catch (error) { - console.error("Error approving NGO:", error); - res.status(500).json({ error: "Internal server error" }); - } + + //ACCEPTING donor request from data base + donor.approved = true; + await donor.save(); + + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (error) { + console.error("Error declining doner:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); + +//making DELETE method for DELETING the complaints +router.post("/delete-complain/:id/:userId", async (req, res) => { + const compId = req.params.id; + const userId = req.params.userId; + const comp = await problem.findById(compId); + if (!comp) { + return res.status(404).json({ error: "Complain not found" }); + } + try { + //DELETING the complain from data base + await problem.findByIdAndDelete(compId); + + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, }); + } catch (error) { + res.status(500).jso({ error: "Internal server error" }); + } +}); + +//making POST method for accepting the complaints +router.post("/accept-complain/:id/:userId", async (req, res) => { + const compId = req.params.id; + const userId = req.params.userId; + const comp = await problem.findById(compId); + if (!comp) { + return res.status(404).json({ error: "Complain not found" }); + } + try { + //ACCEPTING the complain from data base + comp.approved = true; + await comp.save(); + // navigating to the admin dashboard + 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(); + res.render("Admin_Dashboard", { + name: admin.fullName, + email: admin.fullName, + mobile: admin.Mobile, + username: admin.username, + id: admin._id, + NGOname: ngo, + Donername: dooner, + UserName: "sahil114", + complain: query1, + }); + } catch (error) { + res.status(500).jso({ error: "Internal server error" }); + } +}); -module.exports = router \ No newline at end of file +module.exports = router; diff --git a/routers/userRoutes.js b/routers/userRoutes.js index f12da8a..673704c 100644 --- a/routers/userRoutes.js +++ b/routers/userRoutes.js @@ -1,220 +1,284 @@ -const express = require("express") -const router = new express.Router() +const express = require("express"); +const router = new express.Router(); -const bcrypt=require("bcrypt") +const bcrypt = require("bcrypt"); const saltRounds = 10; const jwt = require("jsonwebtoken"); -const User=require("../model/user") +const User = require("../model/user"); const Query = require("../model/query"); // Adjust the path based on your project structure -const {transporter}=require("../helpers/emailHelpers") - +const { transporter } = require("../helpers/emailHelpers"); +const NGO = require("../model/ngo"); router.get("/", function (req, res) { - res.render("index"); + res.render("index"); }); router.get("/user_login", function (req, res) { - res.render("user_login"); + res.render("user_login"); }); router.get("/Ngo_login", function (req, res) { - res.render("NGO_login"); + res.render("NGO_login"); }); router.get("/admin_login", function (req, res) { - res.render("admin_login"); + res.render("admin_login"); }); router.get("/User_singUp", function (req, res) { - res.render("User_singUp"); + res.render("User_singUp"); }); router.get("/success", function (req, res) { - res.render("success"); + res.render("success"); }); - router.post("/", async function (req, res) { - try { - const newQuery = new Query({ - name: req.body.Fname, - email: req.body.Email, - subject: req.body.sub, - message: req.body.sms, + try { + const newQuery = new Query({ + name: req.body.Fname, + email: req.body.Email, + subject: req.body.sub, + message: req.body.sms, }); - - - await newQuery.save(); - - res.status(200).send("Successfully Received Message... Thank You!"); - console.log(newQuery); - } catch (error) { - console.error(error); - res.status(500).send("Internal Server Error"); - } - }); - // user login (seems to be something wrong here - user cant login even if he gives correct credentials) + await newQuery.save(); + + res.status(200).send("Successfully Received Message... Thank You!"); + console.log(newQuery); + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } +}); + +// 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; - - try { - const foundUser = await User.findOne({ email:username }); - - if (!foundUser) { - return res.render("loginError", { message: 'User not found' }); - } - - const result = await bcrypt.compare(password, foundUser.password); - - if (result) { - return res.render("UserDashBoard" , {fullName :foundUser.fullName,email :foundUser.email,phoneNo :foundUser.Mobile,address :foundUser.address}); - } else { - return res.render("loginError", { message: 'Incorrect password' }); - } - } catch (error) { - console.error('Error during login:', error); - return res.status(500).send('Internal Server Error'); + const { username, password } = req.body; + + try { + const foundUser = await User.findOne({ email: username }); + + if (!foundUser) { + return res.render("loginError", { message: "User not found" }); } - }); - router.route("/forgot-password").get(async (req, res) => { - res.render("forget-password"); - }) - -router.route("/reset-password").get(async (req, res) => { - const { email, token } = req.query; + const result = await bcrypt.compare(password, foundUser.password); - try { - const user = await User.findOne({ email, resetToken: token, resetTokenExpiration: { $gt: Date.now() } }); + if (result) { + return res.render("UserDashBoard", { + fullName: foundUser.fullName, + email: foundUser.email, + phoneNo: foundUser.Mobile, + address: foundUser.address, + }); + } else { + return res.render("loginError", { message: "Incorrect password" }); + } + } catch (error) { + console.error("Error during login:", error); + return res.status(500).send("Internal Server Error"); + } +}); - if (!user) { - return res.status(400).send("Invalid or expired reset token"); - } +router.route("/forgot-password").get(async (req, res) => { + res.render("forget-password"); +}); - // Verify the token - try { - const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); - // Process the decoded token (e.g., extract information from it) - console.log(decodedToken); - // Continue with the reset-password logic - res.render("reset-password", { email, token }); - } catch (error) { - // Handle JWT verification errors - console.error('JWT verification error:', error.message); - // You might want to send an error response or redirect the user - res.status(401).send('Unauthorized'); - } +router.route("/reset-password").get(async (req, res) => { + const { email, token } = req.query; + try { + const user = await User.findOne({ + email, + resetToken: token, + resetTokenExpiration: { $gt: Date.now() }, + }); + + if (!user) { + return res.status(400).send("Invalid or expired reset token"); + } + + // Verify the token + try { + const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); + // Process the decoded token (e.g., extract information from it) + console.log(decodedToken); + // Continue with the reset-password logic + res.render("reset-password", { email, token }); } catch (error) { - console.error(error); - res.status(500).send("Internal Server Error"); + // Handle JWT verification errors + console.error("JWT verification error:", error.message); + // You might want to send an error response or redirect the user + res.status(401).send("Unauthorized"); } - }) - + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } +}); router.post(async (req, res) => { - const { email, token, newPassword } = req.body; - - try { - // Verify the token again - const user = await User.findOne({ email, resetToken: token, resetTokenExpiration: { $gt: Date.now() } }); + const { email, token, newPassword } = req.body; - if (!user) { - return res.status(400).send("Invalid or expired reset token"); - } + try { + // Verify the token again + const user = await User.findOne({ + email, + resetToken: token, + resetTokenExpiration: { $gt: Date.now() }, + }); - try { - const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); - // Process the decoded token (e.g., extract information from it) - console.log(decodedToken); - - // Update the user's password and reset the resetToken fields - const hash = await bcrypt.hash(newPassword, saltRounds); - user.password = hash; - user.resetToken = null; - user.resetTokenExpiration = null; - await user.save(); - - res.redirect("/login"); // Redirect to login page or any other desired page - } catch (error) { - // Handle JWT verification errors - console.error('JWT verification error:', error.message); - // You might want to send an error response or redirect the user - res.status(401).send('Unauthorized'); - } - } catch (error) { - console.error(error); - res.status(500).send("Internal Server Error"); + if (!user) { + return res.status(400).send("Invalid or expired reset token"); } - }); - - // extra details added for the user -router.post('/add-details', async (req, res) => { try { - // Find the user by their email - let user = await User.findOne({ email: req.body.email }); - - // If the user exists, update their details - if (user) { - // Update the user's details - user.flatNo = req.body.flatNo; - user.addressLine1 = req.body.addressLine1; - user.addressLine2 = req.body.addressLine2; - user.city = req.body.city; - user.state = req.body.state; - user.zip = req.body.zip; - user.foodInventory.push({ foodItem: req.body.foodItem, quantity: req.body.quantity }); - - // Save the updated user document - await user.save(); - res.status(200).json({ message: 'Details added successfully' }); - } else { - res.status(404).json({ error: 'User not found' }); - } + const decodedToken = jwt.verify(token, process.env.ACCESS_TOKEN_SECRET); + // Process the decoded token (e.g., extract information from it) + console.log(decodedToken); + + // Update the user's password and reset the resetToken fields + const hash = await bcrypt.hash(newPassword, saltRounds); + user.password = hash; + user.resetToken = null; + user.resetTokenExpiration = null; + await user.save(); + + res.redirect("/login"); // Redirect to login page or any other desired page } catch (error) { - console.error('Error adding details:', error); - res.status(500).json({ error: 'Internal server error' }); + // Handle JWT verification errors + console.error("JWT verification error:", error.message); + // You might want to send an error response or redirect the user + res.status(401).send("Unauthorized"); } + } catch (error) { + console.error(error); + res.status(500).send("Internal Server Error"); + } }); +// extra details added for the user +router.post("/add-details", async (req, res) => { + try { + // Find the user by their email + let user = await User.findOne({ email: req.body.email }); + + // If the user exists, update their details + if (user) { + // Update the user's details + user.flatNo = req.body.flatNo; + user.addressLine1 = req.body.addressLine1; + user.addressLine2 = req.body.addressLine2; + user.city = req.body.city; + user.state = req.body.state; + user.zip = req.body.zip; + user.foodInventory.push({ + foodItem: req.body.foodItem, + quantity: req.body.quantity, + }); + + // Save the updated user document + const saveDetails = await user.save(); + if (saveDetails) { + res.status(200).json({ message: "Details added successfully" }); + console.log("added details", saveDetails); + } + } else { + res.status(404).json({ error: "User not found" }); + } + } catch (error) { + console.error("Error adding details:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); // user delete from the databse +router.post("/delete-details/:email/:ngoEmail", async (req, res) => { + const ngoEmail = req.params.ngoEmail; + try { + // Find the user by their email + let user = await User.findOne({ email: req.params.email }); + + // If the user exists, delete their details + if (user) { + // Update the user's details + user.flatNo = ""; + user.addressLine1 = ""; + user.addressLine2 = ""; + user.city = ""; + user.state = ""; + user.zip = ""; + user.foodInventory = []; + user.approved = false; + + // Save the updated user document + await user.save(); + + //navigating to the NGO DASHBOARD + const ngo = await NGO.findOne({ username: ngoEmail }); + const dooner = await User.find(); // Assuming User is your Mongoose model for users + + res.render("NGO-Dashboard", { + fullName: ngo.NGOName, + email: ngo.username, + id: ngo.NGOID, + phoneNo: ngo.Mobile, + address: ngo.NGOLocation, + Donation: dooner, + Pickup: dooner, + complain: "", + }); + } else { + res.status(404).json({ error: "User not found" }); + } + } catch (error) { + console.error("Error deleting details:", error); + res.status(500).json({ error: "Internal server error" }); + } +}); -router.post("/delete-details", async (req, res) => { +//making a POST method for accepting the USER DONATION +router.post("/approve-donation/:email/:ngoEmail", async (req, res) => { + const ngoEmail = req.params.ngoEmail; try { - // Find the user by their email - let user = await User.findOne({ email: req.body.email }); - - // If the user exists, delete their details - if (user) { - // Update the user's details - user.flatNo = ""; - user.addressLine1 = ""; - user.addressLine2 = ""; - user.city = ""; - user.state = ""; - user.zip = ""; - user.foodInventory = []; - - // Save the updated user document - await user.save(); - res.status(200).json({ message: 'Details deleted successfully' }); - } else { - res.status(404).json({ error: 'User not found' }); - } + // Find the user by their email + let user = await User.findOne({ email: req.params.email }); + + // If the user exists, approved their donation + if (user) { + user.approved = true; + + // Save the updated user document + await user.save(); + + const ngo = await NGO.findOne({ username: ngoEmail }); + //navigating to the NGO DASHBOARD + const dooner = await User.find(); // Assuming User is your Mongoose model for users + + res.render("NGO-Dashboard", { + fullName: ngo.NGOName, + email: ngo.username, + id: ngo.NGOID, + phoneNo: ngo.Mobile, + address: ngo.NGOLocation, + Donation: dooner, + Pickup: dooner, + complain: "", + }); + } else { + res.status(404).json({ error: "User not found" }); + } } catch (error) { - console.error('Error deleting details:', error); - res.status(500).json({ error: 'Internal server error' }); + console.error("Error approving donation:", error); + res.status(500).json({ error: "Internal server error" }); } }); router.get("/logout", function (req, res) { - - return res.redirect("/"); + return res.redirect("/"); }); // user Registration @@ -222,69 +286,71 @@ router.post("/User_singUp", async function (req, res) { const { username } = req.body; try { - // Check if the email already exists - const existingUser = await User.findOne({ email: username }).exec(); - - if (existingUser) { - // Email already exists, handle accordingly (e.g., show an error message) - return res.render("registrationError", { message: 'Email is already registered' }); - } + // Check if the email already exists + const existingUser = await User.findOne({ email: username }).exec(); - // Email does not exist, proceed with user registration - const hash = await bcrypt.hash(req.body.password, saltRounds); - - const newUser = new User({ - username: username, - fullName: req.body.fname, - Mobile: req.body.phn, - address: req.body.address, - dob: req.body.dob, - gender: req.body.gender, - email: username, - password: hash + if (existingUser) { + // Email already exists, handle accordingly (e.g., show an error message) + return res.render("registrationError", { + message: "Email is already registered", }); + } - await newUser.save() - .then((user) => { - let mailOptions = { - to: user.email, - subject: 'Welcome To Petari', - template: 'Email.template', - context: { - user: { - fname: user.fullName, - _id: user._id, - username: user.fullName, - email: user.email - }, - year: new Date().getFullYear() - }, - attachments: [{ - filename: 'logo.png', - path: path.join(__dirname, 'public', 'img', 'logo.png'), - cid: 'logo' - }] - }; - transporter.sendMail(mailOptions, function(error, info){ - if (error) { - console.log(error); - } else { - console.log('Email sent: ' + info.response); - } - }); - - }) + // Email does not exist, proceed with user registration + const hash = await bcrypt.hash(req.body.password, saltRounds); + + const newUser = new User({ + username: username, + fullName: req.body.fname, + Mobile: req.body.phn, + address: req.body.address, + dob: req.body.dob, + gender: req.body.gender, + email: username, + password: hash, + }); - return res.render("UserDashBoard", { - fullName: req.body.fname, - email: username, - phoneNo: req.body.phn, - address: req.body.address - // Do not include 'profile' here unless it's relevant to registration + await newUser.save().then((user) => { + let mailOptions = { + to: user.email, + subject: "Welcome To Petari", + template: "Email.template", + context: { + user: { + fname: user.fullName, + _id: user._id, + username: user.fullName, + email: user.email, + }, + year: new Date().getFullYear(), + }, + attachments: [ + { + filename: "logo.png", + path: path.join(__dirname, "public", "img", "logo.png"), + cid: "logo", + }, + ], + }; + transporter.sendMail(mailOptions, function (error, info) { + if (error) { + console.log(error); + } else { + console.log("Email sent: " + info.response); + } }); + }); + + return res.render("UserDashBoard", { + fullName: req.body.fname, + email: username, + phoneNo: req.body.phn, + address: req.body.address, + // Do not include 'profile' here unless it's relevant to registration + }); } catch (error) { - console.error('Error during user registration:', error); - return res.status(500).send('Internal Server Error'); + console.error("Error during user registration:", error); + return res.status(500).send("Internal Server Error"); } }); @@ -297,38 +363,42 @@ router.post(async (req, res) => { } // Generate a reset token and save it to the user - const resetToken = jwt.sign({ email: user.email }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: "1h" }); + const resetToken = jwt.sign( + { email: user.email }, + process.env.ACCESS_TOKEN_SECRET, + { expiresIn: "1h" } + ); user.resetTokenExpiration = Date.now() + 300000; // 5 minutes await user.save(); // Send the reset link to the user via email - const resetLink = `http://localhost:3000/reset-password?email=${encodeURIComponent(user.email)}&token=${encodeURIComponent(resetToken)}`; - ; // Replace with the actual path to your logo -console.log(resetLink); + const resetLink = `http://localhost:3000/reset-password?email=${encodeURIComponent( + user.email + )}&token=${encodeURIComponent(resetToken)}`; // Replace with the actual path to your logo + console.log(resetLink); const mailOptions = { to: user.email, - subject: 'Password Reset', - template: 'reset-password', // Use the Handlebars template + subject: "Password Reset", + template: "reset-password", // Use the Handlebars template context: { user: { fname: user.fullName, _id: user._id, username: user.username, - email: user.email - + email: user.email, }, resetLink, - }, - attachments: [{ - filename: 'logo.png', - path: path.join(__dirname, 'public', 'img', 'logo.png'), - cid: 'logo' - }] - + attachments: [ + { + filename: "logo.png", + path: path.join(__dirname, "public", "img", "logo.png"), + cid: "logo", + }, + ], }; - console.log('User email:', user.email); + console.log("User email:", user.email); transporter.sendMail(mailOptions, (error, info) => { if (error) { @@ -344,4 +414,4 @@ console.log(resetLink); } }); -module.exports = router \ No newline at end of file +module.exports = router; diff --git a/views/Admin_Dashboard.ejs b/views/Admin_Dashboard.ejs index cfbc259..26bb159 100644 --- a/views/Admin_Dashboard.ejs +++ b/views/Admin_Dashboard.ejs @@ -62,7 +62,7 @@ } .top-border { - + border-style: double; border-color: #F07070; } @@ -112,11 +112,12 @@ cursor: pointer; z-index: 2; } - .dash{ + + .dash { position: fixed; left: 35px; } - + /* aditya End */ /* colors */ @@ -261,204 +262,202 @@ background-color: #333; color: #FFF; } + body.dark .top { background-color: #333; color: #FFF; } - button{ + button { border-radius: 50%; padding: 10px; background-color: rgb(55, 153, 55); } /* CSS Styles */ -.section-title { - text-align: center; - margin-bottom: 2rem; - font-size: 1.5rem; -} - -.donor-list { - list-style-type: none; - padding: 0; - margin: 0; -} - -.donor-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 1rem; - border-bottom: 1px solid #ccc; -} - -.donor-name { - font-weight: bold; -} - -.donor-actions { - display: flex; - gap: 0.5rem; -} - -.btn-accept, -.btn-decline { - padding: 0.5rem 1rem; - border: none; - border-radius: 0.25rem; - cursor: pointer; -} - -.btn-accept { - background-color: rgb(88, 167, 88); - color: white; -} - -.btn-decline { - background-color: red; - color: white; -} - -.NGO-sec { - margin: 20px auto; - max-width: 800px; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.donor-list { - list-style-type: none; - padding: 0; -} - -.donor-item { - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid #eee; - padding: 10px 0; -} - -.donor-details { - flex-grow: 1; -} - -.donor-actions { - flex-shrink: 0; -} - -.btn-accept, -.btn-decline { - padding: 5px 10px; - border: none; - border-radius: 3px; - background-color: #4CAF50; - color: white; - cursor: pointer; - margin-right: 5px; -} - -.btn-decline { - background-color: #f44336; -} -.Doners-sec { - margin: 20px auto; - max-width: 800px; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.donor-list { - list-style-type: none; - padding: 0; -} - -.donor-item { - display: flex; - justify-content: space-between; - align-items: center; - border-bottom: 1px solid #eee; - padding: 10px 0; -} - -.donor-details { - flex-grow: 1; -} - -.donor-actions { - flex-shrink: 0; -} - -.btn-accept, -.btn-decline { - padding: 5px 10px; - border: none; - border-radius: 3px; - background-color: #4CAF50; - color: white; - cursor: pointer; - margin-right: 5px; -} - -.btn-decline { - background-color: #f44336; -} - - -.Complains-sec { - display: flex; - flex-direction: column; - align-items: center; - margin-top: 2rem; -} - -.donor-list { - list-style-type: none; - padding: 0; - margin: 0; -} - -.donor-item { - background-color: #f9f9f9; - border-radius: 8px; - padding: 1rem; - margin-bottom: 1rem; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.donor-details { - display: flex; - flex-direction: column; -} - -.donor-name { - font-weight: bold; - margin-bottom: 0.5rem; -} - -.donor-email { - color: #666; - margin-bottom: 0.5rem; -} - -.donor-message { - margin-bottom: 0.5rem; -} - -/* Optional: Hover effect */ -.donor-item:hover { - background-color: #f0f0f0; - transition: background-color 0.3s; -} + .section-title { + text-align: center; + margin-bottom: 2rem; + font-size: 1.5rem; + } + + .donor-list { + list-style-type: none; + padding: 0; + margin: 0; + } + + .donor-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 1rem; + border-bottom: 1px solid #ccc; + } + + .donor-name { + font-weight: bold; + } + + .donor-actions { + display: flex; + gap: 0.5rem; + } + + .btn-accept, + .btn-decline { + padding: 0.5rem 1rem; + border: none; + border-radius: 0.25rem; + cursor: pointer; + } + + .btn-accept { + background-color: rgb(88, 167, 88); + color: white; + } + + .btn-decline { + background-color: red; + color: white; + } + + .NGO-sec { + margin: 20px auto; + max-width: 800px; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + .donor-list { + list-style-type: none; + padding: 0; + } + + .donor-item { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #eee; + padding: 10px 0; + } + .donor-details { + flex-grow: 1; + } + .donor-actions { + flex-shrink: 0; + } + .btn-accept, + .btn-decline { + padding: 5px 10px; + border: none; + border-radius: 3px; + background-color: #4CAF50; + color: white; + cursor: pointer; + margin-right: 5px; + } + + .btn-decline { + background-color: #f44336; + } + .Doners-sec { + margin: 20px auto; + max-width: 800px; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + .donor-list { + list-style-type: none; + padding: 0; + } + + .donor-item { + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid #eee; + padding: 10px 0; + } + + .donor-details { + flex-grow: 1; + } + + .donor-actions { + flex-shrink: 0; + } + + .btn-accept, + .btn-decline { + padding: 5px 10px; + border: none; + border-radius: 3px; + background-color: #4CAF50; + color: white; + cursor: pointer; + margin-right: 5px; + } + + .btn-decline { + background-color: #f44336; + } + + + .Complains-sec { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 2rem; + } + + .donor-list { + list-style-type: none; + padding: 0; + margin: 0; + } + + .donor-item { + background-color: #f9f9f9; + border-radius: 8px; + padding: 1rem; + margin-bottom: 1rem; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + } + + .donor-details { + display: flex; + flex-direction: column; + } + + .donor-name { + font-weight: bold; + margin-bottom: 0.5rem; + } + + .donor-email { + color: #666; + margin-bottom: 0.5rem; + } + + .donor-message { + margin-bottom: 0.5rem; + } + + /* Optional: Hover effect */ + .donor-item:hover { + background-color: #f0f0f0; + transition: background-color 0.3s; + } @@ -469,7 +468,7 @@ - +
@@ -478,90 +477,201 @@
DashBoard
Welcome, <%= email %>!
- +
- -

Full Name: <%= name %>

- - - - + +

Full Name: <%= name %> +

+ + + +
- + - - - + + +
- + - +