feat: use intl hook for functional components (#796)

This commit is contained in:
Zainab Amir
2023-03-29 12:21:12 +05:00
committed by GitHub
parent 1dd88795c3
commit 2d4c6a1d3b
34 changed files with 430 additions and 439 deletions

View File

@@ -1,46 +1,49 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthLargeLayout = ({ intl, username }) => (
<div className="w-50 d-flex">
<div className="col-md-10 bg-light-200 p-0">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className="large-screen-left-container mr-n4.5 large-yellow-line mt-5" />
<div>
<h1 className="welcome-to-platform data-hj-suppress">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="complete-your-profile">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthLargeLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<div className="w-50 d-flex">
<div className="col-md-10 bg-light-200 p-0">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className="large-screen-left-container mr-n4.5 large-yellow-line mt-5" />
<div>
<h1 className="welcome-to-platform data-hj-suppress">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="complete-your-profile">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="m1-n1 w-100 h-100 large-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="m1-n1 w-100 h-100 large-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
);
);
};
AuthLargeLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthLargeLayout);
export default AuthLargeLayout;

View File

@@ -1,49 +1,52 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthMediumLayout = ({ intl, username }) => (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-light-200">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ml-5">
<div className="medium-yellow-line mt-5 mr-n2" />
<div>
<h1 className="h3 data-hj-suppress mw-320">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="display-1">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthMediumLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-light-200">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ml-5">
<div className="medium-yellow-line mt-5 mr-n2" />
<div>
<h1 className="h3 data-hj-suppress mw-320">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="display-1">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
</>
);
</>
);
};
AuthMediumLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthMediumLayout);
export default AuthMediumLayout;

View File

@@ -1,38 +1,41 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthSmallLayout = ({ intl, username }) => (
<div className="min-vw-100 bg-light-200">
<div className="col-md-12 small-screen-top-stripe" />
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className="small-yellow-line mt-4.5" />
<div>
<h1 className="h5 data-hj-suppress">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="h1">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthSmallLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<div className="min-vw-100 bg-light-200">
<div className="col-md-12 small-screen-top-stripe" />
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className="small-yellow-line mt-4.5" />
<div>
<h1 className="h5 data-hj-suppress">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="h1">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
</div>
);
);
};
AuthSmallLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthSmallLayout);
export default AuthSmallLayout;

View File

@@ -1,46 +1,45 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import messages from './messages';
const LargeLayout = ({ intl }) => (
<div className="w-50 d-flex">
<div className="col-md-9 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className={classNames({ 'large-yellow-line mr-n4.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'display-2 text-white mw-xs',
{ 'ml-6': getConfig().SITE_NAME !== 'edX' },
)}
>
{intl.formatMessage(messages['start.learning'])}
<div className="text-accent-a">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</div>
</h1>
const LargeLayout = () => {
const { formatMessage } = useIntl();
return (
<div className="w-50 d-flex">
<div className="col-md-9 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className={classNames({ 'large-yellow-line mr-n4.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'display-2 text-white mw-xs',
{ 'ml-6': getConfig().SITE_NAME !== 'edX' },
)}
>
{formatMessage(messages['start.learning'])}
<div className="text-accent-a">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</div>
</h1>
</div>
</div>
<div className="col-md-3 bg-white p-0">
<svg className="ml-n1 w-100 h-100 large-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-3 bg-white p-0">
<svg className="ml-n1 w-100 h-100 large-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
);
LargeLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
);
};
export default injectIntl(LargeLayout);
export default LargeLayout;

View File

