add mailing system
This commit is contained in:
parent
22215f3e1b
commit
9ba975cc92
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,2 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
.next
|
.next
|
||||||
|
node_shell
|
||||||
|
.env
|
||||||
31
functions/frontend/submitContactForm.js
Normal file
31
functions/frontend/submitContactForm.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
export default async function submitContactForm(e, setSuccess) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let name = e.target[0].value;
|
||||||
|
let email = e.target[1].value;
|
||||||
|
let message = e.target[2].value;
|
||||||
|
|
||||||
|
let body = {
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
message: message,
|
||||||
|
};
|
||||||
|
|
||||||
|
let res = await fetch("/api/contactForm", {
|
||||||
|
method: "post",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
|
||||||
|
let data = await res.json();
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
|
if (data.msg === "Success") {
|
||||||
|
setSuccess("Success");
|
||||||
|
} else {
|
||||||
|
setSuccess("Failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
299
package-lock.json
generated
299
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -25,6 +25,7 @@
|
|||||||
"homepage": "https://github.com/BenjaminToby/personal_site#readme",
|
"homepage": "https://github.com/BenjaminToby/personal_site#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "^12.0.4",
|
"next": "^12.0.4",
|
||||||
|
"nodemailer": "^6.7.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2"
|
"react-dom": "^17.0.2"
|
||||||
}
|
}
|
||||||
|
|||||||
68
pages/api/contactForm.js
Normal file
68
pages/api/contactForm.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Imports
|
||||||
|
* ------------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const nodemailer = require("nodemailer");
|
||||||
|
|
||||||
|
/** ********************* Functions and Other API Imports */
|
||||||
|
|
||||||
|
// let transporter = nodemailer.createTransport({
|
||||||
|
// host: "smtp.dreamhost.com",
|
||||||
|
// port: 465,
|
||||||
|
// secure: true, // true for 465, false for other ports
|
||||||
|
// auth: {
|
||||||
|
// user: "info@tben.design",
|
||||||
|
// pass: "tobybenoti",
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
|
||||||
|
let transporter = nodemailer.createTransport({
|
||||||
|
host: "smtp.gmail.com",
|
||||||
|
port: 465,
|
||||||
|
secure: true,
|
||||||
|
auth: {
|
||||||
|
user: "benoti.san@gmail.com",
|
||||||
|
pass: "pzeacyigrdutlbbr",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* API handler
|
||||||
|
* ------------------------------------------------------------------------------
|
||||||
|
* @param {Object} req - http incoming request
|
||||||
|
* @param {Object} res - http response
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
/** ********************* Get Page Data */
|
||||||
|
if (req.method === "POST") {
|
||||||
|
let name = req.body.name;
|
||||||
|
let email = req.body.email;
|
||||||
|
let message = req.body.message;
|
||||||
|
|
||||||
|
console.log("Message Sending ...");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// send mail with defined transport object
|
||||||
|
let info = await transporter.sendMail({
|
||||||
|
from: email, // sender address
|
||||||
|
to: "benoti.san@gmail.com", // list of receivers
|
||||||
|
subject: "Tben Client Request", // Subject line
|
||||||
|
text: "Hello from tben",
|
||||||
|
html: `<h1>Message from ${name}</h1><p>${message}</p>`, // html body
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Message sent: %s", info.messageId);
|
||||||
|
res.json({ msg: "Success", info: info });
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
res.json({ msg: "Failed" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,8 +1,12 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import TextShuffler from '../components/actions/TextShuffler'
|
import TextShuffler from '../components/actions/TextShuffler'
|
||||||
|
import submitContactForm from '../functions/frontend/submitContactForm'
|
||||||
import GeneralLayout from '../layouts/general_layout/GeneralLayout'
|
import GeneralLayout from '../layouts/general_layout/GeneralLayout'
|
||||||
|
|
||||||
const contact = () => {
|
const contact = () => {
|
||||||
|
|
||||||
|
let [success, setSuccess] = React.useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GeneralLayout>
|
<GeneralLayout>
|
||||||
<h1><TextShuffler textInput="Great things await ..." /></h1>
|
<h1><TextShuffler textInput="Great things await ..." /></h1>
|
||||||
@ -10,11 +14,13 @@ const contact = () => {
|
|||||||
<TextShuffler textInput="Let's talk" />
|
<TextShuffler textInput="Let's talk" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<form autoComplete='true'>
|
<form autoComplete='on' onSubmit={(e) => { submitContactForm(e, setSuccess) }}>
|
||||||
<input type="text" placeholder='Your Name' />
|
<input type="text" placeholder='Your Name' autoComplete='name' />
|
||||||
<input type="email" placeholder='Your Email Address' />
|
<input type="email" placeholder='Your Email Address' autoComplete='email' />
|
||||||
<textarea name="message" id="contact-form-message" cols="30" rows="10" placeholder='Message'></textarea>
|
<textarea name="message" id="contact-form-message" cols="30" rows="10" placeholder='Message'></textarea>
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
|
{success === "Success" && <div className='message-response'>Success!!! <button onClick={() => { window.location.reload() }}>Reload</button></div>}
|
||||||
|
{success === "Failed" && <div className='message-response failed'>Failed <button onClick={() => { window.location.reload() }}>Reload</button></div>}
|
||||||
</form>
|
</form>
|
||||||
</GeneralLayout>
|
</GeneralLayout>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const index = () => {
|
|||||||
<GeneralLayout>
|
<GeneralLayout>
|
||||||
<h1><TextShuffler textInput="UI/UX designer, Full Stack Web Developer, Web/graphic/motion designer" /></h1>
|
<h1><TextShuffler textInput="UI/UX designer, Full Stack Web Developer, Web/graphic/motion designer" /></h1>
|
||||||
<span className='hero-sub-text'>
|
<span className='hero-sub-text'>
|
||||||
<TextShuffler textInput="Hi, I'm Ben, a highly talented fullstack web developer with extensive enxperience in web design, frontend and backend development." />
|
<TextShuffler textInput="Hi, I'm Benjamin Toby, a highly talented fullstack web developer with extensive enxperience in web design, frontend and backend development." />
|
||||||
</span>
|
</span>
|
||||||
<div className="hero-ctas-section">
|
<div className="hero-ctas-section">
|
||||||
<a href='/documents/Benjamin_Toby_CV.pdf' download={true}>See my resume</a>
|
<a href='/documents/Benjamin_Toby_CV.pdf' download={true}>See my resume</a>
|
||||||
|
|||||||
@ -29,7 +29,6 @@ body {
|
|||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 40px;
|
padding: 40px;
|
||||||
top: 0;
|
top: 0;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background-color: var(--dark-color);
|
background-color: var(--dark-color);
|
||||||
color: white;
|
color: white;
|
||||||
@ -250,6 +249,7 @@ form {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
@ -262,6 +262,26 @@ textarea {
|
|||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-response {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: var(--dark-color);
|
||||||
|
border: 2px solid #688e26;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 24px;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-response.failed {
|
||||||
|
border: 2px solid #d42222;
|
||||||
|
}
|
||||||
|
|
||||||
/* ###############################################################################################
|
/* ###############################################################################################
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user