Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-1936 & GH-1920 Remove email opt-in from account creation in panel and hub #495

Merged
merged 8 commits into from Feb 14, 2020
Next

Opt-in to emails by default on account creation in panel and hub. Rem…

…ove checkboxes
  • Loading branch information
benstrumeyer committed Feb 6, 2020
commit fb7fd8b24dcbf2fdfeb04c6d6efbda48c2e0f9e9
@@ -1646,9 +1646,6 @@
"hub_create_account_label_password_invalid_length": {
"message": "Use between 8 and 50 characters."
},
"hub_create_account_checkbox_promotions": {
"message": "Send me Ghostery updates & promotions."
},
"hub_create_account_already_have_account": {
"message": "Already have a Ghostery Account?"
},
@@ -26,8 +26,8 @@ import {
GET_USER_FAIL,
GET_USER_SETTINGS_SUCCESS,
GET_USER_SETTINGS_FAIL,
UPDATE_PROMOTIOS_FAIL,
UPDATE_PROMOTIOS_SUCCESS,
OPT_INTO_PROMOTIONS_FAIL,
OPT_INTO_PROMOTIONS_SUCCESS,
GET_USER_SUBSCRIPTION_DATA_FAIL,
GET_USER_SUBSCRIPTION_DATA_SUCCESS
} from './AccountConstants';
@@ -192,22 +192,22 @@ export const resetPassword = email => dispatch => (
})
);

