From 1de53e433f6690f6c611f27fba34d46faf327342 Mon Sep 17 00:00:00 2001
From: Brian Smith
Date: Wed, 29 Oct 2025 16:09:10 -0400
Subject: [PATCH 1/3] feat: put account settings into cards
---
src/account-settings/EditableField.jsx | 169 +++++++++---------
src/account-settings/EditableSelectField.jsx | 163 +++++++++--------
src/account-settings/EmailField.jsx | 168 +++++++++--------
.../reset-password/ResetPassword.jsx | 80 +++++----
4 files changed, 311 insertions(+), 269 deletions(-)
diff --git a/src/account-settings/EditableField.jsx b/src/account-settings/EditableField.jsx
index 725f7ad2a..fa1bf32fa 100644
--- a/src/account-settings/EditableField.jsx
+++ b/src/account-settings/EditableField.jsx
@@ -3,10 +3,9 @@ import { connect } from 'react-redux';
import classNames from 'classnames';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
- Button, Form, StatefulButton,
+ ActionRow, Button, Card, Form, StatefulButton,
} from '@openedx/paragon';
-import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { EditOutline } from '@openedx/paragon/icons';
import SwitchContent from './SwitchContent';
import messages from './AccountSettingsPage.messages';
@@ -94,83 +93,93 @@ const EditableField = (props) => {
};
return (
-
-
- {label}
-
- {!!helpText && {helpText}}
- {error != null && {error}}
- {others.children}
-
-
- {
- // 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 (saveState === 'pending') { e.preventDefault(); }
- }}
- disabledStates={[]}
- data-testid="editable-field-save"
- />
-
-
+ {
+ // 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 (saveState === 'pending') { e.preventDefault(); }
+ }}
+ disabledStates={[]}
+ data-testid="editable-field-save"
+ />
+
+
- {
- // 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 (saveState === 'pending') { e.preventDefault(); }
- }}
- disabledStates={[]}
- />
-
-
+ {
+ // 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 (saveState === 'pending') { e.preventDefault(); }
+ }}
+ disabledStates={[]}
+ />
+
+
- {
- // 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 (saveState === 'pending') { e.preventDefault(); }
- }}
- disabledStates={[]}
- />
-
-
+ {
+ // 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 (saveState === 'pending') { e.preventDefault(); }
+ }}
+ disabledStates={[]}
+ />
+
+
- {
- // 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 (status === 'pending') {
- e.preventDefault();
- }
- props.resetPassword(email);
- }}
- disabledStates={[]}
- labels={{
- default: intl.formatMessage(messages['account.settings.editable.field.password.reset.button']),
- }}
- />
-
+ {
+ // 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 (status === 'pending') {
+ e.preventDefault();
+ }
+ props.resetPassword(email);
+ }}
+ disabledStates={[]}
+ labels={{
+ default: intl.formatMessage(messages['account.settings.editable.field.password.reset.button']),
+ }}
+ />
+
`;
exports[`EditableSelectField renders EditableSelectField with an error 1`] = `
-
- Main Label
-
-
+
+
+ Test Field
+
+
+
+
-
- Edit
-
+
+
+
-
- Test Field
-
-
- Default Confirmation Message
-
+
+
+ Default Confirmation Message
+
+
+
@@ -277,68 +349,97 @@ exports[`EditableSelectField renders EditableSelectField with an error 1`] = `
exports[`EditableSelectField renders selectOptions when option does not have a group 1`] = `
-
- Main Label
-
-
+
+
+ Test Field
+
+
+
+
-
- Edit
-
+
+
+
-
- Test Field
-
-
- Default Confirmation Message
-
+
+
+ Default Confirmation Message
+
+
+
@@ -346,68 +447,97 @@ exports[`EditableSelectField renders selectOptions when option does not have a g
exports[`EditableSelectField renders selectOptions when option has a group 1`] = `
-
- Main Label
-
-
+
+
+ Test Field
+
+
+
+
-
- Edit
-
+
+
+
-
- Test Field
-
-
- Default Confirmation Message
-
+
+
+ Default Confirmation Message
+
+
+
@@ -415,68 +545,97 @@ exports[`EditableSelectField renders selectOptions when option has a group 1`] =
exports[`EditableSelectField renders selectOptions with multiple groups 1`] = `
- {
- // 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 (status === 'pending') {
- e.preventDefault();
- }
- props.resetPassword(email);
- }}
- disabledStates={[]}
- labels={{
- default: intl.formatMessage(messages['account.settings.editable.field.password.reset.button']),
- }}
- />
-
+ {
+ // 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 (status === 'pending') {
+ e.preventDefault();
+ }
+ props.resetPassword(email);
+ }}
+ disabledStates={[]}
+ labels={{
+ default: intl.formatMessage(messages['account.settings.editable.field.password.reset.button']),
+ }}
+ />
{status && (