Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a66bc1cedc | |||
| 3f068dfcec |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wedding",
|
"name": "wedding",
|
||||||
"version": "1.0.0",
|
"version": "1.0.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.5",
|
"node": ">=6.5",
|
||||||
|
|||||||
@@ -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,12 +8,40 @@ 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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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/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;
|
||||||
|
|||||||
@@ -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';
|
||||||
@@ -222,7 +222,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