diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 4aab001e4..bd019b4ee 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -2228,6 +2228,23 @@ "cliqz_feature_status_off": { "message": "Off" }, + "create_account_form_legal_consent_checkbox_label": { + "message": "I accept the $LINK_TERMS_START$Terms and Conditions$LINK_END$, the $LINK_LICENSE_START$Public License Agreement$LINK_END$, and consent to data practices found in the $LINK_PRIVACY_START$Privacy Policy$LINK_END$.", + "placeholders": { + "link_end": { + "content": "" + }, + "link_license_start": { + "content": "" + }, + "link_privacy_start": { + "content": "" + }, + "link_terms_start": { + "content": "" + } + } + }, "ghostery_rewards": { "message": "ghostery rewards" } diff --git a/app/hub/Views/CreateAccountView/CreateAccountView.jsx b/app/hub/Views/CreateAccountView/CreateAccountView.jsx index ce7bf937a..432463ee7 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountView.jsx +++ b/app/hub/Views/CreateAccountView/CreateAccountView.jsx @@ -33,9 +33,12 @@ const CreateAccountView = (props) => { password, passwordInvalidError, passwordLengthError, + legalConsentChecked, + legalConsentNotCheckedError, promotionsChecked, handleInputChange, - handleCheckboxChange, + handleLegalConsentCheckboxChange, + handlePromotionsCheckboxChange, handleSubmit, } = props; @@ -45,6 +48,9 @@ const CreateAccountView = (props) => { const confirmInputClassNames = ClassNames('CreateAccountView__inputBox', { error: confirmEmailError, }); + const legalConsentCheckboxInputLabelClassNames = ClassNames('CreateAccountView__inputLabel clickable', { + error: legalConsentNotCheckedError, + }); const passwordInputClassNames = ClassNames('CreateAccountView__inputBox', { error: passwordInvalidError || passwordLengthError, }); @@ -165,12 +171,25 @@ const CreateAccountView = (props) => { )}
-
+
+ + +
+
- + {t('hub_create_account_checkbox_promotions')}
@@ -212,12 +231,14 @@ CreateAccountView.propTypes = { confirmEmailError: PropTypes.bool.isRequired, firstName: PropTypes.string.isRequired, lastName: PropTypes.string.isRequired, + legalConsentChecked: PropTypes.bool.isRequired, password: PropTypes.string.isRequired, passwordInvalidError: PropTypes.bool.isRequired, passwordLengthError: PropTypes.bool.isRequired, promotionsChecked: PropTypes.bool.isRequired, handleInputChange: PropTypes.func.isRequired, - handleCheckboxChange: PropTypes.func.isRequired, + handleLegalConsentCheckboxChange: PropTypes.func.isRequired, + handlePromotionsCheckboxChange: PropTypes.func.isRequired, handleSubmit: PropTypes.func.isRequired, }; diff --git a/app/hub/Views/CreateAccountView/CreateAccountView.scss b/app/hub/Views/CreateAccountView/CreateAccountView.scss index bc3b7012c..489e3ecbe 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountView.scss +++ b/app/hub/Views/CreateAccountView/CreateAccountView.scss @@ -11,6 +11,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0 */ +$color-create-account-form-error-red: #e74055; + // Create Account View .CreateAccountView { padding-top: 80px; @@ -54,17 +56,17 @@ } .CreateAccountView__inputBox.error { margin-bottom: 8px; - border-color: #e74055; + border-color: $color-create-account-form-error-red; } .CreateAccountView__inputBox:focus { // Foundation Overrides box-shadow: none; - border-color: #4a4a4a; + border-color: $color-create-account-form-error-red; } .CreateAccountView__inputError { font-size: 12; line-height: 14px; - color: #e74055; + color: $color-create-account-form-error-red; margin-bottom: 13px; } .CreateAccountView__link { @@ -77,6 +79,13 @@ .CreateAccountView__button { min-width: 180px; } +.CreateAccountView__inputLabel { + flex-grow: 1; // ensure left-justify alignment in single column layout + padding-top: 10px; // align with checkbox top +} +.CreateAccountView__inputLabel.error{ + color: $color-create-account-form-error-red; +} @media only screen and (max-width: 740px) { .CreateAccountView { padding-top: 20px; diff --git a/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx b/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx index 0167899c6..f44f9cf34 100644 --- a/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx +++ b/app/hub/Views/CreateAccountView/CreateAccountViewContainer.jsx @@ -37,6 +37,8 @@ class CreateAccountViewContainer extends Component { confirmEmailError: false, firstName: '', lastName: '', + legalConsentChecked: false, + legalConsentNotCheckedError: false, password: '', passwordInvalidError: false, passwordLengthError: false, @@ -93,11 +95,17 @@ class CreateAccountViewContainer extends Component { } /** - * Update input checkbox values by updating state. + * Update legal consetnt checkbox value by updating state */ - _handleCheckboxChange = () => { - const promotionsChecked = !this.state.promotionsChecked; - this.setState({ promotionsChecked }); + _handleLegalConsentCheckboxChange = () => { + this.setState(prevState => ({ legalConsentChecked: !prevState.legalConsentChecked })); + } + + /** + * Update promotions checkbox value by updating state + */ + _handlePromotionsCheckboxChange = () => { + this.setState(prevState => ({ promotionsChecked: !prevState.promotionsChecked })); } /** @@ -111,6 +119,7 @@ class CreateAccountViewContainer extends Component { confirmEmail, firstName, lastName, + legalConsentChecked, password, promotionsChecked } = this.state; @@ -123,12 +132,13 @@ class CreateAccountViewContainer extends Component { this.setState({ emailError: !emailIsValid, confirmEmailError: !confirmIsValid, + legalConsentNotCheckedError: !legalConsentChecked, passwordInvalidError: invalidChars, passwordLengthError: invalidLength, validateInput: true, }); - if (!emailIsValid || !confirmIsValid || !passwordIsValid) { + if (!emailIsValid || !confirmIsValid || !legalConsentChecked || !passwordIsValid) { return; } this.props.actions.setToast({ @@ -166,6 +176,8 @@ class CreateAccountViewContainer extends Component { confirmEmailError, firstName, lastName, + legalConsentChecked, + legalConsentNotCheckedError, password, passwordInvalidError, passwordLengthError, @@ -178,12 +190,15 @@ class CreateAccountViewContainer extends Component { confirmEmailError, firstName, lastName, + legalConsentChecked, + legalConsentNotCheckedError, password, passwordInvalidError, passwordLengthError, promotionsChecked, handleInputChange: this._handleInputChange, - handleCheckboxChange: this._handleCheckboxChange, + handleLegalConsentCheckboxChange: this._handleLegalConsentCheckboxChange, + handlePromotionsCheckboxChange: this._handlePromotionsCheckboxChange, handleSubmit: this._handleCreateAccountAttempt }; const signedInChildProps = { diff --git a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap index 7c9fd68cb..521f262e7 100644 --- a/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap +++ b/app/hub/Views/CreateAccountView/__tests__/__snapshots__/CreateAccountView.test.jsx.snap @@ -145,11 +145,33 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re className="columns small-12 medium-5" >
+ + + +
+ +
+
+
hub_create_account_checkbox_promotions @@ -388,11 +409,33 @@ exports[`app/hub/Views/CreateAccount component Snapshot tests with react-test-re className="columns small-12 medium-5" >
+ + + +
+ +
+
+
hub_create_account_checkbox_promotions diff --git a/app/panel/components/CreateAccount.jsx b/app/panel/components/CreateAccount.jsx index e00b5dd2b..fab828e02 100644 --- a/app/panel/components/CreateAccount.jsx +++ b/app/panel/components/CreateAccount.jsx @@ -32,6 +32,8 @@ class CreateAccount extends React.Component { confirmEmailError: false, firstName: '', lastName: '', + legalConsentChecked: false, + legalConsentNotCheckedError: false, password: '', promotionsChecked: true, loading: false, @@ -67,7 +69,7 @@ class CreateAccount extends React.Component { e.preventDefault(); this.setState({ loading: true }, () => { const { - email, confirmEmail, firstName, lastName, password, promotionsChecked + email, confirmEmail, firstName, lastName, legalConsentChecked, password, promotionsChecked } = this.state; this.setState({ loading: true }, () => { if (!validateEmail(email)) { @@ -98,10 +100,18 @@ class CreateAccount extends React.Component { } return; } + if (!legalConsentChecked) { + this.setState({ + legalConsentNotCheckedError: true, + loading: false, + }); + return; + } this.setState({ emailError: false, confirmEmailError: false, + legalConsentNotCheckedError: false, passwordInvalidError: false, passwordLengthError: false, }, () => { @@ -129,7 +139,7 @@ class CreateAccount extends React.Component { */ render() { const { - email, confirmEmail, firstName, lastName, password, promotionsChecked, loading, emailError, confirmEmailError, passwordInvalidError, passwordLengthError + email, confirmEmail, firstName, lastName, password, promotionsChecked, legalConsentChecked, loading, emailError, confirmEmailError, legalConsentNotCheckedError, passwordInvalidError, passwordLengthError } = this.state; const buttonClasses = ClassNames('button ghostery-button', { loading }); return ( @@ -200,6 +210,15 @@ class CreateAccount extends React.Component {
+
+
+ +
+
@@ -210,9 +229,6 @@ class CreateAccount extends React.Component {
-
-

-

diff --git a/app/scss/partials/_account.scss b/app/scss/partials/_account.scss index 3d7ab7f11..04b88af6a 100644 --- a/app/scss/partials/_account.scss +++ b/app/scss/partials/_account.scss @@ -67,6 +67,11 @@ p.warning { color: #CC5F5A; } } +.checkbox-error { + label { + color: #a94442; + } +} /* SIGNIN PANEL */ #signin-panel { @@ -223,8 +228,18 @@ p.warning { #create-account-promotions { margin-bottom: 10px; label { - font-size: 13px; + font-size: 11px; + font-weight: 500; + } + } + #create-account-legal-consent-checkbox { + margin-bottom: 10px; + label { + font-size: 11px; font-weight: 500; + vertical-align: top; + margin-right: 0; + max-width: 94%; } } #create-account-privacy-container { diff --git a/app/shared-components/ToggleCheckbox/ToggleCheckbox.scss b/app/shared-components/ToggleCheckbox/ToggleCheckbox.scss index 179335ff4..07999cbe5 100644 --- a/app/shared-components/ToggleCheckbox/ToggleCheckbox.scss +++ b/app/shared-components/ToggleCheckbox/ToggleCheckbox.scss @@ -17,6 +17,7 @@ width: 48px; padding: 12px; cursor: pointer; + flex-shrink: 0; } .ToggleCheckbox path { fill: #6d6d6d; @@ -24,3 +25,7 @@ .ToggleCheckbox.ToggleCheckbox--active path { fill: #1dafed; } +.ToggleCheckbox--flush-left { + width: 36px; + padding-left: 0px; +}