Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cdc6614c63 | |||
| 75740699f1 | |||
| 6d75606134 | |||
| a66bc1cedc | |||
| 3f068dfcec |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wedding",
|
"name": "wedding",
|
||||||
"version": "1.0.0",
|
"version": "1.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.5",
|
"node": ">=6.5",
|
||||||
|
|||||||
BIN
public/img/moors_2560.jpg
Normal file
BIN
public/img/moors_2560.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 636 KiB |
@@ -13,6 +13,10 @@ html {
|
|||||||
line-height: 1.375; /* ~22px */
|
line-height: 1.375; /* ~22px */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #0074c2;
|
color: #0074c2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,14 @@
|
|||||||
right: 0;
|
right: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background: rgba(0, 0, 0, 0.1);
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
z-index: 100;
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
transition: background 0.3s, ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navDark {
|
||||||
|
background: rgba(60, 60, 60, 0.95);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|||||||
@@ -8,18 +8,47 @@ class Navigation extends React.Component {
|
|||||||
current: PropTypes.string,
|
current: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
scrollAtTop: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('scroll', this.handleScroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleScroll = (event) => {
|
||||||
|
const scrollTop = event.srcElement.body.scrollTop;
|
||||||
|
this.setState({
|
||||||
|
scrollAtTop: scrollTop < 10,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.current) {
|
if (!this.props.current) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className={s.root} role="navigation">
|
<div
|
||||||
|
className={[
|
||||||
|
s.root,
|
||||||
|
this.state.scrollAtTop ? null : s.navDark,
|
||||||
|
].join(' ')}
|
||||||
|
role="navigation"
|
||||||
|
>
|
||||||
<div className={s.container}>
|
<div className={s.container}>
|
||||||
<Link className={[s.link, this.props.current === 'home' ? s.active : null].join(' ')} to="/">RSVP</Link>
|
<Link className={[s.link, this.props.current === 'home' ? s.active : null].join(' ')} to="/">RSVP</Link>
|
||||||
<Link className={[s.link, this.props.current === 'ceremony' ? s.active : null].join(' ')} to="/church">Church</Link>
|
<Link className={[s.link, this.props.current === 'ceremony' ? s.active : null].join(' ')} to="/church">Church</Link>
|
||||||
<Link className={[s.link, this.props.current === 'reception' ? s.active : null].join(' ')} to="/venue">Venue</Link>
|
<Link className={[s.link, this.props.current === 'reception' ? s.active : null].join(' ')} to="/venue">Venue</Link>
|
||||||
<Link className={[s.link, this.props.current === 'accomodation' ? s.active : null].join(' ')} to="/hotels">Hotels</Link>
|
<Link className={[s.link, this.props.current === 'accomodation' ? s.active : null].join(' ')} to="/hotels">Hotels</Link>
|
||||||
<Link className={[s.link, this.props.current === 'transport' ? s.active : null].join(' ')} to="/transport">Transport</Link>
|
<Link className={[s.link, this.props.current === 'transport' ? s.active : null].join(' ')} to="/transport">Transport</Link>
|
||||||
|
<Link className={[s.link, this.props.current === 'giftlist' ? s.active : null].join(' ')} to="/giftlist">Gift list</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Navigation",
|
"name": "Navigation",
|
||||||
"version": "1.0.0",
|
"version": "1.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./Navigation.js"
|
"main": "./Navigation.js"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ function getEmailText(person) {
|
|||||||
return `Dear ${person.firstname}.\n\n
|
return `Dear ${person.firstname}.\n\n
|
||||||
Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.\n
|
Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.\n
|
||||||
${person.attending ? `Your meal choices are ${starters[person.starter]} and ${mains[person.main]}.\n` : ''}
|
${person.attending ? `Your meal choices are ${starters[person.starter]} and ${mains[person.main]}.\n` : ''}
|
||||||
${person.attending && person.dietary.length > 0 ? `Your dietary requirements are: ${person.dietary}.\n` : ''}
|
${person.attending && person.dietary && person.dietary.trim().length > 0 ? `Your dietary requirements are: ${person.dietary}.\n` : ''}
|
||||||
You can modify your RSVP up until ${getRsvpEnd()} here: https://danielandhana.com/${person.password}.\n
|
You can modify your RSVP up until ${getRsvpEnd()} here: https://danielandhana.com/${person.password}.\n
|
||||||
${person.attending ? 'See you at our wedding,' : 'Hope to see you soon,'}\n
|
${person.attending ? 'See you at our wedding,' : 'Hope to see you soon,'}\n
|
||||||
Daniel and Hana
|
Daniel and Hana
|
||||||
@@ -29,7 +29,7 @@ function getEmailHTML(person) {
|
|||||||
return `<p>Dear ${person.firstname}.</p>
|
return `<p>Dear ${person.firstname}.</p>
|
||||||
<p>Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.</p>
|
<p>Thanks for your RSVP, ${person.attending ? 'we\'re delighted to hear you will be attending' : 'we\'re sorry to hear you will not be attending'}.</p>
|
||||||
${person.attending ? `<p>Your meal choices are <b>${starters[person.starter]}</b> and <b>${mains[person.main]}</b>.</p>` : ''}
|
${person.attending ? `<p>Your meal choices are <b>${starters[person.starter]}</b> and <b>${mains[person.main]}</b>.</p>` : ''}
|
||||||
${person.attending && person.dietary.length > 0 ? `<p>Your dietary requirements are: <b>${person.dietary}</b>.</p>` : ''}
|
${person.attending && person.dietary && person.dietary.trim().length > 0 ? `<p>Your dietary requirements are: <b>${person.dietary}</b>.</p>` : ''}
|
||||||
<p>You can modify your RSVP up until <b>${getRsvpEnd()}</b> <a href="https://danielandhana.com/${person.password}">here</a>.</p>
|
<p>You can modify your RSVP up until <b>${getRsvpEnd()}</b> <a href="https://danielandhana.com/${person.password}">here</a>.</p>
|
||||||
<p>${person.attending ? 'See you at our wedding,' : 'Hope to see you soon,'}</p>
|
<p>${person.attending ? 'See you at our wedding,' : 'Hope to see you soon,'}</p>
|
||||||
<p>Daniel and Hana</p>
|
<p>Daniel and Hana</p>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/offley_2560.jpg');
|
background: url('/img/offley_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 54%;
|
background-position-x: 54%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.4);
|
filter: grayscale(1) brightness(0.4);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/church_2560.jpg');
|
background: url('/img/church_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 54%;
|
background-position-x: 54%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.4);
|
filter: grayscale(1) brightness(0.4);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
75
src/routes/giftlist/Giftlist.css
Normal file
75
src/routes/giftlist/Giftlist.css
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
@import '../../components/variables.css';
|
||||||
|
|
||||||
|
.root {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bgImage {
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: url('/img/moors_2560.jpg');
|
||||||
|
background-size: cover;
|
||||||
|
background-position-x: 78%;
|
||||||
|
background-position-y: 66%;
|
||||||
|
background-color: #c1c1c1;
|
||||||
|
filter: grayscale(1) brightness(0.4);
|
||||||
|
z-index: -1;
|
||||||
|
transition: filter ease-in-out 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding-top: 50px;
|
||||||
|
margin: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headings {
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0 auto 40px;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 3px 3px 8px var(--colour-nearblack);
|
||||||
|
font-size: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.headings h1 {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sig {
|
||||||
|
font-family: var(--font-family-cursive);
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: #fff;
|
||||||
|
text-shadow: 1px 1px 4px var(--colour-nearblack);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 20px;
|
||||||
|
opacity: 0.75;
|
||||||
|
outline: 0;
|
||||||
|
border: 4px solid #fff;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: var(--colour-nearblack);
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 1.3333333;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity ease-in-out 0.25s, box-shadow ease-in-out 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover,
|
||||||
|
.button:focus {
|
||||||
|
opacity: 0.9;
|
||||||
|
box-shadow: 0 0 4px #fff;
|
||||||
|
}
|
||||||
44
src/routes/giftlist/Giftlist.js
Normal file
44
src/routes/giftlist/Giftlist.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
||||||
|
import s from './Giftlist.css';
|
||||||
|
|
||||||
|
class Giftlist extends React.Component {
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className={s.root}>
|
||||||
|
<div className={s.bgImage} />
|
||||||
|
<div className={s.container}>
|
||||||
|
<div className={s.headings}>
|
||||||
|
<h1>Gift list</h1>
|
||||||
|
</div>
|
||||||
|
<div className={s.content}>
|
||||||
|
<p>We’ve been asked what we’d like for a gift and the answer
|
||||||
|
is simple: you, at our wedding, having a great time.</p>
|
||||||
|
<p>However, if you insist then we’ll say what we’d also love
|
||||||
|
is the most amazing honeymoon possible. We have the basics covered but
|
||||||
|
we’re hoping for the holiday of a lifetime. We would like to see
|
||||||
|
and do everything we’ve dreamed about!</p>
|
||||||
|
<p>Here’s how our gift list works. Just pick the item you’d
|
||||||
|
most like to give us. You’ll then be asked to leave your name
|
||||||
|
and any message you have for us. There is the option to use the PayPal
|
||||||
|
system to send your gift (you can use a credit card – you
|
||||||
|
don’t need a PayPal account). Or, on the day, you could bring
|
||||||
|
the value of your gift in a card.</p>
|
||||||
|
<p>We’ll send you a link to our online photo gallery when we get
|
||||||
|
back and we’ll be sure to tell (bore) you all about it in great
|
||||||
|
detail.</p>
|
||||||
|
<p className={s.sig}>Dan and Hana</p>
|
||||||
|
<a
|
||||||
|
className={s.button}
|
||||||
|
href="https://www.our-wedding-list.co.uk/danielandhana/list"
|
||||||
|
>
|
||||||
|
View our list
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withStyles(s)(Giftlist);
|
||||||
15
src/routes/giftlist/index.js
Normal file
15
src/routes/giftlist/index.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Giftlist from './Giftlist';
|
||||||
|
import Layout from '../../components/Layout';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
|
||||||
|
path: '/giftlist',
|
||||||
|
|
||||||
|
action() {
|
||||||
|
return {
|
||||||
|
title: 'Gift list',
|
||||||
|
component: <Layout current="giftlist"><Giftlist /></Layout>,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/prague_2560.jpg');
|
background: url('/img/prague_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 54%;
|
background-position-x: 54%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.6);
|
filter: grayscale(1) brightness(0.6);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export default {
|
|||||||
require('./reception').default,
|
require('./reception').default,
|
||||||
require('./accomodation').default,
|
require('./accomodation').default,
|
||||||
require('./transport').default,
|
require('./transport').default,
|
||||||
|
require('./giftlist').default,
|
||||||
require('./login').default,
|
require('./login').default,
|
||||||
require('./admin').default,
|
require('./admin').default,
|
||||||
require('./adminPeople').default,
|
require('./adminPeople').default,
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/offley_2560.jpg');
|
background: url('/img/offley_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 54%;
|
background-position-x: 54%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.4);
|
filter: grayscale(1) brightness(0.4);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -39,6 +39,23 @@ class Reception extends React.Component {
|
|||||||
defaultCenter={offley.position}
|
defaultCenter={offley.position}
|
||||||
markers={[offley]}
|
markers={[offley]}
|
||||||
/>
|
/>
|
||||||
|
<h3>About Offley Place</h3>
|
||||||
|
<p>Legend has it that in the 8th century, King Offa discovered the bones of
|
||||||
|
Saint Alban and set about creating St Albans Abbey in a tribute to him.
|
||||||
|
While it was being completed he looked for a place to call home and
|
||||||
|
discovered the local area. After building a grand palace the village is
|
||||||
|
thought to have become known as Great Off Lee.</p>
|
||||||
|
<p>Great Offley Place was first built in the 17th century. Rebuilt in 1810
|
||||||
|
but still retaining a Tudor porch and a 17th century wing, the grand house
|
||||||
|
has a long history which has seen the same family line keep ownership for
|
||||||
|
an impressive 350 years.</p>
|
||||||
|
<p>In 1929 the family ownership was brought to an end when the last owner,
|
||||||
|
Guy George, sold the estate to a director of WH Smith who was well liked
|
||||||
|
in the village and built a cricket pavilion and pitch.</p>
|
||||||
|
<p>When World War II broke out it was sold again, this time to become a
|
||||||
|
teacher training college, and then finally in 2003 it was taken over again
|
||||||
|
and transformed into the luxury hotel, wedding venue and restaurant it
|
||||||
|
is today.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/cervenalhota_2560.jpg');
|
background: url('/img/cervenalhota_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 30%;
|
background-position-x: 30%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.6);
|
filter: grayscale(1) brightness(0.6);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import NotFound from '../notFound/NotFound';
|
|||||||
import { rsvpEndDate, getRsvpEnd } from '../../config';
|
import { rsvpEndDate, getRsvpEnd } from '../../config';
|
||||||
|
|
||||||
let title = 'RSVP';
|
let title = 'RSVP';
|
||||||
|
let attending = 'day';
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
path: '/rsvp/:password',
|
path: '/rsvp/:password',
|
||||||
|
|
||||||
isEditable() {
|
isEditable() {
|
||||||
return new Date() < rsvpEndDate;
|
return new Date() < rsvpEndDate[attending];
|
||||||
},
|
},
|
||||||
|
|
||||||
async action({ params }) {
|
async action({ params }) {
|
||||||
@@ -35,6 +35,9 @@ export default {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assuming all connected guests have the same invite
|
||||||
|
attending = people[0].ceremony ? 'day' : 'evening';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
component: (
|
component: (
|
||||||
@@ -42,7 +45,7 @@ export default {
|
|||||||
<Rsvp
|
<Rsvp
|
||||||
title={title}
|
title={title}
|
||||||
people={people}
|
people={people}
|
||||||
rsvpEnd={getRsvpEnd()}
|
rsvpEnd={getRsvpEnd(attending)}
|
||||||
isEditable={this.isEditable()}
|
isEditable={this.isEditable()}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
background: url('/img/offley_2560.jpg');
|
background: url('/img/offley_2560.jpg');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-position-x: 54%;
|
background-position-x: 54%;
|
||||||
|
background-position-y: 66%;
|
||||||
background-color: #c1c1c1;
|
background-color: #c1c1c1;
|
||||||
filter: grayscale(1) brightness(0.4);
|
filter: grayscale(1) brightness(0.4);
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import models from './data/models';
|
|||||||
import schema from './data/schema';
|
import schema from './data/schema';
|
||||||
import routes from './routes';
|
import routes from './routes';
|
||||||
import assets from './assets'; // eslint-disable-line import/no-unresolved
|
import assets from './assets'; // eslint-disable-line import/no-unresolved
|
||||||
import { port, auth, starters, mains, rsvpEndDate } from './config';
|
import { port, auth, starters, mains, rsvpEndDate, exportApiKey } from './config';
|
||||||
import Person from './data/models/Person';
|
import Person from './data/models/Person';
|
||||||
import Settings from './data/models/Settings';
|
import Settings from './data/models/Settings';
|
||||||
import Rollbar from './core/rollbar';
|
import Rollbar from './core/rollbar';
|
||||||
@@ -149,12 +149,6 @@ app.get('/rsvp/:code', bouncer.block, (req, res, next) => {
|
|||||||
|
|
||||||
app.post('/rsvp/save', (req, res) => {
|
app.post('/rsvp/save', (req, res) => {
|
||||||
try {
|
try {
|
||||||
if (new Date() > rsvpEndDate) {
|
|
||||||
res.json({
|
|
||||||
success: false,
|
|
||||||
err: 'RSVP end date has elapsed',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const update = {};
|
const update = {};
|
||||||
update[req.body.prop] = req.body.value;
|
update[req.body.prop] = req.body.value;
|
||||||
Person.update(update, {
|
Person.update(update, {
|
||||||
@@ -165,7 +159,13 @@ app.post('/rsvp/save', (req, res) => {
|
|||||||
Person.findOne({
|
Person.findOne({
|
||||||
where: { key: req.body.key },
|
where: { key: req.body.key },
|
||||||
}).then(data => {
|
}).then(data => {
|
||||||
if (data.completed) {
|
const endDate = rsvpEndDate[(data.ceremony ? 'day' : 'evening')];
|
||||||
|
if (new Date() > endDate) {
|
||||||
|
return res.json({
|
||||||
|
success: false,
|
||||||
|
err: 'RSVP end date has elapsed',
|
||||||
|
});
|
||||||
|
} else if (data.completed) {
|
||||||
const attending = `\nAttending: ${data.attending ? 'Yes' : 'No'}`;
|
const attending = `\nAttending: ${data.attending ? 'Yes' : 'No'}`;
|
||||||
const starter = (data.attending && data.starter !== -1) ? `\nStarter: ${starters[data.starter]}` : '';
|
const starter = (data.attending && data.starter !== -1) ? `\nStarter: ${starters[data.starter]}` : '';
|
||||||
const main = (data.attending && data.main !== -1) ? `\nMain: ${mains[data.main]}` : '';
|
const main = (data.attending && data.main !== -1) ? `\nMain: ${mains[data.main]}` : '';
|
||||||
@@ -174,7 +174,7 @@ app.post('/rsvp/save', (req, res) => {
|
|||||||
sendSlackMsgWithDebounce(`${data.firstname} ${data.lastname} has saved their RSVP:${attending}${starter}${main}${dietary}`, '#wedding-rsvps', req.body.key);
|
sendSlackMsgWithDebounce(`${data.firstname} ${data.lastname} has saved their RSVP:${attending}${starter}${main}${dietary}`, '#wedding-rsvps', req.body.key);
|
||||||
sendRSVPEmailWithDebounce(data);
|
sendRSVPEmailWithDebounce(data);
|
||||||
}
|
}
|
||||||
res.json({
|
return res.json({
|
||||||
success: true,
|
success: true,
|
||||||
prop: req.body.prop,
|
prop: req.body.prop,
|
||||||
});
|
});
|
||||||
@@ -192,7 +192,6 @@ app.post('/rsvp/save', (req, res) => {
|
|||||||
err,
|
err,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Rollbar.handleError(err);
|
Rollbar.handleError(err);
|
||||||
res.json({
|
res.json({
|
||||||
@@ -222,7 +221,10 @@ app.get('/login', (req, res, next) => {
|
|||||||
|
|
||||||
app.use('/admin*', (req, res, next) => {
|
app.use('/admin*', (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
if (!req.user || !admin(req.user.email)) {
|
// Allow if api key is valid and path is /admin/people/export
|
||||||
|
if (req.headers['x-api-key'] === exportApiKey && req.originalUrl === '/admin/people/export') {
|
||||||
|
next();
|
||||||
|
} else if (!req.user || !admin(req.user.email)) {
|
||||||
res.redirect(401, '/login');
|
res.redirect(401, '/login');
|
||||||
} else {
|
} else {
|
||||||
next();
|
next();
|
||||||
|
|||||||
Reference in New Issue
Block a user