Skip to content

Commit

Permalink
Adding Contact controller and routes
Browse files Browse the repository at this point in the history
  • Loading branch information
bertrandshema committed Jul 21, 2024
1 parent 189d16f commit fe995e5
Show file tree
Hide file tree
Showing 6 changed files with 230 additions and 3 deletions.
27 changes: 27 additions & 0 deletions src/controller/contactController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Request, Response } from 'express';
import errorHandler from '../middlewares/errorHandler';
import sendEmail from '../emails/contact';
export const handleContact = errorHandler(
async (req: Request, res: Response) => {
const { name, email, phone, message } = req.body;

// Validate input
if (!name || !email || !message) {
return res
.status(400)
.json({ error: 'Name, email, and message are required' });
}

process.env.NODE_ENV !== 'test' &&
(await sendEmail('contact', 'bentopride@gmail.com', {
name,
email,
phone,
message,
}));

return res.status(200).json({
message: 'Feedback sent successfully',
});
}
);
62 changes: 62 additions & 0 deletions src/emails/contact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import axios from 'axios';
import handlebars from 'handlebars';
import fs from 'fs';
type EmailType = 'contact';
type Data = {
name: string;
phone: string;
email: string;
message: string;
};
/**
* Sends an email of the specified type to the recipient using the provided data.
*
* @param emailType - The type of email to send. Must be either "confirm" or "reset".
* @param recipient - The email address of the recipient.
* @param data - The data to be used for generating the email content. A name and link are required.
* @returns A Promise that resolves to the response from the email service.
* @throws An error if there is an issue sending the email.
*/
async function sendEmail(emailType: EmailType, recipient: string, data: Data) {
const templatePath = './src/emails/templates/contact.html';
try {
// Read the Handlebars template file
const templateFile = fs.readFileSync(templatePath, 'utf-8');

// Compile the template
const template = handlebars.compile(templateFile);

// Generate the HTML content using the template and data
const html = template(data);

// Send the Email

const domain = process.env.MAILGUN_DOMAIN;
const key = process.env.MAILGUN_TOKEN as string;
const body = {
from: `Dynamites Account Team <info@${domain}>`,
to: [recipient],
subject: 'New Contact',
html: html,
};
const mailgunResponse = await axios.post(
`https://api.mailgun.net/v3/${domain}/messages`,
body,
{
auth: {
username: 'api',
password: key,
},
headers: {
'Content-Type': 'multipart/form-data',
},
}
);

return mailgunResponse;
} catch (error) {
throw new Error(`Error sending email: ${error}`);
}
}

export default sendEmail;
2 changes: 1 addition & 1 deletion src/emails/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,4 @@ async function sendEmail(emailType: EmailType, recipient: string, data: Data) {
}
}

export default sendEmail;
export default sendEmail;
127 changes: 127 additions & 0 deletions src/emails/templates/contact.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap"
rel="stylesheet"
/>
<style>
body {
font-family: 'Open Sans', sans-serif;
background-color: #f7fafc;
}

.container {
min-height: 100vh;
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
padding: 12px;
box-sizing: border-box;
background-color: #f7fafc;
}

.card {
max-width: 720px;
width: 100%;
background-color: #ffffff;
padding: 24px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.title {
margin-top: 24px;
margin-bottom: 16px;
font-size: 24px;
font-weight: bold;
color: #1a202c;
text-align: center;
}

.message {
margin-bottom: 16px;
font-size: 14px;
color: #4a5568;
text-align: center;
}

.button {
display: block;
width: 100%;
padding: 12px;
border: none;
border-radius: 4px;
font-size: 14px;
font-weight: bold;
color: #f7fafc;
background-color: #4c51bf;
text-align: center;
text-decoration: none;
cursor: pointer;
}

.button:hover {
background-color: #434190;
}

.link {
color: #4c51bf;
text-decoration: none;
}

.link:hover {
color: #434190;
}
table {
width: 100%;
padding: 0;
border-width: 0;
}
th,
td {
padding: 0;
margin-bottom: 32px;
border-width: 0;
text-align: left;
font-size: 17px;
}
</style>
</head>
<body>
<div class="container">
<div class="card">
<div class="title">New Message</div>
<p class="message">hello Admin,</p>
<p class="message">
you have new message from {{name}}. Here are the message details
</p>
<div>
<table>
<tr>
<th>Full Name:</th>
<td>{{name}}</td>
</tr>
<tr>
<th>Email:</th>
<td>{{email}}</td>
</tr>
<tr>
<th>Phone Number:</th>
<td>{{phone}}</td>
</tr>
<tr>
<th>Message:</th>
<td>
<p>{{message}}</p>
</td>
</tr>
</table>
</div>
</div>
</div>
</body>
</html>
9 changes: 9 additions & 0 deletions src/routes/contactRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Router } from 'express';

import { handleContact } from '../controller/contactController';

const contactRoutes = Router();

contactRoutes.route('/').post(handleContact);

export default contactRoutes;
6 changes: 4 additions & 2 deletions src/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ import couponRouter from './couponRoute';
import chekoutRoutes from './checkoutRoutes';
import reviewRoute from './reviewRoutes';
import orderRoutes from './orderRoutes';
import noticificationRoute from './notificationRoutes'
import noticificationRoute from './notificationRoutes';
import contactRoutes from './contactRoutes';
const router = Router();

router.use('/user', userRouter);
Expand All @@ -22,5 +23,6 @@ router.use('/coupons', couponRouter);
router.use('/checkout', chekoutRoutes);
router.use('/review', reviewRoute);
router.use('/order', orderRoutes);
router.use('/notification',noticificationRoute)
router.use('/notification', noticificationRoute);
router.use('/contact', contactRoutes);
export default router;

0 comments on commit fe995e5

Please sign in to comment.