Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 11c833d644 | |||
| 07f606b5dc | |||
| 2e32b09a5c | |||
| cdc6614c63 | |||
| 75740699f1 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "wedding",
|
"name": "wedding",
|
||||||
"version": "1.1.0",
|
"version": "1.3.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.5",
|
"node": ">=6.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "Navigation",
|
"name": "Navigation",
|
||||||
"version": "1.1.0",
|
"version": "1.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "./Navigation.js"
|
"main": "./Navigation.js"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import Nodemailer from 'nodemailer';
|
import Nodemailer from 'nodemailer';
|
||||||
import { email, starters, mains, getRsvpEnd } from '../config';
|
import { email, starters, mains, prettifyDate } from '../config';
|
||||||
import Rollbar from './rollbar';
|
import Rollbar from './rollbar';
|
||||||
import Settings from '../data/models/Settings';
|
import Settings from '../data/models/Settings';
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ function getEmailText(person) {
|
|||||||
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 && person.dietary.trim().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 ${prettifyDate(person.enddate)} 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
|
||||||
`;
|
`;
|
||||||
@@ -30,7 +30,7 @@ function getEmailHTML(person) {
|
|||||||
<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 && person.dietary.trim().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>${prettifyDate(person.enddate)}</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>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ const Person = Model.define('Person', {
|
|||||||
defaultValue: -1,
|
defaultValue: -1,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
enddate: {
|
||||||
|
type: DataType.DATE,
|
||||||
|
},
|
||||||
|
|
||||||
}, {
|
}, {
|
||||||
|
|
||||||
indexes: [
|
indexes: [
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const PersonItemType = new ObjectType({
|
|||||||
dietary: { type: StringType },
|
dietary: { type: StringType },
|
||||||
starter: { type: StringType },
|
starter: { type: StringType },
|
||||||
main: { type: StringType },
|
main: { type: StringType },
|
||||||
|
enddate: { type: StringType },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
|||||||
import s from './AdminPeople.css';
|
import s from './AdminPeople.css';
|
||||||
import Link from '../../components/Link';
|
import Link from '../../components/Link';
|
||||||
import Button from '../../components/Button';
|
import Button from '../../components/Button';
|
||||||
|
import { prettifyDate } from '../../config';
|
||||||
|
|
||||||
class AdminPeople extends React.Component {
|
class AdminPeople extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
@@ -16,6 +17,7 @@ class AdminPeople extends React.Component {
|
|||||||
email: PropTypes.string,
|
email: PropTypes.string,
|
||||||
password: PropTypes.string,
|
password: PropTypes.string,
|
||||||
attending: PropTypes.boolean,
|
attending: PropTypes.boolean,
|
||||||
|
enddate: PropTypes.string,
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -138,6 +140,22 @@ class AdminPeople extends React.Component {
|
|||||||
>⬆</span>
|
>⬆</span>
|
||||||
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'ceremony')}>Ceremony</a>
|
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'ceremony')}>Ceremony</a>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<span
|
||||||
|
className={[
|
||||||
|
s.sortIcon,
|
||||||
|
this.state.sortedBy === 'enddate' && this.state.sortDirection ? s.showSortIcon : null,
|
||||||
|
].join(' ')}
|
||||||
|
>⬇</span>
|
||||||
|
<span
|
||||||
|
className={[
|
||||||
|
s.sortIcon,
|
||||||
|
this.state.sortedBy === 'enddate' && !this.state.sortDirection ? s.showSortIcon : null,
|
||||||
|
].join(' ')}
|
||||||
|
>⬆</span>
|
||||||
|
<a href="#sortcolumn" onClick={event => this.sortPeople(event, 'enddate')}>End date</a>
|
||||||
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<span
|
<span
|
||||||
className={[
|
className={[
|
||||||
@@ -163,6 +181,7 @@ class AdminPeople extends React.Component {
|
|||||||
<td>{person.email}</td>
|
<td>{person.email}</td>
|
||||||
<td><Link to={`/rsvp/${person.password}`}>{person.password}</Link></td>
|
<td><Link to={`/rsvp/${person.password}`}>{person.password}</Link></td>
|
||||||
<td>{person.ceremony ? 'Full day' : 'Evening only'}</td>
|
<td>{person.ceremony ? 'Full day' : 'Evening only'}</td>
|
||||||
|
<td>{prettifyDate(person.enddate)}</td>
|
||||||
<td>{person.completed ? 'Yes' : 'No'}</td>
|
<td>{person.completed ? 'Yes' : 'No'}</td>
|
||||||
<td>
|
<td>
|
||||||
<Button to={`/admin/person/${person.key}`}>Edit</Button>
|
<Button to={`/admin/person/${person.key}`}>Edit</Button>
|
||||||
@@ -239,6 +258,17 @@ class AdminPeople extends React.Component {
|
|||||||
<option value="false">Evening only</option>
|
<option value="false">Evening only</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={s.formGroup}>
|
||||||
|
<label className={s.label} htmlFor="enddate">
|
||||||
|
End date:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className={s.input}
|
||||||
|
type="date"
|
||||||
|
id="enddate"
|
||||||
|
name="enddate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className={s.formGroup}>
|
<div className={s.formGroup}>
|
||||||
<label className={s.label} htmlFor="password">
|
<label className={s.label} htmlFor="password">
|
||||||
Password (blank will autogenerate):
|
Password (blank will autogenerate):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default {
|
|||||||
path: '/admin/people',
|
path: '/admin/people',
|
||||||
|
|
||||||
async action() {
|
async action() {
|
||||||
const resp = await fetchQL('{getAllPersons{key,firstname,lastname,email,ceremony,completed,password}}');
|
const resp = await fetchQL('{getAllPersons{key,firstname,lastname,email,ceremony,completed,password,enddate}}');
|
||||||
|
|
||||||
let people = await resp.json();
|
let people = await resp.json();
|
||||||
if (people.data && people.data.getAllPersons) {
|
if (people.data && people.data.getAllPersons) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class AdminPerson extends React.Component {
|
|||||||
password: PropTypes.string,
|
password: PropTypes.string,
|
||||||
attending: PropTypes.boolean,
|
attending: PropTypes.boolean,
|
||||||
ceremony: PropTypes.boolean,
|
ceremony: PropTypes.boolean,
|
||||||
|
enddate: PropTypes.string,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,6 +24,14 @@ class AdminPerson extends React.Component {
|
|||||||
lastname: this.props.person.lastname,
|
lastname: this.props.person.lastname,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getISODate = (date) => {
|
||||||
|
const d = new Date(date);
|
||||||
|
const year = d.getFullYear();
|
||||||
|
const month = d.getMonth() + 1 < 10 ? `0${d.getMonth() + 1}` : d.getMonth() + 1;
|
||||||
|
const day = d.getDate() < 10 ? `0${d.getDate()}` : d.getDate();
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
handleFirstnameChange = (event) => {
|
handleFirstnameChange = (event) => {
|
||||||
this.setState({ firstname: event.target.value });
|
this.setState({ firstname: event.target.value });
|
||||||
}
|
}
|
||||||
@@ -94,6 +103,18 @@ class AdminPerson extends React.Component {
|
|||||||
<option value="false">Evening only</option>
|
<option value="false">Evening only</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={s.formGroup}>
|
||||||
|
<label className={s.label} htmlFor="enddate">
|
||||||
|
End date:
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
className={s.input}
|
||||||
|
type="date"
|
||||||
|
id="enddate"
|
||||||
|
name="enddate"
|
||||||
|
defaultValue={this.getISODate(this.props.person.enddate)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className={s.formGroup}>
|
<div className={s.formGroup}>
|
||||||
<label className={s.label} htmlFor="password">
|
<label className={s.label} htmlFor="password">
|
||||||
Password:
|
Password:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export default {
|
|||||||
return { redirect: '/admin' };
|
return { redirect: '/admin' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await fetchQL('{getPersonByKey{key,firstname,lastname,email,completed,password,ceremony,starter,main,dietary}}', {
|
const resp = await fetchQL('{getPersonByKey{key,firstname,lastname,email,completed,password,ceremony,starter,main,dietary,enddate}}', {
|
||||||
key: params.key,
|
key: params.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,21 @@ const church = {
|
|||||||
showInfo: true,
|
showInfo: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const carPark = {
|
||||||
|
title: 'Langley Hill Car Park',
|
||||||
|
position: {
|
||||||
|
lat: 51.7121,
|
||||||
|
lng: -0.4507,
|
||||||
|
},
|
||||||
|
showInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
class Ceremony extends React.Component {
|
class Ceremony extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.markers = [church, carPark];
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={s.root}>
|
<div className={s.root}>
|
||||||
@@ -29,11 +43,11 @@ class Ceremony extends React.Component {
|
|||||||
<p>The ceremony begins at 1pm</p>
|
<p>The ceremony begins at 1pm</p>
|
||||||
<h3>Where</h3>
|
<h3>Where</h3>
|
||||||
<p>The church is located at the southern end of Kings Langley high street.
|
<p>The church is located at the southern end of Kings Langley high street.
|
||||||
Parking is available across the road at the Rose and Crown pub.</p>
|
Free parking is available on Langley Hill.</p>
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={14}
|
defaultZoom={15}
|
||||||
defaultCenter={church.position}
|
defaultCenter={church.position}
|
||||||
markers={[church]}
|
markers={this.markers}
|
||||||
/>
|
/>
|
||||||
<h3>About the church</h3>
|
<h3>About the church</h3>
|
||||||
<p>All Saints Church is a medieval church with parts dating from the 13th century.
|
<p>All Saints Church is a medieval church with parts dating from the 13th century.
|
||||||
|
|||||||
@@ -48,3 +48,28 @@
|
|||||||
color: #fff;
|
color: #fff;
|
||||||
text-shadow: 1px 1px 4px var(--colour-nearblack);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,10 +18,22 @@ class Giftlist extends React.Component {
|
|||||||
is the most amazing honeymoon possible. We have the basics covered but
|
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
|
we’re hoping for the holiday of a lifetime. We would like to see
|
||||||
and do everything we’ve dreamed about!</p>
|
and do everything we’ve dreamed about!</p>
|
||||||
<p>Right now we’re busy curating our list, but fret not, we
|
<p>Here’s how our gift list works. Just pick the item you’d
|
||||||
won’t take long! Please do check back here in the coming days,
|
most like to give us. You’ll then be asked to leave your name
|
||||||
we’ll have a link on this page.</p>
|
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>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class Rsvp extends React.Component {
|
|||||||
dietary: PropTypes.string,
|
dietary: PropTypes.string,
|
||||||
starter: PropTypes.string,
|
starter: PropTypes.string,
|
||||||
main: PropTypes.string,
|
main: PropTypes.string,
|
||||||
|
enddate: PropTypes.string,
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
rsvpEnd: PropTypes.string.isRequired,
|
rsvpEnd: PropTypes.string.isRequired,
|
||||||
isEditable: PropTypes.bool.isRequired,
|
isEditable: PropTypes.bool.isRequired,
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ import Layout from '../../components/Layout';
|
|||||||
import fetchQL from '../../core/fetchQL';
|
import fetchQL from '../../core/fetchQL';
|
||||||
import Rsvp from './Rsvp';
|
import Rsvp from './Rsvp';
|
||||||
import NotFound from '../notFound/NotFound';
|
import NotFound from '../notFound/NotFound';
|
||||||
import { rsvpEndDate, getRsvpEnd } from '../../config';
|
import { prettifyDate } from '../../config';
|
||||||
|
|
||||||
let title = 'RSVP';
|
let title = 'RSVP';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
path: '/rsvp/:password',
|
path: '/rsvp/:password',
|
||||||
|
|
||||||
isEditable() {
|
isEditable(date) {
|
||||||
return new Date() < rsvpEndDate;
|
return new Date() < new Date(date);
|
||||||
},
|
},
|
||||||
|
|
||||||
async action({ params }) {
|
async action({ params }) {
|
||||||
@@ -20,7 +19,7 @@ export default {
|
|||||||
return { redirect: '/' };
|
return { redirect: '/' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const resp = await fetchQL('{getPersonsByPassword{key,firstname,lastname,attending,ceremony,dietary,starter,main}}', {
|
const resp = await fetchQL('{getPersonsByPassword{key,firstname,lastname,attending,ceremony,dietary,starter,main,enddate}}', {
|
||||||
password: params.password,
|
password: params.password,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -35,6 +34,9 @@ export default {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Assuming all connected guests have the same invite
|
||||||
|
const firstDate = people[0].enddate;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
component: (
|
component: (
|
||||||
@@ -42,8 +44,8 @@ export default {
|
|||||||
<Rsvp
|
<Rsvp
|
||||||
title={title}
|
title={title}
|
||||||
people={people}
|
people={people}
|
||||||
rsvpEnd={getRsvpEnd()}
|
rsvpEnd={prettifyDate(firstDate)}
|
||||||
isEditable={this.isEditable()}
|
isEditable={this.isEditable(firstDate)}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -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, exportApiKey } from './config';
|
import { port, auth, starters, mains, 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,32 +149,27 @@ 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) {
|
Person.findOne({
|
||||||
res.json({
|
where: { key: req.body.key },
|
||||||
success: false,
|
}).then(data => {
|
||||||
err: 'RSVP end date has elapsed',
|
const endDate = new Date(data.enddate);
|
||||||
});
|
if (new Date() < endDate) {
|
||||||
} else {
|
const update = {};
|
||||||
const update = {};
|
update[req.body.prop] = req.body.value;
|
||||||
update[req.body.prop] = req.body.value;
|
return Person.update(update, {
|
||||||
Person.update(update, {
|
where: {
|
||||||
where: {
|
key: req.body.key,
|
||||||
key: req.body.key,
|
},
|
||||||
},
|
}).then(() => {
|
||||||
}).then(() => {
|
|
||||||
Person.findOne({
|
|
||||||
where: { key: req.body.key },
|
|
||||||
}).then(data => {
|
|
||||||
if (data.completed) {
|
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]}` : '';
|
||||||
const dietary = (data.attending && data.dietary) ? `\nDietary requirements: ${data.dietary}` : '';
|
const dietary = (data.attending && data.dietary) ? `\nDietary requirements: ${data.dietary}` : '';
|
||||||
|
|
||||||
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,
|
||||||
});
|
});
|
||||||
@@ -185,14 +180,18 @@ app.post('/rsvp/save', (req, res) => {
|
|||||||
err,
|
err,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).catch(err => {
|
}
|
||||||
Rollbar.handleError(err);
|
return res.json({
|
||||||
res.json({
|
success: false,
|
||||||
success: false,
|
err: 'RSVP end date has elapsed',
|
||||||
err,
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}).catch(err => {
|
||||||
|
Rollbar.handleError(err);
|
||||||
|
res.json({
|
||||||
|
success: false,
|
||||||
|
err,
|
||||||
|
});
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Rollbar.handleError(err);
|
Rollbar.handleError(err);
|
||||||
res.json({
|
res.json({
|
||||||
@@ -243,6 +242,7 @@ app.post('/admin/person', (req, res, next) => {
|
|||||||
lastname: req.body.lastname,
|
lastname: req.body.lastname,
|
||||||
email: req.body.email,
|
email: req.body.email,
|
||||||
ceremony: req.body.ceremony,
|
ceremony: req.body.ceremony,
|
||||||
|
enddate: new Date(req.body.enddate),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (req.body.password && req.body.password !== '') {
|
if (req.body.password && req.body.password !== '') {
|
||||||
|
|||||||
@@ -4042,7 +4042,7 @@ lodash.toplainobject@^3.0.0:
|
|||||||
lodash._basecopy "^3.0.0"
|
lodash._basecopy "^3.0.0"
|
||||||
lodash.keysin "^3.0.0"
|
lodash.keysin "^3.0.0"
|
||||||
|
|
||||||
lodash@4.12.0, lodash@^4.2.0:
|
lodash@4.12.0:
|
||||||
version "4.12.0"
|
version "4.12.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.12.0.tgz#2bd6dc46a040f59e686c972ed21d93dc59053258"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.12.0.tgz#2bd6dc46a040f59e686c972ed21d93dc59053258"
|
||||||
|
|
||||||
@@ -4054,11 +4054,7 @@ lodash@^3.10.1:
|
|||||||
version "3.10.1"
|
version "3.10.1"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||||
|
|
||||||
lodash@^4.0.0, lodash@^4.15.0, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.6.1:
|
lodash@^4.0.0, lodash@^4.1.0, lodash@^4.15.0, lodash@^4.16.2, lodash@^4.16.4, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@^4.6.1:
|
||||||
version "4.17.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.2.tgz#34a3055babe04ce42467b607d700072c7ff6bf42"
|
|
||||||
|
|
||||||
lodash@^4.1.0, lodash@^4.16.2, lodash@^4.17.4, lodash@^4.3.0:
|
|
||||||
version "4.17.4"
|
version "4.17.4"
|
||||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user