mirror of
https://github.com/kingomarnajjar/flex-template-web.git
synced 2026-07-29 05:00:43 +10:00
Add distinct thunks for email and phone updates
This commit is contained in:
parent
70c5f559d7
commit
14669b389f
3 changed files with 139 additions and 14 deletions
|
|
@ -1,3 +1,4 @@
|
|||
import merge from 'lodash/merge';
|
||||
import { storableError } from '../../util/errors';
|
||||
import { currentUserShowSuccess } from '../../ducks/user.duck';
|
||||
|
||||
|
|
@ -5,14 +6,16 @@ import { currentUserShowSuccess } from '../../ducks/user.duck';
|
|||
|
||||
export const SAVE_CONTACT_DETAILS_REQUEST = 'app/ContactDetailsPage/SAVE_CONTACT_DETAILS_REQUEST';
|
||||
export const SAVE_CONTACT_DETAILS_SUCCESS = 'app/ContactDetailsPage/SAVE_CONTACT_DETAILS_SUCCESS';
|
||||
export const SAVE_CONTACT_DETAILS_ERROR = 'app/ContactDetailsPage/SAVE_CONTACT_DETAILS_ERROR';
|
||||
export const SAVE_EMAIL_ERROR = 'app/ContactDetailsPage/SAVE_EMAIL_ERROR';
|
||||
export const SAVE_PHONE_NUMBER_ERROR = 'app/ContactDetailsPage/SAVE_PHONE_NUMBER_ERROR';
|
||||
|
||||
export const SAVE_CONTACT_DETAILS_CLEAR = 'app/ContactDetailsPage/SAVE_CONTACT_DETAILS_CLEAR';
|
||||
|
||||
// ================ Reducer ================ //
|
||||
|
||||
const initialState = {
|
||||
saveContactDetailsError: null,
|
||||
saveEmailError: null,
|
||||
savePhoneNumberError: null,
|
||||
saveContactDetailsInProgress: false,
|
||||
contactDetailsChanged: false,
|
||||
};
|
||||
|
|
@ -29,8 +32,10 @@ export default function reducer(state = initialState, action = {}) {
|
|||
};
|
||||
case SAVE_CONTACT_DETAILS_SUCCESS:
|
||||
return { ...state, saveContactDetailsInProgress: false, contactDetailsChanged: true };
|
||||
case SAVE_CONTACT_DETAILS_ERROR:
|
||||
return { ...state, saveContactDetailsInProgress: false, saveContactDetailsError: payload };
|
||||
case SAVE_EMAIL_ERROR:
|
||||
return { ...state, saveContactDetailsInProgress: false, saveEmailError: payload };
|
||||
case SAVE_PHONE_NUMBER_ERROR:
|
||||
return { ...state, saveContactDetailsInProgress: false, savePhoneNumberError: payload };
|
||||
|
||||
case SAVE_CONTACT_DETAILS_CLEAR:
|
||||
return {
|
||||
|
|
@ -49,8 +54,13 @@ export default function reducer(state = initialState, action = {}) {
|
|||
|
||||
export const saveContactDetailsRequest = () => ({ type: SAVE_CONTACT_DETAILS_REQUEST });
|
||||
export const saveContactDetailsSuccess = () => ({ type: SAVE_CONTACT_DETAILS_SUCCESS });
|
||||
export const saveContactDetailsError = error => ({
|
||||
type: SAVE_CONTACT_DETAILS_ERROR,
|
||||
export const saveEmailError = error => ({
|
||||
type: SAVE_EMAIL_ERROR,
|
||||
payload: error,
|
||||
error: true,
|
||||
});
|
||||
export const savePhoneNumberError = error => ({
|
||||
type: SAVE_PHONE_NUMBER_ERROR,
|
||||
payload: error,
|
||||
error: true,
|
||||
});
|
||||
|
|
@ -59,16 +69,104 @@ export const saveContactDetailsClear = () => ({ type: SAVE_CONTACT_DETAILS_CLEAR
|
|||
|
||||
// ================ Thunks ================ //
|
||||
|
||||
export const saveContactDetails = params => (dispatch, getState, sdk) => {
|
||||
dispatch(saveContactDetailsRequest());
|
||||
/**
|
||||
* Make a phone number update request to the API and return the current user.
|
||||
*/
|
||||
const requestSavePhoneNumber = params => (dispatch, getState, sdk) => {
|
||||
const phoneNumber = params.phoneNumber;
|
||||
|
||||
return sdk.currentUser
|
||||
.updateProfile({ protectedData: { phoneNumber } }, { expand: true })
|
||||
.then(response => {
|
||||
// return user
|
||||
return response.data.data;
|
||||
})
|
||||
.catch(e => {
|
||||
dispatch(savePhoneNumberError(storableError(e)));
|
||||
// pass the same error so that the SAVE_CONTACT_DETAILS_SUCCESS
|
||||
// action will not be fired
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Make a email update request to the API and return the current user.
|
||||
*/
|
||||
const requestSaveEmail = params => (dispatch, getState, sdk) => {
|
||||
const { email, currentPassword } = params;
|
||||
|
||||
return sdk.currentUser
|
||||
.changeEmail({ email, currentPassword }, { expand: true })
|
||||
.then(response => {
|
||||
const currentUser = response.data.data;
|
||||
dispatch(saveContactDetailsSuccess());
|
||||
dispatch(currentUserShowSuccess(currentUser));
|
||||
// return user
|
||||
return response.data.data;
|
||||
})
|
||||
.catch(e => dispatch(saveContactDetailsError(storableError(e))));
|
||||
.catch(e => {
|
||||
dispatch(saveEmailError(storableError(e)));
|
||||
// pass the same error so that the SAVE_CONTACT_DETAILS_SUCCESS
|
||||
// action will not be fired
|
||||
throw e;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Save email and update the current user.
|
||||
*/
|
||||
export const saveEmail = params => (dispatch, getState, sdk) => {
|
||||
dispatch(saveContactDetailsRequest());
|
||||
|
||||
return dispatch(requestSaveEmail(params))
|
||||
.then(user => {
|
||||
dispatch(currentUserShowSuccess(user));
|
||||
dispatch(saveContactDetailsSuccess());
|
||||
})
|
||||
.catch(e => null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Save phone number and update the current user.
|
||||
*/
|
||||
export const savePhoneNumber = params => (dispatch, getState, sdk) => {
|
||||
dispatch(saveContactDetailsRequest());
|
||||
|
||||
return dispatch(requestSavePhoneNumber(params))
|
||||
.then(user => {
|
||||
dispatch(currentUserShowSuccess(user));
|
||||
dispatch(saveContactDetailsSuccess());
|
||||
})
|
||||
.catch(e => null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Save email and phone number and update the current user.
|
||||
*/
|
||||
export const saveContactDetails = params => (dispatch, getState, sdk) => {
|
||||
dispatch(saveContactDetailsRequest());
|
||||
const { email, phoneNumber, currentPassword } = params;
|
||||
|
||||
// order of promises: 1. email, 2. phone number
|
||||
const promises = [
|
||||
dispatch(requestSaveEmail({ email, currentPassword })),
|
||||
dispatch(requestSavePhoneNumber({ phoneNumber })),
|
||||
];
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(values => {
|
||||
// Array of two user objects is resolved
|
||||
// the first one is from the email update
|
||||
// the second one is from the phone number update
|
||||
|
||||
const saveEmailUser = values[0];
|
||||
const savePhoneNumberUser = values[1];
|
||||
|
||||
// merge the protected data from the user object returned
|
||||
// by the phone update operation
|
||||
const protectedData = savePhoneNumberUser.attributes.profile.protectedData;
|
||||
const phoneNumberMergeSource = { attributes: { profile: { protectedData } } };
|
||||
|
||||
const currentUser = merge(saveEmailUser, phoneNumberMergeSource);
|
||||
dispatch(currentUserShowSuccess(currentUser));
|
||||
dispatch(saveContactDetailsSuccess());
|
||||
})
|
||||
.catch(e => null);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -19,7 +19,12 @@ import {
|
|||
import { ContactDetailsForm, TopbarContainer } from '../../containers';
|
||||
|
||||
import { isScrollingDisabled } from '../../ducks/UI.duck';
|
||||
import { saveContactDetails, saveContactDetailsClear } from './ContactDetailsPage.duck';
|
||||
import {
|
||||
saveContactDetails,
|
||||
saveContactDetailsClear,
|
||||
saveEmail,
|
||||
savePhoneNumber,
|
||||
} from './ContactDetailsPage.duck';
|
||||
import css from './ContactDetailsPage.css';
|
||||
|
||||
export const ContactDetailsPageComponent = props => {
|
||||
|
|
@ -34,9 +39,25 @@ export const ContactDetailsPageComponent = props => {
|
|||
sendVerificationEmailError,
|
||||
onResendVerificationEmail,
|
||||
onSubmitContactDetails,
|
||||
onSubmitEmail,
|
||||
onSubmitPhoneNumber,
|
||||
intl,
|
||||
} = props;
|
||||
|
||||
const handleSubmit = (values, currentEmail, currentPhoneNumber) => {
|
||||
const { email, currentPassword, phoneNumber } = values;
|
||||
const emailChanged = email !== currentEmail;
|
||||
const phoneNumberChanged = phoneNumber !== currentPhoneNumber;
|
||||
|
||||
if (emailChanged && phoneNumberChanged) {
|
||||
onSubmitContactDetails({ email, currentPassword, phoneNumber });
|
||||
} else if (emailChanged) {
|
||||
onSubmitEmail({ email, currentPassword });
|
||||
} else if (phoneNumberChanged) {
|
||||
onSubmitPhoneNumber({ phoneNumber });
|
||||
}
|
||||
};
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
text: <FormattedMessage id="ContactDetailsPage.contactDetailsTabTitle" />,
|
||||
|
|
@ -72,7 +93,7 @@ export const ContactDetailsPageComponent = props => {
|
|||
saveContactDetailsError={saveContactDetailsError}
|
||||
currentUser={currentUser}
|
||||
onResendVerificationEmail={onResendVerificationEmail}
|
||||
onSubmit={onSubmitContactDetails}
|
||||
onSubmit={values => handleSubmit(values, email, phoneNumber)}
|
||||
onChange={onChange}
|
||||
inProgress={saveContactDetailsInProgress}
|
||||
ready={contactDetailsChanged}
|
||||
|
|
@ -126,6 +147,8 @@ ContactDetailsPageComponent.propTypes = {
|
|||
contactDetailsChanged: bool.isRequired,
|
||||
onChange: func.isRequired,
|
||||
onSubmitContactDetails: func.isRequired,
|
||||
onSubmitEmail: func.isRequired,
|
||||
onSubmitPhoneNumber: func.isRequired,
|
||||
scrollingDisabled: bool.isRequired,
|
||||
sendVerificationEmailInProgress: bool.isRequired,
|
||||
sendVerificationEmailError: propTypes.error,
|
||||
|
|
@ -158,6 +181,8 @@ const mapDispatchToProps = dispatch => ({
|
|||
onChange: () => dispatch(saveContactDetailsClear()),
|
||||
onResendVerificationEmail: () => dispatch(sendVerificationEmail()),
|
||||
onSubmitContactDetails: values => dispatch(saveContactDetails(values)),
|
||||
onSubmitEmail: values => dispatch(saveEmail(values)),
|
||||
onSubmitPhoneNumber: values => dispatch(savePhoneNumber(values)),
|
||||
});
|
||||
|
||||
const ContactDetailsPage = compose(connect(mapStateToProps, mapDispatchToProps), injectIntl)(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ describe('ContactDetailsPage', () => {
|
|||
sendVerificationEmailInProgress={false}
|
||||
onResendVerificationEmail={noop}
|
||||
onSubmitContactDetails={noop}
|
||||
onSubmitEmail={noop}
|
||||
onSubmitPhoneNumber={noop}
|
||||
saveContactDetailsInProgress={false}
|
||||
contactDetailsChanged={false}
|
||||
intl={fakeIntl}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue