fix: Side banner didn't show. (#409)
This commit is contained in:
@@ -3,7 +3,6 @@ import { Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import { AppProvider } from '@edx/frontend-platform/react';
|
||||
|
||||
import BaseComponent from './base-component';
|
||||
import {
|
||||
UnAuthOnlyRoute, registerIcons, NotFoundPage, Logistration,
|
||||
} from './common-components';
|
||||
@@ -21,22 +20,20 @@ registerIcons();
|
||||
|
||||
const MainApp = () => (
|
||||
<AppProvider store={configureStore()}>
|
||||
<BaseComponent>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
<Redirect to={updatePathWithQueryParams(REGISTER_PAGE)} />
|
||||
</Route>
|
||||
<UnAuthOnlyRoute exact path={LOGIN_PAGE} render={() => <Logistration selectedPage={LOGIN_PAGE} />} />
|
||||
<UnAuthOnlyRoute exact path={REGISTER_PAGE} component={Logistration} />
|
||||
<UnAuthOnlyRoute exact path={RESET_PAGE} component={ForgotPasswordPage} />
|
||||
<Route exact path={PASSWORD_RESET_CONFIRM} component={ResetPasswordPage} />
|
||||
<Route exact path={WELCOME_PAGE} component={WelcomePage} />
|
||||
<Route path={PAGE_NOT_FOUND} component={NotFoundPage} />
|
||||
<Route path="*">
|
||||
<Redirect to={PAGE_NOT_FOUND} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</BaseComponent>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
<Redirect to={updatePathWithQueryParams(REGISTER_PAGE)} />
|
||||
</Route>
|
||||
<UnAuthOnlyRoute exact path={LOGIN_PAGE} render={() => <Logistration selectedPage={LOGIN_PAGE} />} />
|
||||
<UnAuthOnlyRoute exact path={REGISTER_PAGE} component={Logistration} />
|
||||
<UnAuthOnlyRoute exact path={RESET_PAGE} component={ForgotPasswordPage} />
|
||||
<Route exact path={PASSWORD_RESET_CONFIRM} component={ResetPasswordPage} />
|
||||
<Route exact path={WELCOME_PAGE} component={WelcomePage} />
|
||||
<Route path={PAGE_NOT_FOUND} component={NotFoundPage} />
|
||||
<Route path="*">
|
||||
<Redirect to={PAGE_NOT_FOUND} />
|
||||
</Route>
|
||||
</Switch>
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
|
||||
import { updatePathWithQueryParams, getTpaHint } from '../data/utils';
|
||||
import { LoginPage } from '../login';
|
||||
import { RegistrationPage } from '../register';
|
||||
import BaseComponent from '../base-component';
|
||||
|
||||
const Logistration = (props) => {
|
||||
const { intl, selectedPage } = props;
|
||||
@@ -51,32 +52,34 @@ const Logistration = (props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{institutionLogin
|
||||
? (
|
||||
<Tabs defaultActiveKey="" id="controlled-tab" onSelect={handleInstitutionLogin}>
|
||||
<Tab title={tabTitle} eventKey={selectedPage === LOGIN_PAGE ? LOGIN_PAGE : REGISTER_PAGE} />
|
||||
</Tabs>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
{!tpa && (
|
||||
<Tabs defaultActiveKey={selectedPage} id="controlled-tab" onSelect={handleOnSelect}>
|
||||
<Tab title={intl.formatMessage(messages['logistration.register'])} eventKey={REGISTER_PAGE} />
|
||||
<Tab title={intl.formatMessage(messages['logistration.sign.in'])} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
)}
|
||||
</>
|
||||
<BaseComponent>
|
||||
<div>
|
||||
{institutionLogin
|
||||
? (
|
||||
<Tabs defaultActiveKey="" id="controlled-tab" onSelect={handleInstitutionLogin}>
|
||||
<Tab title={tabTitle} eventKey={selectedPage === LOGIN_PAGE ? LOGIN_PAGE : REGISTER_PAGE} />
|
||||
</Tabs>
|
||||
)
|
||||
: (
|
||||
<>
|
||||
{!tpa && (
|
||||
<Tabs defaultActiveKey={selectedPage} id="controlled-tab" onSelect={handleOnSelect}>
|
||||
<Tab title={intl.formatMessage(messages['logistration.register'])} eventKey={REGISTER_PAGE} />
|
||||
<Tab title={intl.formatMessage(messages['logistration.sign.in'])} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
<div id="main-content" className="main-content">
|
||||
{selectedPage === LOGIN_PAGE
|
||||
? <LoginPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />
|
||||
: <RegistrationPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />}
|
||||
<div id="main-content" className="main-content">
|
||||
{selectedPage === LOGIN_PAGE
|
||||
? <LoginPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />
|
||||
: <RegistrationPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseComponent>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -8,11 +8,13 @@ import { getConfig, mergeConfig } from '@edx/frontend-platform';
|
||||
import * as analytics from '@edx/frontend-platform/analytics';
|
||||
import { configure, injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import * as auth from '@edx/frontend-platform/auth';
|
||||
import Logistration from '../Logistration';
|
||||
import { RenderInstitutionButton } from '../InstitutionLogistration';
|
||||
import { COMPLETE_STATE, LOGIN_PAGE } from '../../data/constants';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
analytics.sendPageEvent = jest.fn();
|
||||
|
||||
const mockStore = configureStore();
|
||||
@@ -36,6 +38,9 @@ describe('Logistration', () => {
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'edX' }));
|
||||
});
|
||||
it('should render registration page', () => {
|
||||
configure({
|
||||
loggingService: { logError: jest.fn() },
|
||||
@@ -163,7 +168,7 @@ describe('Logistration', () => {
|
||||
});
|
||||
|
||||
delete window.location;
|
||||
window.location = { href: getConfig().BASE_URL };
|
||||
window.location = { hostname: getConfig().SITE_NAME, href: getConfig().BASE_URL };
|
||||
|
||||
const root = mount(reduxWrapper(<IntlLogistration />));
|
||||
root.find(RenderInstitutionButton).simulate('click', { institutionLogin: true });
|
||||
|
||||
@@ -27,6 +27,7 @@ import { FormGroup } from '../common-components';
|
||||
import { DEFAULT_STATE, LOGIN_PAGE, VALID_EMAIL_REGEX } from '../data/constants';
|
||||
import { updatePathWithQueryParams, windowScrollTo } from '../data/utils';
|
||||
import ForgotPasswordAlert from './ForgotPasswordAlert';
|
||||
import BaseComponent from '../base-component';
|
||||
|
||||
const ForgotPasswordPage = (props) => {
|
||||
const { intl, status, submitState } = props;
|
||||
@@ -63,87 +64,89 @@ const ForgotPasswordPage = (props) => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Tabs activeKey="" id="controlled-tab-example" onSelect={(k) => setKey(k)}>
|
||||
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
<div id="main-content" className="main-content">
|
||||
<Formik
|
||||
initialValues={{ email: '' }}
|
||||
validateOnChange={false}
|
||||
validate={(values) => {
|
||||
const validationMessage = getValidationMessage(values.email);
|
||||
<BaseComponent>
|
||||
<div>
|
||||
<Tabs activeKey="" id="controlled-tab-example" onSelect={(k) => setKey(k)}>
|
||||
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
<div id="main-content" className="main-content">
|
||||
<Formik
|
||||
initialValues={{ email: '' }}
|
||||
validateOnChange={false}
|
||||
validate={(values) => {
|
||||
const validationMessage = getValidationMessage(values.email);
|
||||
|
||||
if (validationMessage !== '') {
|
||||
windowScrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
||||
return { email: validationMessage };
|
||||
}
|
||||
if (validationMessage !== '') {
|
||||
windowScrollTo({ left: 0, top: 0, behavior: 'smooth' });
|
||||
return { email: validationMessage };
|
||||
}
|
||||
|
||||
return {};
|
||||
}}
|
||||
onSubmit={(values) => { props.forgotPassword(values.email); }}
|
||||
>
|
||||
{({
|
||||
errors, handleSubmit, setFieldValue, values,
|
||||
}) => (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['forgot.password.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<Form className="mw-xs">
|
||||
<ForgotPasswordAlert email={props.email} emailError={errors.email} status={status} />
|
||||
<h4>
|
||||
{intl.formatMessage(messages['forgot.password.page.heading'])}
|
||||
</h4>
|
||||
<p className="mb-4">
|
||||
{intl.formatMessage(messages['forgot.password.page.instructions'])}
|
||||
</p>
|
||||
<FormGroup
|
||||
floatingLabel={intl.formatMessage(messages['forgot.password.page.email.field.label'])}
|
||||
name="email"
|
||||
errorMessage={validationError}
|
||||
value={values.email}
|
||||
handleBlur={() => getValidationMessage(values.email)}
|
||||
handleChange={e => setFieldValue('email', e.target.value)}
|
||||
handleFocus={() => setValidationError('')}
|
||||
helpText={[intl.formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
|
||||
/>
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="login-button-width"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['forgot.password.page.submit.button']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
<Hyperlink
|
||||
id="forgot-password"
|
||||
className="ml-4 font-weight-500 text-body"
|
||||
destination={supportUrl}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
window.open(supportUrl, '_blank');
|
||||
}}
|
||||
>{intl.formatMessage(messages['need.help.sign.in.text'])}
|
||||
</Hyperlink>
|
||||
<p className="mt-5 one-rem-font">{intl.formatMessage(messages['additional.help.text'])}
|
||||
<span><Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink></span>
|
||||
</p>
|
||||
</Form>
|
||||
</>
|
||||
)}
|
||||
</Formik>
|
||||
return {};
|
||||
}}
|
||||
onSubmit={(values) => { props.forgotPassword(values.email); }}
|
||||
>
|
||||
{({
|
||||
errors, handleSubmit, setFieldValue, values,
|
||||
}) => (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['forgot.password.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<Form className="mw-xs">
|
||||
<ForgotPasswordAlert email={props.email} emailError={errors.email} status={status} />
|
||||
<h4>
|
||||
{intl.formatMessage(messages['forgot.password.page.heading'])}
|
||||
</h4>
|
||||
<p className="mb-4">
|
||||
{intl.formatMessage(messages['forgot.password.page.instructions'])}
|
||||
</p>
|
||||
<FormGroup
|
||||
floatingLabel={intl.formatMessage(messages['forgot.password.page.email.field.label'])}
|
||||
name="email"
|
||||
errorMessage={validationError}
|
||||
value={values.email}
|
||||
handleBlur={() => getValidationMessage(values.email)}
|
||||
handleChange={e => setFieldValue('email', e.target.value)}
|
||||
handleFocus={() => setValidationError('')}
|
||||
helpText={[intl.formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
|
||||
/>
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="login-button-width"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['forgot.password.page.submit.button']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
<Hyperlink
|
||||
id="forgot-password"
|
||||
className="ml-4 font-weight-500 text-body"
|
||||
destination={supportUrl}
|
||||
onClick={e => {
|
||||
e.preventDefault();
|
||||
window.open(supportUrl, '_blank');
|
||||
}}
|
||||
>{intl.formatMessage(messages['need.help.sign.in.text'])}
|
||||
</Hyperlink>
|
||||
<p className="mt-5 one-rem-font">{intl.formatMessage(messages['additional.help.text'])}
|
||||
<span><Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink></span>
|
||||
</p>
|
||||
</Form>
|
||||
</>
|
||||
)}
|
||||
</Formik>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseComponent>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,13 +10,15 @@ import { createMemoryHistory } from 'history';
|
||||
import * as analytics from '@edx/frontend-platform/analytics';
|
||||
import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner';
|
||||
import { mergeConfig } from '@edx/frontend-platform';
|
||||
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider, injectIntl, configure } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import * as auth from '@edx/frontend-platform/auth';
|
||||
import ForgotPasswordPage from '../ForgotPasswordPage';
|
||||
import { INTERNAL_SERVER_ERROR, LOGIN_PAGE } from '../../data/constants';
|
||||
import { PASSWORD_RESET } from '../../reset-password/data/constants';
|
||||
|
||||
jest.mock('@edx/frontend-platform/analytics');
|
||||
jest.mock('@edx/frontend-platform/auth');
|
||||
|
||||
analytics.sendPageEvent = jest.fn();
|
||||
|
||||
@@ -49,6 +51,15 @@ describe('ForgotPasswordPage', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
store = mockStore(initialState);
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'edX' }));
|
||||
configure({
|
||||
loggingService: { logError: jest.fn() },
|
||||
config: {
|
||||
ENVIRONMENT: 'production',
|
||||
LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum',
|
||||
},
|
||||
messages: { 'es-419': {}, de: {}, 'en-us': {} },
|
||||
});
|
||||
props = {
|
||||
forgotPassword: jest.fn(),
|
||||
status: null,
|
||||
|
||||
@@ -29,6 +29,7 @@ import {
|
||||
FORM_SUBMISSION_ERROR, PASSWORD_RESET_ERROR, PASSWORD_VALIDATION_ERROR, TOKEN_STATE,
|
||||
} from './data/constants';
|
||||
import { updatePathWithQueryParams, windowScrollTo } from '../data/utils';
|
||||
import BaseComponent from '../base-component';
|
||||
|
||||
const ResetPasswordPage = (props) => {
|
||||
const { intl } = props;
|
||||
@@ -133,58 +134,60 @@ const ResetPasswordPage = (props) => {
|
||||
return <Redirect to={updatePathWithQueryParams(LOGIN_PAGE)} />;
|
||||
} else {
|
||||
return (
|
||||
<div>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['reset.password.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<Tabs activeKey="" id="controlled-tab" onSelect={(k) => setKey(k)}>
|
||||
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
<div id="main-content" className="main-content">
|
||||
<div className="mw-xs">
|
||||
<ResetPasswordFailure errorCode={errorCode} errorMsg={props.errorMsg} />
|
||||
<h4>{intl.formatMessage(messages['reset.password'])}</h4>
|
||||
<p className="mb-4">{intl.formatMessage(messages['reset.password.page.instructions'])}</p>
|
||||
<Form>
|
||||
<PasswordField
|
||||
name="newPassword"
|
||||
value={newPassword}
|
||||
handleChange={(e) => setNewPassword(e.target.value)}
|
||||
handleBlur={(e) => validateInput(e.target.name, e.target.value)}
|
||||
handleFocus={handleOnFocus}
|
||||
errorMessage={formErrors.newPassword}
|
||||
floatingLabel={intl.formatMessage(messages['new.password.label'])}
|
||||
/>
|
||||
<PasswordField
|
||||
name="confirmPassword"
|
||||
value={confirmPassword}
|
||||
handleChange={handleConfirmPasswordChange}
|
||||
handleFocus={handleOnFocus}
|
||||
errorMessage={formErrors.confirmPassword}
|
||||
showRequirements={false}
|
||||
floatingLabel={intl.formatMessage(messages['confirm.password.label'])}
|
||||
/>
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="stateful-button-width"
|
||||
state={props.status}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['reset.password']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={e => handleSubmit(e)}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
</Form>
|
||||
<BaseComponent>
|
||||
<div>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['reset.password.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<Tabs activeKey="" id="controlled-tab" onSelect={(k) => setKey(k)}>
|
||||
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
|
||||
</Tabs>
|
||||
{ key && (
|
||||
<Redirect to={updatePathWithQueryParams(key)} />
|
||||
)}
|
||||
<div id="main-content" className="main-content">
|
||||
<div className="mw-xs">
|
||||
<ResetPasswordFailure errorCode={errorCode} errorMsg={props.errorMsg} />
|
||||
<h4>{intl.formatMessage(messages['reset.password'])}</h4>
|
||||
<p className="mb-4">{intl.formatMessage(messages['reset.password.page.instructions'])}</p>
|
||||
<Form>
|
||||
<PasswordField
|
||||
name="newPassword"
|
||||
value={newPassword}
|
||||
handleChange={(e) => setNewPassword(e.target.value)}
|
||||
handleBlur={(e) => validateInput(e.target.name, e.target.value)}
|
||||
handleFocus={handleOnFocus}
|
||||
errorMessage={formErrors.newPassword}
|
||||
floatingLabel={intl.formatMessage(messages['new.password.label'])}
|
||||
/>
|
||||
<PasswordField
|
||||
name="confirmPassword"
|
||||
value={confirmPassword}
|
||||
handleChange={handleConfirmPasswordChange}
|
||||
handleFocus={handleOnFocus}
|
||||
errorMessage={formErrors.confirmPassword}
|
||||
showRequirements={false}
|
||||
floatingLabel={intl.formatMessage(messages['confirm.password.label'])}
|
||||
/>
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="stateful-button-width"
|
||||
state={props.status}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['reset.password']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={e => handleSubmit(e)}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaseComponent>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { createMemoryHistory } from 'history';
|
||||
|
||||
import * as auth from '@edx/frontend-platform/auth';
|
||||
import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner';
|
||||
import { IntlProvider, injectIntl } from '@edx/frontend-platform/i18n';
|
||||
import { IntlProvider, injectIntl, configure } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { resetPassword } from '../data/actions';
|
||||
import { PASSWORD_RESET, TOKEN_STATE } from '../data/constants';
|
||||
@@ -36,6 +36,14 @@ describe('ResetPasswordPage', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
store = mockStore();
|
||||
configure({
|
||||
loggingService: { logError: jest.fn() },
|
||||
config: {
|
||||
ENVIRONMENT: 'production',
|
||||
LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum',
|
||||
},
|
||||
messages: { 'es-419': {}, de: {}, 'en-us': {} },
|
||||
});
|
||||
props = {
|
||||
resetPassword: jest.fn(),
|
||||
status: null,
|
||||
|
||||
@@ -32,6 +32,7 @@ import { RedirectLogistration } from '../common-components';
|
||||
import { DEFAULT_REDIRECT_URL, DEFAULT_STATE } from '../data/constants';
|
||||
import { EDUCATION_LEVELS, GENDER_OPTIONS, YEAR_OF_BIRTH_OPTIONS } from '../register/data/constants';
|
||||
import WelcomePageModal from './WelcomePageModal';
|
||||
import BaseComponent from '../base-component';
|
||||
|
||||
const WelcomePage = (props) => {
|
||||
const { intl, submitState, showError } = props;
|
||||
@@ -121,104 +122,106 @@ const WelcomePage = (props) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['progressive.profiling.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<WelcomePageModal isOpen={openDialog} redirectUrl={registrationResult.redirectUrl} />
|
||||
{props.shouldRedirect ? (
|
||||
<RedirectLogistration
|
||||
success
|
||||
redirectUrl={registrationResult.redirectUrl}
|
||||
/>
|
||||
) : null}
|
||||
<div className="mw-xs welcome-page-content">
|
||||
<div className="welcome-page-heading">
|
||||
<h2 className="h3 text-primary">{intl.formatMessage(messages['progressive.profiling.page.heading'])}</h2>
|
||||
</div>
|
||||
<hr className="border-light-700 mb-4" />
|
||||
{showError ? (
|
||||
<Alert id="welcome-page-errors" className="mb-3" variant="danger" icon={Error}>
|
||||
<Alert.Heading>{intl.formatMessage(messages['welcome.page.error.heading'])}</Alert.Heading>
|
||||
<p>{intl.formatMessage(messages['welcome.page.error.message'])}</p>
|
||||
</Alert>
|
||||
<BaseComponent>
|
||||
<Helmet>
|
||||
<title>{intl.formatMessage(messages['progressive.profiling.page.title'],
|
||||
{ siteName: getConfig().SITE_NAME })}
|
||||
</title>
|
||||
</Helmet>
|
||||
<WelcomePageModal isOpen={openDialog} redirectUrl={registrationResult.redirectUrl} />
|
||||
{props.shouldRedirect ? (
|
||||
<RedirectLogistration
|
||||
success
|
||||
redirectUrl={registrationResult.redirectUrl}
|
||||
/>
|
||||
) : null}
|
||||
<Form>
|
||||
<Form.Group controlId="levelOfEducation">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="levelOfEducation"
|
||||
value={values.levelOfEducation}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['education.levels.label'])}
|
||||
>
|
||||
{getOptions('levelOfEducation')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="yearOfBirth">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="yearOfBirth"
|
||||
value={values.yearOfBirth}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['year.of.birth.label'])}
|
||||
>
|
||||
<option value="">{intl.formatMessage(messages['year.of.birth.label'])}</option>
|
||||
{getOptions('yearOfBirth')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="gender" className="mb-3">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="gender"
|
||||
value={values.gender}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['gender.options.label'])}
|
||||
>
|
||||
{getOptions('gender')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<span className="progressive-profiling-support">
|
||||
<Hyperlink
|
||||
isInline
|
||||
variant="muted"
|
||||
destination={getConfig().WELCOME_PAGE_SUPPORT_LINK}
|
||||
target="_blank"
|
||||
showLaunchIcon={false}
|
||||
>
|
||||
{intl.formatMessage(messages['optional.fields.information.link'])}
|
||||
</Hyperlink>
|
||||
</span>
|
||||
<div className="d-flex mt-4">
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="login-button-width"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['optional.fields.submit.button']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
<StatefulButton
|
||||
className="text-gray-700 font-weight-500"
|
||||
type="submit"
|
||||
variant="link"
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['optional.fields.skip.button']),
|
||||
}}
|
||||
onClick={handleSkip}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
<div className="mw-xs welcome-page-content">
|
||||
<div className="welcome-page-heading">
|
||||
<h2 className="h3 text-primary">{intl.formatMessage(messages['progressive.profiling.page.heading'])}</h2>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
<hr className="border-light-700 mb-4" />
|
||||
{showError ? (
|
||||
<Alert id="welcome-page-errors" className="mb-3" variant="danger" icon={Error}>
|
||||
<Alert.Heading>{intl.formatMessage(messages['welcome.page.error.heading'])}</Alert.Heading>
|
||||
<p>{intl.formatMessage(messages['welcome.page.error.message'])}</p>
|
||||
</Alert>
|
||||
) : null}
|
||||
<Form>
|
||||
<Form.Group controlId="levelOfEducation">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="levelOfEducation"
|
||||
value={values.levelOfEducation}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['education.levels.label'])}
|
||||
>
|
||||
{getOptions('levelOfEducation')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="yearOfBirth">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="yearOfBirth"
|
||||
value={values.yearOfBirth}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['year.of.birth.label'])}
|
||||
>
|
||||
<option value="">{intl.formatMessage(messages['year.of.birth.label'])}</option>
|
||||
{getOptions('yearOfBirth')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<Form.Group controlId="gender" className="mb-3">
|
||||
<Form.Control
|
||||
as="select"
|
||||
name="gender"
|
||||
value={values.gender}
|
||||
onChange={(e) => onChangeHandler(e)}
|
||||
trailingElement={<Icon src={ExpandMore} />}
|
||||
floatingLabel={intl.formatMessage(messages['gender.options.label'])}
|
||||
>
|
||||
{getOptions('gender')}
|
||||
</Form.Control>
|
||||
</Form.Group>
|
||||
<span className="progressive-profiling-support">
|
||||
<Hyperlink
|
||||
isInline
|
||||
variant="muted"
|
||||
destination={getConfig().WELCOME_PAGE_SUPPORT_LINK}
|
||||
target="_blank"
|
||||
showLaunchIcon={false}
|
||||
>
|
||||
{intl.formatMessage(messages['optional.fields.information.link'])}
|
||||
</Hyperlink>
|
||||
</span>
|
||||
<div className="d-flex mt-4">
|
||||
<StatefulButton
|
||||
type="submit"
|
||||
variant="brand"
|
||||
className="login-button-width"
|
||||
state={submitState}
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['optional.fields.submit.button']),
|
||||
pending: '',
|
||||
}}
|
||||
onClick={handleSubmit}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
<StatefulButton
|
||||
className="text-gray-700 font-weight-500"
|
||||
type="submit"
|
||||
variant="link"
|
||||
labels={{
|
||||
default: intl.formatMessage(messages['optional.fields.skip.button']),
|
||||
}}
|
||||
onClick={handleSkip}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
/>
|
||||
</div>
|
||||
</Form>
|
||||
</div>
|
||||
</BaseComponent>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@ import configureStore from 'redux-mock-store';
|
||||
import { mergeConfig } from '@edx/frontend-platform';
|
||||
import * as analytics from '@edx/frontend-platform/analytics';
|
||||
import * as auth from '@edx/frontend-platform/auth';
|
||||
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
|
||||
import { injectIntl, IntlProvider, configure } from '@edx/frontend-platform/i18n';
|
||||
|
||||
import { saveUserProfile } from '../data/actions';
|
||||
import WelcomePage from '../WelcomePage';
|
||||
@@ -50,6 +50,14 @@ describe('WelcomePageTests', () => {
|
||||
beforeEach(() => {
|
||||
store = mockStore({});
|
||||
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'edX' }));
|
||||
configure({
|
||||
loggingService: { logError: jest.fn() },
|
||||
config: {
|
||||
ENVIRONMENT: 'production',
|
||||
LANGUAGE_PREFERENCE_COOKIE_NAME: 'yum',
|
||||
},
|
||||
messages: { 'es-419': {}, de: {}, 'en-us': {} },
|
||||
});
|
||||
});
|
||||
|
||||
it('should submit user profile details on form submission', async () => {
|
||||
|
||||
Reference in New Issue
Block a user