Skip to content

Commit

Permalink
Merge branch 'dhairyagothi:main' into calender3
Browse files Browse the repository at this point in the history
  • Loading branch information
akash70629 authored Nov 8, 2024
2 parents be51bc4 + 0a71f93 commit 8313a5e
Show file tree
Hide file tree
Showing 68 changed files with 6,654 additions and 2,319 deletions.
69 changes: 60 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,43 @@
<div align="center">

# 🎨 STATION GUIDE 🖌️

<img src="https://readme-typing-svg.herokuapp.com?color=45ffaa&center=true&vCenter=true&size=40&width=900&height=80&lines=Welcome+to+Station+Guide!"/>
</div>

<div align = "center">
<br>

<table align="center">
<thead align="center">
<tr border: 1px;>
<td><b>🌟 Stars</b></td>
<td><b>🍴 Forks</b></td>
<td><b>🐛 Issues</b></td>
<td><b>🔔 Open PRs</b></td>
<td><b>🔕 Close PRs</b></td>
<td><b>🛠️ Languages</b></td>
<td><b>👥 Contributors</b></td>
</tr>
</thead>
<tbody>
<tr>
<td><img alt="Stars" src="https://img.shields.io/github/stars/dhairyagothi/StationGuide?style=flat&logo=github"/></td>
<td><img alt="Forks" src="https://img.shields.io/github/forks/dhairyagothi/StationGuide?style=flat&logo=github"/></td>
<td><img alt="Issues" src="https://img.shields.io/github/issues/dhairyagothi/StationGuide?style=flat&logo=github"/></td>
<td><img alt="Open Pull Requests" src="https://img.shields.io/github/issues-pr/dhairyagothi/StationGuide?style=flat&logo=github"/></td>
<td><img alt="Close Pull Requests" src="https://img.shields.io/github/issues-pr-closed/dhairyagothi/StationGuide?style=flat&color=critical&logo=github"/></td>
<td><img alt="GitHub language count" src="https://img.shields.io/github/languages/count/dhairyagothi/StationGuide?style=flat&color=green&logo=github"></td>
<td><img alt="GitHub Contributors count" src="https://img.shields.io/github/contributors/dhairyagothi/StationGuide?style=flat&color=blue&logo=github"/></td>
</tr>
</tbody>
</table>
</div>
<br>

<!--Line-->
<img src="https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif" width="900">

# STATION GUIDE : YOUR PLATFORM GUIDE
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

Expand Down Expand Up @@ -25,10 +65,14 @@ Welcome to repository of Station Guide
<!-- Added the GSSoc Accepted image -->
### This project is now OFFICIALLY accepted for

<div align="center">
<img src="https://github.com/apu52/METAVERSE/assets/114172928/e79eb6de-81b1-4ffb-b6ed-f018bb977e88" alt="GSSoC 2024 Extd" width="80%">
</div>
<br>
## 📋 Participating Programs

| Name | Logo | Purpose |
|-----------------------|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| GSSoC'2024-Extd | ![GSSoC Logo](assets/GSSoC-Ext.png) | The coding period is from October 1st to October 30th, during which contributors make contributions and earn points on the platform. |
| Hacktoberfest 2024 | ![Hacktoberfest Logo](assets/hacktoberfest.png) | Hacktoberfest is a month-long October event welcoming all skill levels to join the open-source community. |

---

