backpack-ui
Version:
Lonely Planet's Components
573 lines (487 loc) • 17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _keys = require("babel-runtime/core-js/object/keys");
var _keys2 = _interopRequireDefault(_keys);
var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of");
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require("babel-runtime/helpers/createClass");
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn");
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require("babel-runtime/helpers/inherits");
var _inherits3 = _interopRequireDefault(_inherits2);
var _defineProperty2 = require("babel-runtime/helpers/defineProperty");
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
var _propTypes = require("prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _radium = require("radium");
var _radium2 = _interopRequireDefault(_radium);
var _axios = require("axios");
var _axios2 = _interopRequireDefault(_axios);
var _reactRecaptcha = require("react-recaptcha");
var _reactRecaptcha2 = _interopRequireDefault(_reactRecaptcha);
var _colors = require("../../styles/colors");
var _colors2 = _interopRequireDefault(_colors);
var _mq = require("../../styles/mq");
var _mq2 = _interopRequireDefault(_mq);
var _typography = require("../../styles/typography");
var _font = require("../../utils/font");
var _font2 = _interopRequireDefault(_font);
var _mixins = require("../../utils/mixins");
var _button = require("../button");
var _button2 = _interopRequireDefault(_button);
var _checkbox = require("../checkbox");
var _checkbox2 = _interopRequireDefault(_checkbox);
var _container = require("../container");
var _container2 = _interopRequireDefault(_container);
var _heading2 = require("../heading");
var _heading3 = _interopRequireDefault(_heading2);
var _icon = require("../icon");
var _icon2 = _interopRequireDefault(_icon);
var _input = require("../input");
var _input2 = _interopRequireDefault(_input);
var _moreLink = require("../moreLink");
var _moreLink2 = _interopRequireDefault(_moreLink);
var _analytics = require("../../utils/analytics");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var styles = {
wrap: {
backgroundColor: _colors2.default.bgSecondary,
minHeight: "320px",
textAlign: "center"
},
container: {
alignItems: "center",
display: "flex",
flexDirection: "column",
flexShrink: 1,
justifyContent: "center",
paddingBottom: "48px",
paddingTop: "48px",
width: "100%"
},
heading: (0, _defineProperty3.default)({
fontSize: "20px",
letterSpacing: "-.3px",
lineHeight: 32 / 20
}, "@media (min-width: " + _mq2.default.min[480] + ")", {
fontSize: "24px",
letterSpacing: "-.4px",
lineHeight: 32 / 28
}),
underline: {
backgroundColor: _colors2.default.accentGray,
height: "2px",
marginBottom: "16px",
marginLeft: "auto",
marginRight: "auto",
marginTop: "16px",
width: "30px"
},
copy: (0, _defineProperty3.default)({
color: _colors2.default.textSecondary,
fontFamily: (0, _font2.default)("miller"),
fontSize: "14px",
fontStyle: "italic",
letterSpacing: "-.1px",
lineHeight: 18 / 12,
marginLeft: "auto",
marginRight: "auto",
maxWidth: "386px"
}, "@media (min-width: " + _mq2.default.min[480] + ")", {
letterSpacing: ".4px",
lineHeight: 32 / 18
}),
button: {
marginTop: "20px",
minWidth: "100%"
},
error: {
color: _colors2.default.accentRed,
fontSize: "14px"
},
email: {
color: _colors2.default.textPrimary
},
form: {
marginTop: "25px",
maxWidth: "410px",
width: "100%"
},
inputFieldset: {
display: "flex",
width: "100%"
},
input: {
borderWidth: 0,
fontSize: "13px",
fontWeight: _typography.fontWeightLight,
height: "44px",
minHeight: null,
paddingBottom: 0,
paddingLeft: "16px",
paddingRight: "16px",
paddingTop: "4px",
":focus": (0, _mixins.outline)()
},
legalSection: {
marginTop: "32px"
},
legalText: {
display: "block",
width: "100%"
},
reset: {
bottom: "24px",
left: 0,
position: "absolute",
right: 0,
width: "100%"
}
};
var Newsletter = function (_Component) {
(0, _inherits3.default)(Newsletter, _Component);
function Newsletter(props) {
(0, _classCallCheck3.default)(this, Newsletter);
var _this = (0, _possibleConstructorReturn3.default)(this, (Newsletter.__proto__ || (0, _getPrototypeOf2.default)(Newsletter)).call(this, props));
_this.state = {
disabled: true,
success: false,
showCaptcha: false,
showSuccess: false,
email: "",
response: {},
error: {},
loading: false,
waiting: false,
acceptLegalOptIn: false
};
_this.handleInput = _this.handleInput.bind(_this);
_this.handleOptIn = _this.handleOptIn.bind(_this);
_this.handleSubmit = _this.handleSubmit.bind(_this);
_this.resetForm = _this.resetForm.bind(_this);
_this.submitRequest = _this.submitRequest.bind(_this);
_this.recaptchCallback = _this.recaptchCallback.bind(_this);
return _this;
}
(0, _createClass3.default)(Newsletter, [{
key: "getErrorMessage",
value: function getErrorMessage() {
var has = Object.prototype.hasOwnProperty;
var error = this.state.error;
var errorMessage = {
409: "You are already subscribed."
};
if (error.response && has.call(errorMessage, error.response.status)) {
return errorMessage[error.response.status];
}
return "There was an error processing your request. Please try again later.";
}
}, {
key: "recaptchCallback",
value: function recaptchCallback() {
this.setState({ loading: false });
}
}, {
key: "handleInput",
value: function handleInput(event) {
var validEmail = event.target.validity.valid;
this.setState({
disabled: !validEmail
});
}
}, {
key: "handleOptIn",
value: function handleOptIn() {
this.setState({
acceptLegalOptIn: !this.state.acceptLegalOptIn
});
}
}, {
key: "handleSubmit",
value: function handleSubmit(event) {
event.preventDefault();
this.setState({
loading: true,
showCaptcha: true,
email: event.currentTarget.elements["newsletter[email]"].value
});
}
}, {
key: "submitRequest",
value: function submitRequest(reCaptchaResponse) {
var _newsletter,
_this2 = this;
var _props = this.props,
endpoint = _props.endpoint,
signup = _props.signup,
hasOptin = _props.hasOptin;
this.setState({ waiting: true });
var data = {
newsletter: (_newsletter = {}, (0, _defineProperty3.default)(_newsletter, signup.vars.replace(/newsletter\[(.*)\]/, "$1"), true), (0, _defineProperty3.default)(_newsletter, "source", signup.source), (0, _defineProperty3.default)(_newsletter, "legalOptIn", hasOptin ? this.state.acceptLegalOptIn : true), (0, _defineProperty3.default)(_newsletter, "email", this.state.email), (0, _defineProperty3.default)(_newsletter, "g-recaptcha-response", reCaptchaResponse), _newsletter)
};
var config = {
headers: {
"X-Requested-With": "XMLHttpRequest"
},
withCredentials: true
};
_axios2.default.post(endpoint, data, config).then(function (response) {
_this2.setState({
success: true,
showSuccess: true,
showCaptcha: false,
response: response,
waiting: false
});
(0, _analytics.dataLayerPush)({
event: "newsletter-subscribe"
});
}).catch(function (error) {
return _this2.setState({
success: false,
disabled: true,
showCaptcha: false,
error: error,
waiting: false
});
});
}
}, {
key: "resetForm",
value: function resetForm() {
this.setState({
disabled: true,
success: false,
showCaptcha: false,
showSuccess: false,
email: "",
response: {},
error: {},
loading: false,
waiting: false,
acceptLegalOptIn: false
});
}
}, {
key: "render",
value: function render() {
var _props2 = this.props,
title = _props2.title,
subtitle = _props2.subtitle,
placeholder = _props2.placeholder,
cta = _props2.cta,
confirmation = _props2.confirmation,
legalOptInLabel = _props2.legalOptInLabel,
hasOptin = _props2.hasOptin,
captchaSiteKey = _props2.captchaSiteKey,
endpoint = _props2.endpoint,
overrideStyles = _props2.style,
qaHook = _props2.qaHook;
if (!captchaSiteKey) {
throw new Error("You did not supply an API key for Recaptcha.");
}
return _react2.default.createElement(
"div",
{ className: "Newsletter", style: [styles.wrap, overrideStyles && overrideStyles] },
_react2.default.createElement(_radium.Style, {
scopeSelector: ".Newsletter",
rules: {
"a:focus": (0, _mixins.outline)(),
".Checkbox label, .Legal span": {
color: _colors2.default.textSecondary + " !important",
fontSize: "9px !important",
height: "auto !important",
lineHeight: 16 / 9 + " !important",
textAlign: "left !important"
},
".Checkbox span:first-of-type": {
marginTop: "2px",
padding: "0 !important"
},
".Checkbox label span + span": {
lineHeight: "inherit !important",
paddingRight: "8px",
paddingTop: "0 !important"
}
}
}),
_react2.default.createElement(
_container2.default,
{ style: styles.container },
_react2.default.createElement(
_heading3.default,
{ level: 2, weight: "thick", tracking: "tight", override: styles.heading },
title,
_react2.default.createElement("div", { style: styles.underline })
),
this.state.loading && "Loading…",
this.state.showSuccess && _react2.default.createElement(
"div",
null,
_react2.default.createElement(
"p",
{ style: styles.copy },
confirmation.title,
" ",
_react2.default.createElement("br", null),
confirmation.text,
" ",
_react2.default.createElement(
"span",
{ style: styles.email },
this.state.email
)
),
_react2.default.createElement(
_moreLink2.default,
{ onClick: this.resetForm, style: styles.reset, size: "small", hideIcon: true, caps: true },
"Change Email Address"
)
),
!this.state.success && !this.state.showCaptcha && _react2.default.createElement(
"div",
null,
(0, _keys2.default)(this.state.error).length > 0 ? _react2.default.createElement(
"p",
{ style: styles.error },
this.getErrorMessage()
) : _react2.default.createElement(
"p",
{ style: styles.copy },
!this.state.success && subtitle,
this.state.success && confirmation.text + " " + this.state.response.email
),
_react2.default.createElement(
"form",
{ "data-testid": qaHook ? "newsletter-form" : null, style: styles.form, action: endpoint, onSubmit: this.handleSubmit },
_react2.default.createElement(
"div",
{ style: styles.inputFieldset },
_react2.default.createElement(_input2.default, {
type: "email",
placeholder: placeholder,
required: true,
id: "newsletter-email",
name: "newsletter[email]",
style: styles.input,
onChange: this.handleInput,
"data-testid": qaHook ? "newsletter-email-input" : null
})
),
_react2.default.createElement(
"div",
{ className: !hasOptin ? "Legal" : "", style: styles.legalSection },
hasOptin ? _react2.default.createElement(_checkbox2.default, {
id: "legalOptIn",
label: legalOptInLabel,
style: styles.legalText,
checked: this.state.acceptLegalOptIn,
onClick: this.handleOptIn,
value: "legalOptIn",
name: "legalOptIn",
"data-testid": qaHook ? "legal-checkbox" : null,
required: true
}) : _react2.default.createElement(
"span",
{ style: styles.legalText },
legalOptInLabel
)
),
_react2.default.createElement(
"div",
{ style: styles.inputFieldset },
_react2.default.createElement(
_button2.default,
{
color: "blue",
size: "small",
disabled: this.state.disabled,
customStyles: styles.button,
qaHook: qaHook
},
!this.state.waiting && cta,
this.state.waiting && _react2.default.createElement(_icon2.default.Loading, null)
)
)
)
),
this.state.showCaptcha && _react2.default.createElement(
"div",
{ style: { marginTop: "24px" } },
_react2.default.createElement(_reactRecaptcha2.default, {
sitekey: captchaSiteKey,
render: "explicit",
verifyCallback: this.submitRequest,
onloadCallback: this.recaptchCallback
})
)
)
);
}
}]);
return Newsletter;
}(_react.Component);
Newsletter.propTypes = {
captchaSiteKey: _propTypes2.default.string.isRequired,
title: _propTypes2.default.string,
subtitle: _propTypes2.default.string,
placeholder: _propTypes2.default.string,
cta: _propTypes2.default.string,
confirmation: _propTypes2.default.shape({
title: _propTypes2.default.string,
text: _propTypes2.default.string
}),
signup: _propTypes2.default.shape({
vars: _propTypes2.default.string,
source: _propTypes2.default.string
}),
legalOptInLabel: _propTypes2.default.arrayOf(_propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.string])),
hasOptin: _propTypes2.default.bool,
endpoint: _propTypes2.default.string,
style: _propTypes2.default.objectOf(_propTypes2.default.object),
qaHook: _propTypes2.default.bool
};
Newsletter.defaultProps = {
title: "Sign up for our weekly newsletter",
subtitle: "Get more travel inspiration, tips and\n exclusive offers sent straight to your inbox",
placeholder: "Enter email",
cta: "Sign up",
confirmation: {
title: "Thanks for signing up!",
text: "We just sent a confirmation email to"
},
signup: {
vars: "newsletter[LP_Editorial_Newsletter]",
source: "homepage"
},
legalOptInLabel: ["I want emails from Lonely Planet with travel and product information, promotions, advertisements, third-party offers, and surveys. I can unsubscribe any time using the unsubscribe link at the end of all emails. ", _react2.default.createElement(
"a",
{
key: "contact-lp",
href: "https://www.lonelyplanet.com/contact",
target: "_blank",
rel: "noopener noreferrer"
},
"Contact Lonely Planet here"
), ". Lonely Planet ", _react2.default.createElement(
"a",
{
key: "privacy-policy",
href: "https://www.lonelyplanet.com/legal/privacy-policy/",
target: "_blank",
rel: "noopener noreferrer"
},
"Privacy Policy"
), "."],
captchaSiteKey: null,
endpoint: "https://www.lonelyplanet.com/newsletter",
qaHook: false
};
exports.default = (0, _radium2.default)(Newsletter);