mirror of
https://github.com/aurora-dot/pastel.codes.git
synced 2024-11-22 00:02:24 +00:00
Completed contact page??
This commit is contained in:
parent
f638cf4d8b
commit
ffe3b01e32
2
app.js
2
app.js
@ -5,6 +5,7 @@ var cookieParser = require('cookie-parser');
|
||||
var mLogger = require('morgan');
|
||||
var sassMiddleware = require('node-sass-middleware');
|
||||
var logger = require('./config/winston');
|
||||
const helmet = require("helmet");
|
||||
|
||||
var indexRouter = require('./routes/index');
|
||||
var aboutRouter = require('./routes/about');
|
||||
@ -25,6 +26,7 @@ if (process.env.NODE_ENV === 'production') {
|
||||
app.use(mLogger('dev'));
|
||||
}
|
||||
|
||||
app.use(helmet());
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: false }));
|
||||
app.use(cookieParser());
|
||||
|
116
package-lock.json
generated
116
package-lock.json
generated
@ -250,6 +250,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"bowser": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz",
|
||||
"integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA=="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
@ -278,6 +283,11 @@
|
||||
"map-obj": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"camelize": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
|
||||
"integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
@ -428,6 +438,11 @@
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-security-policy-builder": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz",
|
||||
"integrity": "sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ=="
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
@ -482,6 +497,11 @@
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"dasherize": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
|
||||
"integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
@ -520,6 +540,11 @@
|
||||
"resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
|
||||
"integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
|
||||
},
|
||||
"dont-sniff-mimetype": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz",
|
||||
"integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug=="
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
@ -634,6 +659,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"express-rate-limit": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.1.3.tgz",
|
||||
"integrity": "sha512-TINcxve5510pXj4n9/1AMupkj3iWxl3JuZaWhCdYDlZeoCPqweGZrxbrlqTCFb1CT5wli7s8e2SH/Qz2c9GorA=="
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
@ -659,6 +689,11 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz",
|
||||
"integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA=="
|
||||
},
|
||||
"feature-policy": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
|
||||
"integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ=="
|
||||
},
|
||||
"fecha": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.0.tgz",
|
||||
@ -877,11 +912,77 @@
|
||||
"resolved": "https://registry.npmjs.org/hcaptcha/-/hcaptcha-0.0.2.tgz",
|
||||
"integrity": "sha512-wWOncj/sY+q8s7tV12tjn3cFNoQhSu3l/7nTJi4QkFKALQi9XnduoXrV/KFzLg5lnB+5560zSAoi9YdYPDw6Eg=="
|
||||
},
|
||||
"helmet": {
|
||||
"version": "3.23.3",
|
||||
"resolved": "https://registry.npmjs.org/helmet/-/helmet-3.23.3.tgz",
|
||||
"integrity": "sha512-U3MeYdzPJQhtvqAVBPntVgAvNSOJyagwZwyKsFdyRa8TV3pOKVFljalPOCxbw5Wwf2kncGhmP0qHjyazIdNdSA==",
|
||||
"requires": {
|
||||
"depd": "2.0.0",
|
||||
"dont-sniff-mimetype": "1.1.0",
|
||||
"feature-policy": "0.3.0",
|
||||
"helmet-crossdomain": "0.4.0",
|
||||
"helmet-csp": "2.10.0",
|
||||
"hide-powered-by": "1.1.0",
|
||||
"hpkp": "2.0.0",
|
||||
"hsts": "2.2.0",
|
||||
"nocache": "2.1.0",
|
||||
"referrer-policy": "1.2.0",
|
||||
"x-xss-protection": "1.3.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"helmet-crossdomain": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.4.0.tgz",
|
||||
"integrity": "sha512-AB4DTykRw3HCOxovD1nPR16hllrVImeFp5VBV9/twj66lJ2nU75DP8FPL0/Jp4jj79JhTfG+pFI2MD02kWJ+fA=="
|
||||
},
|
||||
"helmet-csp": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.10.0.tgz",
|
||||
"integrity": "sha512-Rz953ZNEFk8sT2XvewXkYN0Ho4GEZdjAZy4stjiEQV3eN7GDxg1QKmYggH7otDyIA7uGA6XnUMVSgeJwbR5X+w==",
|
||||
"requires": {
|
||||
"bowser": "2.9.0",
|
||||
"camelize": "1.0.0",
|
||||
"content-security-policy-builder": "2.1.0",
|
||||
"dasherize": "2.0.0"
|
||||
}
|
||||
},
|
||||
"hide-powered-by": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.1.0.tgz",
|
||||
"integrity": "sha512-Io1zA2yOA1YJslkr+AJlWSf2yWFkKjvkcL9Ni1XSUqnGLr/qRQe2UI3Cn/J9MsJht7yEVCe0SscY1HgVMujbgg=="
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg=="
|
||||
},
|
||||
"hpkp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
|
||||
"integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
|
||||
},
|
||||
"hsts": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
|
||||
"integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
|
||||
"requires": {
|
||||
"depd": "2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
|
||||
@ -1262,6 +1363,11 @@
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"nocache": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
|
||||
"integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
|
||||
},
|
||||
"node-gyp": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
|
||||
@ -1735,6 +1841,11 @@
|
||||
"strip-indent": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"referrer-policy": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
|
||||
"integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
|
||||
},
|
||||
"repeating": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
|
||||
@ -2289,6 +2400,11 @@
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"x-xss-protection": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz",
|
||||
"integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg=="
|
||||
},
|
||||
"y18n": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
|
||||
|
@ -12,7 +12,9 @@
|
||||
"cookie-parser": "1.4.4",
|
||||
"debug": "4.1.1",
|
||||
"express": "4.17.1",
|
||||
"express-rate-limit": "^5.1.3",
|
||||
"hcaptcha": "0.0.2",
|
||||
"helmet": "^3.23.3",
|
||||
"http-errors": "1.7.3",
|
||||
"morgan": "1.10.0",
|
||||
"node-sass-middleware": "0.11.0",
|
||||
|
@ -25,9 +25,12 @@ h2 {
|
||||
font-weight: bold;
|
||||
font-family: "Apercu Mono", monospace; }
|
||||
|
||||
p {
|
||||
p, label, input, textarea {
|
||||
font-family: "Apercu Mono", monospace; }
|
||||
|
||||
label {
|
||||
font-size: 3vh; }
|
||||
|
||||
a:hover {
|
||||
color: #CDE7B0; }
|
||||
|
||||
@ -147,6 +150,27 @@ footer {
|
||||
.start {
|
||||
margin-top: 3vh; }
|
||||
|
||||
#contact-message {
|
||||
margin-top: 2vh; }
|
||||
#contact-message p {
|
||||
color: #CDE7B0; }
|
||||
#contact-message p span {
|
||||
text-decoration: underline #CDE7B0; }
|
||||
|
||||
.h-captcha {
|
||||
margin-bottom: 0.5vh; }
|
||||
|
||||
.btn-primary {
|
||||
font-family: "Apercu Mono";
|
||||
background-color: #CC7A98;
|
||||
color: #002234;
|
||||
border-color: #002234; }
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #002234;
|
||||
color: #CC7A98;
|
||||
border-color: #CC7A98; }
|
||||
|
||||
.ham {
|
||||
width: 30px;
|
||||
height: 20px;
|
||||
|
@ -29,13 +29,15 @@ h2
|
||||
font-weight: bold
|
||||
font-family: "Apercu Mono", monospace
|
||||
|
||||
p
|
||||
p, label, input, textarea
|
||||
font-family: "Apercu Mono", monospace
|
||||
|
||||
label
|
||||
font-size: 3vh
|
||||
|
||||
a:hover
|
||||
color: $green
|
||||
|
||||
|
||||
article
|
||||
min-height: 100%
|
||||
display: grid
|
||||
@ -166,6 +168,27 @@ footer
|
||||
.start
|
||||
margin-top: 3vh
|
||||
|
||||
#contact-message
|
||||
margin-top: 2vh
|
||||
p
|
||||
color: $green
|
||||
span
|
||||
text-decoration: underline $green
|
||||
|
||||
.h-captcha
|
||||
margin-bottom: 0.5vh
|
||||
|
||||
.btn-primary
|
||||
font-family: "Apercu Mono"
|
||||
background-color: $pink
|
||||
color: $black
|
||||
border-color: $black
|
||||
|
||||
.btn-primary:hover
|
||||
background-color: $black
|
||||
color: $pink
|
||||
border-color: $pink
|
||||
|
||||
// Nav stuff
|
||||
|
||||
.ham
|
||||
|
@ -4,8 +4,8 @@ var router = express.Router();
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function(req, res, next) {
|
||||
const ghost_key = process.env.GHOST_KEY
|
||||
const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${ghost_key}`
|
||||
const GHOST_KEY = process.env.GHOST_KEY
|
||||
const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`
|
||||
|
||||
axios.all([
|
||||
axios.get(`${base_url}&limit=3`),
|
||||
@ -22,7 +22,6 @@ router.get('/', function(req, res, next) {
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
// https://blog.pastel.codes/ghost/api/v3/content/posts/?key=
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
@ -1,19 +1,29 @@
|
||||
var express = require('express');
|
||||
var rate_limit = require("express-rate-limit")
|
||||
const {verify} = require('hcaptcha');
|
||||
const nodemailer = require('nodemailer')
|
||||
var router = express.Router();
|
||||
|
||||
const contact_rate_limit = rate_limit({
|
||||
windowMs: 10 * 60 * 1000, // 10 minutes
|
||||
max: 1, // limit each IP to 10 requests per windowMs
|
||||
message: "Too many contact requests, try again later.",
|
||||
handler: function(req, res /*, next*/) {
|
||||
res.render('error', {title:"Error", message: "Too many contact requests, try again later.", error: {status: null}})
|
||||
},
|
||||
});
|
||||
|
||||
// POST route from contact form
|
||||
router.post('/', (req, res) => {
|
||||
router.post('/', contact_rate_limit,(req, res) => {
|
||||
const TO_GMAIL_USER = process.env.TO_GMAIL_USER
|
||||
const FROM_GMAIL_USER = process.env.FROM_GMAIL_USER
|
||||
const GMAIL_PASS = process.env.GMAIL_PASS
|
||||
const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY
|
||||
const token = req.body["g-recaptcha-response"];
|
||||
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
|
||||
|
||||
verify(HCAPTCHA_KEY, token)
|
||||
.then((data) => {
|
||||
console.log(data)
|
||||
if (data.success === true) {
|
||||
// Instantiate the SMTP server
|
||||
const smtpTrans = nodemailer.createTransport({
|
||||
@ -31,7 +41,7 @@ router.post('/', (req, res) => {
|
||||
from: 'Pastel.codes Contact Notifications', // This is ignored by Gmail
|
||||
to: TO_GMAIL_USER,
|
||||
subject: 'New message from contact form at pastel.codes',
|
||||
text: `${req.body.name} (${req.body.email}) says: ${req.body.message}`
|
||||
text: `${req.body.firstname} ${req.body.lastname} (${req.body.email})\nsays: ${req.body.message}\n\nip: ${ip}`
|
||||
}
|
||||
|
||||
// maybe send conformation email?
|
||||
@ -40,26 +50,26 @@ router.post('/', (req, res) => {
|
||||
smtpTrans.sendMail(mailOpts, (error, response) => {
|
||||
if (error) {
|
||||
console.log(error)
|
||||
res.render('error', {message: "Email did not send"}) // Show a page indicating failure
|
||||
res.render('error', { message: "Email did not send" }) // Show a page indicating failure
|
||||
}
|
||||
else {
|
||||
res.render('contact-success') // Show a page indicating success
|
||||
res.render('contact', { message: "I will get back to you soon!", success: "Make sure the email is from ", email: TO_GMAIL_USER }) // Show a page indicating success
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// rerender with same info in the text box and show error message
|
||||
res.render('contact', { title: 'Contact', description: "Contact me!", message: "Captcha failed, try again" });
|
||||
res.render('contact', { message: "Captcha failed, try again" });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
res.render('contact', {title: 'Contact', description: "Contact me!", message: "Something wrong happened, try again later"});
|
||||
res.render('contact', { message: "Something wrong happened, try again later" });
|
||||
});
|
||||
})
|
||||
|
||||
/* GET home page. */
|
||||
router.get('/', function(req, res, next) {
|
||||
res.render('contact', { title: 'Contact', description: "Contact me!", message: null });
|
||||
res.render('contact', { title: 'Contact', description: "Contact me!"});
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
@ -1,10 +1,10 @@
|
||||
extends layout
|
||||
|
||||
block nav-links
|
||||
li.nav-item.active
|
||||
li.nav-item
|
||||
a.nav-link(href='/')
|
||||
span Home
|
||||
li.nav-item
|
||||
li.nav-item.active
|
||||
a.nav-link(href='#')
|
||||
span About
|
||||
li.nav-item
|
||||
@ -28,7 +28,8 @@ block content
|
||||
h1
|
||||
span Hello.
|
||||
p I’m Esther, a 19 year old student in 2nd year of university, who studies computer science & artificial intelligence.
|
||||
p In my free time, I create small projects to learn new skills and for them to function well for others to use; additionally, I do some graphic design / art as a hobby but has helped me create catching designs.
|
||||
p In my free time, I create small projects to learn new skills to be helpful for others, recently i have been focusing on node.js.
|
||||
p Graphic design is also very fun and i enjoy making small projects to post on instagram, it helps with programming too which is neat
|
||||
.row
|
||||
.col.start
|
||||
h1
|
||||
|
@ -1,4 +0,0 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
p fuck
|
@ -1,4 +0,0 @@
|
||||
extends layout
|
||||
|
||||
block content
|
||||
p yay
|
@ -4,7 +4,7 @@ block head
|
||||
script(src='https://hcaptcha.com/1/api.js' async='' defer='defer')
|
||||
|
||||
block nav-links
|
||||
li.nav-item.active
|
||||
li.nav-item
|
||||
a.nav-link(href='/')
|
||||
span Home
|
||||
li.nav-item
|
||||
@ -19,24 +19,42 @@ block nav-links
|
||||
li.nav-item
|
||||
a.nav-link(href='https://blog.pastel.codes')
|
||||
span Blog
|
||||
li.nav-item
|
||||
li.nav-item.active
|
||||
a.nav-link(href='#')
|
||||
span Contact
|
||||
|
||||
block content
|
||||
.container
|
||||
form#contact-form(action='/contact' method='post' role='form')
|
||||
.form-group
|
||||
label(for='name') Name
|
||||
input#name(name='name' class="form-control" type='text' placeholder='Your name' required='')
|
||||
.form-group
|
||||
label(for='email') Email
|
||||
input#email(name='email' class="form-control" type='text' placeholder='Your email' required='')
|
||||
.form-group
|
||||
label(for='message') Message
|
||||
textarea#message(name='message' class="form-control" placeholder='Enter your message here' rows='3' required='')
|
||||
.h-captcha(data-sitekey='49abba50-1813-4ab3-acbf-2a8bfff1f7c3')
|
||||
button(type='submit' class="btn btn-primary") Submit
|
||||
if message
|
||||
#contact-error
|
||||
p=message
|
||||
.row
|
||||
.col
|
||||
h1
|
||||
span Contact.
|
||||
.row
|
||||
.col
|
||||
form#contact-form(action='/contact' method='post' role='form')
|
||||
.form-group
|
||||
label Name
|
||||
.form-row
|
||||
.col
|
||||
input#fname(name='firstname' class="form-control" type='text' placeholder='First name' required="true" pattern="^[\\w'\\-,.][^0-9_!¡?÷?¿/\\\\+=@#$%ˆ&*(){}|~<>;:[\\]]{2,}$")
|
||||
.col
|
||||
input#lname(name='lastname' class="form-control" type='text' placeholder='Last name' required="true" pattern="^[\\w'\\-,.][^0-9_!¡?÷?¿/\\\\+=@#$%ˆ&*(){}|~<>;:[\\]]{2,}$")
|
||||
|
||||
.form-group
|
||||
label(for='email') Email
|
||||
input#email(name='email' class="form-control" type='text' placeholder='Email (example@email.com)' required='true' pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$")
|
||||
.form-group
|
||||
label(for='message') Message
|
||||
textarea#message(name='message' class="form-control" placeholder='Enter your message here' rows='3' required='true')
|
||||
.form-group
|
||||
.h-captcha(data-sitekey='49abba50-1813-4ab3-acbf-2a8bfff1f7c3')
|
||||
button(type='submit' class="btn btn-primary") Submit
|
||||
|
||||
.row
|
||||
.col
|
||||
if message
|
||||
#contact-message
|
||||
p=message
|
||||
if success
|
||||
p=success
|
||||
span#email=email
|
||||
|
Loading…
Reference in New Issue
Block a user