@@ -1,51 +1,50 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import messages from './messages';
const MediumLayout = ({ intl }) => (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image alt={getConfig().SITE_NAME} className="logo" src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ">
<div className={classNames({ 'mt-1 medium-yellow-line': getConfig().SITE_NAME === 'edX' })} />
<div>
<h1
className={classNames(
'display-1 text-white mt-5 mb-5 mr-2',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span className="mr-2">{intl.formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
const MediumLayout = () => {
const { formatMessage } = useIntl();
return (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image alt={getConfig().SITE_NAME} className="logo" src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ">
<div className={classNames({ 'mt-1 medium-yellow-line': getConfig().SITE_NAME === 'edX' })} />
<div>
<h1
className={classNames(
'display-1 text-white mt-5 mb-5 mr-2',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span className="mr-2">{formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
</>
);
MediumLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
</>
);
};
export default injectIntl(MediumLayout);
export default MediumLayout;

View File

@@ -1,40 +1,39 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import messages from './messages';
const SmallLayout = ({ intl }) => (
<span className="bg-primary-400 w-100">
<div className="col-md-12 small-screen-top-stripe" />
<div>
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className={classNames({ 'small-yellow-line mr-n2.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'text-white mt-3.5 mb-3.5',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span className="mr-1">{intl.formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>
</div>
</span>
);
const SmallLayout = () => {
const { formatMessage } = useIntl();
SmallLayout.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
return (
<span className="bg-primary-400 w-100">
<div className="col-md-12 small-screen-top-stripe" />
<div>
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className={classNames({ 'small-yellow-line mr-n2.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'text-white mt-3.5 mb-3.5',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span className="mr-1">{formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>
</div>
</span>
);
};
export default injectIntl(SmallLayout);
export default SmallLayout;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Button, Form,
} from '@edx/paragon';
@@ -16,7 +16,7 @@ import messages from './messages';
* This component renders the Single sign-on (SSO) button only for the tpa provider passed
* */
const EnterpriseSSO = (props) => {
const { intl } = props;
const { formatMessage } = useIntl();
const tpaProvider = props.provider;
const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false;
@@ -36,7 +36,7 @@ const EnterpriseSSO = (props) => {
<div className="d-flex flex-column">
<div className="mw-450">
<Form className="m-0">
<p>{intl.formatMessage(messages['enterprisetpa.title.heading'], { providerName: tpaProvider.name })}</p>
<p>{formatMessage(messages['enterprisetpa.title.heading'], { providerName: tpaProvider.name })}</p>
<Button
id={tpaProvider.id}
key={tpaProvider.id}
@@ -72,8 +72,8 @@ const EnterpriseSSO = (props) => {
onClick={(e) => handleClick(e)}
>
{disablePublicAccountCreation
? intl.formatMessage(messages['enterprisetpa.login.button.text.public.account.creation.disabled'])
: intl.formatMessage(messages['enterprisetpa.login.button.text'])}
? formatMessage(messages['enterprisetpa.login.button.text.public.account.creation.disabled'])
: formatMessage(messages['enterprisetpa.login.button.text'])}
</Button>
</Form>
</div>
@@ -104,7 +104,6 @@ EnterpriseSSO.propTypes = {
loginUrl: PropTypes.string,
registerUrl: PropTypes.string,
}),
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(EnterpriseSSO);
export default EnterpriseSSO;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Hyperlink, Icon } from '@edx/paragon';
import { Institution } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -32,8 +32,8 @@ export const RenderInstitutionButton = props => {
* */
const InstitutionLogistration = props => {
const lmsBaseUrl = getConfig().LMS_BASE_URL;
const { formatMessage } = useIntl();
const {
intl,
secondaryProviders,
headingTitle,
} = props;
@@ -46,7 +46,7 @@ const InstitutionLogistration = props => {
{headingTitle}
</h4>
<p className="mb-2">
{intl.formatMessage(messages['institution.login.page.sub.heading'])}
{formatMessage(messages['institution.login.page.sub.heading'])}
</p>
</div>
</div>
@@ -95,7 +95,6 @@ RenderInstitutionButton.defaultProps = {
InstitutionLogistration.propTypes = {
...LogistrationProps,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
headingTitle: PropTypes.string,
};
InstitutionLogistration.defaultProps = {
@@ -103,4 +102,4 @@ InstitutionLogistration.defaultProps = {
headingTitle: '',
};
export default injectIntl(InstitutionLogistration);
export default InstitutionLogistration;

View File

@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthService } from '@edx/frontend-platform/auth';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Icon,
Tab,
@@ -26,11 +26,12 @@ import {
import messages from './messages';
const Logistration = (props) => {
const { intl, selectedPage, tpaProviders } = props;
const { selectedPage, tpaProviders } = props;
const tpaHint = getTpaHint();
const {
providers, secondaryProviders,
} = tpaProviders;
const { formatMessage } = useIntl();
const [institutionLogin, setInstitutionLogin] = useState(false);
const [key, setKey] = useState('');
const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false;
@@ -66,8 +67,8 @@ const Logistration = (props) => {
<Icon src={ChevronLeft} className="left-icon" />
<span className="ml-2">
{selectedPage === LOGIN_PAGE
? intl.formatMessage(messages['logistration.sign.in'])
: intl.formatMessage(messages['logistration.register'])}
? formatMessage(messages['logistration.sign.in'])
: formatMessage(messages['logistration.register'])}
</span>
</div>
);
@@ -91,7 +92,7 @@ const Logistration = (props) => {
)}
<div id="main-content" className="main-content">
{!institutionLogin && (
<h3 className="mb-4.5">{intl.formatMessage(messages['logistration.sign.in'])}</h3>
<h3 className="mb-4.5">{formatMessage(messages['logistration.sign.in'])}</h3>
)}
<LoginPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />
</div>
@@ -108,8 +109,8 @@ const Logistration = (props) => {
: (!isValidTpaHint() && (
<>
<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} />
<Tab title={formatMessage(messages['logistration.register'])} eventKey={REGISTER_PAGE} />
<Tab title={formatMessage(messages['logistration.sign.in'])} eventKey={LOGIN_PAGE} />
</Tabs>
</>
))}
@@ -134,7 +135,6 @@ const Logistration = (props) => {
};
Logistration.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
selectedPage: PropTypes.string,
backupRegistrationForm: PropTypes.func.isRequired,
tpaProviders: PropTypes.shape({
@@ -163,4 +163,4 @@ export default connect(
{
backupRegistrationForm,
},
)(injectIntl(Logistration));
)(Logistration);

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form, Icon, IconButton, OverlayTrigger, Tooltip, useToggle,
} from '@edx/paragon';
@@ -13,7 +13,7 @@ import { LETTER_REGEX, NUMBER_REGEX } from '../data/constants';
import messages from './messages';
const PasswordField = (props) => {
const { formatMessage } = props.intl;
const { formatMessage } = useIntl();
const [isPasswordHidden, setHiddenTrue, setHiddenFalse] = useToggle(true);
const [showTooltip, setShowTooltip] = useState(false);
@@ -100,11 +100,10 @@ PasswordField.propTypes = {
handleBlur: PropTypes.func,
handleFocus: PropTypes.func,
handleChange: PropTypes.func,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
name: PropTypes.string.isRequired,
showRequirements: PropTypes.bool,
value: PropTypes.string.isRequired,
autoComplete: PropTypes.string,
};
export default injectIntl(PasswordField);
export default PasswordField;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
@@ -10,7 +10,8 @@ import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
import messages from './messages';
function SocialAuthProviders(props) {
const { intl, referrer, socialAuthProviders } = props;
const { formatMessage } = useIntl();
const { referrer, socialAuthProviders } = props;
function handleSubmit(e) {
e.preventDefault();
@@ -45,8 +46,8 @@ function SocialAuthProviders(props) {
<span id="provider-name" className="notranslate mr-auto pl-2" aria-hidden="true">{provider.name}</span>
<span className="sr-only">
{referrer === LOGIN_PAGE
? intl.formatMessage(messages['sso.sign.in.with'], { providerName: provider.name })
: intl.formatMessage(messages['sso.create.account.using'], { providerName: provider.name })}
? formatMessage(messages['sso.sign.in.with'], { providerName: provider.name })
: formatMessage(messages['sso.create.account.using'], { providerName: provider.name })}
</span>
</button>
));
@@ -60,7 +61,6 @@ SocialAuthProviders.defaultProps = {
};
SocialAuthProviders.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
referrer: PropTypes.string,
socialAuthProviders: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
@@ -72,4 +72,4 @@ SocialAuthProviders.propTypes = {
})),
};
export default injectIntl(SocialAuthProviders);
export default SocialAuthProviders;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import PropTypes from 'prop-types';
@@ -9,14 +9,15 @@ import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
import messages from './messages';
const ThirdPartyAuthAlert = (props) => {
const { currentProvider, intl, referrer } = props;
const { formatMessage } = useIntl();
const { currentProvider, referrer } = props;
const platformName = getConfig().SITE_NAME;
let message;
if (referrer === LOGIN_PAGE) {
message = intl.formatMessage(messages['login.third.party.auth.account.not.linked'], { currentProvider, platformName });
message = formatMessage(messages['login.third.party.auth.account.not.linked'], { currentProvider, platformName });
} else {
message = intl.formatMessage(messages['register.third.party.auth.account.not.linked'], { currentProvider, platformName });
message = formatMessage(messages['register.third.party.auth.account.not.linked'], { currentProvider, platformName });
}
if (!currentProvider) {
@@ -27,12 +28,12 @@ const ThirdPartyAuthAlert = (props) => {
<>
<Alert id="tpa-alert" className={referrer === REGISTER_PAGE ? 'alert-success mt-n2' : 'alert-warning mt-n2'}>
{referrer === REGISTER_PAGE ? (
<Alert.Heading>{intl.formatMessage(messages['tpa.alert.heading'])}</Alert.Heading>
<Alert.Heading>{formatMessage(messages['tpa.alert.heading'])}</Alert.Heading>
) : null}
<p>{ message }</p>
</Alert>
{referrer === REGISTER_PAGE ? (
<h4 className="mt-4 mb-4">{intl.formatMessage(messages['registration.using.tpa.form.heading'])}</h4>
<h4 className="mt-4 mb-4">{formatMessage(messages['registration.using.tpa.form.heading'])}</h4>
) : null}
</>
);
@@ -45,8 +46,7 @@ ThirdPartyAuthAlert.defaultProps = {
ThirdPartyAuthAlert.propTypes = {
currentProvider: PropTypes.string,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
referrer: PropTypes.string,
};
export default injectIntl(ThirdPartyAuthAlert);
export default ThirdPartyAuthAlert;

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { CheckCircle, Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -13,9 +13,10 @@ import { PASSWORD_RESET } from '../reset-password/data/constants';
import messages from './messages';
const ForgotPasswordAlert = (props) => {
const { email, emailError, intl } = props;
const { formatMessage } = useIntl();
const { email, emailError } = props;
let message = '';
let heading = intl.formatMessage(messages['forgot.password.error.alert.title']);
let heading = formatMessage(messages['forgot.password.error.alert.title']);
let { status } = props;
if (emailError) {
@@ -24,7 +25,7 @@ const ForgotPasswordAlert = (props) => {
switch (status) {
case COMPLETE_STATE:
heading = intl.formatMessage(messages['confirmation.message.title']);
heading = formatMessage(messages['confirmation.message.title']);
message = (
<FormattedMessage
id="forgot.password.confirmation.message"
@@ -36,7 +37,7 @@ const ForgotPasswordAlert = (props) => {
email: <span className="data-hj-suppress">{email}</span>,
supportLink: (
<Alert.Link href={getConfig().PASSWORD_RESET_SUPPORT_LINK} target="_blank">
{intl.formatMessage(messages['confirmation.support.link'])}
{formatMessage(messages['confirmation.support.link'])}
</Alert.Link>
),
}}
@@ -44,26 +45,26 @@ const ForgotPasswordAlert = (props) => {
);
break;
case INTERNAL_SERVER_ERROR:
message = intl.formatMessage(messages['internal.server.error']);
message = formatMessage(messages['internal.server.error']);
break;
case FORBIDDEN_STATE:
heading = intl.formatMessage(messages['forgot.password.error.message.title']);
message = intl.formatMessage(messages['forgot.password.request.in.progress.message']);
heading = formatMessage(messages['forgot.password.error.message.title']);
message = formatMessage(messages['forgot.password.request.in.progress.message']);
break;
case FORM_SUBMISSION_ERROR:
message = intl.formatMessage(messages['extend.field.errors'], { emailError });
message = formatMessage(messages['extend.field.errors'], { emailError });
break;
case PASSWORD_RESET.INVALID_TOKEN:
heading = intl.formatMessage(messages['invalid.token.heading']);
message = intl.formatMessage(messages['invalid.token.error.message']);
heading = formatMessage(messages['invalid.token.heading']);
message = formatMessage(messages['invalid.token.error.message']);
break;
case PASSWORD_RESET.FORBIDDEN_REQUEST:
heading = intl.formatMessage(messages['token.validation.rate.limit.error.heading']);
message = intl.formatMessage(messages['token.validation.rate.limit.error']);
heading = formatMessage(messages['token.validation.rate.limit.error.heading']);
message = formatMessage(messages['token.validation.rate.limit.error']);
break;
case PASSWORD_RESET.INTERNAL_SERVER_ERROR:
heading = intl.formatMessage(messages['token.validation.internal.sever.error.heading']);
message = intl.formatMessage(messages['token.validation.internal.sever.error']);
heading = formatMessage(messages['token.validation.internal.sever.error.heading']);
message = formatMessage(messages['token.validation.internal.sever.error']);
break;
default:
break;
@@ -93,8 +94,7 @@ ForgotPasswordAlert.defaultProps = {
ForgotPasswordAlert.propTypes = {
status: PropTypes.string.isRequired,
email: PropTypes.string,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
emailError: PropTypes.string,
};
export default injectIntl(ForgotPasswordAlert);
export default ForgotPasswordAlert;

View File

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form,
Hyperlink,
@@ -30,9 +30,10 @@ const ForgotPasswordPage = (props) => {
const platformName = getConfig().SITE_NAME;
const emailRegex = new RegExp(VALID_EMAIL_REGEX, 'i');
const {
intl, status, submitState, emailValidationError,
status, submitState, emailValidationError,
} = props;
const { formatMessage } = useIntl();
const [email, setEmail] = useState(props.email);
const [bannerEmail, setBannerEmail] = useState('');
const [formErrors, setFormErrors] = useState('');
@@ -58,9 +59,9 @@ const ForgotPasswordPage = (props) => {
let error = '';
if (value === '') {
error = intl.formatMessage(messages['forgot.password.empty.email.field.error']);
error = formatMessage(messages['forgot.password.empty.email.field.error']);
} else if (!emailRegex.test(value)) {
error = intl.formatMessage(messages['forgot.password.page.invalid.email.message']);
error = formatMessage(messages['forgot.password.page.invalid.email.message']);
}
return error;
@@ -89,14 +90,14 @@ const ForgotPasswordPage = (props) => {
const tabTitle = (
<div className="d-inline-flex flex-wrap align-items-center">
<Icon src={ChevronLeft} />
<span className="ml-2">{intl.formatMessage(messages['sign.in.text'])}</span>
<span className="ml-2">{formatMessage(messages['sign.in.text'])}</span>
</div>
);
return (
<BaseComponent>
<Helmet>
<title>{intl.formatMessage(messages['forgot.password.page.title'],
<title>{formatMessage(messages['forgot.password.page.title'],
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
@@ -111,13 +112,13 @@ const ForgotPasswordPage = (props) => {
<Form id="forget-password-form" name="forget-password-form" className="mw-xs">
<ForgotPasswordAlert email={bannerEmail} emailError={formErrors} status={status} />
<h2 className="h4">
{intl.formatMessage(messages['forgot.password.page.heading'])}
{formatMessage(messages['forgot.password.page.heading'])}
</h2>
<p className="mb-4">
{intl.formatMessage(messages['forgot.password.page.instructions'])}
{formatMessage(messages['forgot.password.page.instructions'])}
</p>
<FormGroup
floatingLabel={intl.formatMessage(messages['forgot.password.page.email.field.label'])}
floatingLabel={formatMessage(messages['forgot.password.page.email.field.label'])}
name="email"
value={email}
autoComplete="on"
@@ -125,7 +126,7 @@ const ForgotPasswordPage = (props) => {
handleChange={(e) => setEmail(e.target.value)}
handleBlur={handleBlur}
handleFocus={handleFocus}
helpText={[intl.formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
helpText={[formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
/>
<StatefulButton
id="submit-forget-password"
@@ -135,7 +136,7 @@ const ForgotPasswordPage = (props) => {
className="forgot-password-button-width"
state={submitState}
labels={{
default: intl.formatMessage(messages['forgot.password.page.submit.button']),
default: formatMessage(messages['forgot.password.page.submit.button']),
pending: '',
}}
onClick={handleSubmit}
@@ -150,11 +151,11 @@ const ForgotPasswordPage = (props) => {
target="_blank"
showLaunchIcon={false}
>
{intl.formatMessage(messages['need.help.sign.in.text'])}
{formatMessage(messages['need.help.sign.in.text'])}
</Hyperlink>
)}
<p className="mt-5.5 small text-gray-700">
{intl.formatMessage(messages['additional.help.text'], { platformName })}
{formatMessage(messages['additional.help.text'], { platformName })}
<span>
<Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink>
</span>
@@ -170,7 +171,6 @@ ForgotPasswordPage.propTypes = {
email: PropTypes.string,
emailValidationError: PropTypes.string,
forgotPassword: PropTypes.func.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
setForgotPasswordFormData: PropTypes.func.isRequired,
status: PropTypes.string,
submitState: PropTypes.string,
@@ -189,4 +189,4 @@ export default connect(
forgotPassword,
setForgotPasswordFormData,
},
)(injectIntl(ForgotPasswordPage));
)(ForgotPasswordPage);

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { CheckCircle, Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -10,7 +10,8 @@ import { ACCOUNT_ACTIVATION_MESSAGE } from './data/constants';
import messages from './messages';
const AccountActivationMessage = (props) => {
const { intl, messageType } = props;
const { formatMessage } = useIntl();
const { messageType } = props;
const variant = messageType === ACCOUNT_ACTIVATION_MESSAGE.ERROR ? 'danger' : messageType;
const activationOrVerification = getConfig().MARKETING_EMAILS_OPT_IN ? 'confirmation' : 'activation';
@@ -25,22 +26,22 @@ const AccountActivationMessage = (props) => {
switch (messageType) {
case ACCOUNT_ACTIVATION_MESSAGE.SUCCESS: {
heading = intl.formatMessage(messages[`account.${activationOrVerification}.success.message.title`]);
activationMessage = <span>{intl.formatMessage(messages[`account.${activationOrVerification}.success.message`])}</span>;
heading = formatMessage(messages[`account.${activationOrVerification}.success.message.title`]);
activationMessage = <span>{formatMessage(messages[`account.${activationOrVerification}.success.message`])}</span>;
break;
}
case ACCOUNT_ACTIVATION_MESSAGE.INFO: {
activationMessage = intl.formatMessage(messages[`account.${activationOrVerification}.info.message`]);
activationMessage = formatMessage(messages[`account.${activationOrVerification}.info.message`]);
break;
}
case ACCOUNT_ACTIVATION_MESSAGE.ERROR: {
const supportLink = (
<Alert.Link href={getConfig().ACTIVATION_EMAIL_SUPPORT_LINK}>
{intl.formatMessage(messages['account.activation.support.link'])}
{formatMessage(messages['account.activation.support.link'])}
</Alert.Link>
);
heading = intl.formatMessage(messages[`account.${activationOrVerification}.error.message.title`]);
heading = formatMessage(messages[`account.${activationOrVerification}.error.message.title`]);
activationMessage = (
<FormattedMessage
id="account.activation.error.message"
@@ -70,7 +71,6 @@ const AccountActivationMessage = (props) => {
AccountActivationMessage.propTypes = {
messageType: PropTypes.string.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(AccountActivationMessage);
export default AccountActivationMessage;

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
ActionRow, ModalDialog, useToggle,
} from '@edx/paragon';
@@ -14,7 +14,7 @@ import { updatePathWithQueryParams } from '../data/utils';
import useMobileResponsive from '../data/utils/useMobileResponsive';
import messages from './messages';
const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
const ChangePasswordPrompt = ({ variant, redirectUrl }) => {
const isMobileView = useMobileResponsive();
const [redirectToResetPasswordPage, setRedirectToResetPasswordPage] = useState(false);
const handlers = {
@@ -28,6 +28,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
};
// eslint-disable-next-line no-unused-vars
const [isOpen, open, close] = useToggle(true, handlers);
const { formatMessage } = useIntl();
if (redirectToResetPasswordPage) {
return <Redirect to={updatePathWithQueryParams(RESET_PAGE)} />;
@@ -42,11 +43,11 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
>
<ModalDialog.Header>
<ModalDialog.Title>
{intl.formatMessage(messages[`password.security.${variant}.title`])}
{formatMessage(messages[`password.security.${variant}.title`])}
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
{intl.formatMessage(messages[`password.security.${variant}.body`])}
{formatMessage(messages[`password.security.${variant}.body`])}
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow className={classNames(
@@ -55,7 +56,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
>
{variant === 'nudge' ? (
<ModalDialog.CloseButton id="password-security-close" variant="tertiary">
{intl.formatMessage(messages['password.security.close.button'])}
{formatMessage(messages['password.security.close.button'])}
</ModalDialog.CloseButton>
) : null}
<Link
@@ -66,7 +67,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
)}
to={updatePathWithQueryParams(RESET_PAGE)}
>
{intl.formatMessage(messages['password.security.redirect.to.reset.password.button'])}
{formatMessage(messages['password.security.redirect.to.reset.password.button'])}
</Link>
</ActionRow>
</ModalDialog.Footer>
@@ -80,9 +81,8 @@ ChangePasswordPrompt.defaultProps = {
};
ChangePasswordPrompt.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
variant: PropTypes.oneOf(['nudge', 'block']),
redirectUrl: PropTypes.string,
};
export default injectIntl(ChangePasswordPrompt);
export default ChangePasswordPrompt;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { getAuthService } from '@edx/frontend-platform/auth';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Hyperlink } from '@edx/paragon';
import { Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -24,13 +24,13 @@ import {
import messages from './messages';
const LoginFailureMessage = (props) => {
const { intl } = props;
const { formatMessage } = useIntl();
const { context, errorCode } = props.loginError;
const authService = getAuthService();
let errorList;
let resetLink = (
<Hyperlink destination="reset" isInline>
{intl.formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
{formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
</Hyperlink>
);
@@ -38,19 +38,19 @@ const LoginFailureMessage = (props) => {
case NON_COMPLIANT_PASSWORD_EXCEPTION: {
errorList = (
<>
<strong>{intl.formatMessage(messages['non.compliant.password.title'])}</strong>
<p>{intl.formatMessage(messages['non.compliant.password.message'])}</p>
<strong>{formatMessage(messages['non.compliant.password.title'])}</strong>
<p>{formatMessage(messages['non.compliant.password.message'])}</p>
</>
);
break;
}
case FORBIDDEN_REQUEST:
errorList = <p>{intl.formatMessage(messages['login.rate.limit.reached.message'])}</p>;
errorList = <p>{formatMessage(messages['login.rate.limit.reached.message'])}</p>;
break;
case INACTIVE_USER: {
const supportLink = (
<a href={context.supportLink}>
{intl.formatMessage(messages['contact.support.link'], { platformName: context.platformName })}
{formatMessage(messages['contact.support.link'], { platformName: context.platformName })}
</a>
);
errorList = (
@@ -74,7 +74,7 @@ const LoginFailureMessage = (props) => {
const url = `${getConfig().LMS_BASE_URL}/dashboard/?tpa_hint=${context.tpaHint}`;
const tpaLink = (
<a href={url}>
{intl.formatMessage(messages['tpa.account.link'], { provider: context.provider })}
{formatMessage(messages['tpa.account.link'], { provider: context.provider })}
</a>
);
errorList = (
@@ -90,12 +90,12 @@ const LoginFailureMessage = (props) => {
break;
}
case INVALID_FORM:
errorList = <p>{intl.formatMessage(messages['login.form.invalid.error.message'])}</p>;
errorList = <p>{formatMessage(messages['login.form.invalid.error.message'])}</p>;
break;
case FAILED_LOGIN_ATTEMPT: {
resetLink = (
<Hyperlink destination="reset" isInline>
{intl.formatMessage(messages['login.incorrect.credentials.error.before.account.blocked.text'])}
{formatMessage(messages['login.incorrect.credentials.error.before.account.blocked.text'])}
</Hyperlink>
);
errorList = (
@@ -124,7 +124,7 @@ const LoginFailureMessage = (props) => {
case ACCOUNT_LOCKED_OUT: {
errorList = (
<>
<p>{intl.formatMessage(messages['account.locked.out.message.1'])}</p>
<p>{formatMessage(messages['account.locked.out.message.1'])}</p>
<p>
<FormattedMessage
id="account.locked.out.message.2"
@@ -139,7 +139,7 @@ const LoginFailureMessage = (props) => {
}
case INCORRECT_EMAIL_PASSWORD:
if (context.failureCount <= 1) {
errorList = <p>{intl.formatMessage(messages['login.incorrect.credentials.error'])}</p>;
errorList = <p>{formatMessage(messages['login.incorrect.credentials.error'])}</p>;
} else if (context.failureCount === 2) {
errorList = (
<p>
@@ -167,13 +167,13 @@ const LoginFailureMessage = (props) => {
return <ChangePasswordPrompt />;
case INTERNAL_SERVER_ERROR:
default:
errorList = <p>{intl.formatMessage(messages['internal.server.error.message'])}</p>;
errorList = <p>{formatMessage(messages['internal.server.error.message'])}</p>;
break;
}
return (
<Alert id="login-failure-alert" className="mb-5" variant="danger" icon={Error}>
<Alert.Heading>{intl.formatMessage(messages['login.failure.header.title'])}</Alert.Heading>
<Alert.Heading>{formatMessage(messages['login.failure.header.title'])}</Alert.Heading>
{ errorList }
</Alert>
);
@@ -193,7 +193,6 @@ LoginFailureMessage.propTypes = {
errorCode: PropTypes.string,
redirectUrl: PropTypes.string,
}),
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(LoginFailureMessage);
export default LoginFailureMessage;

View File

@@ -10,7 +10,7 @@ import {
getAuthenticatedUser,
hydrateAuthenticatedUser,
} from '@edx/frontend-platform/auth';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { getLoggingService } from '@edx/frontend-platform/logging';
import {
Alert,
@@ -40,10 +40,12 @@ import ProgressiveProfilingPageModal from './ProgressiveProfilingPageModal';
const ProgressiveProfiling = (props) => {
const {
formRenderState, intl, submitState, showError, location,
formRenderState, submitState, showError, location,
} = props;
const enablePersonalizedRecommendations = getConfig().ENABLE_PERSONALIZED_RECOMMENDATIONS;
const registrationResponse = location.state?.registrationResult;
const { formatMessage } = useIntl();
const [ready, setReady] = useState(false);
const [registrationResult, setRegistrationResult] = useState({ redirectUrl: '' });
const [values, setValues] = useState({});
@@ -160,7 +162,7 @@ const ProgressiveProfiling = (props) => {
<>
<BaseComponent showWelcomeBanner>
<Helmet>
<title>{intl.formatMessage(messages['progressive.profiling.page.title'],
<title>{formatMessage(messages['progressive.profiling.page.title'],
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
@@ -176,13 +178,13 @@ const ProgressiveProfiling = (props) => {
) : null}
<div className="mw-xs pp-page-content">
<div>
<h2 className="pp-page-heading text-primary">{intl.formatMessage(messages['progressive.profiling.page.heading'])}</h2>
<h2 className="pp-page-heading text-primary">{formatMessage(messages['progressive.profiling.page.heading'])}</h2>
</div>
<hr className="border-light-700 mb-4" />
{showError ? (
<Alert id="pp-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.Heading>{formatMessage(messages['welcome.page.error.heading'])}</Alert.Heading>
<p>{formatMessage(messages['welcome.page.error.message'])}</p>
</Alert>
) : null}
<Form>
@@ -197,7 +199,7 @@ const ProgressiveProfiling = (props) => {
showLaunchIcon={false}
onClick={() => (sendTrackEvent('edx.bi.welcome.page.support.link.clicked'))}
>
{intl.formatMessage(messages['optional.fields.information.link'])}
{formatMessage(messages['optional.fields.information.link'])}
</Hyperlink>
</span>
)}
@@ -208,7 +210,7 @@ const ProgressiveProfiling = (props) => {
className="login-button-width"
state={submitState}
labels={{
default: showRecommendationsPage ? intl.formatMessage(messages['optional.fields.next.button']) : intl.formatMessage(messages['optional.fields.submit.button']),
default: showRecommendationsPage ? formatMessage(messages['optional.fields.next.button']) : formatMessage(messages['optional.fields.submit.button']),
pending: '',
}}
onClick={handleSubmit}
@@ -219,7 +221,7 @@ const ProgressiveProfiling = (props) => {
type="submit"
variant="link"
labels={{
default: intl.formatMessage(messages['optional.fields.skip.button']),
default: formatMessage(messages['optional.fields.skip.button']),
}}
onClick={handleSkip}
onMouseDown={(e) => e.preventDefault()}
@@ -234,7 +236,6 @@ const ProgressiveProfiling = (props) => {
ProgressiveProfiling.propTypes = {
formRenderState: PropTypes.string.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
location: PropTypes.shape({
state: PropTypes.object,
}),
@@ -263,4 +264,4 @@ export default connect(
{
saveUserProfile,
},
)(injectIntl(ProgressiveProfiling));
)(ProgressiveProfiling);

View File

@@ -1,14 +1,15 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { ActionRow, Button, ModalDialog } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const ProgressiveProfilingPageModal = (props) => {
const { intl, isOpen, redirectUrl } = props;
const { formatMessage } = useIntl();
const { isOpen, redirectUrl } = props;
const platformName = getConfig().SITE_NAME;
const handleSubmit = (e) => {
@@ -18,7 +19,7 @@ const ProgressiveProfilingPageModal = (props) => {
return (
<ModalDialog
title={intl.formatMessage(messages['modal.title'])}
title={formatMessage(messages['modal.title'])}
isOpen={isOpen}
onClose={() => {}}
size="sm"
@@ -27,18 +28,18 @@ const ProgressiveProfilingPageModal = (props) => {
>
<ModalDialog.Header>
<ModalDialog.Title>
{intl.formatMessage(messages['modal.title'])}
{formatMessage(messages['modal.title'])}
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
{intl.formatMessage(messages['modal.description'])}
{formatMessage(messages['modal.description'])}
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow>
<Button onClick={handleSubmit} variant="primary">
{intl.formatMessage(messages['continue.to.platform'], { platformName })}
{formatMessage(messages['continue.to.platform'], { platformName })}
</Button>
</ActionRow>
</ModalDialog.Footer>
@@ -47,7 +48,6 @@ const ProgressiveProfilingPageModal = (props) => {
};
ProgressiveProfilingPageModal.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
isOpen: PropTypes.bool,
redirectUrl: PropTypes.string.isRequired,
};
@@ -56,4 +56,4 @@ ProgressiveProfilingPageModal.defaultProps = {
isOpen: false,
};
export default injectIntl(ProgressiveProfilingPageModal);
export default ProgressiveProfilingPageModal;

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { Card, Hyperlink } from '@edx/paragon';
import PropTypes from 'prop-types';
@@ -84,4 +83,4 @@ RecommendationCard.defaultProps = {
userId: null,
};
export default injectIntl(RecommendationCard);
export default RecommendationCard;

View File

@@ -1,6 +1,5 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { Container } from '@edx/paragon';
import PropTypes from 'prop-types';
@@ -53,4 +52,4 @@ RecommendationsList.defaultProps = {
userId: null,
};
export default injectIntl(RecommendationsList);
export default RecommendationsList;

View File

@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Hyperlink, Image, Spinner, StatefulButton,
} from '@edx/paragon';
@@ -17,11 +17,12 @@ import RecommendationsList from './RecommendationsList';
import { trackRecommendationsViewed } from './track';
const RecommendationsPage = (props) => {
const { intl, location } = props;
const { location } = props;
const registrationResponse = location.state?.registrationResult;
const userId = location.state?.userId;
const DASHBOARD_URL = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
const { formatMessage } = useIntl();
const [isLoading, setIsLoading] = useState(true);
const [recommendations, setRecommendations] = useState([]);
const [algoliaRecommendations, setAlgoliaRecommendations] = useState([]);
@@ -94,7 +95,7 @@ const RecommendationsPage = (props) => {
return (
<>
<Helmet>
<title>{intl.formatMessage(messages['recommendation.page.title'],
<title>{formatMessage(messages['recommendation.page.title'],
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
@@ -108,7 +109,7 @@ const RecommendationsPage = (props) => {
{(!isLoading && recommendations.length === RECOMMENDATIONS_COUNT) ? (
<div className="d-flex flex-column align-items-center justify-content-center flex-grow-1 p-1">
<RecommendationsList
title={intl.formatMessage(messages['recommendation.page.heading'])}
title={formatMessage(messages['recommendation.page.heading'])}
recommendations={recommendations}
userId={userId}
/>
@@ -118,7 +119,7 @@ const RecommendationsPage = (props) => {
type="submit"
variant="brand"
labels={{
default: intl.formatMessage(messages['recommendation.skip.button']),
default: formatMessage(messages['recommendation.skip.button']),
}}
onClick={handleSkip}
/>
@@ -134,7 +135,6 @@ const RecommendationsPage = (props) => {
};
RecommendationsPage.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
location: PropTypes.shape({
state: PropTypes.object,
}),
@@ -145,4 +145,4 @@ RecommendationsPage.defaultProps = {
location: { state: {} },
};
export default injectIntl(RecommendationsPage);
export default RecommendationsPage;

View File

@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import FormFieldRenderer from '../field-renderer';
@@ -24,13 +24,13 @@ import CountryField from './registrationFields/CountryField';
* it for edX.
* */
const ConfigurableRegistrationForm = (props) => {
const { formatMessage } = useIntl();
const {
countryList,
email,
fieldDescriptions,
fieldErrors,
formFields,
intl,
setFieldErrors,
setFocusedField,
setFormFields,
@@ -72,7 +72,7 @@ const ConfigurableRegistrationForm = (props) => {
let error = '';
if (name === 'country') {
const countryValidation = validateCountryField(
value.trim(), countryList, intl.formatMessage(messages['empty.country.field.error']),
value.trim(), countryList, formatMessage(messages['empty.country.field.error']),
);
const { countryCode, displayValue } = countryValidation;
error = countryValidation.error;
@@ -80,7 +80,7 @@ const ConfigurableRegistrationForm = (props) => {
} else if (!value || !value.trim()) {
error = fieldDescriptions[name].error_message;
} else if (name === 'confirm_email' && value !== email) {
error = intl.formatMessage(messages['email.do.not.match']);
error = formatMessage(messages['email.do.not.match']);
}
setFocusedField(null);
setFieldErrors(prevErrors => ({ ...prevErrors, [name]: error }));
@@ -167,7 +167,7 @@ const ConfigurableRegistrationForm = (props) => {
<FormFieldRenderer
fieldData={{
type: 'checkbox',
label: intl.formatMessage(messages['registration.opt.in.label'], { siteName: getConfig().SITE_NAME }),
label: formatMessage(messages['registration.opt.in.label'], { siteName: getConfig().SITE_NAME }),
name: 'marketingEmailsOptIn',
}}
value={formFields.marketingEmailsOptIn}
@@ -213,7 +213,6 @@ ConfigurableRegistrationForm.propTypes = {
honor_code: PropTypes.bool,
marketingEmailsOptIn: PropTypes.bool,
}).isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
setFieldErrors: PropTypes.func.isRequired,
setFocusedField: PropTypes.func.isRequired,
setFormFields: PropTypes.func.isRequired,
@@ -223,4 +222,4 @@ ConfigurableRegistrationForm.defaultProps = {
fieldDescriptions: {},
};
export default injectIntl(ConfigurableRegistrationForm);
export default ConfigurableRegistrationForm;

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -10,8 +10,9 @@ import { FORBIDDEN_REQUEST, INTERNAL_SERVER_ERROR, TPA_SESSION_EXPIRED } from '.
import messages from './messages';
const RegistrationFailureMessage = (props) => {
const { formatMessage } = useIntl();
const {
context, errorCode, failureCount, intl,
context, errorCode, failureCount,
} = props;
useEffect(() => {
@@ -25,22 +26,22 @@ const RegistrationFailureMessage = (props) => {
let errorMessage;
switch (errorCode) {
case INTERNAL_SERVER_ERROR:
errorMessage = intl.formatMessage(messages['registration.request.server.error']);
errorMessage = formatMessage(messages['registration.request.server.error']);
break;
case FORBIDDEN_REQUEST:
errorMessage = intl.formatMessage(messages['registration.rate.limit.error']);
errorMessage = formatMessage(messages['registration.rate.limit.error']);
break;
case TPA_SESSION_EXPIRED:
errorMessage = intl.formatMessage(messages['registration.tpa.session.expired'], { provider: context.provider });
errorMessage = formatMessage(messages['registration.tpa.session.expired'], { provider: context.provider });
break;
default:
errorMessage = intl.formatMessage(messages['registration.empty.form.submission.error']);
errorMessage = formatMessage(messages['registration.empty.form.submission.error']);
break;
}
return (
<Alert id="validation-errors" className="mb-5" variant="danger" icon={Error}>
<Alert.Heading>{props.intl.formatMessage(messages['registration.request.failure.header'])}</Alert.Heading>
<Alert.Heading>{formatMessage(messages['registration.request.failure.header'])}</Alert.Heading>
<p>{errorMessage}</p>
</Alert>
);
@@ -56,7 +57,6 @@ RegistrationFailureMessage.propTypes = {
}),
errorCode: PropTypes.string.isRequired,
failureCount: PropTypes.number.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(RegistrationFailureMessage);
export default RegistrationFailureMessage;

View File

@@ -6,7 +6,7 @@ import { connect } from 'react-redux';
import { getConfig, snakeCaseObject } from '@edx/frontend-platform';
import { sendPageEvent } from '@edx/frontend-platform/analytics';
import {
getCountryList, getLocale, injectIntl,
getCountryList, getLocale, useIntl,
} from '@edx/frontend-platform/i18n';
import { Form, StatefulButton } from '@edx/paragon';
import PropTypes from 'prop-types';
@@ -56,7 +56,6 @@ const RegistrationPage = (props) => {
backendValidations,
fieldDescriptions,
handleInstitutionLogin,
intl,
institutionLogin,
optionalFields,
registrationError,
@@ -77,6 +76,7 @@ const RegistrationPage = (props) => {
clearBackendError,
} = props;
const { formatMessage } = useIntl();
const countryList = useMemo(() => getCountryList(getLocale()), []);
const queryParams = useMemo(() => getAllPossibleQueryParams(), []);
const tpaHint = useMemo(() => getTpaHint(), []);
@@ -212,24 +212,24 @@ const RegistrationPage = (props) => {
switch (fieldName) {
case 'name':
if (!value.trim()) {
fieldError = intl.formatMessage(messages['empty.name.field.error']);
fieldError = formatMessage(messages['empty.name.field.error']);
} else if (value && value.match(urlRegex)) {
fieldError = intl.formatMessage(messages['name.validation.message']);
fieldError = formatMessage(messages['name.validation.message']);
} else if (value && !payload.username.trim() && shouldValidateFromBackend) {
validateFromBackend(payload);
}
break;
case 'email':
if (!value) {
fieldError = intl.formatMessage(messages['empty.email.field.error']);
fieldError = formatMessage(messages['empty.email.field.error']);
} else if (value.length <= 2) {
fieldError = intl.formatMessage(messages['email.invalid.format.error']);
fieldError = formatMessage(messages['email.invalid.format.error']);
} else {
const [username, domainName] = value.split('@');
// Check if email address is invalid. If we have a suggestion for invalid email
// provide that along with the error message.
if (!emailRegex.test(value)) {
fieldError = intl.formatMessage(messages['email.invalid.format.error']);
fieldError = formatMessage(messages['email.invalid.format.error']);
setEmailSuggestion({
suggestion: getSuggestionForInvalidEmail(domainName, username),
type: 'error',
@@ -237,7 +237,7 @@ const RegistrationPage = (props) => {
} else {
const response = validateEmailAddress(value, username, domainName);
if (response.hasError) {
fieldError = intl.formatMessage(messages['email.invalid.format.error']);
fieldError = formatMessage(messages['email.invalid.format.error']);
delete response.hasError;
} else if (shouldValidateFromBackend) {
validateFromBackend(payload);
@@ -245,23 +245,23 @@ const RegistrationPage = (props) => {
setEmailSuggestion({ ...response });
if (configurableFormFields.confirm_email && value !== configurableFormFields.confirm_email) {
confirmEmailError = intl.formatMessage(messages['email.do.not.match']);
confirmEmailError = formatMessage(messages['email.do.not.match']);
}
}
}
break;
case 'username':
if (!value || value.length <= 1 || value.length > 30) {
fieldError = intl.formatMessage(messages['username.validation.message']);
fieldError = formatMessage(messages['username.validation.message']);
} else if (!value.match(/^[a-zA-Z0-9_-]*$/i)) {
fieldError = intl.formatMessage(messages['username.format.validation.message']);
fieldError = formatMessage(messages['username.format.validation.message']);
} else if (shouldValidateFromBackend) {
validateFromBackend(payload);
}
break;
case 'password':
if (!value || !LETTER_REGEX.test(value) || !NUMBER_REGEX.test(value) || value.length < 8) {
fieldError = intl.formatMessage(messages['password.validation.message']);
fieldError = formatMessage(messages['password.validation.message']);
} else if (shouldValidateFromBackend) {
validateFromBackend(payload);
}
@@ -269,7 +269,7 @@ const RegistrationPage = (props) => {
case 'country':
if (flags.showConfigurableEdxFields || flags.showConfigurableRegistrationFields) {
const { countryCode, displayValue, error } = validateCountryField(
value.displayValue.trim(), countryList, intl.formatMessage(messages['empty.country.field.error']),
value.displayValue.trim(), countryList, formatMessage(messages['empty.country.field.error']),
);
fieldError = error;
countryFieldCode = countryCode;
@@ -281,7 +281,7 @@ const RegistrationPage = (props) => {
if (!value && fieldDescriptions[fieldName].error_message) {
fieldError = fieldDescriptions[fieldName].error_message;
} else if (fieldName === 'confirm_email' && formFields.email && value !== formFields.email) {
fieldError = intl.formatMessage(messages['email.do.not.match']);
fieldError = formatMessage(messages['email.do.not.match']);
}
}
break;
@@ -301,7 +301,7 @@ const RegistrationPage = (props) => {
let isValid = !focusedFieldError;
Object.keys(payload).forEach(key => {
if (!payload[key]) {
fieldErrors[key] = intl.formatMessage(messages[`empty.${key}.field.error`]);
fieldErrors[key] = formatMessage(messages[`empty.${key}.field.error`]);
}
if (fieldErrors[key]) {
isValid = false;
@@ -310,7 +310,7 @@ const RegistrationPage = (props) => {
if (flags.showConfigurableEdxFields) {
if (!configurableFormFields.country.displayValue) {
fieldErrors.country = intl.formatMessage(messages['empty.country.field.error']);
fieldErrors.country = formatMessage(messages['empty.country.field.error']);
}
if (fieldErrors.country) {
isValid = false;
@@ -320,7 +320,7 @@ const RegistrationPage = (props) => {
if (flags.showConfigurableRegistrationFields) {
Object.keys(fieldDescriptions).forEach(key => {
if (key === 'country' && !configurableFormFields.country.displayValue) {
fieldErrors[key] = intl.formatMessage(messages['empty.country.field.error']);
fieldErrors[key] = formatMessage(messages['empty.country.field.error']);
} else if (!configurableFormFields[key]) {
fieldErrors[key] = fieldDescriptions[key].error_message;
}
@@ -463,14 +463,14 @@ const RegistrationPage = (props) => {
return (
<InstitutionLogistration
secondaryProviders={secondaryProviders}
headingTitle={intl.formatMessage(messages['register.institution.login.page.title'])}
headingTitle={formatMessage(messages['register.institution.login.page.title'])}
/>
);
}
return (
<>
<Helmet>
<title>{intl.formatMessage(messages['register.page.title'], { siteName: getConfig().SITE_NAME })}</title>
<title>{formatMessage(messages['register.page.title'], { siteName: getConfig().SITE_NAME })}</title>
</Helmet>
<RedirectLogistration
success={registrationResult.success}
@@ -500,8 +500,8 @@ const RegistrationPage = (props) => {
handleBlur={handleOnBlur}
handleFocus={handleOnFocus}
errorMessage={errors.name}
helpText={[intl.formatMessage(messages['help.text.name'])]}
floatingLabel={intl.formatMessage(messages['registration.fullname.label'])}
helpText={[formatMessage(messages['help.text.name'])]}
floatingLabel={formatMessage(messages['registration.fullname.label'])}
/>
<EmailField
name="email"
@@ -513,8 +513,8 @@ const RegistrationPage = (props) => {
handleOnClose={handleEmailSuggestionClosed}
emailSuggestion={emailSuggestion}
errorMessage={errors.email}
helpText={[intl.formatMessage(messages['help.text.email'])]}
floatingLabel={intl.formatMessage(messages['registration.email.label'])}
helpText={[formatMessage(messages['help.text.email'])]}
floatingLabel={formatMessage(messages['registration.email.label'])}
/>
<UsernameField
name="username"
@@ -527,8 +527,8 @@ const RegistrationPage = (props) => {
handleUsernameSuggestionClose={handleUsernameSuggestionClosed}
usernameSuggestions={usernameSuggestions}
errorMessage={errors.username}
helpText={[intl.formatMessage(messages['help.text.username.1']), intl.formatMessage(messages['help.text.username.2'])]}
floatingLabel={intl.formatMessage(messages['registration.username.label'])}
helpText={[formatMessage(messages['help.text.username.1']), formatMessage(messages['help.text.username.2'])]}
floatingLabel={formatMessage(messages['registration.username.label'])}
/>
{!currentProvider && (
<PasswordField
@@ -538,7 +538,7 @@ const RegistrationPage = (props) => {
handleBlur={handleOnBlur}
handleFocus={handleOnFocus}
errorMessage={errors.password}
floatingLabel={intl.formatMessage(messages['registration.password.label'])}
floatingLabel={formatMessage(messages['registration.password.label'])}
/>
)}
<ConfigurableRegistrationForm
@@ -559,7 +559,7 @@ const RegistrationPage = (props) => {
className="register-stateful-button-width mt-4 mb-4"
state={submitState}
labels={{
default: intl.formatMessage(messages['create.account.for.free.button']),
default: formatMessage(messages['create.account.for.free.button']),
pending: '',
}}
onClick={handleSubmit}
@@ -587,7 +587,7 @@ const RegistrationPage = (props) => {
window.location.href = getConfig().LMS_BASE_URL + provider.registerUrl;
return null;
}
return provider ? <EnterpriseSSO provider={provider} intl={intl} /> : renderForm();
return provider ? <EnterpriseSSO provider={provider} /> : renderForm();
}
return (
renderForm()
@@ -631,7 +631,6 @@ RegistrationPage.propTypes = {
}),
fieldDescriptions: PropTypes.shape({}),
institutionLogin: PropTypes.bool.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
optionalFields: PropTypes.shape({}),
registrationErrorCode: PropTypes.string,
registrationResult: PropTypes.shape({
@@ -717,4 +716,4 @@ export default connect(
setUserPipelineDetailsLoaded: setUserPipelineDataLoaded,
clearBackendError: clearRegistertionBackendError,
},
)(injectIntl(RegistrationPage));
)(RegistrationPage);

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import PropTypes from 'prop-types';
import Skeleton from 'react-loading-skeleton';
@@ -18,8 +18,9 @@ import messages from './messages';
* This component renders the Single sign-on (SSO) buttons for the providers passed.
* */
const ThirdPartyAuth = (props) => {
const { formatMessage } = useIntl();
const {
providers, secondaryProviders, currentProvider, handleInstitutionLogin, thirdPartyAuthApiStatus, intl,
providers, secondaryProviders, currentProvider, handleInstitutionLogin, thirdPartyAuthApiStatus,
} = props;
const isInstitutionAuthActive = !!secondaryProviders.length && !currentProvider;
const isSocialAuthActive = !!providers.length && !currentProvider;
@@ -29,7 +30,7 @@ const ThirdPartyAuth = (props) => {
<>
{((isEnterpriseLoginDisabled && isInstitutionAuthActive) || isSocialAuthActive) && (
<div className="mt-4 mb-3 h4">
{intl.formatMessage(messages['registration.other.options.heading'])}
{formatMessage(messages['registration.other.options.heading'])}
</div>
)}
@@ -40,7 +41,7 @@ const ThirdPartyAuth = (props) => {
{(isEnterpriseLoginDisabled && isInstitutionAuthActive) && (
<RenderInstitutionButton
onSubmitHandler={handleInstitutionLogin}
buttonTitle={intl.formatMessage(messages['register.institution.login.button'])}
buttonTitle={formatMessage(messages['register.institution.login.button'])}
/>
)}
{isSocialAuthActive && (
@@ -64,10 +65,9 @@ ThirdPartyAuth.defaultProps = {
ThirdPartyAuth.propTypes = {
currentProvider: PropTypes.string,
handleInstitutionLogin: PropTypes.func.isRequired,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
providers: PropTypes.arrayOf(PropTypes.any),
secondaryProviders: PropTypes.arrayOf(PropTypes.any),
thirdPartyAuthApiStatus: PropTypes.string,
};
export default injectIntl(ThirdPartyAuth);
export default ThirdPartyAuth;

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Icon, IconButton } from '@edx/paragon';
import { ExpandLess, ExpandMore } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -10,11 +10,10 @@ import { COUNTRY_CODE_KEY, COUNTRY_DISPLAY_KEY } from '../data/constants';
import messages from '../messages';
const CountryField = (props) => {
const {
intl, countryList, selectedCountry,
} = props;
const { countryList, selectedCountry } = props;
const dropdownRef = useRef(null);
const { formatMessage } = useIntl();
const [errorMessage, setErrorMessage] = useState(props.errorMessage);
const [dropDownItems, setDropDownItems] = useState([]);
const [displayValue, setDisplayValue] = useState('');
@@ -160,7 +159,7 @@ const CountryField = (props) => {
name="country"
autoComplete="chrome-off"
className="mb-0"
floatingLabel={intl.formatMessage(messages['registration.country.label'])}
floatingLabel={formatMessage(messages['registration.country.label'])}
trailingElement={trailingIcon}
value={displayValue}
errorMessage={errorMessage}
@@ -178,7 +177,6 @@ const CountryField = (props) => {
CountryField.propTypes = {
countryList: PropTypes.arrayOf(PropTypes.object).isRequired,
errorMessage: PropTypes.string,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
onBlurHandler: PropTypes.func.isRequired,
onChangeHandler: PropTypes.func.isRequired,
onFocusHandler: PropTypes.func.isRequired,
@@ -195,4 +193,4 @@ CountryField.defaultProps = {
},
};
export default injectIntl(CountryField);
export default CountryField;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Icon } from '@edx/paragon';
import { Close, Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -9,8 +9,8 @@ import { FormGroup } from '../../common-components';
import messages from '../messages';
const EmailField = (props) => {
const { formatMessage } = useIntl();
const {
intl,
emailSuggestion,
handleSuggestionClick,
handleOnClose,
@@ -21,7 +21,7 @@ const EmailField = (props) => {
return (
<Alert variant="danger" className="email-error-alert mt-1" icon={Error}>
<span className="alert-text">
{intl.formatMessage(messages['did.you.mean.alert.text'])}{' '}
{formatMessage(messages['did.you.mean.alert.text'])}{' '}
<Alert.Link
href="#"
name="email"
@@ -35,7 +35,7 @@ const EmailField = (props) => {
}
return (
<span id="email-warning" className="small">
{intl.formatMessage(messages['did.you.mean.alert.text'])}:{' '}
{formatMessage(messages['did.you.mean.alert.text'])}:{' '}
<Alert.Link
href="#"
name="email"
@@ -73,10 +73,9 @@ EmailField.propTypes = {
suggestion: PropTypes.string,
type: PropTypes.string,
}),
intl: PropTypes.objectOf(PropTypes.object).isRequired,
value: PropTypes.string.isRequired,
handleOnClose: PropTypes.func.isRequired,
handleSuggestionClick: PropTypes.func.isRequired,
};
export default injectIntl(EmailField);
export default EmailField;

View File

@@ -1,15 +1,16 @@
import React, { useEffect } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Form, Hyperlink } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from '../messages';
const HonorCode = (props) => {
const { formatMessage } = useIntl();
const {
intl, errorMessage, onChangeHandler, fieldType, value,
errorMessage, onChangeHandler, fieldType, value,
} = props;
useEffect(() => {
@@ -30,12 +31,12 @@ const HonorCode = (props) => {
platformName: getConfig().SITE_NAME,
tosAndHonorCode: (
<Hyperlink variant="muted" destination={getConfig().TOS_AND_HONOR_CODE || '#'} target="_blank">
{intl.formatMessage(messages['terms.of.service.and.honor.code'])}
{formatMessage(messages['terms.of.service.and.honor.code'])}
</Hyperlink>
),
privacyPolicy: (
<Hyperlink variant="muted" destination={getConfig().PRIVACY_POLICY || '#'} target="_blank">
{intl.formatMessage(messages['privacy.policy'])}
{formatMessage(messages['privacy.policy'])}
</Hyperlink>
),
}}
@@ -62,7 +63,7 @@ const HonorCode = (props) => {
platformName: getConfig().SITE_NAME,
tosAndHonorCode: (
<Hyperlink variant="muted" destination={getConfig().TOS_AND_HONOR_CODE || '#'} target="_blank">
{intl.formatMessage(messages['honor.code'])}
{formatMessage(messages['honor.code'])}
</Hyperlink>
),
}}
@@ -85,11 +86,10 @@ HonorCode.defaultProps = {
};
HonorCode.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
errorMessage: PropTypes.string,
onChangeHandler: PropTypes.func,
fieldType: PropTypes.string,
value: PropTypes.bool,
};
export default injectIntl(HonorCode);
export default HonorCode;

View File

@@ -1,15 +1,16 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Form, Hyperlink } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from '../messages';
const TermsOfService = (props) => {
const { formatMessage } = useIntl();
const {
intl, errorMessage, onChangeHandler, value,
errorMessage, onChangeHandler, value,
} = props;
return (
@@ -31,7 +32,7 @@ const TermsOfService = (props) => {
platformName: getConfig().SITE_NAME,
termsOfService: (
<Hyperlink variant="muted" destination={getConfig().TOS_LINK || '#'} target="_blank">
{intl.formatMessage(messages['terms.of.service'])}
{formatMessage(messages['terms.of.service'])}
</Hyperlink>
),
}}
@@ -52,10 +53,9 @@ TermsOfService.defaultProps = {
};
TermsOfService.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
errorMessage: PropTypes.string,
onChangeHandler: PropTypes.func.isRequired,
value: PropTypes.bool,
};
export default injectIntl(TermsOfService);
export default TermsOfService;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Icon, IconButton } from '@edx/paragon';
import { Close } from '@edx/paragon/icons';
import PropTypes, { string } from 'prop-types';
@@ -9,15 +9,16 @@ import { FormGroup } from '../../common-components';
import messages from '../messages';
const UsernameField = (props) => {
const { formatMessage } = useIntl();
const {
intl, handleSuggestionClick, handleUsernameSuggestionClose, usernameSuggestions, errorMessage,
handleSuggestionClick, handleUsernameSuggestionClose, usernameSuggestions, errorMessage,
} = props;
let className = '';
let suggestedUsernameDiv = <></>;
let iconButton = <></>;
const suggestedUsernames = () => (
<div className={className}>
<span className="text-gray username-suggestion-label">{intl.formatMessage(messages['registration.username.suggestion.label'])}</span>
<span className="text-gray username-suggestion-label">{formatMessage(messages['registration.username.suggestion.label'])}</span>
<div className="scroll-suggested-username">
{usernameSuggestions.map((username, index) => (
<Button
@@ -65,10 +66,9 @@ UsernameField.propTypes = {
handleSuggestionClick: PropTypes.func.isRequired,
handleUsernameSuggestionClose: PropTypes.func.isRequired,
errorMessage: PropTypes.string,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
autoComplete: PropTypes.string,
};
export default injectIntl(UsernameField);
export default UsernameField;

View File

@@ -1,6 +1,6 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -9,23 +9,24 @@ import { FORM_SUBMISSION_ERROR, PASSWORD_RESET, PASSWORD_VALIDATION_ERROR } from
import messages from './messages';
const ResetPasswordFailure = (props) => {
const { errorCode, errorMsg, intl } = props;
const { formatMessage } = useIntl();
const { errorCode, errorMsg } = props;
let errorMessage = null;
let heading = intl.formatMessage(messages['reset.password.failure.heading']);
let heading = formatMessage(messages['reset.password.failure.heading']);
switch (errorCode) {
case PASSWORD_RESET.FORBIDDEN_REQUEST:
heading = intl.formatMessage(messages['reset.server.rate.limit.error']);
errorMessage = intl.formatMessage(messages['rate.limit.error']);
heading = formatMessage(messages['reset.server.rate.limit.error']);
errorMessage = formatMessage(messages['rate.limit.error']);
break;
case PASSWORD_RESET.INTERNAL_SERVER_ERROR:
errorMessage = intl.formatMessage(messages['internal.server.error']);
errorMessage = formatMessage(messages['internal.server.error']);
break;
case PASSWORD_VALIDATION_ERROR:
errorMessage = errorMsg;
break;
case FORM_SUBMISSION_ERROR:
errorMessage = intl.formatMessage(messages['reset.password.form.submission.error']);
errorMessage = formatMessage(messages['reset.password.form.submission.error']);
break;
default:
break;
@@ -51,7 +52,6 @@ ResetPasswordFailure.defaultProps = {
ResetPasswordFailure.propTypes = {
errorCode: PropTypes.string,
errorMsg: PropTypes.string,
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(ResetPasswordFailure);
export default ResetPasswordFailure;

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { getConfig, getQueryParameters } from '@edx/frontend-platform';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form,
Icon,
@@ -32,7 +32,8 @@ import messages from './messages';
import ResetPasswordFailure from './ResetPasswordFailure';
const ResetPasswordPage = (props) => {
const { intl } = props;
const { formatMessage } = useIntl();
const newPasswordError = formatMessage(messages['password.validation.message']);
const [newPassword, setNewPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
@@ -45,9 +46,9 @@ const ResetPasswordPage = (props) => {
setErrorCode(props.status);
}
if (props.status === PASSWORD_VALIDATION_ERROR) {
setFormErrors({ newPassword: intl.formatMessage(messages['password.validation.message']) });
setFormErrors({ newPassword: newPasswordError });
}
}, [props.status, intl]);
}, [props.status, newPasswordError]);
const validatePasswordFromBackend = async (password) => {
let errorMessage = '';
@@ -67,16 +68,16 @@ const ResetPasswordPage = (props) => {
switch (name) {
case 'newPassword':
if (!value || !LETTER_REGEX.test(value) || !NUMBER_REGEX.test(value) || value.length < 8) {
formErrors.newPassword = intl.formatMessage(messages['password.validation.message']);
formErrors.newPassword = formatMessage(messages['password.validation.message']);
} else {
validatePasswordFromBackend(value);
}
break;
case 'confirmPassword':
if (!value) {
formErrors.confirmPassword = intl.formatMessage(messages['confirm.your.password']);
formErrors.confirmPassword = formatMessage(messages['confirm.your.password']);
} else if (value !== newPassword) {
formErrors.confirmPassword = intl.formatMessage(messages['passwords.do.not.match']);
formErrors.confirmPassword = formatMessage(messages['passwords.do.not.match']);
} else {
formErrors.confirmPassword = '';
}
@@ -139,7 +140,7 @@ const ResetPasswordPage = (props) => {
const tabTitle = (
<div className="d-inline-flex flex-wrap align-items-center">
<Icon src={ChevronLeft} />
<span className="ml-2">{intl.formatMessage(messages['sign.in'])}</span>
<span className="ml-2">{formatMessage(messages['sign.in'])}</span>
</div>
);
@@ -158,7 +159,7 @@ const ResetPasswordPage = (props) => {
<BaseComponent>
<div>
<Helmet>
<title>{intl.formatMessage(messages['reset.password.page.title'],
<title>{formatMessage(messages['reset.password.page.title'],
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
@@ -171,8 +172,8 @@ const ResetPasswordPage = (props) => {
<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>
<h4>{formatMessage(messages['reset.password'])}</h4>
<p className="mb-4">{formatMessage(messages['reset.password.page.instructions'])}</p>
<Form id="set-reset-password-form" name="set-reset-password-form">
<PasswordField
name="newPassword"
@@ -181,7 +182,7 @@ const ResetPasswordPage = (props) => {
handleBlur={handleOnBlur}
handleFocus={handleOnFocus}
errorMessage={formErrors.newPassword}
floatingLabel={intl.formatMessage(messages['new.password.label'])}
floatingLabel={formatMessage(messages['new.password.label'])}
/>
<PasswordField
name="confirmPassword"
@@ -190,7 +191,7 @@ const ResetPasswordPage = (props) => {
handleFocus={handleOnFocus}
errorMessage={formErrors.confirmPassword}
showRequirements={false}
floatingLabel={intl.formatMessage(messages['confirm.password.label'])}
floatingLabel={formatMessage(messages['confirm.password.label'])}
/>
<StatefulButton
id="submit-new-password"
@@ -200,7 +201,7 @@ const ResetPasswordPage = (props) => {
className="stateful-button-width"
state={props.status}
labels={{
default: intl.formatMessage(messages['reset.password']),
default: formatMessage(messages['reset.password']),
pending: '',
}}
onClick={e => handleSubmit(e)}
@@ -224,7 +225,6 @@ ResetPasswordPage.defaultProps = {
};
ResetPasswordPage.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
resetPassword: PropTypes.func.isRequired,
validateToken: PropTypes.func.isRequired,
token: PropTypes.string,
@@ -243,4 +243,4 @@ export default connect(
resetPassword,
validateToken,
},
)(injectIntl(ResetPasswordPage));
)(ResetPasswordPage);

View File

@@ -1,26 +1,21 @@
import React from 'react';
import { injectIntl } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const ResetPasswordSuccess = (props) => {
const { intl } = props;
const ResetPasswordSuccess = () => {
const { formatMessage } = useIntl();
return (
<Alert id="reset-password-success" variant="success" className="mb-4">
<Alert.Heading>
{intl.formatMessage(messages['reset.password.success.heading'])}
{formatMessage(messages['reset.password.success.heading'])}
</Alert.Heading>
<p>{intl.formatMessage(messages['reset.password.success'])}</p>
<p>{formatMessage(messages['reset.password.success'])}</p>
</Alert>
);
};
ResetPasswordSuccess.propTypes = {
intl: PropTypes.objectOf(PropTypes.object).isRequired,
};
export default injectIntl(ResetPasswordSuccess);
export default ResetPasswordSuccess;