<!--Line-->
<img src="https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif" width="900">
Expand All @@ -42,7 +86,7 @@ Welcome to repository of Station Guide
- **[Code of Conduct](#code-of-conduct)**
- **[How to Fork](#how-to-fork)**
- **[Contributors](#contributors)**
- **[Contact Information](#contact-information)**
- **[Contact Information](#-team)**

<!--Line-->
<img src="https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif" width="900">
Expand Down Expand Up @@ -403,10 +447,11 @@ Forking allows you to create a personal copy of the repository, where you can ex
<!-- Added the Team section -->
## 👥 Team
| ![Dhairya Gothi](https://avatars.githubusercontent.com/u/142989448?v=4&s=80)|
|:--:|
| **Dhairya Gothi** <br> <sub>Project Admin</sub> |
| [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](https://www.linkedin.com/in/dhairya-gothi-65945b288/) |
| ![Dhairya Gothi](https://avatars.githubusercontent.com/u/142989448?v=4&s=80) | ![Rishita](https://avatars.githubusercontent.com/u/167749636?v=4&s=80) | ![Shreya](https://media.licdn.com/dms/image/v2/D4D03AQFG5YVopdYt7g/profile-displayphoto-shrink_100_100/profile-displayphoto-shrink_100_100/0/1727992516667?e=1735776000&v=beta&t=UxOs0ZcgEiGTENny_brMh7mZ5ObiAF7KMlJVvJyJLlM) | ![Riddhi](https://avatars.githubusercontent.com/u/180189764?v=4&s=80) | ![Mrityunjay](https://avatars.githubusercontent.com/u/137044290?v=4&s=80) | ![Prem](https://media.licdn.com/dms/image/v2/D4D03AQEfHKeIrJS3FA/profile-displayphoto-shrink_100_100/profile-displayphoto-shrink_100_100/0/1727376973786?e=1735776000&v=beta&t=7FuOV4TXYLCx7mknNwzq0QJJk97iiQz3YZ4orvRbg0k) |
|:--:|:--:|:--:|:--:|:--:|:--:|
| **Dhairya Gothi** <br> <sub>Project Admin</sub> | **Rishita** <br> <sub>Co-lead</sub> | **Shreya** <br> <sub>Researcher</sub> | **Riddhi** <br> <sub>Designer</sub> | **Mrityunjay** <br> <sub>Developer</sub> | **Prem** <br> <sub>Developer</sub> |
| [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](https://www.linkedin.com/in/dhairya-gothi-65945b288/) | [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](#) | [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](#) | [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](#) | [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](#) | [![LinkedIn](https://img.icons8.com/fluency/32/000000/linkedin.png)](#) |
If you have questions, suggestions, or feedback, please reach out via email at dhairyag31@gmail.com. You can also join our [discussion forum](https://github.com/dhairyagothi/StationGuide/discussions).
Expand All @@ -418,3 +463,9 @@ We value open communication and are happy to help!
<!-- Added a Support section for the project README -->
## ⭐️ Support the Project
If you find this project helpful, please consider giving it a ⭐ on GitHub! Your support helps to grow the project and reach more contributors.
<div align="center">
<a href="#top">
<img src="https://img.shields.io/badge/Back%20to%20Top-000000?style=for-the-badge&logo=github&logoColor=white" alt="Back to Top">
</a>
</div>
Binary file added assets/GSSoC-Ext.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/hacktoberfest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions assets/image
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

10 changes: 10 additions & 0 deletions backend/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
EMAIL_USER=your_gmail
#your email
EMAIL_USER=your_gmail
MONGODB_URI=

# To create a passkey on the phone or computer you’re on:

# 1. Go to https://myaccount.google.com/signinoptions/passkeys.
# 2. Tap Create a passkey and then Continue.(You'll be required to unlock your device.)
# 3. A 16 character passkey is generated which you can use in below.
87 changes: 81 additions & 6 deletions backend/controllers/authController.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import User from '../models/User.js';
import crypto from 'crypto'; // For generating OTP
import nodemailer from 'nodemailer';
import { hashPassword, comparePassword, generateToken, verifyToken, addCookie, getCookies, removeCookie } from '../utils/authFunctions.js';

export const registerUser = async (req, res) => {
Expand All @@ -19,45 +21,118 @@ export const registerUser = async (req, res) => {
return res.status(400).json({ error: 'User already exists' });
}

const otp = crypto.randomInt(100000, 999999).toString(); // Generate OTP (6 digits)

if (isGoogle == true) {
const newUser = new User({
name,
email,
phoneNumber: phoneNumber ? phoneNumber : '',
password: ''
password: '',
otp: otp,
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour
});

await newUser.save();

const token = await generateToken(newUser._id);
await sendOtpEmail(email, otp); // Send OTP to the user's email

const token = await generateToken(newUser._id);
addCookie(res, 'token', token);

return res.status(201).json({ message: 'User registered successfully', userId: newUser._id , token: token });
return res.status(201).json({
message: 'User registered successfully. Please check your email for the OTP to verify your email.',
userId: newUser._id,
token: token,
});
} else {
const hashedPassword = await hashPassword(password);

const newUser = new User({
name,
email,
phoneNumber: phoneNumber ? phoneNumber : '',
password: hashedPassword
password: hashedPassword,
otp: otp,
otpExpiry: Date.now() + 3600000, // OTP expires in 1 hour
});

await newUser.save();

const token = await generateToken(newUser._id);
await sendOtpEmail(email, otp); // Send OTP to the user's email

const token = await generateToken(newUser._id);
addCookie(res, 'token', token);

res.status(201).json({ message: 'User registered successfully', userId: newUser._id, token: token });
res.status(201).json({
message: 'User registered successfully. Please check your email for the OTP to verify your email.',
userId: newUser._id,
token: token,
});
}
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message || 'Internal Server Error' });
}
};

const sendOtpEmail = async (userEmail, otp) => {
try {
const transporter = nodemailer.createTransport({
service: 'gmail', // Or use another email provider
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});

const mailOptions = {
from: process.env.EMAIL_USER,
to: userEmail,
subject: 'Email Verification - Station Sarthi',
text: `Your OTP for email verification is: ${otp}`,
};

await transporter.sendMail(mailOptions);
} catch (error) {
console.error('Error sending email:', error);
throw new Error('Failed to send OTP');
}
};

export const verifyOtp = async (req, res) => {
try {
const { email, otp } = req.body;

const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({ error: 'User not found' });
}

// Check if OTP has expired
if (Date.now() > user.otpExpiry) {
return res.status(400).json({ error: 'OTP has expired' });
}

// Check if OTP is correct
if (user.otp !== otp) {
return res.status(400).json({ error: 'Invalid OTP' });
}

// OTP is correct, mark user as verified
user.isVerified = true;
user.otp = null; // Clear OTP after verification
user.otpExpiry = null; // Clear OTP expiry after verification
await user.save();

res.status(200).json({ message: 'Email verified successfully' });
} catch (error) {
console.error(error);
res.status(500).json({ error: error.message || 'Internal Server Error' });
}
};


export const loginUser = async (req, res) => {
try {
const { email, password } = req.body;
Expand Down
84 changes: 84 additions & 0 deletions backend/controllers/complaintController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
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",
html: `
<div style="font-family: Arial, sans-serif; color: #333; line-height: 1.6; max-width: 600px; margin: 0 auto; border: 1px solid #e0e0e0; border-radius: 8px;">
<!-- Header -->
<div style="background-color: #a6e4f5; padding: 20px; text-align: center; border-top-left-radius: 8px; border-top-right-radius: 8px;">
<img src="cid:headerImage" alt="Station Saarthi" style="width: 150px; margin-bottom: 10px;">
<h2 style="margin: 0;">Complaint Received</h2>
</div>
<!-- Body Content -->
<div style="padding: 20px;">
<p style="font-size: 16px; color: #333;">Dear ${name},</p>
<p>Thank you for submitting your complaint to Station Saarthi. We have received your complaint and will look into the matter as soon as possible.</p>
<p style="font-size: 16px;">Your satisfaction is important to us. Please feel free to reach out if you have any further questions or require assistance.</p>
<!-- Button -->
<div style="text-align: center; margin-top: 20px;">
<a href="https://stationsaarthi.com" style="display: inline-block; padding: 12px 25px; background-color: #007bff; color: white; font-size: 16px; font-weight: bold; text-decoration: none; border-radius: 5px;">Visit Our Website</a>
</div>
</div>
<!-- Footer -->
<div style="background-color: #f5f5f5; padding: 15px; text-align: center; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;">
<p style="font-size: 14px; color: #666;">Best regards,<br><strong>Station Saarthi Team</strong></p>
<p style="font-size: 12px; color: #999;">&copy; ${new Date().getFullYear()} Station Saarthi. All rights reserved.</p>
</div>
</div>
`,
attachments: [
{
filename: "image",
path: "C:/Users/ayush/OneDrive/Desktop/StationGuide/frontend/src/assets/station.png", // Update this to the path where the image is stored
cid: "headerImage",
},
],
};

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;
66 changes: 66 additions & 0 deletions backend/controllers/contactusController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import nodemailer from "nodemailer";
import ContactUs from "../models/Contact.js";
import "dotenv/config";


// POST Controller: Handles contact form submission
export const createContactUs = async (req, res) => {
const { mail, subject, message } = req.body;

// Check if required fields are present and valid
if (!mail || !subject || !message) {
return res.status(400).json({
status: "error",
message: "All fields (email, subject, message) are required.",
});
}

// Validate email format using a simple regex
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(mail)) {
return res.status(400).json({
status: "error",
message: "Please provide a valid email address.",
});
}

try {
// Save the contact form data to the database
const newContactRequest = new ContactUs({
mail,
subject,
message,
});
await newContactRequest.save(); // Save the document to the MongoDB database

// Send email using Nodemailer
const transporter = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: process.env.EMAIL_USER,
pass: process.env.EMAIL_PASS,
},
});

const mailOptions = {
from: mail,
to: process.env.EMAIL_USER,
subject: subject,
text: message,
};

// Send mail with defined transport object
await transporter.sendMail(mailOptions);

res.status(200).json({
status: "success",
message: "Your contact request has been successfully received.",
});
} catch (err) {
console.error(`Error during processing contact form: ${err.message}`);
res.status(500).json({
status: "error",
message: "There was an error processing your message. Please try again later.",
});
}
};
Loading

0 comments on commit 8313a5e

Please sign in to comment.