Skip to content

Commit

Permalink
contact page
Browse files Browse the repository at this point in the history
  • Loading branch information
Isha1233 committed Jul 17, 2024
1 parent e26a431 commit d0e3425
Show file tree
Hide file tree
Showing 12 changed files with 309 additions and 21 deletions.
Binary file added client/public/c7.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 client/public/cr2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Product from "./pages/Product";
import Cart from "./pages/Cart";
import ScrollToTop from "./components/ScrollToTop";
import './App.css'
import Contact from './pages/Contact/Contact.jsx';
function App() {
return (
<BrowserRouter>
Expand All @@ -34,6 +35,7 @@ function App() {
<Route path="retailer" element={<Layout_retailer />}>
<Route index element={<Retailer_home />} />
</Route>
<Route path="contact" element={<Contact />} />
</Route>
</Routes>
</BrowserRouter>
Expand Down
1 change: 1 addition & 0 deletions client/src/components/Footer/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Footer = () => {
<NavLink to="categories">Categories</NavLink>
<NavLink to="customize">Customize</NavLink>
<NavLink to="shop">Shop</NavLink>
<NavLink to="/contact">Contact</NavLink>
</div>
<div className="flex items-center w-[20%] gap-3 my-3 justify-end max-lg:justify-center">
<a
Expand Down
98 changes: 98 additions & 0 deletions client/src/pages/contact/Contact.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
.contact-container {
position: absolute;
overflow: hidden;
top: 50%;
left: 50%;
transform: translate(-280%, -100%);
background-color: #f9f9f9;
padding: 2rem;
border-radius: 1rem;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
width: 20rem;
}

.contact-heading,
.contact-subheading {
color: #2e2d32;
font-size: 2.6rem;
font-weight: 600;
text-align: center;
margin-bottom: 1.5rem;
font-family: serif;
}

.contact-heading:hover {
color: #6A0DAD;
transition: color 0.3s ease;
}

.form-container {
padding-top: 1rem;
}

.form-label {
display: block;
margin-bottom: 1rem;
}

.form-label-text {
font-weight: bold;
display: block;
color: #333;
font-size: 1rem;
font-family: cursive;
}

.form-input,
.form-textarea {
width: 100%;
padding: 0.75rem;
margin-top: 0.5rem;
border: 1px solid #ccc;
border-radius: 0.5rem;
outline: none;
color: #333;
font-size: 1rem;
font-family: Arial, sans-serif;
}

.form-textarea {
height: 8rem;
resize: none;
overflow-y: auto;
}

.form-input,
.form-textarea {
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.form-button {
background-color: #0f74c1;
color: #fff;
border: none;
padding: 0.75rem 2rem;
border-radius: 0.5rem;
cursor: pointer;
font-weight: bold;
margin-top: 1.5rem;
display: block;
margin: 0 auto;
box-shadow: 0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08);
transition: background-color 0.3s ease;
}

.form-button:hover {
background-color: #06418e;
}

.image-container {
margin-top: 2rem;
text-align: center;
}

.image {
width: 100%;
height: auto;
}
120 changes: 120 additions & 0 deletions client/src/pages/contact/Contact.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React, { useRef, useState } from "react";
import { useNavigate } from "react-router-dom";
import "./Contact.css"; // Ensure to import Tailwind CSS in your main stylesheet

const Contact = () => {
const formRef = useRef();
const [form, setForm] = useState({
name: "",
email: "",
message: "",
});

const [loading, setLoading] = useState(false);
const navigate = useNavigate();

const handleChange = (e) => {
const { name, value } = e.target;

setForm({
...form,
[name]: value,
});
};

const handleClose = () => {
navigate("/");
};

const handleEmailSubmit = async (e) => {
e.preventDefault();
setLoading(true);

try {
const response = await fetch("http://localhost:5000/contact/send-email", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: form.name,
email: form.email,
message: form.message,
}),
});

if (!response.ok) {
throw new Error("Failed to send email");
}

setLoading(false);
alert("Thank you. We will get back to you as soon as possible.");

setForm({
name: "",
email: "",
message: "",
});

handleClose();
} catch (error) {
setLoading(false);
console.error(error);

alert("Sorry, something went wrong while sending your message. Please try again later.");
}
};

return (
<div className=" bg-red-200 -mb-24 pb-8 min-h-screen flex items-center justify-center pb-16">
<div className="w-96 bg-gray-50 p-8 rounded-lg shadow-lg relative">
<div className="close-button absolute top-0 right-0 mt-2 mr-2" onClick={handleClose}>
<img src="cr2.png" alt="Close" className="w-6 h-6 cursor-pointer" />
</div>
<p className="contact-heading text-3xl font-semibold text-gray-800 text-center mb-6">Get in touch</p>
<div className="form-container">
<form ref={formRef} onSubmit={handleEmailSubmit} className="form">
<label className="form-label">
<span className="form-label-text font-bold block text-gray-700 text-sm">Your Name</span>
<input
type="text"
name="name"
value={form.name}
onChange={handleChange}
placeholder="What's your good name?"
className="form-input w-full px-3 py-2 mt-1 border border-gray-300 rounded-lg outline-none text-gray-800 placeholder-gray-400 focus:ring-2 focus:ring-blue-500"
/>
</label>
<label className="form-label">
<span className="form-label-text font-bold block text-gray-700 text-sm">Your email</span>
<input
type="email"
name="email"
value={form.email}
onChange={handleChange}
placeholder="What's your web address?"
className="form-input w-full px-3 py-2 mt-1 border border-gray-300 rounded-lg outline-none text-gray-800 placeholder-gray-400 focus:ring-2 focus:ring-blue-500"
/>
</label>
<label className="form-label">
<span className="form-label-text font-bold block text-gray-700 text-sm">Your Message</span>
<textarea
rows={5}
name="message"
value={form.message}
onChange={handleChange}
placeholder="What you want to say?"
className="form-textarea w-full px-3 py-2 mt-1 border border-gray-300 rounded-lg outline-none text-gray-800 placeholder-gray-400 focus:ring-2 focus:ring-blue-500"
/>
</label>
<button type="submit" className="form-button bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-6 mx-auto block">
{loading ? "Sending..." : "Send Mail"}
</button>
</form>
</div>
</div>
</div>
);
};

export default Contact;
2 changes: 2 additions & 0 deletions server/.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
PORT = 3000
JWT_SECRET = secret
EMAIL_USER=[email protected]
EMAIL_PASS=your-email-password
6 changes: 5 additions & 1 deletion server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import productrouter from "./routes/products.js";
import cors from 'cors';
import cookieParser from "cookie-parser";
import cartrouter from './routes/cart.js';
import bodyParser from "body-parser";
import contactRoutes from "./routes/contactRoutes.js";

export const app = express();

Expand All @@ -26,4 +28,6 @@ app.use(express.json());
app.use(cookieParser());
app.use("/api/users", userrouter);
app.use("/api/products", productrouter);
app.use("/api/cart", cartrouter);
app.use("/api/cart", cartrouter);
app.use(bodyParser.json());
app.use("/contact", contactRoutes);
41 changes: 41 additions & 0 deletions server/controllers/contactController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const nodemailer = require("nodemailer");

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

// Create a Nodemailer transporter
const transporter = nodemailer.createTransport({
service: "gmail",
auth: {
user: "[email protected]",
pass: "your-email-password",
},
});

// Email to be sent to the website admin
const mailOptionsToAdmin = {
from: email,
to: "[email protected]",
subject: `New message from ${name}`,
text: message,
};

// Confirmation email to be sent to the user
const mailOptionsToUser = {
from: "[email protected]",
to: email,
subject: "We have received your query",
text: `Hello ${name},\n\nThank you for reaching out. We have received your message and will get back to you soon.\n\nBest regards,\nFoodiesWeb Team`,
};

try {
await transporter.sendMail(mailOptionsToAdmin);
await transporter.sendMail(mailOptionsToUser);
res.status(200).json({ message: "Emails sent successfully." });
} catch (error) {
console.error("Error sending emails:", error);
res.status(500).json({ error: "Failed to send emails." });
}
};

module.exports = { sendEmail };
Loading

0 comments on commit d0e3425

Please sign in to comment.