diff --git a/backend/.env.sample b/backend/.env.sample index 3d377ae..5cd7ffa 100644 --- a/backend/.env.sample +++ b/backend/.env.sample @@ -1,6 +1,7 @@ EMAIL_USER=your_gmail #your email EMAIL_USER=your_gmail +MONGODB_URI= # To create a passkey on the phone or computer you’re on: diff --git a/backend/controllers/complaintController.js b/backend/controllers/complaintController.js new file mode 100644 index 0000000..e010865 --- /dev/null +++ b/backend/controllers/complaintController.js @@ -0,0 +1,47 @@ + +import nodemailer from 'nodemailer' +import Complaint from '../models/Complaint.js'; + +const transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS + } +}); + + +const sendConfirmationEmail = (email, name) => { + const mailOptions = { + from: process.env.EMAIL_USER, + to: email, + subject: 'Complaint Received - Station Saarthi', + text: `Dear ${name},\n\nThank you for submitting your complaint. We have received your complaint and will look into the matter soon.\n\nBest regards,\nStation Saarthi` + }; + + return transporter.sendMail(mailOptions); +}; + +const submitComplaint = async (req, res) => { + const { name, phoneNumber, email, complain } = req.body; + + if (!name || !phoneNumber || !email || !complain) { + return res.status(400).json({ message: 'All fields are required.' }); + } + + try { + // Create a new complaint record in the database + const newComplaint = new Complaint({ name, phoneNumber, email, complain }); + await newComplaint.save(); + + // Send a confirmation email to the user + await sendConfirmationEmail(email, name); + + res.status(200).json({ message: 'Complaint submitted successfully! We will get back to you soon.' }); + } catch (error) { + console.error('Error submitting complaint:', error); + res.status(500).json({ message: 'There was an error submitting your complaint. Please try again later.' }); + } + } + +export default submitComplaint; \ No newline at end of file diff --git a/backend/index.js b/backend/index.js index 7eb5448..88e9e76 100644 --- a/backend/index.js +++ b/backend/index.js @@ -31,9 +31,11 @@ import authRoutes from "./routes/authRoutes.js"; import stationRoutes from "./routes/stationRoutes.js"; import trainRoutes from "./routes/trainRoutes.js"; import contactUs from "./routes/contactUsRouter.js"; +import complaintRoutes from "./routes/complaintRoutes.js"; app.use("/auth", authRoutes); app.use("/api", authRoutes); +app.use("/api", complaintRoutes); app.use("/station", stationRoutes); app.use("/train", trainRoutes); app.use("/contact", contactUs); diff --git a/backend/models/Complaint.js b/backend/models/Complaint.js new file mode 100644 index 0000000..70c7e9a --- /dev/null +++ b/backend/models/Complaint.js @@ -0,0 +1,27 @@ +import mongoose from "mongoose"; + +const complaintSchema = new mongoose.Schema({ + name: { + type: String, + required: true + }, + phoneNumber: { + type: String, + required: true + }, + email: { + type: String, + required: true + }, + complain: { + type: String, + required: true + }, + createdAt: { + type: Date, + default: Date.now + } +}); + +const Complaint = mongoose.model('Complaint', complaintSchema); +export default Complaint; diff --git a/backend/package-lock.json b/backend/package-lock.json index a8bc557..627068b 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -18,9 +18,9 @@ "express": "^4.21.1", "express-rate-limit": "^7.4.1", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.7.0", + "mongoose": "^8.8.0", "node": "^22.8.0", - "nodemailer": "^6.9.15", + "nodemailer": "^6.9.16", "nodemon": "^3.1.7", "socket.io": "^4.8.0" } @@ -219,7 +219,6 @@ "version": "1.1.9", "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.9.tgz", "integrity": "sha512-tVkljjeEaAhCqTzajSdgbQ6gE6f3oneVwa3iXR6csiEwXXOFsiC6Uh9iAjAhXPtqa/XMDHWjjeNH/77m/Yq2dw==", - "license": "MIT", "dependencies": { "sparse-bitfield": "^3.0.3" } @@ -269,14 +268,12 @@ "node_modules/@types/webidl-conversions": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz", - "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==", - "license": "MIT" + "integrity": "sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==" }, "node_modules/@types/whatwg-url": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-11.0.5.tgz", "integrity": "sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==", - "license": "MIT", "dependencies": { "@types/webidl-conversions": "*" } @@ -570,10 +567,9 @@ } }, "node_modules/bson": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.8.0.tgz", - "integrity": "sha512-iOJg8pr7wq2tg/zSlCCHMi3hMm5JTOxLTagf3zxhcenHsFp+c6uOs6K7W5UE7A4QIJGtqh/ZovFNMP4mOPJynQ==", - "license": "Apache-2.0", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.9.0.tgz", + "integrity": "sha512-X9hJeyeM0//Fus+0pc5dSUMhhrrmWwQUtdavaQeF3Ta6m69matZkGWV/MrBcnwUeLC8W9kwwc2hfkZgUuCX3Ig==", "engines": { "node": ">=16.20.1" } @@ -935,7 +931,6 @@ "version": "16.4.5", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -1113,7 +1108,6 @@ "version": "4.21.1", "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -1951,8 +1945,7 @@ "node_modules/memory-pager": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", - "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", - "license": "MIT" + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==" }, "node_modules/merge-descriptors": { "version": "1.0.3", @@ -2080,10 +2073,9 @@ } }, "node_modules/mongodb": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.9.0.tgz", - "integrity": "sha512-UMopBVx1LmEUbW/QE0Hw18u583PEDVQmUmVzzBRH0o/xtE9DBRA5ZYLOjpLIa03i8FXjzvQECJcqoMvCXftTUA==", - "license": "Apache-2.0", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-6.10.0.tgz", + "integrity": "sha512-gP9vduuYWb9ZkDM546M+MP2qKVk5ZG2wPF63OvSRuUbqCR+11ZCAE1mOfllhlAG0wcoJY5yDL/rV3OmYEwXIzg==", "dependencies": { "@mongodb-js/saslprep": "^1.1.5", "bson": "^6.7.0", @@ -2129,21 +2121,19 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-3.0.1.tgz", "integrity": "sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==", - "license": "Apache-2.0", "dependencies": { "@types/whatwg-url": "^11.0.2", "whatwg-url": "^13.0.0" } }, "node_modules/mongoose": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.7.1.tgz", - "integrity": "sha512-RpNMyhyzLVCVbf8xTVbrf/18G3MqQzNw5pJdvOJ60fzbCa3cOZzz9L+8XpqzBXtRlgZGWv0T7MmOtvrT8ocp1Q==", - "license": "MIT", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-8.8.0.tgz", + "integrity": "sha512-KluvgwnQB1GPOYZZXUHJRjS1TW6xxwTlf/YgjWExuuNanIe3W7VcR7dDXQVCIRk8L7NYge8EnoTcu2grWtN+XQ==", "dependencies": { "bson": "^6.7.0", "kareem": "2.6.3", - "mongodb": "6.9.0", + "mongodb": "~6.10.0", "mpath": "0.9.0", "mquery": "5.0.0", "ms": "2.1.3", @@ -2323,10 +2313,9 @@ } }, "node_modules/nodemailer": { - "version": "6.9.15", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", - "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", - "license": "MIT-0", + "version": "6.9.16", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.16.tgz", + "integrity": "sha512-psAuZdTIRN08HKVd/E8ObdV6NO7NTBY3KsC30F7M4H1OnmLCUNaS56FpYxyb26zWLSyYF9Ozch9KYHhHegsiOQ==", "engines": { "node": ">=6.0.0" } @@ -2616,7 +2605,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "license": "MIT", "engines": { "node": ">=6" } @@ -2987,7 +2975,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", - "license": "MIT", "dependencies": { "memory-pager": "^1.0.2" } @@ -3126,7 +3113,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "license": "MIT", "dependencies": { "punycode": "^2.3.0" }, @@ -3196,7 +3182,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", "engines": { "node": ">=12" } @@ -3205,7 +3190,6 @@ "version": "13.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", - "license": "MIT", "dependencies": { "tr46": "^4.1.1", "webidl-conversions": "^7.0.0" diff --git a/backend/package.json b/backend/package.json index d201d0b..9271c14 100644 --- a/backend/package.json +++ b/backend/package.json @@ -13,9 +13,9 @@ "express": "^4.21.1", "express-rate-limit": "^7.4.1", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.7.0", + "mongoose": "^8.8.0", "node": "^22.8.0", - "nodemailer": "^6.9.15", + "nodemailer": "^6.9.16", "nodemon": "^3.1.7", "socket.io": "^4.8.0" }, diff --git a/backend/routes/complaintRoutes.js b/backend/routes/complaintRoutes.js new file mode 100644 index 0000000..9aef63b --- /dev/null +++ b/backend/routes/complaintRoutes.js @@ -0,0 +1,11 @@ +// routes/complaint.js +import express from 'express' +import submitComplaint from '../controllers/complaintController.js'; + + +const router = express.Router(); + +// Handle complaint submission +router.post('/complaint', submitComplaint); + +export default router diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 7b0f140..4c23a5b 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -2887,7 +2887,6 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", diff --git a/frontend/src/Pages/ComplainBox.jsx b/frontend/src/Pages/ComplainBox.jsx index 07af57d..5da9187 100644 --- a/frontend/src/Pages/ComplainBox.jsx +++ b/frontend/src/Pages/ComplainBox.jsx @@ -1,107 +1,130 @@ -import React, { useState } from 'react'; - - import logo from '../assets/stationsaarthi.svg'; // Import your logo +import React, { useState } from 'react'; +import axios from 'axios'; +import logo from '../assets/stationsaarthi.svg'; // Import your logo const ComplainBox = () => { const [name, setName] = useState(''); const [phoneNumber, setPhoneNumber] = useState(''); const [email, setEmail] = useState(''); const [complain, setComplain] = useState(''); - - const handleComplain = (e) => { - e.preventDefault(); - - - // Handle login logic here - }; - - - return ( -
Your Trusted Platform Guide
-Your Trusted Platform Guide
+