Files
wedding/src/components/RsvpButton/RsvpButton.js
Dan Head b6f0822826 Hide RSVP button on blur
darken bg images
update copy
change URLs for routes
2017-03-03 22:18:33 +00:00

153 lines
3.9 KiB
JavaScript

import React, { PropTypes } from 'react';
import withStyles from 'isomorphic-style-loader/lib/withStyles';
import s from './RsvpButton.css';
import fetch from '../../core/fetch';
import Button from '../Button';
class RsvpButton extends React.Component {
static propTypes = {
focusCallback: PropTypes.func,
};
constructor(props) {
super(props);
this.state = {};
}
showRsvpForm = () => {
this.setState({ showRsvpForm: true });
setTimeout(() => {
this.rsvpInput.focus();
}, 500);
}
handleRsvpFocus = () => {
if (this.props.focusCallback) {
this.props.focusCallback(true);
}
this.setState({ inputError: false });
}
handleRsvpBlur = () => {
if (this.props.focusCallback) {
this.props.focusCallback(false);
}
this.setState({ showRsvpForm: false });
}
handleRsvpChange = () => {
this.setState({ inputInvalidMsg: null });
if (this.rsvpInput.value && this.rsvpInput.value.length === 4) {
this.validateRsvp();
}
}
handleFormSubmit = (event) => {
event.preventDefault();
this.validateRsvp();
}
validateRsvp = () => {
fetch(`rsvp/${this.rsvpInput.value}`, {
method: 'get',
credentials: 'include',
}).then(data => {
if (data.status === 200) {
location.href = data.url;
} else if (data.status === 429) {
this.setState({
inputInvalid: true,
inputInvalidMsg: 'You have made too many incorrect attempts. Please try again later.',
inputDisabled: true,
});
setTimeout(() => {
this.setState({
inputInvalid: false,
inputDisabled: false,
});
}, 10 * 60 * 1000);
} else {
this.setState({
inputInvalid: true,
inputInvalidMsg: 'Sorry, that RSVP code is invalid.',
});
setTimeout(() => {
this.setState({
inputInvalid: false,
});
}, 500);
}
}).catch(() => {
this.setState({
inputInvalid: true,
inputInvalidMsg: 'Sorry, there was a problem validating your RSVP code, please try again later.',
});
});
}
render() {
return (
<div className={s.root}>
<div
className={[
s.rsvp,
!this.state.showRsvpForm ? s.rsvpVisible : null,
].join(' ')}
>
<Button onClick={this.showRsvpForm}>
RSVP
</Button>
</div>
<div
className={[
s.rsvpForm,
this.state.showRsvpForm ? s.rsvpFormVisible : null,
].join(' ')}
>
<form
method="post"
action="/rsvp"
ref={(form) => { this.rsvpForm = form; }}
onSubmit={this.handleFormSubmit}
>
<div className={s.formGroup}>
<label className={s.label} htmlFor="code">
Enter your RSVP code
</label>
<input
className={[
s.input,
this.state.inputInvalid ? s.inputInvalid : null,
].join(' ')}
ref={(input) => { this.rsvpInput = input; }}
onFocus={this.handleRsvpFocus}
onBlur={this.handleRsvpBlur}
onChange={this.handleRsvpChange}
disabled={this.state.inputDisabled}
id="code"
type="text"
name="code"
minLength="4"
maxLength="4"
placeholder="Enter your RSVP code"
autoComplete="off"
/>
</div>
</form>
<div
className={[
s.invalidMsg,
this.state.inputInvalidMsg ? s.invalidMsgVisible : null,
].join(' ')}
role="alert"
>
{this.state.inputInvalidMsg}
</div>
</div>
</div>
);
}
}
export default withStyles(s)(RsvpButton);