export const updateAccountPromotions = promotions => dispatch => (
sendMessageInPromise('account.promotions', { promotions }).then((res) => {
export const optIntoPromotions = () => dispatch => (
sendMessageInPromise('account.promotions').then((res) => {
const { errors } = res;
if (errors) {
dispatch({
type: UPDATE_PROMOTIOS_FAIL,
type: OPT_INTO_PROMOTIONS_FAIL,
payload: { errors },
});
return false;
}
dispatch({ type: UPDATE_PROMOTIOS_SUCCESS });
dispatch({ type: OPT_INTO_PROMOTIONS_SUCCESS });
return true;
}).catch((err) => {
const errors = [{ title: err.toString(), detail: err.toString() }];
dispatch({
type: UPDATE_PROMOTIOS_FAIL,
type: OPT_INTO_PROMOTIONS_FAIL,
payload: {
errors,
},
@@ -33,9 +33,9 @@ export const GET_USER_FAIL = 'GET_USER_FAIL';
export const GET_USER_SETTINGS_SUCCESS = 'GET_USER_SETTINGS_SUCCESS';
export const GET_USER_SETTINGS_FAIL = 'GET_USER_SETTINGS_FAIL';

// Update Promotions
export const UPDATE_PROMOTIOS_FAIL = 'UPDATE_PROMOTIOS_FAIL';
export const UPDATE_PROMOTIOS_SUCCESS = 'UPDATE_PROMOTIOS_SUCCESS';
// Opt into Promotions
export const OPT_INTO_PROMOTIONS_FAIL = 'OPT_INTO_PROMOTIONS_FAIL';
export const OPT_INTO_PROMOTIONS_SUCCESS = 'OPT_INTO_PROMOTIONS_SUCCESS';

// Update Subscription Data
export const GET_USER_SUBSCRIPTION_DATA_FAIL = 'GET_USER_SUBSCRIPTION_DATA_FAIL';
@@ -35,10 +35,8 @@ const CreateAccountView = (props) => {
passwordLengthError,
legalConsentChecked,
legalConsentNotCheckedError,
promotionsChecked,
handleInputChange,
handleLegalConsentCheckboxChange,
handlePromotionsCheckboxChange,
handleSubmit,
} = props;

@@ -183,16 +181,6 @@ const CreateAccountView = (props) => {
dangerouslySetInnerHTML={{ __html: t('create_account_form_legal_consent_checkbox_label') }}
/>
</div>
<div className="CreateAccountView__checkboxContainer CreateAccountView--marginBottom flex-container">
<ToggleCheckbox
checked={promotionsChecked}
className="ToggleCheckbox--flush-left"
onChange={handlePromotionsCheckboxChange}
/>
<span className="CreateAccountView__inputLabel clickable" onClick={handlePromotionsCheckboxChange}>
{t('hub_create_account_checkbox_promotions')}
</span>
</div>
</div>
</div>
<div className="row align-center">
@@ -235,10 +223,8 @@ CreateAccountView.propTypes = {
password: PropTypes.string.isRequired,
passwordInvalidError: PropTypes.bool.isRequired,
passwordLengthError: PropTypes.bool.isRequired,
promotionsChecked: PropTypes.bool.isRequired,
handleInputChange: PropTypes.func.isRequired,
handleLegalConsentCheckboxChange: PropTypes.func.isRequired,
handlePromotionsCheckboxChange: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
};

@@ -42,7 +42,6 @@ class CreateAccountViewContainer extends Component {
password: '',
passwordInvalidError: false,
passwordLengthError: false,
promotionsChecked: false,
validateInput: false,
};

@@ -101,13 +100,6 @@ class CreateAccountViewContainer extends Component {
this.setState(prevState => ({ legalConsentChecked: !prevState.legalConsentChecked }));
}

/**
* Update promotions checkbox value by updating state
*/
_handlePromotionsCheckboxChange = () => {
this.setState(prevState => ({ promotionsChecked: !prevState.promotionsChecked }));
}

/**
* Handle creating an account, but validate the data first.
* @param {Object} event the 'submit' event
@@ -121,7 +113,6 @@ class CreateAccountViewContainer extends Component {
lastName,
legalConsentChecked,
password,
promotionsChecked
} = this.state;
const emailIsValid = email && validateEmail(email);
const confirmIsValid = confirmEmail && validateConfirmEmail(email, confirmEmail);
@@ -147,7 +138,7 @@ class CreateAccountViewContainer extends Component {
});
this.props.actions.register(email, confirmEmail, firstName, lastName, password).then((success) => {
if (success) {
this.props.actions.updateAccountPromotions(promotionsChecked);
this.props.actions.optIntoPromotions();
this.props.actions.getUser();
this.props.actions.setToast({
toastMessage: t('hub_create_account_toast_success'),
@@ -181,7 +172,6 @@ class CreateAccountViewContainer extends Component {
password,
passwordInvalidError,
passwordLengthError,
promotionsChecked,
} = this.state;
const createAccountChildProps = {
email,
@@ -195,10 +185,8 @@ class CreateAccountViewContainer extends Component {
password,
passwordInvalidError,
passwordLengthError,
promotionsChecked,
handleInputChange: this._handleInputChange,
handleLegalConsentCheckboxChange: this._handleLegalConsentCheckboxChange,
handlePromotionsCheckboxChange: this._handlePromotionsCheckboxChange,
handleSubmit: this._handleCreateAccountAttempt
};
const signedInChildProps = {
@@ -219,7 +207,6 @@ CreateAccountViewContainer.propTypes = {
setToast: PropTypes.func.isRequired,
register: PropTypes.func.isRequired,
getUser: PropTypes.func.isRequired,
updateAccountPromotions: PropTypes.func.isRequired,
This conversation was marked as resolved by Eden12345

This comment has been minimized.

@Eden12345

Eden12345 Feb 10, 2020
Contributor

This should be replaced with the function you renamed optIntoPromotions

This comment has been minimized.

@benstrumeyer

benstrumeyer Feb 11, 2020
Author Contributor

Pesky proptypes at it again. Good catch!

}).isRequired,
};

@@ -15,7 +15,7 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';

import CreateAccountViewContainer from './CreateAccountViewContainer';
import { register, getUser, updateAccountPromotions } from '../../../Account/AccountActions';
import { register, getUser, optIntoPromotions } from '../../../Account/AccountActions';
import { setToast } from '../AppView/AppViewActions';

/**
@@ -37,7 +37,7 @@ const mapDispatchToProps = dispatch => ({
setToast,
register,
getUser,
updateAccountPromotions,
optIntoPromotions,
}), dispatch),
});

@@ -36,7 +36,6 @@ class CreateAccount extends React.Component {
legalConsentChecked: false,
legalConsentNotCheckedError: false,
password: '',
promotionsChecked: false,
loading: false,
passwordInvalidError: false,
passwordLengthError: false,
@@ -70,7 +69,7 @@ class CreateAccount extends React.Component {
e.preventDefault();
this.setState({ loading: true }, () => {
const {
email, confirmEmail, firstName, lastName, legalConsentChecked, password, promotionsChecked
email, confirmEmail, firstName, lastName, legalConsentChecked, password,
} = this.state;
this.setState({ loading: true }, () => {
if (!validateEmail(email)) {
@@ -119,7 +118,7 @@ class CreateAccount extends React.Component {
this.props.actions.register(email, confirmEmail, firstName, lastName, password).then((success) => {
this.setState({ loading: false });
if (success) {
this.props.actions.updateAccountPromotions(promotionsChecked);
this.props.actions.optIntoPromotions();
new RSVP.Promise((resolve) => {
this.props.actions.getUser()
.then(() => resolve())
@@ -140,7 +139,7 @@ class CreateAccount extends React.Component {
*/
render() {
const {
email, confirmEmail, firstName, lastName, password, promotionsChecked, legalConsentChecked, loading, emailError, confirmEmailError, legalConsentNotCheckedError, passwordInvalidError, passwordLengthError
email, confirmEmail, firstName, lastName, password, legalConsentChecked, loading, emailError, confirmEmailError, legalConsentNotCheckedError, passwordInvalidError, passwordLengthError
} = this.state;
const buttonClasses = ClassNames('button ghostery-button', { loading });
return (
@@ -222,14 +221,6 @@ class CreateAccount extends React.Component {
</div>
</div>
</div>
<div className="row">
<div className="small-12 columns">
<div id="create-account-promotions">
<input id="promotionsChecked" name="promotionsChecked" type="checkbox" checked={promotionsChecked} onChange={this.handleCheckboxChange} />
<label htmlFor="promotionsChecked">{t('hub_create_account_checkbox_promotions')}</label>
</div>
</div>
</div>
<div className="row">
<div className="small-12 columns">
<div id="account-creation-buttons" className="row align-center">
@@ -15,7 +15,7 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import CreateAccount from '../components/CreateAccount';
import * as actions from '../actions/PanelActions'; // get shared actions from Panel
import { register, getUser, updateAccountPromotions } from '../../Account/AccountActions';
import { register, getUser, optIntoPromotions } from '../../Account/AccountActions';

/**
* Map redux store state properties to CreateAccount component own properties.
@@ -38,7 +38,7 @@ const mapStateToProps = state => Object.assign({}, state.createAccount, {
* @param {Object} ownProps CreateAccount component own props
* @return {function} to be used as an argument in redux connect call
*/
const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(Object.assign(actions, { register, getUser, updateAccountPromotions }), dispatch) });
const mapDispatchToProps = dispatch => ({ actions: bindActionCreators(Object.assign(actions, { register, getUser, optIntoPromotions }), dispatch) });
/**
* Connects CreateAccount component to the Redux store.
* @memberOf PanelContainers
@@ -204,7 +204,7 @@ p.warning {

/* CREATE ACCOUNT PANEL */
#create-account-panel {
margin-top: 10px;
margin-top: 38px;
input {
margin-bottom: 5px;
margin-top: 5px;
@@ -897,8 +897,7 @@ function onMessageHandler(request, sender, callback) {
return true;
}
if (name === 'account.promotions') {
const { promotions } = message;
account.updateEmailPreferences(promotions).then((success) => {
account.updateEmailPreferences().then((success) => {
callback(success);
}).catch((err) => {
callback({ errors: _getJSONAPIErrorsObject(err) });
@@ -215,14 +215,14 @@ class Account {
})
)

updateEmailPreferences = set => (
updateEmailPreferences = () => (
this._getUserID().then(userID => (
api.update('email_preferences', {
type: 'email_preferences',
id: userID,
attributes: {
updates: set,
promotions: set,
updates: true,
promotions: true,
}
})
))
ProTip! Use n and p to navigate between commits in a pull request.