Skip to content

fix: migrate payment profiles to MUI components#925

Open
tomrndom wants to merge 2 commits into
masterfrom
fix/payment-profile-mui
Open

fix: migrate payment profiles to MUI components#925
tomrndom wants to merge 2 commits into
masterfrom
fix/payment-profile-mui

Conversation

@tomrndom
Copy link
Copy Markdown

@tomrndom tomrndom commented May 8, 2026

ref: https://app.clickup.com/t/86b9tgt19

image image image image

Signed-off-by: Tomás Castillo tcastilloboireau@gmail.com

Summary by CodeRabbit

  • New Features

    • Payment profile list page and a modal dialog to create/edit profiles and manage fee types.
    • Search, sorting and full pagination support in the payment profiles list.
  • Improvements

    • Unified snackbar-based success/error notifications for payment operations.
    • Updated payment-related UI text and localization strings.
  • Removed

    • Legacy standalone pages/routes for editing and listing payment profiles/fee types replaced by the new UI.

Review Change Stack

Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 8, 2026

📝 Walkthrough

Walkthrough

Consolidates payment profile and fee-type management into a single list page with a modal dialog, adds search/pagination state to Redux, standardizes snackbar-based API notifications, simplifies routing, and replaces several route-based pages with a unified UI component.

Changes

Payment Profile Dialog-Based Management

Layer / File(s) Summary
State & Pagination Tracking
src/reducers/payment_profiles/payment-profile-list-reducer.js
Reducer now tracks term, currentPage, lastPage, and perPage; RECEIVE_PAYMENT_PROFILES reads pagination metadata from API responses.
API Actions & Error Handling
src/actions/ticket-actions.js
Imports snackbarErrorHandler/snackbarSuccessHandler; getPaymentProfiles adds term search param; payment profile/fee-type actions switch to snackbar handlers; savePaymentFeeType shows success for both create/update and uses .finally().
Layout & Routing Simplification
src/layouts/payment-profile-layout.js
Layout exposes only the list-page route and a fallback NoMatchPage; removed separate edit/create routes for profiles and fee types.
Unified Payment Profile Dialog
src/pages/tickets/payment-profile/components/payment-profile-dialog.js
Adds MUI Dialog with two Formik forms (profile and fee-type), Yup validation, conditional fee-type UI for existing Stripe SponsorServices profiles, and handlers for save/edit/delete fee types.
Consolidated List Page
src/pages/tickets/payment-profile/payment-profile-list-page.js
New connected page combining listing, search, pagination, sort, and CRUD; opens PaymentProfileDialog for edit/create and reloads list/fee-types after changes.
Removed Legacy Pages
src/pages/tickets/edit-payment-profile-page.js, src/pages/tickets/edit-payment-fee-type-page.js, src/pages/tickets/payment-profile-list-page.js (old)
Removed route-based edit/list pages; functionality migrated to the consolidated list + dialog.
Localization Strings
src/i18n/en.json
Updated deletion confirmation to reference profile name, added placeholders.search_profiles, and added payment_type_fees labels including save_fee_type.

Sequence Diagram

sequenceDiagram
  participant User
  participant ListPage
  participant Dialog
  participant Redux
  participant API
  participant Snack as Snackbar
  User->>ListPage: search / paginate / open edit
  ListPage->>Redux: dispatch getPaymentProfiles / getPaymentProfile / getPaymentFeeTypes
  Redux->>API: http requests
  API-->>Redux: responses (with pagination)
  Redux->>ListPage: update state
  ListPage->>Dialog: open with entity & feeTypes
  Dialog->>Redux: dispatch savePaymentProfile / savePaymentFeeType
  Redux->>API: save request
  API-->>Redux: success / error
  Redux->>Snack: snackbarSuccessHandler / snackbarErrorHandler
  Snack->>User: show notification
  Redux->>ListPage: refresh list
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Suggested reviewers

  • smarcet
  • santipalenque

Poem

A rabbit hops through code today,
One dialog holds profiles in play,
Pages folded into a list so neat,
Snackbars chirp when saves complete,
Fee types dance in modal light—hooray! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: migrating payment profiles UI components to Material-UI, which is reflected in the removal of old page files and addition of new MUI-based components (PaymentProfileDialog, PaymentProfileListPage).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/payment-profile-mui

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/reducers/payment_profiles/payment-profile-list-reducer.js (1)

43-45: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Persist the requested term and perPage in list state.

Right now only order/orderDir are stored here. After a search or rows-per-page change, Redux still holds the previous term/perPage, so subsequent paging/sorting re-queries with stale values and drops the active filter/page size.

