Change contact email to a message form
This commit is contained in:
parent
c69dc9a98e
commit
95bfdf5068
10 changed files with 153 additions and 27 deletions
9
app.js
9
app.js
|
@ -5,6 +5,7 @@ let session = require("express-session");
|
||||||
let logger = require("morgan");
|
let logger = require("morgan");
|
||||||
let { I18n } = require("i18n");
|
let { I18n } = require("i18n");
|
||||||
let Recaptcha = require("express-recaptcha").RecaptchaV3;
|
let Recaptcha = require("express-recaptcha").RecaptchaV3;
|
||||||
|
let SMTPClient = require("emailjs").SMTPClient;
|
||||||
let config = process.env.NODE_ENV === "test" ? {} : require("./config/config.json");
|
let config = process.env.NODE_ENV === "test" ? {} : require("./config/config.json");
|
||||||
|
|
||||||
let indexRouter = require("./routes/index");
|
let indexRouter = require("./routes/index");
|
||||||
|
@ -16,6 +17,7 @@ let ordersRouter = require("./routes/orders");
|
||||||
let sandwichesRouter = require("./routes/sandwiches");
|
let sandwichesRouter = require("./routes/sandwiches");
|
||||||
let profileRouter = require("./routes/profile");
|
let profileRouter = require("./routes/profile");
|
||||||
let adminRouter = require("./routes/admin");
|
let adminRouter = require("./routes/admin");
|
||||||
|
let contactRouter = require("./routes/contact");
|
||||||
|
|
||||||
let app = express();
|
let app = express();
|
||||||
let sess = {
|
let sess = {
|
||||||
|
@ -29,7 +31,9 @@ let i18n = new I18n({
|
||||||
directory: __dirname + "/locales",
|
directory: __dirname + "/locales",
|
||||||
objectNotation: true
|
objectNotation: true
|
||||||
});
|
});
|
||||||
let recaptcha = process.env.NODE_ENV === "test" ? null : new Recaptcha(config.siteKey, config.secretKey, {callback: "cb"});
|
let recaptcha = process.env.NODE_ENV === "test" ? null : new Recaptcha(config.reCaptcha.siteKey,
|
||||||
|
config.reCaptcha.secretKey, {callback: "cb"});
|
||||||
|
let mailClient = new SMTPClient(process.env.NODE_ENV === "test" ? {} : config.email.server);
|
||||||
|
|
||||||
if (app.get("env") === "production") {
|
if (app.get("env") === "production") {
|
||||||
app.set("trust proxy", 1);
|
app.set("trust proxy", 1);
|
||||||
|
@ -39,7 +43,9 @@ if (app.get("env") === "production") {
|
||||||
// view engine setup
|
// view engine setup
|
||||||
app.set("views", path.join(__dirname, "views"));
|
app.set("views", path.join(__dirname, "views"));
|
||||||
app.set("view engine", "pug");
|
app.set("view engine", "pug");
|
||||||
|
app.set("config", config);
|
||||||
app.set("recaptcha", recaptcha);
|
app.set("recaptcha", recaptcha);
|
||||||
|
app.set("mailClient", mailClient);
|
||||||
|
|
||||||
app.use(logger("dev"));
|
app.use(logger("dev"));
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
@ -65,6 +71,7 @@ app.use("/orders", ordersRouter);
|
||||||
app.use("/sandwiches", sandwichesRouter);
|
app.use("/sandwiches", sandwichesRouter);
|
||||||
app.use("/profile", profileRouter);
|
app.use("/profile", profileRouter);
|
||||||
app.use("/admin", adminRouter);
|
app.use("/admin", adminRouter);
|
||||||
|
app.use("/contact", contactRouter);
|
||||||
|
|
||||||
// catch 404 and forward to error handler
|
// catch 404 and forward to error handler
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
|
|
|
@ -7,6 +7,18 @@
|
||||||
"host": "127.0.0.1",
|
"host": "127.0.0.1",
|
||||||
"dialect": "mysql"
|
"dialect": "mysql"
|
||||||
},
|
},
|
||||||
"siteKey": "yjt,kugcjvhkyhgchkuyjgugjgcvkuh",
|
"reCaptcha": {
|
||||||
"secretKey": "yjt,vhjtfykjvhkhiuyhjvkjuiyvhjblhioguikjkly_lui"
|
"siteKey": "yjt,kugcjvhkyhgchkuyjgugjgcvkuh",
|
||||||
|
"secretKey": "yjt,vhjtfykjvhkhiuyhjvkjuiyvhjblhioguikjkly_lui"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"server": {
|
||||||
|
"user": "user",
|
||||||
|
"password": "password",
|
||||||
|
"host": "smtp.your-email.com",
|
||||||
|
"ssl": true
|
||||||
|
},
|
||||||
|
"from": "Contact Email <you@email.fr>",
|
||||||
|
"contact": "Your Contact <contact@your-email.fr>"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,17 @@
|
||||||
"GEA": "Management of companies and administrations student office",
|
"GEA": "Management of companies and administrations student office",
|
||||||
"IT": "IT student office",
|
"IT": "IT student office",
|
||||||
"made": "Made with ❤️ by",
|
"made": "Made with ❤️ by",
|
||||||
"contact": "Contact",
|
"orderIssue": "Order issue",
|
||||||
"orderIssue": "Order issue"
|
"phoneNumber": "Phone number",
|
||||||
|
"message": "Message",
|
||||||
|
"send": "Send",
|
||||||
|
"subject": "Subject",
|
||||||
|
"warnMessage": "Don't forget to specify the order number (s) if necessary",
|
||||||
|
"commandEdit": "Order modification",
|
||||||
|
"commandRemove": "Order deletion",
|
||||||
|
"question": "Practical question",
|
||||||
|
"profile": "My profile",
|
||||||
|
"other": "Another question"
|
||||||
},
|
},
|
||||||
"index": {
|
"index": {
|
||||||
"welcome": "Welcome to Sandwiches Order Doua",
|
"welcome": "Welcome to Sandwiches Order Doua",
|
||||||
|
@ -64,5 +73,7 @@
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"order": "Order",
|
"order": "Order",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
"sandwich": "Sandwich"
|
"sandwich": "Sandwich",
|
||||||
|
"contact": "Contact",
|
||||||
|
"messageSend": "The message has been sent"
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,17 @@
|
||||||
"GEA": "BDE GEA",
|
"GEA": "BDE GEA",
|
||||||
"IT": "BDE Info",
|
"IT": "BDE Info",
|
||||||
"made": "Fait avec ❤️ par",
|
"made": "Fait avec ❤️ par",
|
||||||
"contact": "Contact",
|
"orderIssue": "Problème de commande",
|
||||||
"orderIssue": "Problème de commande"
|
"phoneNumber": "Numéro de téléphone",
|
||||||
|
"message": "Message",
|
||||||
|
"send": "Envoyer",
|
||||||
|
"subject": "Sujet",
|
||||||
|
"warnMessage": "N'oubliez pas de spécifier le/les numéro/s de commande/s si nécessaire",
|
||||||
|
"commandEdit": "Modification de commande",
|
||||||
|
"commandRemove": "Suppression de commande",
|
||||||
|
"question": "Question Pratique",
|
||||||
|
"profile": "Mon profil",
|
||||||
|
"other": "Autre question"
|
||||||
},
|
},
|
||||||
"index": {
|
"index": {
|
||||||
"welcome": "Bienvenue sur Sandwiches Order Doua",
|
"welcome": "Bienvenue sur Sandwiches Order Doua",
|
||||||
|
@ -64,5 +73,7 @@
|
||||||
"date": "Date",
|
"date": "Date",
|
||||||
"order": "Commande",
|
"order": "Commande",
|
||||||
"save": "Enregistrer",
|
"save": "Enregistrer",
|
||||||
"sandwich": "Sandwich"
|
"sandwich": "Sandwich",
|
||||||
|
"contact": "Contact",
|
||||||
|
"messageSend": "Le message a bien été envoyé"
|
||||||
}
|
}
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -706,6 +706,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
},
|
},
|
||||||
|
"emailjs": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/emailjs/-/emailjs-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-O8fUbXhyzZEokeLq+mrefYaSdToLXlW3oQfCU+75kqkwL27W8Cb6PW/ipjF1ePapLNoAvWPvwInh/x7x4z/jKA=="
|
||||||
|
},
|
||||||
"emoji-regex": {
|
"emoji-regex": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
|
"emailjs": "^3.3.0",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"express-recaptcha": "^5.0.2",
|
"express-recaptcha": "^5.0.2",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
|
|
|
@ -56,8 +56,7 @@ a {
|
||||||
font-size: 100%;
|
font-size: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.field input[type="text"], .field input[type="list"], .field input[type="date"], .field input[type="password"],
|
.field input {
|
||||||
.field input[type="number"], .field input[type="checkbox"], .field input[type="email"] {
|
|
||||||
height: 2.5vh;
|
height: 2.5vh;
|
||||||
border-top: none;
|
border-top: none;
|
||||||
border-left: none;
|
border-left: none;
|
||||||
|
@ -102,6 +101,28 @@ a {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#contact .cont {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#contact .cont .field {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field.message {
|
||||||
|
width: max-content;
|
||||||
|
height: max-content;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message>textarea {
|
||||||
|
width: 60vw;
|
||||||
|
height: 30vh;
|
||||||
|
overflow: auto;
|
||||||
|
resize: none;
|
||||||
|
font-size: large;
|
||||||
|
}
|
||||||
|
|
||||||
.popup {
|
.popup {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
@ -225,4 +246,8 @@ p.before-link a::before {
|
||||||
body {
|
body {
|
||||||
font-size: xx-large;
|
font-size: xx-large;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message>textarea {
|
||||||
|
font-size: xx-large;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
32
routes/contact.js
Normal file
32
routes/contact.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
let express = require("express");
|
||||||
|
let router = express.Router();
|
||||||
|
let error = require("./utils/error");
|
||||||
|
let reCaptcha = require("../middlewares/reCaptcha");
|
||||||
|
let Message = require("emailjs").Message;
|
||||||
|
|
||||||
|
|
||||||
|
router.post("/", reCaptcha, async (req, res) => {
|
||||||
|
if (!req.body.firstName || !req.body.lastName || !req.body.email || !req.body.subject || ! req.body.message)
|
||||||
|
return error(req, res, "Invalid contact form !", 400, "Missing arg");
|
||||||
|
|
||||||
|
let config = req.app.get("config");
|
||||||
|
|
||||||
|
req.app.get("mailClient").send( new Message({
|
||||||
|
text:
|
||||||
|
`${req.body.firstName} ${req.body.lastName} <${req.body.email}> ${req.body.phoneNumber ? "["+req.body.phoneNumber+"] " : ""}- ${req.body.subject}
|
||||||
|
|
||||||
|
${req.body.message}`,
|
||||||
|
from: config.email.from,
|
||||||
|
to: config.email.contact,
|
||||||
|
cc: `${req.body.firstName} ${req.body.lastName} <${req.body.email}>`,
|
||||||
|
subject: res.__("contact")+": "+req.body.subject
|
||||||
|
}), (err, message) => {
|
||||||
|
if (err)
|
||||||
|
return error(req, res, "Fail to send message !", 500,
|
||||||
|
req.app.get("env") !== "production" ? err : undefined);
|
||||||
|
else
|
||||||
|
res.render("contact", {title: "SOD - Contact"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
6
views/contact.pug
Normal file
6
views/contact.pug
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
extends layout
|
||||||
|
|
||||||
|
block content
|
||||||
|
div.card
|
||||||
|
h1=__("contact")
|
||||||
|
p=__("messageSend")
|
|
@ -30,7 +30,7 @@ html
|
||||||
|
|
||||||
div#more
|
div#more
|
||||||
a=__("layout.about")
|
a=__("layout.about")
|
||||||
a=__("layout.contact")
|
a=__("contact")
|
||||||
|
|
||||||
div#dark.hide
|
div#dark.hide
|
||||||
div#about.popup.card.hide
|
div#about.popup.card.hide
|
||||||
|
@ -58,20 +58,36 @@ html
|
||||||
p.before-link=__("layout.made")
|
p.before-link=__("layout.made")
|
||||||
a(href="https://www.linkedin.com/in/florian-charlaix" target="_blank") Florian Charlaix
|
a(href="https://www.linkedin.com/in/florian-charlaix" target="_blank") Florian Charlaix
|
||||||
div#contact.popup.card.hide
|
div#contact.popup.card.hide
|
||||||
h1=__("layout.contact")
|
h1=__("contact")
|
||||||
p.before-link=__("layout.orderIssue") + ":"
|
form(action="/contact" method="POST")
|
||||||
a(href="mailto: ") test@test.fr
|
div.cont
|
||||||
p.before-link=__("layout.bio") + ":"
|
div.field
|
||||||
a(href="mailto: ")
|
label(for="firstNameContact")="* "+__("firstName")
|
||||||
p.before-link=__("layout.chemistry") + ":"
|
input#firstNameContact(type="text" name="firstName" value=user?user.firstName:"" required)
|
||||||
a(href="mailto: ")
|
div.field
|
||||||
p.before-link=__("layout.GC") + ":"
|
label(for="lastNameContact")="* "+__("lastName")
|
||||||
a(href="mailto: ")
|
input#lastNameContact(type="text" name="lastName" value=user ? user.lastName : "" required)
|
||||||
p.before-link=__("layout.GCPD") + ":"
|
div.cont
|
||||||
a(href="mailto: bde.gcgp.lyon1@gmail.com") bde.gcgp.lyon1@gmail.com
|
div.field
|
||||||
p.before-link=__("layout.GEA") + ":"
|
label(for="emailContact")="* "+__("email")
|
||||||
a(href="mailto: ")
|
input#emailContact(type="email" name="email" value=user ? user.email : "" required)
|
||||||
p.before-link=__("layout.IT") + ":"
|
div.field
|
||||||
a(href="mailto: contact@bde-info.org") contact@bde-info.org
|
label(for="phoneNumberContact")=__("layout.phoneNumber")
|
||||||
|
input#phoneNumberContact(type="tel" name="phoneNumber")
|
||||||
|
div.field
|
||||||
|
label(for="subjectContact")="* "+__("layout.subject")
|
||||||
|
input#subjectContact(list="subjectContactList" autocomplete="off" name="subject" required)
|
||||||
|
datalist#subjectContactList
|
||||||
|
option(value=__("layout.commandEdit"))
|
||||||
|
option(value=__("layout.commandRemove"))
|
||||||
|
option(value=__("layout.question"))
|
||||||
|
option(value=__("layout.profile"))
|
||||||
|
option(value=__("layout.other"))
|
||||||
|
p=__("layout.warnMessage")
|
||||||
|
div.field.message
|
||||||
|
label(for="messageContact")=__("layout.message")
|
||||||
|
textarea#messageContact(name="message" required)
|
||||||
|
div.field
|
||||||
|
+submit(value=__("layout.send"))
|
||||||
|
|
||||||
script(src="/javascripts/layout.js")
|
script(src="/javascripts/layout.js")
|
||||||
|
|
Reference in a new issue