Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added subscribe us feature on newsletter #401

Merged
merged 3 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,12 @@ function App() {
<Cursor />
<ProjectState>
<ProfileState>

<LoadingBar color="blue" progress={progress} onLoaderFinished={() => setProgress(0)} />
<Router>

<LoadingBar color="blue" progress={progress} onLoaderFinished={() => setProgress(0)} />

<div className="alert-container"> <Alert alert={alert} /> </div>
<ProgressBar mode={mode} />
<ProgressBar mode={mode} />
<ScrollTop />
<Layout mode={mode} setProgress={setProgress} toggleMode={toggleMode} showAlert={showAlert} >
<Routes>
Expand All @@ -149,12 +151,13 @@ function App() {
<Route exact path='/contactus' element={<ContactUs mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/privacypolicy' element={<PrivacyPolicy mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/termofuse' element={<TermOfUse mode={mode} setProgress={setProgress} showAlert={showAlert} />} />

<Route exact path='/projects' element={<Projects mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/uploadProject' element={<UploadProject mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/FAQ' element={<FAQ mode={mode} />} />
<Route exact path='/createBlogPost' element={<CreateBlog />} />
<Route exact path='/read-more-blog/:id' element={<ReadMoreBlog mode={mode} setProgress={setProgress} showAlert={showAlert} />} />
<Route exact path='/*' element={<NotFound />} />
<Route exact path='/*' element={<NotFound />} />
</Routes>
</Layout>

Expand Down
23 changes: 18 additions & 5 deletions client/src/component/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import VisitorCounter from './Footers/VisitorCount';

const Footer = (props) => {
const [email, setEmail] = useState("");
const [name, setName] = useState("");
const [message, setMessage] = useState("");
const [isError, setIsError] = useState(false); // Flag to handle message color
const [stars, setStars] = useState(0);
Expand All @@ -16,9 +17,9 @@ const Footer = (props) => {
e.preventDefault();
setMessage(""); // Reset message

if (!email) {
if (!email || !name) {
setIsError(true);
setMessage("Please enter a valid email.");
setMessage("Please enter valid details.");
clearMessageAndResetEmail();
return;
}
Expand All @@ -29,13 +30,15 @@ const Footer = (props) => {
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ email }),
body: JSON.stringify({ name, email }),
});

const data = await response.json();

if (response.ok) {
setIsError(false);
setEmail('');
setName('')
setMessage("Thank you for subscribing!");
} else {
setIsError(true);
Expand All @@ -55,6 +58,7 @@ const Footer = (props) => {
setTimeout(() => {
setMessage("");
setEmail("");
setName("")
}, 7000);
};
useEffect(() => {
Expand Down Expand Up @@ -101,16 +105,25 @@ const Footer = (props) => {
<div className='mb-4' data-aos="fade-up" data-aos-duration='1500'>
<h4 style={{ color: props.mode === 'dark' ? 'white' : 'black' }} className="text-3xl font-semibold text-center mb-4">Subscribe to our Newsletter</h4>
<form
className="flex flex-col items-center gap-4 md:flex-row md:justify-center"
className="flex flex-col items-center gap-4 md:flex-row md:justify-center justify-center"
onSubmit={handleSubscribe}
>
<input
type="text"
placeholder="Enter your name"
value={name}
onChange={(e) => setName(e.target.value)}
required
className="px-4 py-2 border border-gray-300 rounded-md w-full max-w-xs focus:outline-none text-black"

/>
<input
type="email"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="px-4 py-2 border border-gray-300 rounded-md w-full max-w-xs focus:outline-none"
className="px-4 py-2 border border-gray-300 rounded-md w-full max-w-xs focus:outline-none text-black mb-0"

/>
<button
Expand Down
69 changes: 7 additions & 62 deletions server/Controllers/OtherController.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const Newsletter = require("../Models/Newsletter");
const nodemailer = require("nodemailer");
const { sendMailToSubscriber } = require("../sendSubscribeMail");

const subscribeNewsletter = async (req, res) => {
try {
const { email } = req.body;
const { name, email } = req.body;

// Check if email is provided
if (!email) {
if (!email || !name) {
return res.status(400).json({ message: "Email is required" });
}

Expand All @@ -17,67 +17,12 @@ const subscribeNewsletter = async (req, res) => {
}

// Save the subscriber email to the database
const newSubscriber = new Newsletter({ email });
const newSubscriber = new Newsletter({ name, email });
await newSubscriber.save();

Configure the transporter
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: process.env.EMAIL_USER, // Use environment variables in production
pass: process.env.EMAIL_PASS,
},
});

const mailOptions = {
from: "[email protected]",
to: email, // Send confirmation email to the subscriber's email
subject: "Thank you for Subscribing to Our Newsletter",
html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: auto; border: 1px solid #ddd; border-radius: 8px; overflow: hidden;">
<!-- Header -->
<div style="background-color: #4A90E2; padding: 20px; text-align: center; color: white;">
<img src="cid:welcomeImage" alt="Welcome" style="width: 120px; margin-bottom: 10px;" />
<h1 style="font-size: 24px; margin: 0;">Thank You for Subscribing!</h1>
</div>

<!-- Body -->
<div style="padding: 30px; background-color: #f8f8f8; text-align: center;">
<h2 style="color: #333; font-size: 20px; margin-bottom: 15px;">Welcome to the BitBox Community!</h2>
<p style="font-size: 16px; color: #555; line-height: 1.6; margin: 0 0 20px;">
Dear Subscriber,
</p>
<p style="font-size: 16px; color: #555; line-height: 1.6; margin: 0 0 20px;">
We’re thrilled to have you with us. Get ready to stay updated with the latest trends and offers.
</p>

<a href="https://bitbox-in.netlify.app/" style="display: inline-block; padding: 12px 25px; margin-top: 20px; background-color: #4A90E2; color: white; font-size: 16px; font-weight: bold; text-decoration: none; border-radius: 5px;">
Explore More
</a>
</div>

<!-- Footer -->
<div style="background-color: #333; color: white; padding: 20px; text-align: center;">
<p style="margin: 0; font-size: 14px;">Best Regards, <br> <strong>BitBox Team</strong></p>
<p style="margin: 0; font-size: 12px; color: #ccc;">Follow us on our social channels for more updates</p>
</div>
</div>
`,
attachments: [
{
filename: "bitbox",
path: "Controllers/assests/bitboximage.png",
cid: "welcomeImage",
},
],
};

// Send the confirmation email
await transporter.sendMail(mailOptions);

res
.status(200)
.json({ message: "Subscription successful, confirmation email sent" });
sendMailToSubscriber(newSubscriber)
res.status(200).json({ message: "Subscription successful, confirmation email sent" });

} catch (error) {
console.error("Error in subscribing to newsletter:", error.message);
res.status(500).json({ message: error.message });
Expand Down
35 changes: 20 additions & 15 deletions server/Models/Newsletter.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
const mongoose = require("mongoose");

const NewsletterSchema = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
match: [/\S+@\S+\.\S+/, 'Please enter a valid email address']
},
subscribedAt: {
type: Date,
default: Date.now
},
status: {
type: String,
enum: ['Subscribed', 'Unsubscribed'],
default: 'Subscribed'
}
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
match: [/\S+@\S+\.\S+/, 'Please enter a valid email address']
},
subscribedAt: {
type: Date,
default: Date.now
},
status: {
type: String,
enum: ['Subscribed', 'Unsubscribed'],
default: 'Subscribed'
}
});

module.exports = mongoose.model("Newsletter", NewsletterSchema);
65 changes: 65 additions & 0 deletions server/sendSubscribeMail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const nodemailer = require('nodemailer');
require('dotenv').config();

const sendMailToSubscriber = (userdata) => {
const transporter = nodemailer.createTransport({
service: "gmail",
host: "smtp.gmail.com",
port: 587,
secure: false,
auth: {
user: process.env.EMAIL_ID,
pass: process.env.PASS_KEY,
},
});

async function main() {
try {
await transporter.sendMail({
from: {
name: "BitBox",
address: process.env.EMAIL_ID,
},
to: userdata.email,
subject: "Welcome to BitBox! 🚀 Join the Developer Community",
text: "Thank you for joining BitBox, your hub for project sharing and collaboration!",
html: `
<div style="background-color: #f4f4f9; color: #333; padding: 20px; font-family: Arial, sans-serif;">
<div style="max-width: 600px; margin: 0 auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);">
<h2 style="text-align: center; color: #4a90e2;">Welcome to BitBox, ${userdata.name}!</h2>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Hi ${userdata.name},
</p>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Thank you for subscribing to BitBox! We're excited to have you join a growing community of developers who showcase, share, and collaborate on projects.
</p>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
As a BitBox member, you can:
</p>
<ul style="font-size: 16px; line-height: 1.6; color: #555;">
<li>📂 <strong>Upload Projects:</strong> Easily upload and showcase your projects on our platform.</li>
<li>🔍 <strong>Discover Projects:</strong> Explore a wide range of innovative projects shared by fellow developers.</li>
<li>🤝 <strong>Collaborate:</strong> Connect with other developers to share feedback and collaborate on projects.</li>
<li>📚 <strong>Learn and Grow:</strong> Learn from shared projects and contribute to the community’s knowledge base.</li>
</ul>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Join us as we build a supportive environment where developers can grow, learn, and create together. Welcome aboard!
</p>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Warm regards, <br/>
The BitBox Team
</p>
</div>
</div>
`,
});
console.log("Email sent successfully to " + userdata.email);
} catch (error) {
console.error("Error sending email:", error);
}
}

main();
};

module.exports = { sendMailToSubscriber };