import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { getConfig, snakeCaseObject } from '@edx/frontend-platform'; import { identifyAuthenticatedUser, sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics'; import { AxiosJwtAuthService, configure as configureAuth, ensureAuthenticatedUser, getAuthenticatedUser, hydrateAuthenticatedUser, } from '@edx/frontend-platform/auth'; import { injectIntl } from '@edx/frontend-platform/i18n'; import { getLoggingService } from '@edx/frontend-platform/logging'; import { Alert, Form, Hyperlink, StatefulButton, } from '@edx/paragon'; import { Error } from '@edx/paragon/icons'; import PropTypes from 'prop-types'; import { Helmet } from 'react-helmet'; import BaseComponent from '../base-component'; import { RedirectLogistration } from '../common-components'; import { DEFAULT_REDIRECT_URL, DEFAULT_STATE, FAILURE_STATE, } from '../data/constants'; import { getAllPossibleQueryParams } from '../data/utils'; import FormFieldRenderer from '../field-renderer'; import { activateRecommendationsExperiment, RECOMMENDATIONS_EXP_VARIATION, trackRecommendationViewedOptimizely, } from '../recommendations/optimizelyExperiment'; import { trackRecommendationsGroup, trackRecommendationsViewed } from '../recommendations/track'; import { saveUserProfile } from './data/actions'; import { welcomePageSelector } from './data/selectors'; import messages from './messages'; import ProgressiveProfilingPageModal from './ProgressiveProfilingPageModal'; const ProgressiveProfiling = (props) => { const { formRenderState, intl, submitState, showError, location, } = props; const enablePersonalizedRecommendations = getConfig().ENABLE_PERSONALIZED_RECOMMENDATIONS; const registrationResponse = location.state?.registrationResult; const [ready, setReady] = useState(false); const [registrationResult, setRegistrationResult] = useState({ redirectUrl: '' }); const [values, setValues] = useState({}); const [openDialog, setOpenDialog] = useState(false); const [showRecommendationsPage, setShowRecommendationsPage] = useState(false); const authenticatedUser = getAuthenticatedUser(); const DASHBOARD_URL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL); useEffect(() => { configureAuth(AxiosJwtAuthService, { loggingService: getLoggingService(), config: getConfig() }); ensureAuthenticatedUser(DASHBOARD_URL) .then(() => { hydrateAuthenticatedUser().then(() => { setReady(true); }); }) .catch(() => {}); if (registrationResponse) { setRegistrationResult(registrationResponse); } }, [DASHBOARD_URL, registrationResponse]); useEffect(() => { if (registrationResponse && authenticatedUser?.userId) { identifyAuthenticatedUser(authenticatedUser.userId); sendPageEvent('login_and_registration', 'welcome'); } }, [authenticatedUser, registrationResponse]); useEffect(() => { if (registrationResponse && authenticatedUser?.userId) { const queryParams = getAllPossibleQueryParams(registrationResponse.redirectUrl); if (enablePersonalizedRecommendations && !('enrollment_action' in queryParams)) { const userIdStr = authenticatedUser.userId.toString(); const variation = activateRecommendationsExperiment(userIdStr); const showRecommendations = variation === RECOMMENDATIONS_EXP_VARIATION; trackRecommendationsGroup(variation, authenticatedUser.userId); trackRecommendationViewedOptimizely(userIdStr); setShowRecommendationsPage(showRecommendations); if (!showRecommendations) { trackRecommendationsViewed([], true, authenticatedUser.userId); } } } }, [authenticatedUser, enablePersonalizedRecommendations, registrationResponse]); if (!location.state || !location.state.registrationResult || formRenderState === FAILURE_STATE) { global.location.assign(DASHBOARD_URL); return null; } if (!ready) { return null; } const optionalFields = location.state.optionalFields.fields; const extendedProfile = location.state.optionalFields.extended_profile; const handleSubmit = (e) => { e.preventDefault(); window.history.replaceState(location.state, null, ''); const payload = { ...values, extendedProfile: [] }; if (Object.keys(extendedProfile).length > 0) { extendedProfile.forEach(fieldName => { if (values[fieldName]) { payload.extendedProfile.push({ fieldName, fieldValue: values[fieldName] }); } delete payload[fieldName]; }); } props.saveUserProfile(authenticatedUser.username, snakeCaseObject(payload)); sendTrackEvent( 'edx.bi.welcome.page.submit.clicked', { isGenderSelected: !!values.gender, isYearOfBirthSelected: !!values.year_of_birth, isLevelOfEducationSelected: !!values.level_of_education, }, ); }; const handleSkip = (e) => { e.preventDefault(); window.history.replaceState(props.location.state, null, ''); setOpenDialog(true); sendTrackEvent('edx.bi.welcome.page.skip.link.clicked'); }; const onChangeHandler = (e) => { if (e.target.type === 'checkbox') { setValues({ ...values, [e.target.name]: e.target.checked }); } else { setValues({ ...values, [e.target.name]: e.target.value }); } }; const formFields = Object.keys(optionalFields).map((fieldName) => { const fieldData = optionalFields[fieldName]; return ( ); }); return ( <> {intl.formatMessage(messages['progressive.profiling.page.title'], { siteName: getConfig().SITE_NAME })} {props.shouldRedirect ? ( ) : null} {intl.formatMessage(messages['progressive.profiling.page.heading'])} {showError ? ( {intl.formatMessage(messages['welcome.page.error.heading'])} {intl.formatMessage(messages['welcome.page.error.message'])} ) : null} {formFields} {(getConfig().AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK) && ( (sendTrackEvent('edx.bi.welcome.page.support.link.clicked'))} > {intl.formatMessage(messages['optional.fields.information.link'])} )} e.preventDefault()} /> e.preventDefault()} /> > ); }; ProgressiveProfiling.propTypes = { formRenderState: PropTypes.string.isRequired, intl: PropTypes.objectOf(PropTypes.object).isRequired, location: PropTypes.shape({ state: PropTypes.object, }), saveUserProfile: PropTypes.func.isRequired, showError: PropTypes.bool, shouldRedirect: PropTypes.bool, submitState: PropTypes.string, }; ProgressiveProfiling.defaultProps = { location: { state: {} }, shouldRedirect: false, showError: false, submitState: DEFAULT_STATE, }; const mapStateToProps = state => ({ formRenderState: welcomePageSelector(state).formRenderState, shouldRedirect: welcomePageSelector(state).success, submitState: welcomePageSelector(state).submitState, showError: welcomePageSelector(state).showError, }); export default connect( mapStateToProps, { saveUserProfile, }, )(injectIntl(ProgressiveProfiling));
{intl.formatMessage(messages['welcome.page.error.message'])}