diff --git a/package-lock.json b/package-lock.json
index d8e4e95..0062fb4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1009,9 +1009,9 @@
"integrity": "sha512-APBpZvdQrC1MJWMzk33V7FR2RhBRtnH2QPLqZzS+qia7PixwgWNlnX7UfHjhx+YWkM53GdsZKs40EBkSwADuMA=="
},
"@edx/edx-bootstrap": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-2.0.1.tgz",
- "integrity": "sha512-tq9ScRJBkUYw+0ypTshd+9+9Hnow00FkS6Rvh0RfK4xZ+rh8wNAUIVkG3TMclaW5qxvXSIE7Qo7YO7i7JrqV6A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@edx/edx-bootstrap/-/edx-bootstrap-2.1.0.tgz",
+ "integrity": "sha512-9/CkIP1IsldKvOAS/T2OYeBnyuNWwX+u5GVR1kxw1YUCQbFw0W2M/Nz0HbIhG82H4O64uQqfdxnd1QpRJn07LA==",
"requires": {
"bootstrap": "^4.3.1"
}
diff --git a/package.json b/package.json
index 286ad28..e1948a3 100755
--- a/package.json
+++ b/package.json
@@ -25,7 +25,7 @@
},
"dependencies": {
"@cospired/i18n-iso-languages": "^2.0.2",
- "@edx/edx-bootstrap": "^2.0.1",
+ "@edx/edx-bootstrap": "^2.1.0",
"@edx/frontend-analytics": "^1.0.0",
"@edx/frontend-auth": "^5.2.0",
"@edx/frontend-component-footer": "^2.0.3",
diff --git a/src/account-settings/AccountSettingsPage.jsx b/src/account-settings/AccountSettingsPage.jsx
index f0b5cc6..fd0ed70 100644
--- a/src/account-settings/AccountSettingsPage.jsx
+++ b/src/account-settings/AccountSettingsPage.jsx
@@ -68,7 +68,9 @@ class AccountSettingsPage extends React.Component {
-
{this.props.intl.formatMessage(messages['account.settings.section.account.information'])}
+
+
+
{this.props.intl.formatMessage(messages['account.settings.section.account.information'])}
{this.props.intl.formatMessage(messages['account.settings.section.account.information.description'])}
@@ -84,6 +87,7 @@ class AccountSettingsPage extends React.Component {
type="text"
value={this.props.formValues.name}
label={this.props.intl.formatMessage(messages['account.settings.field.full.name'])}
+ helpText={this.props.intl.formatMessage(messages['account.settings.field.full.name.help.text'])}
{...editableFieldProps}
/>
+
-
-
+
+
+
{this.props.intl.formatMessage(messages['account.settings.section.profile.information'])}
+
-
-
{this.props.intl.formatMessage(messages['account.settings.section.social.media'])}
+
+
{this.props.intl.formatMessage(messages['account.settings.section.social.media'])}
{this.props.intl.formatMessage(messages['account.settings.section.social.media.description'])}
+
+
+
+
{this.props.intl.formatMessage(messages['account.settings.section.site.preferences'])}
+
+
+
+
+
{this.props.intl.formatMessage(messages['account.settings.section.linked.accounts'])}
+
{this.props.intl.formatMessage(messages['account.settings.section.linked.accounts.description'])}
+
+
diff --git a/src/account-settings/AccountSettingsPage.messages.jsx b/src/account-settings/AccountSettingsPage.messages.jsx
index e756e67..e951bc2 100644
--- a/src/account-settings/AccountSettingsPage.messages.jsx
+++ b/src/account-settings/AccountSettingsPage.messages.jsx
@@ -26,16 +26,46 @@ const messages = defineMessages({
defaultMessage: 'These settings include basic information about your account.',
description: 'The basic account information section heading description.',
},
+ 'account.settings.section.profile.information': {
+ id: 'account.settings.section.profile.information',
+ defaultMessage: 'Profile Information',
+ description: 'The profile information section heading.',
+ },
+ 'account.settings.section.site.preferences': {
+ id: 'account.settings.section.site.preferences',
+ defaultMessage: 'Site Preferences',
+ description: 'The site preferences section heading.',
+ },
+ 'account.settings.section.linked.accounts': {
+ id: 'account.settings.section.linked.accounts',
+ defaultMessage: 'Linked Accounts',
+ description: 'The linked accounts section heading.',
+ },
+ 'account.settings.section.linked.accounts.description': {
+ id: 'account.settings.section.linked.accounts.description',
+ defaultMessage: 'You can link your identity accounts to simplify signing in to edX.',
+ description: 'The linked accounts section heading description.',
+ },
'account.settings.field.username': {
id: 'account.settings.field.username',
defaultMessage: 'Username',
description: 'Label for account settings username field.',
},
+ 'account.settings.field.username.help.text': {
+ id: 'account.settings.field.username.help.text',
+ defaultMessage: 'The name that identifies you on edX. You cannot change your username.',
+ description: 'Help text for the account settings username field.',
+ },
'account.settings.field.full.name': {
id: 'account.settings.field.full.name',
defaultMessage: 'Full name',
description: 'Label for account settings name field.',
},
+ 'account.settings.field.full.name.help.text': {
+ id: 'account.settings.field.full.name.help.text',
+ defaultMessage: 'The name that is used for ID verification and that appears on your certificates.',
+ description: 'Help text for the account settings name field.',
+ },
'account.settings.field.email': {
id: 'account.settings.field.email',
defaultMessage: 'Email address (Sign in)',
@@ -46,6 +76,11 @@ const messages = defineMessages({
defaultMessage: 'We’ve sent a confirmation message to {value}. Click the link in the message to update your email address.',
description: 'Confirmation message for saving the account settings email field.',
},
+ 'account.settings.field.email.help.text': {
+ id: 'account.settings.field.email.help.text',
+ defaultMessage: 'You receive messages from edX and course teams at this address.',
+ description: 'Help text for the account settings email field.',
+ },
'account.settings.email.field.confirmation.header': {
id: 'account.settings.email.field.confirmation.header',
defaultMessage: 'One more step!',
diff --git a/src/account-settings/actions.js b/src/account-settings/actions.js
index dabd517..4fa8c82 100644
--- a/src/account-settings/actions.js
+++ b/src/account-settings/actions.js
@@ -89,8 +89,9 @@ export const saveSettingsFailure = ({ fieldErrors, message }) => ({
// RESET PASSWORD ACTIONS
-export const resetPassword = () => ({
+export const resetPassword = email => ({
type: RESET_PASSWORD.BASE,
+ payload: { email },
});
export const resetPasswordBegin = () => ({
diff --git a/src/account-settings/components/PasswordReset.jsx b/src/account-settings/components/PasswordReset.jsx
index 75fb511..5606a00 100644
--- a/src/account-settings/components/PasswordReset.jsx
+++ b/src/account-settings/components/PasswordReset.jsx
@@ -54,7 +54,17 @@ function PasswordReset({ email, intl, ...props }) {
{
+ // Swallow clicks if the state is pending.
+ // We do this instead of disabling the button to prevent
+ // it from losing focus (disabled elements cannot have focus).
+ // Disabling it would causes upstream issues in focus management.
+ // Swallowing the onSubmit event on the form would be better, but
+ // we would have to add that logic for every field given our
+ // current structure of the application.
+ if (props.resetPasswordState === 'pending') e.preventDefault();
+ props.resetPassword(email);
+ }}
disabledStates={[]}
labels={{
default: intl.formatMessage(messages['account.settings.editable.field.password.reset.button']),
diff --git a/src/account-settings/components/ThirdPartyAuth.jsx b/src/account-settings/components/ThirdPartyAuth.jsx
index 303b392..42ea7b6 100644
--- a/src/account-settings/components/ThirdPartyAuth.jsx
+++ b/src/account-settings/components/ThirdPartyAuth.jsx
@@ -72,7 +72,7 @@ class ThirdPartyAuth extends React.Component {
);
}
- renderProviders() {
+ render() {
if (this.props.providers === undefined) return null;
if (this.props.providers.length === 0) {
@@ -81,28 +81,6 @@ class ThirdPartyAuth extends React.Component {
return this.props.providers.map(this.renderProvider, this);
}
-
- render() {
- return (
-
-
-
-
-
-
-
- {this.renderProviders()}
-
- );
- }
}
diff --git a/src/account-settings/sagas.js b/src/account-settings/sagas.js
index 812e2a0..ee35bdf 100644
--- a/src/account-settings/sagas.js
+++ b/src/account-settings/sagas.js
@@ -73,10 +73,10 @@ export function* handleSaveSettings(action) {
}
}
-export function* handleResetPassword() {
+export function* handleResetPassword(action) {
try {
yield put(resetPasswordBegin());
- const response = yield call(ApiService.postResetPassword);
+ const response = yield call(ApiService.postResetPassword, action.payload.email);
yield put(resetPasswordSuccess(response));
} catch (e) {
logAPIErrorResponse(e);
diff --git a/src/account-settings/service.js b/src/account-settings/service.js
index 283cb95..5a437e3 100644
--- a/src/account-settings/service.js
+++ b/src/account-settings/service.js
@@ -173,9 +173,9 @@ export async function patchSettings(username, commitValues) {
return combinedResults;
}
-export async function postResetPassword() {
+export async function postResetPassword(email) {
const { data } = await apiClient
- .post(config.PASSWORD_RESET_URL)
+ .post(config.PASSWORD_RESET_URL, { email })
.catch(handleRequestError);
return data;