feat: add multi step registration eventing (#1226)

* feat: implement multi step registration experiment

* feat: add multi step registration eventing
This commit is contained in:
Syed Sajjad Hussain Shah
2024-04-18 11:04:28 +05:00
parent 6f325c20c3
commit 90f650ce3e
5 changed files with 108 additions and 3 deletions

View File

@@ -9,14 +9,24 @@ import PropTypes from 'prop-types';
import messages from './messages';
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
import { CONTROL, MULTI_STEP_REGISTRATION_EXP_VARIATION } from '../register/data/optimizelyExperiment/helper';
import { trackMultiStepRegistrationSSOBtnClicked } from '../register/data/optimizelyExperiment/track';
const SocialAuthProviders = (props) => {
const { formatMessage } = useIntl();
const { referrer, socialAuthProviders } = props;
const {
referrer,
socialAuthProviders,
multiStepRegistrationExpVariation,
} = props;
function handleSubmit(e) {
e.preventDefault();
if (multiStepRegistrationExpVariation === CONTROL
|| multiStepRegistrationExpVariation === MULTI_STEP_REGISTRATION_EXP_VARIATION) {
trackMultiStepRegistrationSSOBtnClicked(multiStepRegistrationExpVariation);
}
const url = e.currentTarget.dataset.providerUrl;
window.location.href = getConfig().LMS_BASE_URL + url;
}
@@ -60,6 +70,7 @@ const SocialAuthProviders = (props) => {
SocialAuthProviders.defaultProps = {
referrer: LOGIN_PAGE,
socialAuthProviders: [],
multiStepRegistrationExpVariation: '',
};
SocialAuthProviders.propTypes = {
@@ -73,6 +84,7 @@ SocialAuthProviders.propTypes = {
registerUrl: PropTypes.string,
skipRegistrationForm: PropTypes.bool,
})),
multiStepRegistrationExpVariation: PropTypes.string,
};
export default SocialAuthProviders;

View File

@@ -32,6 +32,7 @@ const ThirdPartyAuth = (props) => {
handleInstitutionLogin,
thirdPartyAuthApiStatus,
isLoginPage,
multiStepRegistrationExpVariation,
} = props;
const isInstitutionAuthActive = !!secondaryProviders.length && !currentProvider;
const isSocialAuthActive = !!providers.length && !currentProvider;
@@ -78,6 +79,7 @@ const ThirdPartyAuth = (props) => {
<SocialAuthProviders
socialAuthProviders={providers}
referrer={isLoginPage ? LOGIN_PAGE : REGISTER_PAGE}
multiStepRegistrationExpVariation={multiStepRegistrationExpVariation}
/>
</div>
)}
@@ -93,6 +95,7 @@ ThirdPartyAuth.defaultProps = {
secondaryProviders: [],
thirdPartyAuthApiStatus: PENDING_STATE,
isLoginPage: false,
multiStepRegistrationExpVariation: '',
};
ThirdPartyAuth.propTypes = {
@@ -120,6 +123,7 @@ ThirdPartyAuth.propTypes = {
),
thirdPartyAuthApiStatus: PropTypes.string,
isLoginPage: PropTypes.bool,
multiStepRegistrationExpVariation: PropTypes.string,
};
export default ThirdPartyAuth;

View File

@@ -34,10 +34,17 @@ import {
getRegisterButtonLabelInExperiment,
getRegisterButtonSubmitStateInExperiment,
MULTI_STEP_REGISTRATION_EXP_VARIATION,
NOT_INITIALIZED,
SECOND_STEP,
shouldDisplayFieldInExperiment, THIRD_STEP,
} from './data/optimizelyExperiment/helper';
import {
trackMultiStepRegistrationFormSubmitBtnClicked,
trackMultiStepRegistrationStep1SubmitBtnClicked,
trackMultiStepRegistrationStep2SubmitBtnClicked,
trackMultiStepRegistrationStep2Viewed,
trackMultiStepRegistrationStep3SubmitBtnClicked,
trackMultiStepRegistrationStep3Viewed,
} from './data/optimizelyExperiment/track';
import useMultiStepRegistrationExperimentVariation
from './data/optimizelyExperiment/useMultiStepRegistrationExperimentVariation';
import getBackendValidations from './data/selectors';
@@ -136,6 +143,17 @@ const RegistrationPage = (props) => {
) {
setErrorCode({ type: '', count: 0 });
const nextStep = getMultiStepRegistrationNextStep(multiStepRegistrationPageStep);
if (nextStep === SECOND_STEP) {
trackMultiStepRegistrationStep2Viewed(multiStepRegistrationExpVariation);
if (multiStepRegistrationExpVariation === CONTROL) {
trackMultiStepRegistrationFormSubmitBtnClicked(multiStepRegistrationExpVariation);
}
} else if (nextStep === THIRD_STEP) {
trackMultiStepRegistrationStep3Viewed();
if (multiStepRegistrationExpVariation === MULTI_STEP_REGISTRATION_EXP_VARIATION) {
trackMultiStepRegistrationFormSubmitBtnClicked(multiStepRegistrationExpVariation);
}
}
dispatch(setMultiStepRegistrationExpData(multiStepRegistrationExpVariation, nextStep));
}
}, [ // eslint-disable-line react-hooks/exhaustive-deps
@@ -215,7 +233,8 @@ const RegistrationPage = (props) => {
if (registrationResult.success) {
let registeredEventProps = {};
if (multiStepRegistrationExpVariation !== NOT_INITIALIZED) {
if (multiStepRegistrationExpVariation === CONTROL
|| multiStepRegistrationExpVariation === MULTI_STEP_REGISTRATION_EXP_VARIATION) {
registeredEventProps = {
variation: multiStepRegistrationExpVariation,
};
@@ -300,15 +319,25 @@ const RegistrationPage = (props) => {
const handleSubmit = (e) => {
e.preventDefault();
if (multiStepRegistrationExpVariation === CONTROL
&& multiStepRegistrationPageStep === SECOND_STEP) {
trackMultiStepRegistrationStep2SubmitBtnClicked(multiStepRegistrationExpVariation);
}
if (multiStepRegistrationExpVariation === MULTI_STEP_REGISTRATION_EXP_VARIATION
&& multiStepRegistrationPageStep === THIRD_STEP) {
trackMultiStepRegistrationStep3SubmitBtnClicked();
}
if (multiStepRegistrationExpVariation === MULTI_STEP_REGISTRATION_EXP_VARIATION
&& multiStepRegistrationPageStep !== THIRD_STEP) {
let formFieldsPayload = {};
if (multiStepRegistrationPageStep === FIRST_STEP) {
trackMultiStepRegistrationStep1SubmitBtnClicked(multiStepRegistrationExpVariation);
// We only want to validate email in the first step of registration
// Doing manual validations to avoid the case where user clicks CTA without focusing out of field.
formFieldsPayload = { email: formFields.email };
} else if (multiStepRegistrationPageStep === SECOND_STEP) {
trackMultiStepRegistrationStep2SubmitBtnClicked(multiStepRegistrationExpVariation);
// We only want to validate name and password field in the second step of registration
// Doing manual validations to avoid the case where user clicks CTA without focusing out of field.
formFieldsPayload = { name: formFields.name, password: formFields.password };
@@ -328,6 +357,7 @@ const RegistrationPage = (props) => {
dispatch(fetchRealtimeValidations(formFieldsPayload, true));
}
} else if (multiStepRegistrationExpVariation === CONTROL && multiStepRegistrationPageStep !== SECOND_STEP) {
trackMultiStepRegistrationStep1SubmitBtnClicked(multiStepRegistrationExpVariation);
// We only want to validate name, email and password fields in the first step of CONTROL registration
// Doing manual validations to avoid the case where user clicks CTA without focusing out of field.
const formFieldsPayload = { name: formFields.name, email: formFields.email, password: formFields.password };
@@ -518,6 +548,7 @@ const RegistrationPage = (props) => {
secondaryProviders={secondaryProviders}
handleInstitutionLogin={handleInstitutionLogin}
thirdPartyAuthApiStatus={thirdPartyAuthApiStatus}
multiStepRegistrationExpVariation={multiStepRegistrationExpVariation}
/>
)}
</Form>

View File

@@ -0,0 +1,56 @@
import { sendTrackEvent } from '@edx/frontend-platform/analytics';
export const eventNames = {
multiStepRegistrationStep1Viewed: 'edx.bi.user.multistepregistration.step1.viewed',
multiStepRegistrationStep2Viewed: 'edx.bi.user.multistepregistration.step2.viewed',
multiStepRegistrationStep3Viewed: 'edx.bi.user.multistepregistration.step3.viewed',
multiStepRegistrationStep1SubmitBtnClicked: 'edx.bi.user.registration.step1.submit.click',
multiStepRegistrationStep2SubmitBtnClicked: 'edx.bi.user.registration.step2.submit.click',
multiStepRegistrationStep3SubmitBtnClicked: 'edx.bi.user.registration.step3.submit.click',
multiStepRegistrationFormSubmitBtnClicked: 'edx.bi.user.registration.form.submit.click',
multiStepRegistrationSSOBtnClicked: 'edx.bi.user.registration.sso.btn.click',
};
export const trackMultiStepRegistrationStep1Viewed = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationStep1Viewed, {
variation: expVariation,
});
};
export const trackMultiStepRegistrationStep2Viewed = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationStep2Viewed, {
variation: expVariation,
});
};
export const trackMultiStepRegistrationStep3Viewed = () => {
sendTrackEvent(eventNames.multiStepRegistrationStep3Viewed, {});
};
export const trackMultiStepRegistrationStep1SubmitBtnClicked = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationStep1SubmitBtnClicked, {
variation: expVariation,
});
};
export const trackMultiStepRegistrationStep2SubmitBtnClicked = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationStep2SubmitBtnClicked, {
variation: expVariation,
});
};
export const trackMultiStepRegistrationStep3SubmitBtnClicked = () => {
sendTrackEvent(eventNames.multiStepRegistrationStep3SubmitBtnClicked, {});
};
export const trackMultiStepRegistrationFormSubmitBtnClicked = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationFormSubmitBtnClicked, {
variation: expVariation,
});
};
export const trackMultiStepRegistrationSSOBtnClicked = (expVariation) => {
sendTrackEvent(eventNames.multiStepRegistrationSSOBtnClicked, {
variation: expVariation,
});
};

View File

@@ -5,6 +5,7 @@ import {
getMultiStepRegistrationExperimentVariation,
NOT_INITIALIZED,
} from './helper';
import { trackMultiStepRegistrationStep1Viewed } from './track';
import { COMPLETE_STATE } from '../../../data/constants';
/**
@@ -30,6 +31,7 @@ const useMultiStepRegistrationExperimentVariation = (
const expVariation = getMultiStepRegistrationExperimentVariation();
if (expVariation) {
setVariation(expVariation);
trackMultiStepRegistrationStep1Viewed(expVariation);
} else {
// This is to handle the case when user dont get variation for some reason, the register page
// shows unlimited spinner.