Suggested fix
     case REQUEST_PAYMENT_PROFILES: {
-      const { order, orderDir } = payload;
-      return { ...state, order, orderDir };
+      const { term, page, perPage, order, orderDir } = payload;
+      return {
+        ...state,
+        term,
+        currentPage: page,
+        perPage,
+        order,
+        orderDir
+      };
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/reducers/payment_profiles/payment-profile-list-reducer.js` around lines
43 - 45, The REQUEST_PAYMENT_PROFILES case in payment-profile-list-reducer.js
currently only persists order and orderDir; update it to also read term and
perPage from the action payload and include them in the returned state (i.e.,
return { ...state, order, orderDir, term, perPage }) so searches and
rows-per-page changes are stored on the list state; modify the
REQUEST_PAYMENT_PROFILES branch where order/orderDir are extracted to also
extract term and perPage from payload and add them to the new state object.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/pages/tickets/payment-profile/components/payment-profile-dialog.js`:
- Around line 315-354: The live_secret_key and test_secret_key fields are
rendered as plain text; change their MuiFormikTextField usage to mask values by
setting type="password" (for example add type="password" prop on the
MuiFormikTextField for name="live_secret_key" and name="test_secret_key") and
add a toggleable visibility affordance using an endAdornment
(IconButton/visibility icons) so admins can reveal values when needed; keep
existing props (required/fullWidth/variant) and ensure the visibility toggle
updates the input type and includes accessible labels.
- Around line 213-220: Remove the three focus-disabling props from the Dialog
(disableEnforceFocus, disableAutoFocus, disableRestoreFocus) so the modal
regains its focus trap and keyboard/screen-reader navigation; keep the Dialog
open/onClose handling (Dialog, handleClose) as-is. If a specific input or
control inside the dialog is causing focus issues, revert the global changes and
apply a targeted workaround to that control only (for example, render
problematic popovers/menus in a portal, use the control's built-in
disableAutoFocus or disableEnforceFocus flags, or adjust its focus handling)
rather than disabling focus management on the entire Dialog.

In `@src/pages/tickets/payment-profile/payment-profile-list-page.js`:
- Around line 100-104: The inline fee-type save handler handleSaveFeeType should
refresh the fee list but must not close the parent PaymentProfileDialog; remove
the setPaymentProfilePopup(false) call from handleSaveFeeType and keep calling
getPaymentFeeTypes(currentPaymentProfile.id) after savePaymentFeeType(entity)
resolves so the dialog stays open and shows refreshed data, and ensure you do
not trigger any additional unmount/reset logic that conflicts with
PaymentProfileDialog’s own then path.

---

Outside diff comments:
In `@src/reducers/payment_profiles/payment-profile-list-reducer.js`:
- Around line 43-45: The REQUEST_PAYMENT_PROFILES case in
payment-profile-list-reducer.js currently only persists order and orderDir;
update it to also read term and perPage from the action payload and include them
in the returned state (i.e., return { ...state, order, orderDir, term, perPage
}) so searches and rows-per-page changes are stored on the list state; modify
the REQUEST_PAYMENT_PROFILES branch where order/orderDir are extracted to also
extract term and perPage from payload and add them to the new state object.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2529cc2e-39a0-40a8-a92f-524919ed0f65

📥 Commits

Reviewing files that changed from the base of the PR and between bda55af and 1aad0b6.

📒 Files selected for processing (9)
  • src/actions/ticket-actions.js
  • src/i18n/en.json
  • src/layouts/payment-profile-layout.js
  • src/pages/tickets/edit-payment-fee-type-page.js
  • src/pages/tickets/edit-payment-profile-page.js
  • src/pages/tickets/payment-profile-list-page.js
  • src/pages/tickets/payment-profile/components/payment-profile-dialog.js
  • src/pages/tickets/payment-profile/payment-profile-list-page.js
  • src/reducers/payment_profiles/payment-profile-list-reducer.js
💤 Files with no reviewable changes (3)
  • src/pages/tickets/edit-payment-fee-type-page.js
  • src/pages/tickets/edit-payment-profile-page.js
  • src/pages/tickets/payment-profile-list-page.js

Comment on lines +100 to +104
const handleSaveFeeType = (entity) =>
savePaymentFeeType(entity).then(() => {
getPaymentFeeTypes(currentPaymentProfile.id);
setPaymentProfilePopup(false);
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep the payment-profile dialog open after saving a fee type.

This closes the entire parent dialog after an inline fee-type save, so users cannot review the refreshed fee list or continue editing the payment profile. It also leaves PaymentProfileDialog’s own then path resetting fee-type state after the parent has already unmounted it.

Suggested fix
   const handleSaveFeeType = (entity) =>
     savePaymentFeeType(entity).then(() => {
-      getPaymentFeeTypes(currentPaymentProfile.id);
-      setPaymentProfilePopup(false);
+      return getPaymentFeeTypes(currentPaymentProfile.id);
     });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleSaveFeeType = (entity) =>
savePaymentFeeType(entity).then(() => {
getPaymentFeeTypes(currentPaymentProfile.id);
setPaymentProfilePopup(false);
});
const handleSaveFeeType = (entity) =>
savePaymentFeeType(entity).then(() => {
return getPaymentFeeTypes(currentPaymentProfile.id);
});
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/tickets/payment-profile/payment-profile-list-page.js` around lines
100 - 104, The inline fee-type save handler handleSaveFeeType should refresh the
fee list but must not close the parent PaymentProfileDialog; remove the
setPaymentProfilePopup(false) call from handleSaveFeeType and keep calling
getPaymentFeeTypes(currentPaymentProfile.id) after savePaymentFeeType(entity)
resolves so the dialog stays open and shows refreshed data, and ensure you do
not trigger any additional unmount/reset logic that conflicts with
PaymentProfileDialog’s own then path.

@tomrndom tomrndom requested a review from smarcet May 11, 2026 15:53
Signed-off-by: Tomás Castillo <tcastilloboireau@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/pages/tickets/payment-profile/components/payment-profile-dialog.js (1)

588-600: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix PropTypes mismatch: paymentFeeTypes is an object, not an array.

The paymentFeeTypes prop is passed as an object from currentPaymentFeeListTypeState (defined in src/reducers/payment_profiles/payment-fee-types-list-reducer.js) with properties order, orderDir, totalPaymentFeeTypes, and paymentFeeTypes. It is currently typed as PropTypes.array, which fails to validate the actual object structure. Additionally, no default value is provided, risking undefined property access.

Suggested fix
 PaymentProfileDialog.propTypes = {
   onClose: PropTypes.func.isRequired,
   onSave: PropTypes.func.isRequired,
   entity: PropTypes.object,
-  paymentFeeTypes: PropTypes.array,
+  paymentFeeTypes: PropTypes.shape({
+    order: PropTypes.string,
+    orderDir: PropTypes.number,
+    totalPaymentFeeTypes: PropTypes.number,
+    paymentFeeTypes: PropTypes.arrayOf(PropTypes.object)
+  }),
   isSaving: PropTypes.bool,
   onSaveFeeType: PropTypes.func.isRequired,
   onDeleteFeeType: PropTypes.func.isRequired
 };
 
 PaymentProfileDialog.defaultProps = {
-  entity: {}
+  entity: {},
+  paymentFeeTypes: {
+    order: "id",
+    orderDir: 1,
+    totalPaymentFeeTypes: 0,
+    paymentFeeTypes: []
+  }
 };
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/pages/tickets/payment-profile/components/payment-profile-dialog.js`
around lines 588 - 600, PaymentProfileDialog's propTypes incorrectly declare
paymentFeeTypes as PropTypes.array while the component receives an object (from
currentPaymentFeeListTypeState) with keys order, orderDir, totalPaymentFeeTypes,
and paymentFeeTypes; update PaymentProfileDialog.propTypes to use
PropTypes.shape({ order: PropTypes.number, orderDir: PropTypes.string,
totalPaymentFeeTypes: PropTypes.number, paymentFeeTypes: PropTypes.array })
(mark fields required as appropriate) and add a matching default in
PaymentProfileDialog.defaultProps (e.g., an empty shape with sensible defaults)
to avoid undefined access.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/pages/tickets/payment-profile/components/payment-profile-dialog.js`:
- Around line 588-600: PaymentProfileDialog's propTypes incorrectly declare
paymentFeeTypes as PropTypes.array while the component receives an object (from
currentPaymentFeeListTypeState) with keys order, orderDir, totalPaymentFeeTypes,
and paymentFeeTypes; update PaymentProfileDialog.propTypes to use
PropTypes.shape({ order: PropTypes.number, orderDir: PropTypes.string,
totalPaymentFeeTypes: PropTypes.number, paymentFeeTypes: PropTypes.array })
(mark fields required as appropriate) and add a matching default in
PaymentProfileDialog.defaultProps (e.g., an empty shape with sensible defaults)
to avoid undefined access.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2536394-67a8-4c22-af80-ae594c1a9dae

📥 Commits

Reviewing files that changed from the base of the PR and between 1aad0b6 and cadb9f9.

📒 Files selected for processing (2)
  • src/pages/tickets/payment-profile/components/payment-profile-dialog.js
  • src/pages/tickets/payment-profile/payment-profile-list-page.js

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant