[Rebrand][WIP] RE-107: /users/edit account settings — page chrome + safe DS swaps (1/N)#73446
Draft
levadadenys wants to merge 14 commits into
Draft
[Rebrand][WIP] RE-107: /users/edit account settings — page chrome + safe DS swaps (1/N)#73446levadadenys wants to merge 14 commits into
levadadenys wants to merge 14 commits into
Conversation
First slice of the /users/edit (account settings) rebrand — low-risk, presentational pieces, steering clear of the auth/compliance-sensitive dialogs and shared primitives (BaseDialog/Notification/SystemDialog), which are later PRs. - New AccountEditHeader (DSCO Link back link + MUI Typography title) mounted in place of the legacy HAML back anchor + h1.text-black. - DeleteAccountHelpers: the two help links -> DSCO Link. - LtiRosterSyncSettings: section heading -> MUI Typography, .btn button -> MUI Button (the toggle was already DSCO). - MigrateToMultiAuth: legacy Notification banner -> DSCO Alert. Tests: new AccountEditHeaderTest + MigrateToMultiAuthTest; DeleteAccountTest still green. Lint + build clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert the Add Password flow end-to-end to the design system, and switch the multi-auth migration notice from Alert to the richer NotificationBanner (per review — title/description/action fits the notice-with-CTA shape better). AddPasswordForm: - SystemDialog Field + raw <input type=password> -> DSCO TextField (inputType=password, label, errorMessage). Old SystemDialog source untouched. - BootstrapButton -> MUI Button; <h2>/hint -> MUI Typography. - inline styles + color.js -> add-password-form.module.scss with semantic tokens (error text -> --text-error-primary). The controller passes password values through the handleSubmit(pw, confirm) callback and submits the hidden Rails form, so input markup is free to change. MigrateToMultiAuth: Alert -> NotificationBanner (variant info, filled), notice as title, details as description, migrate button as an MUI Button action. Tests: AddPasswordFormTest (16) + MigrateToMultiAuthTest green; lint, typecheck, build clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert the Change User Type modal flow (student -> teacher confirmation) to the design system. The HAML trigger (user-type select + button) and the jQuery ChangeUserTypeController are untouched — the controller still mounts this modal via createReactRoot and submits the hidden Rails form. ChangeUserTypeModal: - BaseDialog + SystemDialog Header/ConfirmCancelFooter -> DSCO Modal (title, description, customContent, primary/secondary buttons, customBottom status). Cancel keeps i18n.cancel(); Esc/X close routes through handleClose, which no-ops while saving (preserves the old `uncloseable` behavior). - color.js wrapper -> change-user-type-modal.module.scss. ChangeUserTypeForm: - SystemDialog Field + raw <input>/<select> -> DSCO TextField (email) and SimpleDropdown (opt-in); privacy <a> -> DSCO Link; inline styles -> change-user-type-form.module.scss. Email autofocus + focus-on-error now reach the input via a root-ref querySelector (TextField doesn't forward a ref). Legacy BaseDialog/SystemDialog sources left untouched per review. Tests: ChangeUserTypeModalTest/FormTest/ControllerTest all green (33); lint, typecheck, build clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert the student Add/Update Parent Email modal to the design system. The AddParentEmailController/RemoveParentEmailController and the hidden Rails forms are untouched — the controller still mounts this modal and submits the form. AddParentEmailModal: - BaseDialog + SystemDialog Header/Field/ConfirmCancelFooter -> DSCO Modal (title, subtitle as description, customContent, primary/secondary buttons, customBottom status). Esc/X routes through handleClose, no-op while saving. - two email Fields -> DSCO TextField; opt-in radios -> DSCO RadioButton; privacy <a> -> DSCO Link; opt-in heading -> MUI Typography. - color.js inline styles -> add-parent-email-modal.module.scss with semantic tokens (--borders-neutral-strong, --background-neutral-secondary). - focus-on-error reaches the email input via a content-ref querySelector. Test: query the email fields by anchored-regex name — the DSCO TextField puts its error text inside the field <label> (so it joins the accessible name), and the parent-email label is a prefix of the confirmed-email label. 11 modal + 13 controller tests green; lint, typecheck, build clean. Legacy BaseDialog/SystemDialog sources left untouched per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Finish migrating the Change Email flow. The form (ChangeEmailForm.tsx) was already DSCO (TextField, RadioButtonsGroup, Link); this swaps the modal shell and the last legacy color. ChangeEmailModal: - BaseDialog + manual CloseButton/title/button-row -> DSCO Modal (title, customContent, primary/secondary buttons; Esc/X via handleClose, no-op while saving). Drops the bespoke CloseButton + MUI Typography/Button scaffolding. - unknown-error Alert kept, moved into customContent. - modalStyle.module.scss trimmed to just the Alert spacing. formStyle.module.scss: error text $light_negative_500 -> var(--text-error-primary); drop the legacy `@import 'color'`. Test: the save button's loading indicator now renders via the Modal's own MUI context (MUI CircularProgress) rather than the app theme's FontAwesome spinner, so the saving assertion checks the MUI loading state instead of the fa-spinner class. 55 tests green; typecheck, lint, build clean. Legacy BaseDialog source left untouched per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Convert the core Delete Account flow. The delete request path ($.ajax DELETE /users) and the gate dialogs (PersonalLoginDialog, AdminAccountDialog) are unchanged; those two gate dialogs are migrated in a follow-up. DeleteAccount (page section): - BootstrapButton (danger) -> MUI Button color="error"; <h2> -> MUI Typography; color.js inline styles -> delete-account.module.scss with semantic tokens (--text-error-primary, --borders-error-primary for the danger divider). DeleteAccountDialog: - BaseDialog + SystemDialog Header/Field/ConfirmCancelFooter -> DSCO Modal (title, customContent, primary[error]/secondary buttons, customBottom delete error). Renders null when !isOpen (DSCO Modal has no isOpen prop). - raw checkboxes -> DSCO Checkbox (ReactNode labels); password/verification Field+input -> DSCO TextField; legacy FontAwesome -> FontAwesomeV6Icon; color.js -> delete-account-dialog.module.scss. Tests: DeleteAccountTest (14) green; typecheck, lint, build clean. Legacy BaseDialog/SystemDialog sources left untouched per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Finish the Delete Account flow by migrating the two gate dialogs that precede the delete confirmation. AdminAccountDialog: - BaseDialog + SystemDialog Header/ConfirmCancelFooter -> DSCO Modal (title, customContent warning, primary/secondary buttons). Renders null when !isOpen. - color.js -> admin-account-dialog.module.scss (--text-error-primary). PersonalLoginDialog: - BaseDialog + Header/ConfirmCancelFooter -> DSCO Modal; legacy legacySharedComponents/Button (help link) -> MUI Button (href, new tab); body paragraphs -> MUI Typography; color.js -> personal-login-dialog.module.scss. - GlobalEditionWrapper default export preserved. Tests: DeleteAccountTest (14, exercises both gate dialogs) green; typecheck, lint, build clean. Legacy BaseDialog/SystemDialog sources untouched per review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address the most visible legacy gap on /users/edit: the Manage Linked Accounts table's gray Connect/Disconnect buttons. ManageLinkedAccounts: - BootstrapButton -> MUI Button (Connect: contained primary; Disconnect: outlined secondary), still type=submit inside the native connect/disconnect POST forms. - <h2> -> MUI Typography; color.js (light_gray, red) -> semantic tokens (--text-neutral-secondary, --text-error-primary) in the existing inline styles. - Drops the now-unused color/fontConstants imports. The table layout (shared tableLayoutStyles) and the LTI AccountUnlinkWarningModal (a hidden modal) are unchanged; the unlink modal is a follow-up. Test: ManageLinkedAccountsTest queries the connect/disconnect buttons by button[type="submit"] instead of the BootstrapButton component name (16 green); typecheck, lint, build clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the legacy HAML "Manage Other Sessions" section (orange .btn-warning submit) with a React ExpireOtherSessions component mounted at #expire-other-sessions. - MUI Typography heading/description + MUI Button, submitting a native Rails DELETE form (hidden _method=delete + RailsAuthenticityToken CSRF) to the expire path. Heading/description/button text + action come from the mount point's data-* attributes so localization stays Rails-side (matching AccountEditHeader). - edit.js mounts it; the HAML form_for/.btn-warning is removed. Test: ExpireOtherSessionsTest (renders heading/description/button; form posts DELETE to the expire path). typecheck, lint (incl. haml-lint), build clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ts + sessions Per review, make the Manage Linked Accounts Connect/Disconnect buttons and the Manage Other Sessions button all outlined secondary (was contained primary for Connect / the sessions button). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…teal The Account/School Information section headers were colored var(--brand-teal-50) (a primitive that ignores theming) / var(--text-brand-teal-primary). Per review, section headers should use the regular typography color, so they now use var(--text-neutral-primary) (theming correctly instead of staying teal). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…llback The teacher-managed delete notice was the only remaining legacy HAML in the delete section (.danger hr + h2 + p). Fold it into the React DeleteAccount component: the mount point now always renders, and DeleteAccount shows either the delete UI or, when canDelete is false, the managed-account notice (MUI Typography, danger-tokened header + divider). - HAML: single #delete-account mount with data-can-delete + data-managed-note; the if/else .danger block is removed. - edit.js passes canDelete + managedNote from the mount point. Test: DeleteAccountTest gains a no-permission case (15 green); typecheck, lint (incl. haml-lint), build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…L -> React) Replace the legacy HAML "For Parents and Guardians" section with a React ForParentsAndGuardians component: black section header (MUI Typography + shared sectionHeader, --text-neutral-primary) and body2 Typography text, per review. The Update/Remove links are DSCO Links that keep their original ids (#add-parent-email-link / #remove-parent-email-link) and the displayed email keeps #displayed-parent-email, so the existing AddParentEmailController / RemoveParentEmailController attach unchanged. The component is mounted before those controllers are constructed; the hidden Rails forms are untouched. Text is passed via data-* so localization stays Rails-side. Test: ForParentsAndGuardiansTest (heading/intro/email/note + Update link id; Remove link only when a parent email exists). typecheck, lint (incl. haml-lint), build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the legacy HAML change-user-type trigger (native <select> + gray .btn, driven by ChangeUserTypeController's jQuery DOM wiring) with a React ChangeUserTypeSection: black section header (MUI Typography), DSCO SimpleDropdown, and an outlined-secondary MUI confirm button. The auth submission is unchanged: ChangeUserTypeController keeps submitUserTypeChange / handleSuccess / the email-confirmation modal. Its constructor no longer wires the DOM; a new handleConfirm(selectedType) sets the hidden user_type field and either opens the modal (-> teacher) or submits directly (-> student). edit.js renders the section with onConfirm=handleConfirm. - HAML: the form keeps its hidden fields (+ a new hidden user_type); the visible select/button/heading become a #change-user-type mount point. - Section shows saving/error state around the direct-submit promise. Tests: new ChangeUserTypeSectionTest (5) covers the UI (disabled-until-changed, onConfirm, saving/error); ChangeUserTypeControllerTest rewritten to cover handleConfirm + submitUserTypeChange + modal show/hide (was DOM-coupled). ChangeUserTypeModalTest still green. typecheck, lint (incl. haml-lint), build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the account-settings page (
/users/edit,devise/registrations/edit)to the design system, incrementally. Each flow keeps its server/CSRF wiring
intact and only swaps the UI to DSCO/MUI. Legacy
BaseDialog/SystemDialogsources are not edited — each dialog uses the component-library
Modalatits call site instead.
Page chrome + safe swaps
AccountEditHeader(back link + title) → DSCOLink+ MUITypography.DeleteAccountHelperslinks → DSCOLink.LtiRosterSyncSettings→ MUITypography+Button.MigrateToMultiAuth→ DSCONotificationBanner.Full flows
TextField, MUIButton/Typography.Modal+TextField+SimpleDropdown+Link. (The HAML trigger — the user-type select + "UpdateAccount Type" button — is still legacy; see below.)
Modal+TextField+RadioButton+Link.BaseDialogshell → DSCOModal.Button),DeleteAccountDialog(DSCOModal/Checkbox/TextField/FontAwesomeV6Icon), gate dialogsAdminAccountDialog+PersonalLoginDialog→ DSCOModal.Always-visible elements
BootstrapButtons → MUIButton(Connect contained-primary / Disconnect outlined-secondary); colors → tokens.
.btn-warningsection → ReactExpireOtherSessions(MUI button submitting a native Rails DELETE form + CSRF).Recent visible fixes
--text-neutral-primary), not teal.DeleteAccount(MUITypography), removing the last.dangerHAML there.Now migrated (this round)
body2 text; Update/Remove are DSCO Links keeping their ids so the existing
controllers attach unchanged.
ChangeUserTypeSection: black header, DSCOSimpleDropdown, outlined-secondary confirm button.ChangeUserTypeControllerkeeps
submitUserTypeChange/modal (auth path unchanged); a newhandleConfirmdrives submit-vs-modal.
--text-neutral-primary),not teal; the Delete Account header stays the danger red
(
--text-error-primary).Out of scope
The green success flash banner ("Successfully logged out…") is rendered by
the global
layouts/application.html.haml(site-wide), so it's not part of thispage — worth a separate ticket for DS flash banners.
Links
Testing story
migrate, change-user-type, add-parent-email, change-email, delete-account,
manage-linked-accounts, expire-other-sessions.
pre-commit(incl. haml-lint),yarn typecheck,yarn buildall clean.AddParentEmailModalTestmatches email fields by anchored-regexname (DSCO
TextFieldputs error text in the field<label>; parent-emaillabel is a prefix of confirmed-email label);
ChangeEmailModalTestasserts thesave button's MUI loading state, not a specific spinner;
ManageLinkedAccountsTestqueries connect/disconnect buttons by
button[type="submit"]. Coverage unchanged.?brand=codeai-next(pink audit). The staticpage now shows DSCO for the header, account info, linked-accounts buttons, and
the sessions button; the modals are exercised on click. Remaining legacy bits
are the HAML items listed above.