Skip to content

Commit

Permalink
Merge pull request #445 from Sawan-Kushwah/feat/newsletter
Browse files Browse the repository at this point in the history
✨ Added newsletter functionality to glassy ui ✨
  • Loading branch information
Jaishree2310 authored Nov 10, 2024
2 parents 6f2a476 + e8e1bcd commit 49ab3f4
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 33 deletions.
9 changes: 7 additions & 2 deletions server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ import dotenv from 'dotenv';
import connectDB from './utils/db.js';
import cors from 'cors';
import contactRoutes from './routes/contactRoutes.js';
import newsletterRoutes from './routes/newsletterRoute.js';

dotenv.config();
const app = express();
connectDB();

app.use(express.json());

// to avoid cross-origin error
app.use(cors());
app.use(
cors({
origin: 'http://localhost:3000', // replace with your frontend origin
}),
);

// Serve static files from the uploads directory
app.use('/api/contact', contactRoutes);
app.use('/api/newsletter', newsletterRoutes);

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
Expand Down
27 changes: 27 additions & 0 deletions server/controllers/newsletterController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import NewsLetter from '../model/Newsletter.js';
import { sendMailToSubscriber } from '../sendSuscribedMail.js';

export async function saveNewsletter(req, res) {
try {
const { name, email } = req.body;

if (!name || !email) {
return res.status(400).json({ message: 'All fields are required.' });
}

// Create new contact document
const newNewsLetter = new NewsLetter({ name, email });
sendMailToSubscriber(newNewsLetter);
await newNewsLetter.save();
res
.status(201)
.json({ message: 'Contact form submitted successfully!', newNewsLetter });
} catch (error) {
console.error('Error saving contact form:', error);
res.status(500).json({ message: 'Failed to submit contact form.', error });
}
}

export async function getNewsletter(req, res) {
res.send('hello newsletter');
}
23 changes: 23 additions & 0 deletions server/model/Newsletter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import mongoose from 'mongoose';

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

const Newsletter = mongoose.model('Newsletter', newsletterSchema);

export default Newsletter;
11 changes: 11 additions & 0 deletions server/routes/newsletterRoute.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import express from 'express';
const router = express.Router();
import {
getNewsletter,
saveNewsletter,
} from '../controllers/newsletterController.js';

router.post('/subscribe', saveNewsletter);
router.get('/getNewsletter', getNewsletter);

export default router;
59 changes: 59 additions & 0 deletions server/sendSuscribedMail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import nodemailer from 'nodemailer';
import dotenv from 'dotenv';
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() {
await transporter.sendMail({
from: {
name: 'GlassyUI-Components',
address: process.env.EMAIL_ID,
},
to: userdata.email,
subject: 'Welcome to GlassyUI-Components! 🎉',
text: 'Thank you for subscribing to GlassyUI-Components!',
html: `
<div style="background-color: #e0f7fa; color: #333; padding: 20px; font-family: Arial, sans-serif;">
<div style="max-width: 600px; margin: 0 auto; background: rgba(255, 255, 255, 0.8); padding: 20px; border-radius: 15px; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2); backdrop-filter: blur(10px);">
<h2 style="text-align: center; color: #00acc1;">Welcome to GlassyUI-Components, ${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;">
We’re thrilled to have you join us at GlassyUI-Components, an open-source library that brings you beautiful glassmorphism-themed React components. Our library is perfect for creating sleek, modern web applications, and we can’t wait for you to explore and enjoy it!
</p>
<h3 style="color: #00acc1; margin-top: 20px;">✨ Features</h3>
<ul style="font-size: 16px; line-height: 1.6; color: #555;">
<li>Glassmorphism-themed React components</li>
<li>Customizable styles with SCSS</li>
<li>Beginner-friendly and easy to contribute</li>
<li>Modular and reusable components</li>
</ul>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Stay tuned for the latest updates and don’t hesitate to contribute to make GlassyUI-Components even better!
</p>
<p style="font-size: 16px; line-height: 1.6; color: #555;">
Best Regards, <br/>
The GlassyUI-Components Team
</p>
</div>
</div>
`,
});
}

main().catch(console.error);
};

export { sendMailToSubscriber };
83 changes: 52 additions & 31 deletions src/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,29 @@ const Footer: React.FC = () => {

const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
console.log(name + ' ' + email);
// try {
// const response = await fetch("http://localhost:5000/api/newsletter/subscribe", {
// method: "POST",
// headers: {
// "Content-Type": "application/json",
// },
// body: JSON.stringify({ name, email }),
// });

// if (response.ok) {
// alert("Subscription successful!");
// setName("");
// setEmail("");
// } else {
// alert("Failed to subscribe.");
// }
// } catch (error) {
// alert("An error occurred. Please try again.");
// }

try {
const response = await fetch(
'http://localhost:5000/api/newsletter/subscribe',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, email }),
},
);

if (response.ok) {
alert('Subscription successful!');
setName('');
setEmail('');
} else {
alert('Failed to subscribe.');
}
} catch (error) {
alert('An error occurred. Please try again.');
}
};

return (
Expand Down Expand Up @@ -57,7 +60,35 @@ const Footer: React.FC = () => {
<GoogleTranslate />
</div>
</div>
<div className='footer-bottom'>
<div className='footer-bottom flex flex-col'>
{/* Newsletter Section */}
<div className='p-6 w-full flex flex-col items-center justify-center'>
<form
onSubmit={handleSubmit}
className='w-full flex flex-col items-center md:flex-row'
>
<input
type='text'
placeholder='Your Name'
value={name}
onChange={e => setName(e.target.value)}
className='mb-4 md:mb-0 md:mr-2 px-4 py-2 w-full md:w-1/2 text-black rounded-md border border-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500'
/>
<input
type='email'
placeholder='Your Email'
value={email}
onChange={e => setEmail(e.target.value)}
className='mb-4 md:mb-0 md:mr-2 px-4 py-2 w-full md:w-1/2 text-black rounded-md border border-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-500'
/>
<button
type='submit'
className='px-6 py-2 text-white bg-black rounded-md hover:bg-gray-800 transition-colors duration-200'
>
Subscribe
</button>
</form>
</div>
<a
href='https://github.com/Jaishree2310/GlassyUI-Components'
target='_blank'
Expand Down Expand Up @@ -157,16 +188,6 @@ const Footer: React.FC = () => {
}
`}</style>
<div>
<p
style={{
fontSize: '14px',
color: '#fff',
position: 'relative',
right: '-300px',
}}
>
&copy; 2024 GlassyUI. All rights reserved.
</p>
<div
style={{
fontSize: '14px',
Expand Down

0 comments on commit 49ab3f4

Please sign in to comment.