2 Commits
1.0.0 ... 1.0.2

Author SHA1 Message Date
a66bc1cedc Add less transparent bg to scrolled nav
Reposition the background images
2017-03-06 23:39:09 +00:00
3f068dfcec Fix bug that prevented sending of email
Add api key for export route
2017-03-06 22:33:32 +00:00
12 changed files with 54 additions and 7 deletions

View File

@@ -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",

View File

@@ -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;
} }

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();