Skip to content

Payment settings design changes#1821

Open
Rubaiyat-E-Mohammad wants to merge 6 commits into
weDevsOfficial:developfrom
Rubaiyat-E-Mohammad:fix/pro-badge-settings-payment-page
Open

Payment settings design changes#1821
Rubaiyat-E-Mohammad wants to merge 6 commits into
weDevsOfficial:developfrom
Rubaiyat-E-Mohammad:fix/pro-badge-settings-payment-page

Conversation

@Rubaiyat-E-Mohammad
Copy link
Copy Markdown
Contributor

@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad commented Feb 25, 2026

fix pro badge

Summary by CodeRabbit

  • New Features

    • Replaces checkbox grid with focusable gateway cards that open per-gateway panels; cards support click and keyboard activation and default to the Bank gateway when available.
    • Per-gateway "Enable Gateway" toggle that syncs with gateway state and controls panel row visibility.
  • Style

    • New admin styles: branded gateway icons, card focus/active styling, and a custom toggle switch; updated accent color.
  • Chores

    • Settings page loads the new gateway stylesheet and provides localized toggle labels.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 25, 2026

Warning

Rate limit exceeded

@Rubaiyat-E-Mohammad has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 4 minutes and 26 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 288854b3-9fc2-496b-8c0f-e2b052668b5b

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0280b and 51e9faa.

📒 Files selected for processing (1)
  • assets/css/admin/settings.css

Walkthrough

Replaces checkbox-driven gateway selector with a card-focused UI and per-gateway injected “Enable Gateway” toggle rows. Adds admin JS helpers, new settings stylesheet, updates assets registration and enqueue, changes gateway data ordering/filters, and tweaks accent/pro-related CSS across stylesheets and LESS.

Changes

Cohort / File(s) Summary
Gateway UI JS
assets/js/admin/settings.js
Reworks gateway settings UI: card-based activation with activateCard, per-gateway injected "Enable Gateway" toggle rows that sync to underlying checkboxes, data-gateway-id tagging via regex map, showGateway(gatewayId) visibility logic, keyboard support, and shared i18n/escape helpers.
Gateway settings CSS
assets/css/admin/settings.css
New stylesheet for gateway cards and custom toggle: sizing, focus-visible styles, switch component, and inline brand SVGs based on data-gateway attribute.
Assets registration & enqueue
includes/Assets.php, includes/Admin/Menu.php
Registers a new settings style handle and enqueues wpuf-settings CSS on the Settings page; localizes gateway i18n string for JS.
Gateway selector render
Lib/WeDevs_Settings_API.php, wpuf-functions.php
Rewrites gateway selector markup to focusable card semantics (ARIA, role, tabindex), removes per-card toggle markup and pro-preview icon path, sanitizes labels; wpuf_get_gateways() filters out pro-preview gateways for selector context and reorders via wpuf_gateway_selector_order.
Global styles adjustments
assets/css/admin.css, assets/less/admin.less
Updates accent color (#10b981#059669), removes pro-locked/toggle-related gateway-card styles and some commented icon rules, aligning with new card/toggle approach.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • sapayth

Poem

🐇 I nudged the cards and clicked the night away,
Toggles hum softly where checkboxes once lay.
Bank, Stripe, PayPal — tiles lined up in a row,
A rabbit's tiny tap makes focused panels glow. 🎋

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "Payment settings design changes" is directly related to the main objective of the PR, which involves a comprehensive redesign of the payment gateway settings UI. The changeset includes reworked gateway selection logic, new CSS styling, updated card-focused panel rendering, and gateway toggle UI changes—all core design improvements to the payment settings interface.
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 unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 4 minutes and 26 seconds.

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: 2

🧹 Nitpick comments (2)
assets/js/admin/settings.js (2)

2-8: Add a defensive early return before binding page-specific handlers.

If .wpuf-settings-wrap, #wpuf-settings-search, or #wpuf-search-section span is missing, the script will throw and stop executing.

Suggested patch
-        var tabs = document.querySelector('.wpuf-settings-wrap').querySelectorAll('h2 a');
-        var content = document.querySelectorAll('.wpuf-settings-wrap .metabox-holder th');
-        var close = document.querySelector('#wpuf-search-section span');
-
-        var search_input = document.querySelector('#wpuf-settings-search');
+        var settingsWrap = document.querySelector('.wpuf-settings-wrap');
+        var close = document.querySelector('#wpuf-search-section span');
+        var search_input = document.querySelector('#wpuf-settings-search');
+        if (!settingsWrap || !close || !search_input) {
+            return;
+        }
+        var tabs = settingsWrap.querySelectorAll('h2 a');
+        var content = settingsWrap.querySelectorAll('.metabox-holder th');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 2 - 8, Add a defensive early return
at the start of the DOMContentLoaded handler to avoid throwing when
page-specific elements are missing: check that
document.querySelector('.wpuf-settings-wrap') exists and that
document.querySelector('#wpuf-settings-search') and
document.querySelector('#wpuf-search-section span') are non-null before
proceeding to compute tabs, content, close, and search_input; if any are
missing, simply return from the function. This change should be applied around
the document.addEventListener('DOMContentLoaded', ...) handler that defines
tabs, content, close, and search_input to prevent errors when those selectors
are absent.

351-355: Scope accordion toggle selectors to the payment table only.

Using document-wide selectors here can accidentally toggle rows/buttons outside this section if class names are reused.

Suggested patch
-                        document.querySelectorAll('.wpuf-accordion-trigger').forEach(function (btn) {
+                        paymentTab.querySelectorAll('.wpuf-accordion-trigger').forEach(function (btn) {
                             btn.classList.remove('active');
                             var g = btn.getAttribute('data-target-group');
-                            document.querySelectorAll('tr[data-group="' + g + '"]').forEach(function (tr) {
+                            theTbody.querySelectorAll('tr[data-group="' + g + '"]').forEach(function (tr) {
                                 tr.classList.remove('active');
                             });
                         });
@@
-                            document.querySelectorAll('tr[data-group="' + key + '"]').forEach(function (tr) {
+                            theTbody.querySelectorAll('tr[data-group="' + key + '"]').forEach(function (tr) {
                                 tr.classList.add('active');
                             });

Also applies to: 362-363

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 351 - 355, Scope the accordion
toggling to the payment table container instead of using document-wide
selectors: find the payments table/container element (e.g., via a selector that
wraps this section) and replace
document.querySelectorAll('.wpuf-accordion-trigger') with
container.querySelectorAll('.wpuf-accordion-trigger') and
document.querySelectorAll('tr[data-group="' + g + '"]') with
container.querySelectorAll('tr[data-group="' + g + '"]'); make the same change
for the other occurrence around the code block at lines 362-363 so only
buttons/rows inside the payments table are affected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/admin/settings.js`:
- Line 294: The external PRO link uses target="_blank" without protecting
against window.opener; update the anchor HTML assigned to dummyTd.innerHTML to
include rel="noopener noreferrer" on the <a> element so the external link opened
in a new tab cannot access the originating window (modify the string assigned to
dummyTd.innerHTML where the anchor is created).
- Around line 160-217: The current .wpuf-accordion-trigger rule removes the
native outline but does not provide a visible focus style, breaking keyboard
accessibility; restore a visible focus indicator by adding a :focus and
:focus-visible style on .wpuf-accordion-trigger (e.g., a distinct outline or
high-contrast box-shadow) and ensure it matches the active hover styles, and
make sure .wpuf-accordion-trigger.is-disabled cannot receive focus (remove
tabindex or set tabindex="-1" / use pointer-events:none) so disabled triggers
don’t show focus. Ensure the new focus rules use :focus-visible where supported
and do not conflict with .is-disabled.

---

Nitpick comments:
In `@assets/js/admin/settings.js`:
- Around line 2-8: Add a defensive early return at the start of the
DOMContentLoaded handler to avoid throwing when page-specific elements are
missing: check that document.querySelector('.wpuf-settings-wrap') exists and
that document.querySelector('#wpuf-settings-search') and
document.querySelector('#wpuf-search-section span') are non-null before
proceeding to compute tabs, content, close, and search_input; if any are
missing, simply return from the function. This change should be applied around
the document.addEventListener('DOMContentLoaded', ...) handler that defines
tabs, content, close, and search_input to prevent errors when those selectors
are absent.
- Around line 351-355: Scope the accordion toggling to the payment table
container instead of using document-wide selectors: find the payments
table/container element (e.g., via a selector that wraps this section) and
replace document.querySelectorAll('.wpuf-accordion-trigger') with
container.querySelectorAll('.wpuf-accordion-trigger') and
document.querySelectorAll('tr[data-group="' + g + '"]') with
container.querySelectorAll('tr[data-group="' + g + '"]'); make the same change
for the other occurrence around the code block at lines 362-363 so only
buttons/rows inside the payments table are affected.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9fe256a and 4a66b9e.

📒 Files selected for processing (1)
  • assets/js/admin/settings.js

Comment thread assets/js/admin/settings.js Outdated
Comment on lines +160 to +217
.wpuf-accordion-trigger {
background: #f1f1f1;
color: #333;
cursor: pointer;
padding: 15px;
width: calc(100% - 25px);
border: 1px solid #ccc;
box-sizing: border-box;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
border-radius: 4px;
display: flex;
align-items: center;
font-weight: 600;
margin-top: 20px;
margin-bottom: 5px;
}
.wpuf-accordion-trigger.active, .wpuf-accordion-trigger:hover {
background: #ddd;
}
.wpuf-accordion-trigger:after {
content: '';
display: block;
width: 8px;
height: 8px;
border-right: 2px solid #777;
border-bottom: 2px solid #777;
transform: translateY(-2px) rotate(45deg);
float: right;
margin-left: auto;
transition: transform 0.3s ease;
}
.wpuf-accordion-trigger.active:after {
transform: translateY(2px) rotate(225deg);
}
.wpuf-accordion-row {
display: none;
}
.wpuf-accordion-row.active {
display: table-row;
}
.wpuf-accordion-trigger.is-disabled {
background: #f9f9f9;
color: #888;
}
.wpuf-accordion-trigger.is-disabled .wpuf-svg-icon-bg {
border-color: #ccc !important;
color: #ccc !important;
}
.wpuf-accordion-trigger.is-disabled:hover {
background: #f9f9f9;
}
.wpuf-accordion-trigger.is-disabled:after {
display: none;
}
`;
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

Keyboard focus visibility is missing for accordion triggers.

Line 169 removes the outline, but there is no replacement focus style. This is an accessibility blocker for keyboard navigation.

Suggested patch
                     .wpuf-accordion-trigger {
@@
-                        outline: none;
+                        outline: none;
@@
                     .wpuf-accordion-trigger.active:after {
                         transform: translateY(2px) rotate(225deg);
                     }
+                    .wpuf-accordion-trigger:focus-visible {
+                        outline: 2px solid `#2271b1`;
+                        outline-offset: 2px;
+                    }
📝 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
.wpuf-accordion-trigger {
background: #f1f1f1;
color: #333;
cursor: pointer;
padding: 15px;
width: calc(100% - 25px);
border: 1px solid #ccc;
box-sizing: border-box;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
border-radius: 4px;
display: flex;
align-items: center;
font-weight: 600;
margin-top: 20px;
margin-bottom: 5px;
}
.wpuf-accordion-trigger.active, .wpuf-accordion-trigger:hover {
background: #ddd;
}
.wpuf-accordion-trigger:after {
content: '';
display: block;
width: 8px;
height: 8px;
border-right: 2px solid #777;
border-bottom: 2px solid #777;
transform: translateY(-2px) rotate(45deg);
float: right;
margin-left: auto;
transition: transform 0.3s ease;
}
.wpuf-accordion-trigger.active:after {
transform: translateY(2px) rotate(225deg);
}
.wpuf-accordion-row {
display: none;
}
.wpuf-accordion-row.active {
display: table-row;
}
.wpuf-accordion-trigger.is-disabled {
background: #f9f9f9;
color: #888;
}
.wpuf-accordion-trigger.is-disabled .wpuf-svg-icon-bg {
border-color: #ccc !important;
color: #ccc !important;
}
.wpuf-accordion-trigger.is-disabled:hover {
background: #f9f9f9;
}
.wpuf-accordion-trigger.is-disabled:after {
display: none;
}
`;
.wpuf-accordion-trigger {
background: `#f1f1f1`;
color: `#333`;
cursor: pointer;
padding: 15px;
width: calc(100% - 25px);
border: 1px solid `#ccc`;
box-sizing: border-box;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
border-radius: 4px;
display: flex;
align-items: center;
font-weight: 600;
margin-top: 20px;
margin-bottom: 5px;
}
.wpuf-accordion-trigger.active, .wpuf-accordion-trigger:hover {
background: `#ddd`;
}
.wpuf-accordion-trigger:after {
content: '';
display: block;
width: 8px;
height: 8px;
border-right: 2px solid `#777`;
border-bottom: 2px solid `#777`;
transform: translateY(-2px) rotate(45deg);
float: right;
margin-left: auto;
transition: transform 0.3s ease;
}
.wpuf-accordion-trigger.active:after {
transform: translateY(2px) rotate(225deg);
}
.wpuf-accordion-trigger:focus-visible {
outline: 2px solid `#2271b1`;
outline-offset: 2px;
}
.wpuf-accordion-row {
display: none;
}
.wpuf-accordion-row.active {
display: table-row;
}
.wpuf-accordion-trigger.is-disabled {
background: `#f9f9f9`;
color: `#888`;
}
.wpuf-accordion-trigger.is-disabled .wpuf-svg-icon-bg {
border-color: `#ccc` !important;
color: `#ccc` !important;
}
.wpuf-accordion-trigger.is-disabled:hover {
background: `#f9f9f9`;
}
.wpuf-accordion-trigger.is-disabled:after {
display: none;
}
`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 160 - 217, The current
.wpuf-accordion-trigger rule removes the native outline but does not provide a
visible focus style, breaking keyboard accessibility; restore a visible focus
indicator by adding a :focus and :focus-visible style on .wpuf-accordion-trigger
(e.g., a distinct outline or high-contrast box-shadow) and ensure it matches the
active hover styles, and make sure .wpuf-accordion-trigger.is-disabled cannot
receive focus (remove tabindex or set tabindex="-1" / use pointer-events:none)
so disabled triggers don’t show focus. Ensure the new focus rules use
:focus-visible where supported and do not conflict with .is-disabled.

Comment thread assets/js/admin/settings.js Outdated
@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad self-assigned this Feb 25, 2026
@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad added the QA Approved This PR is approved by the QA team label Feb 25, 2026
Copy link
Copy Markdown
Contributor

@sapayth sapayth left a comment

Choose a reason for hiding this comment

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

  1. Inline SVG introduces XSS surface via dynamic src construction
    Location: assets/js/admin/settings.js (new lines ~199-207 in diff)
    var baseUrl = anyImg.getAttribute('src').split('/assets/')[0];
    existingProIconSrc = '<img src="' + baseUrl + '/assets/images/pro-badge.svg" ...>';
    The baseUrl is derived from an existing DOM element's src attribute and concatenated into an HTML string that's later injected via innerHTML. If a malicious actor can control an
    img[src] on the page (e.g., via a stored XSS in another plugin), this becomes an injection vector.
    Fix: Use document.createElement('img') and set .src programmatically instead of string concatenation into innerHTML.

  2. Massive inline SVG and CSS strings bloat a JS file — should be enqueued assets
    Location: assets/js/admin/settings.js (lines ~77-170 in new code)
    The PR injects ~50 lines of CSS via document.head.appendChild(style) and embeds full SVG icons as inline HTML strings. This violates separation of concerns.
    Fix: Move CSS to a .css file enqueued via wp_enqueue_style(). Use CSS classes for icons or enqueue an SVG sprite.

@sapayth sapayth added the needs: author reply This PR needs author feedback or code changes label Apr 6, 2026
@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad removed the QA Approved This PR is approved by the QA team label Apr 24, 2026
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: 2

🧹 Nitpick comments (1)
assets/js/admin/settings.js (1)

311-369: Add ARIA state attributes to the accordion triggers to improve screen reader support.

The accordion triggers do not currently expose their expanded/collapsed state to assistive technologies. Add aria-expanded to toggle between true (open) and false (collapsed), aria-controls to reference the associated accordion panel group, and aria-disabled="true" for PRO-locked buttons. This follows the WAI-ARIA disclosure/accordion pattern and complements the interactive behavior already implemented.

💡 Implementation outline
                     triggerBtn.type = 'button';
                     triggerBtn.className = 'wpuf-accordion-trigger';
                     triggerBtn.setAttribute('data-target-group', key);
+                    triggerBtn.setAttribute('aria-expanded', 'false');
+                    triggerBtn.setAttribute('aria-controls', 'wpuf-accordion-panel-' + key);
...
                     if (isProFeatureDisabled) {
                         triggerBtn.classList.add('is-disabled');
+                        triggerBtn.setAttribute('aria-disabled', 'true');
...
                     group.rows.forEach(function (r) {
                         r.classList.add('wpuf-accordion-row');
                         r.setAttribute('data-group', key);
+                        r.setAttribute('id', 'wpuf-accordion-panel-' + key);
                         theTbody.appendChild(r);
                     });
...
                         if (!isActive) {
                             this.classList.add('active');
+                            this.setAttribute('aria-expanded', 'true');
                             document.querySelectorAll('tr[data-group="' + key + '"]').forEach(function (tr) {
                                 tr.classList.add('active');
                             });
+                        } else {
+                            this.setAttribute('aria-expanded', 'false');
+                        }

Also reset aria-expanded to 'false' inside the accordion-close loop (around line 354) when closing other triggers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 311 - 369, Add appropriate ARIA
attributes to the accordion controls: when creating triggerBtn (variable
triggerBtn) set aria-expanded="false" initially, set aria-controls to a unique
id for the panel group (e.g. build a panelId like 'wpuf-accordion-group-'+key
and assign that id to the corresponding rows container/rows), and if
isProFeatureDisabled add aria-disabled="true". In the click handler for
triggerBtn update aria-expanded to "true" when opening and "false" when closing;
also, inside the loop that closes all accordions (the
document.querySelectorAll('.wpuf-accordion-trigger') loop) ensure each btn has
aria-expanded="false" and the opened group rows have the matching id attribute
used by aria-controls so screen readers can map trigger->panel.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/admin/settings.js`:
- Around line 85-131: The code builds a hardcoded groups object (groups) and
then hides the entire allowGatewaysTr row, but only rescues checkboxes whose
value matches paypal|bank|stripe, which causes custom gateways (registered via
wpuf_payment_gateways) to remain hidden; update the input-handling logic to
either (a) create or append an "other" group for any input whose value is not in
groups (so unknown gateways get surfaced via groups['other'].rows and
existingCheckbox), or (b) stop hiding the whole allowGatewaysTr and instead only
hide the rescued wrapperLabel elements (wrapperLabel) after moving them; modify
the branch that sets allowGatewaysTr.style.display = 'none' to implement one of
these two behaviors and ensure inputs iteration (inputs) attaches unknown values
appropriately.
- Around line 87-104: The hardcoded user-facing strings in the gateway
definitions (objects paypal, bank, stripe — titles 'PayPal', 'Bank Transfer',
'Credit Card') and the UI labels 'Enable Gateway' and 'Available with WPUF Pro'
must be wrapped with wp.i18n functions: replace literal titles with
wp.i18n.__(..., 'wp-user-frontend'), wrap the two "Enable Gateway" labels with
wp.i18n.__(..., 'wp-user-frontend'), and convert the "Available with WPUF Pro"
message to a translatable template using wp.i18n.sprintf( wp.i18n.__(...,
'wp-user-frontend'), placeholder ) so it remains one translatable string; also
update the settings script registration (settings handle in includes/Assets.php)
to include 'wp-i18n' in its deps array so the i18n functions are available.

---

Nitpick comments:
In `@assets/js/admin/settings.js`:
- Around line 311-369: Add appropriate ARIA attributes to the accordion
controls: when creating triggerBtn (variable triggerBtn) set
aria-expanded="false" initially, set aria-controls to a unique id for the panel
group (e.g. build a panelId like 'wpuf-accordion-group-'+key and assign that id
to the corresponding rows container/rows), and if isProFeatureDisabled add
aria-disabled="true". In the click handler for triggerBtn update aria-expanded
to "true" when opening and "false" when closing; also, inside the loop that
closes all accordions (the document.querySelectorAll('.wpuf-accordion-trigger')
loop) ensure each btn has aria-expanded="false" and the opened group rows have
the matching id attribute used by aria-controls so screen readers can map
trigger->panel.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 881562ca-3c3e-4608-96dc-1ed4534e8949

📥 Commits

Reviewing files that changed from the base of the PR and between 4a66b9e and 24c49d9.

📒 Files selected for processing (1)
  • assets/js/admin/settings.js

Comment thread assets/js/admin/settings.js Outdated
Comment thread assets/js/admin/settings.js Outdated
Comment on lines +87 to +104
title: 'PayPal',
icon: '<span style="box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;border:1.5px solid #0079C1;background:transparent;color:#0079C1;margin-right:10px;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" style="width:14px;height:14px;fill:currentColor;"><path d="M111.4 295.9l-35.4 223.7c-.5 2.8 1.6 5.4 4.5 5.4H155c2.3 0 4.2-1.7 4.5-4l8.3-51.5c4-23.7 24-41.9 48-41.9h21.1c54.7 0 97.4-21.7 109.8-76 4-17.7 2.1-34.9-4.3-50.1-13-29.6-43.1-42-83.3-42h-85.3c-2.8 0-5.1 2.3-5.1 5.1v31.3zM342.3 84.1c-14.7-21.5-44.5-31.4-86.4-31.4H114.6c-4.1 0-7.6 3.1-8.2 7.2l-32.9 203.4c-.6 3.5 1.9 6.8 5.6 6.8h72.2c4.7 0 8.7-3.4 9.4-8l8.3-51.5c4-23.7 24-41.9 48-41.9h28.5c54.7 0 97.4-21.7 109.8-76 5.9-25.7 3.9-48.4-13-70z"/></svg></span>',
rows: [],
existingCheckbox: null
},
bank: {
title: 'Bank Transfer',
icon: '<span style="box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;border:1.5px solid #10B981;background:transparent;color:#10B981;margin-right:10px;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="width:14px;height:14px;fill:currentColor;"><path d="M243.4 2.6l-224 96c-14 6-21.8 21-18.7 35.8S16.8 160 32 160v8c0 13.3 10.7 24 24 24H456c13.3 0 24-10.7 24-24v-8c15.2 0 28.3-10.7 31.3-25.6s-4.8-29.9-18.7-35.8l-224-96c-8-3.4-17.2-3.4-25.2 0zM128 224H64V420.3c-.6 .3-1.2 .7-1.8 1.1l-48 32c-11.7 7.8-17 22.4-12.9 35.9S17.9 512 32 512H480c14.1 0 26.5-9.2 30.6-22.7s-1.1-28.1-12.9-35.9l-48-32c-.6-.4-1.2-.7-1.8-1.1V224H384V416H344V224H280V416H240V224H176V416H136V224H128zM384 128V96h48v32H384zM136 96v32H80V96h56zM280 96v32H240V96h40z"/></svg></span>',
rows: [],
existingCheckbox: null
},
stripe: {
title: 'Credit Card',
icon: '<span class="wpuf-svg-icon-bg" style="box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:50%;border:1.5px solid #5469d4;background:transparent;color:#5469d4;margin-right:10px;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" style="width:14px;height:14px;fill:currentColor;"><path d="M512 80c8.8 0 16 7.2 16 16V416c0 8.8-7.2 16-16 16H64c-8.8 0-16-7.2-16-16V96c0-8.8 7.2-16 16-16H512zM64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H512c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zM208 256h64c8.8 0 16-7.2 16-16s-7.2-16-16-16H208c-8.8 0-16 7.2-16 16s7.2 16 16 16z"/></svg></span>',
rows: [],
existingCheckbox: null
}
};
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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm how the settings script is enqueued and whether wp-i18n is a dependency.
rg -nP -C3 "settings\.js|admin-settings|wpuf[-_]admin" --type=php -g '!**/tests/**'
rg -nP -C2 "wp_enqueue_script\([^)]*settings" --type=php

Repository: weDevsOfficial/wp-user-frontend

Length of output: 49573


🏁 Script executed:

# Check the full asset registration for settings script
sed -n '361,365p' includes/Assets.php

# Verify the JS file exists and check the specific lines mentioned
wc -l assets/js/admin/settings.js
head -n 110 assets/js/admin/settings.js | tail -n 30

Repository: weDevsOfficial/wp-user-frontend

Length of output: 3741


🏁 Script executed:

# Check lines around 268, 288-297 for other hardcoded strings
sed -n '260,300p' assets/js/admin/settings.js

Repository: weDevsOfficial/wp-user-frontend

Length of output: 2463


Wrap user-facing strings in wp.i18n.__() with the wp-user-frontend text domain.

Gateway titles 'PayPal' (line 87), 'Bank Transfer' (line 93), 'Credit Card' (line 99), the 'Enable Gateway' label (lines 268, 288), and the 'Available with WPUF Pro' message (line 297) are hardcoded English strings. The plugin's PHP codebase uses __( ..., 'wp-user-frontend' ) for translations, so these JavaScript strings must follow the same pattern using wp.i18n.__(). Additionally, the settings script registration in includes/Assets.php must declare wp-i18n as a dependency.

Fix sketch
-                    paypal: {
-                        title: 'PayPal',
+                    paypal: {
+                        title: wp.i18n.__( 'PayPal', 'wp-user-frontend' ),

-                    bank: {
-                        title: 'Bank Transfer',
+                    bank: {
+                        title: wp.i18n.__( 'Bank Transfer', 'wp-user-frontend' ),

-                    stripe: {
-                        title: 'Credit Card',
+                    stripe: {
+                        title: wp.i18n.__( 'Credit Card', 'wp-user-frontend' ),

-                        checkboxTh.innerHTML = 'Enable Gateway';
+                        checkboxTh.textContent = wp.i18n.__( 'Enable Gateway', 'wp-user-frontend' );

-                        enableLabel.appendChild(document.createTextNode('Enable Gateway '));
+                        enableLabel.appendChild(document.createTextNode(
+                            wp.i18n.__( 'Enable Gateway', 'wp-user-frontend' ) + ' '
+                        ));

For the "Available with WPUF Pro" message, use wp.i18n.sprintf() with a placeholder to keep it translatable as a single unit.

Update includes/Assets.php line 362 to add 'deps' => [ 'wp-i18n' ] to the settings script registration.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 87 - 104, The hardcoded user-facing
strings in the gateway definitions (objects paypal, bank, stripe — titles
'PayPal', 'Bank Transfer', 'Credit Card') and the UI labels 'Enable Gateway' and
'Available with WPUF Pro' must be wrapped with wp.i18n functions: replace
literal titles with wp.i18n.__(..., 'wp-user-frontend'), wrap the two "Enable
Gateway" labels with wp.i18n.__(..., 'wp-user-frontend'), and convert the
"Available with WPUF Pro" message to a translatable template using
wp.i18n.sprintf( wp.i18n.__(..., 'wp-user-frontend'), placeholder ) so it
remains one translatable string; also update the settings script registration
(settings handle in includes/Assets.php) to include 'wp-i18n' in its deps array
so the i18n functions are available.

Move inline accordion styles and gateway icon SVGs from settings.js
into assets/css/admin/settings.css and enqueue it on the settings page.
Replace innerHTML/string-built nodes with createElement to avoid HTML
injection paths, and use the data-gateway-id attribute set by the
gateway selector instead of substring-matching row markup. Stripe PRO
upsell now triggers on empty rows rather than label inspection.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Rubaiyat-E-Mohammad
Copy link
Copy Markdown
Contributor Author

  1. Inline SVG introduces XSS surface via dynamic src construction
    Location: assets/js/admin/settings.js (new lines ~199-207 in diff)
    var baseUrl = anyImg.getAttribute('src').split('/assets/')[0];
    existingProIconSrc = '<img src="' + baseUrl + '/assets/images/pro-badge.svg" ...>';
    The baseUrl is derived from an existing DOM element's src attribute and concatenated into an HTML string that's later injected via innerHTML. If a malicious actor can control an
    img[src] on the page (e.g., via a stored XSS in another plugin), this becomes an injection vector.
    Fix: Use document.createElement('img') and set .src programmatically instead of string concatenation into innerHTML.
  2. Massive inline SVG and CSS strings bloat a JS file — should be enqueued assets
    Location: assets/js/admin/settings.js (lines ~77-170 in new code)
    The PR injects ~50 lines of CSS via document.head.appendChild(style) and embeds full SVG icons as inline HTML strings. This violates separation of concerns.
    Fix: Move CSS to a .css file enqueued via wp_enqueue_style(). Use CSS classes for icons or enqueue an SVG sprite.

please review changes @sapayth vai

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: 1

🧹 Nitpick comments (2)
assets/css/admin/settings.css (2)

85-188: Deduplicate the gateway SVG data URIs.

The PayPal, Bank, and Stripe data: URIs are inlined twice — once for .wpuf-gateway-icon--{paypal,bank,stripe} (lines 87/97/107) and again for .wpuf-gateway-card[data-gateway="..."] .wpuf-gateway-card__icon (lines 181/184/187). The Stripe SVG alone is several KB, so this roughly doubles the stylesheet size and forces every future tweak to be made in two places.

Consider hoisting each SVG into a CSS custom property and referencing it from both selectors:

Proposed refactor
+:root {
+    --wpuf-icon-paypal: url("data:image/svg+xml;utf8,<svg .../>");
+    --wpuf-icon-bank:   url("data:image/svg+xml;utf8,<svg .../>");
+    --wpuf-icon-stripe: url("data:image/svg+xml;utf8,<svg .../>");
+}
@@
-.wpuf-gateway-icon--paypal {
-    background-image: url("data:image/svg+xml;utf8,...");
+.wpuf-gateway-icon--paypal {
+    background-image: var(--wpuf-icon-paypal);
@@
-.wpuf-gateway-card[data-gateway="paypal"] .wpuf-gateway-card__icon {
-    background-image: url("data:image/svg+xml;utf8,...");
+.wpuf-gateway-card[data-gateway="paypal"] .wpuf-gateway-card__icon {
+    background-image: var(--wpuf-icon-paypal);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/css/admin/settings.css` around lines 85 - 188, The same large
data:image SVG URIs for PayPal, Bank, and Stripe are duplicated between
.wpuf-gateway-icon--{paypal,bank,stripe} and
.wpuf-gateway-card[data-gateway="..."] .wpuf-gateway-card__icon; hoist each SVG
into a CSS custom property (e.g. --wpuf-gateway-paypal, --wpuf-gateway-bank,
--wpuf-gateway-stripe) defined once (e.g. :root or a common wrapper) and replace
both background-image usages to reference the variable (background-image:
var(--wpuf-gateway-paypal)) for the matching selectors, leaving other properties
(background-repeat/position/size) intact so you only maintain each SVG in one
place.

68-77: Use lowercase currentcolor to satisfy stylelint.

Stylelint's value-keyword-case is flagging both occurrences of currentColor.

Proposed fix
-    border: 1.5px solid currentColor;
+    border: 1.5px solid currentcolor;
@@
-    background-color: currentColor;
+    background-color: currentcolor;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/css/admin/settings.css` around lines 68 - 77, Stylelint flags use of
`currentColor` in CSS value keyword case; update both occurrences to lowercase
`currentcolor` — specifically change the `border: 1.5px solid currentColor;` and
`background-color: currentColor;` declarations (seen in the selector block
containing `.wpuf-gateway-icon::before`) to use `currentcolor` so they pass
`value-keyword-case`.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/js/admin/settings.js`:
- Around line 163-167: The current detection using isProFeatureDisabled = (key
=== 'stripe' && group.rows.length === 0) incorrectly treats an
installed-but-disabled Stripe module as a PRO upsell; update the logic in
settings.js around isProFeatureDisabled to use a server-localized flag (e.g.,
wpufSettings.hasPro) so the upsell only appears when PRO is genuinely
absent—i.e., set isProFeatureDisabled only when key === 'stripe' AND
wpufSettings.hasPro is false AND group.rows.length === 0; for cases where
wpufSettings.hasPro is true but group.rows.length === 0, instead skip rendering
the upsell and show a "module disabled" hint or no group at all (adjust the
branch that currently runs when isProFeatureDisabled is true).

---

Nitpick comments:
In `@assets/css/admin/settings.css`:
- Around line 85-188: The same large data:image SVG URIs for PayPal, Bank, and
Stripe are duplicated between .wpuf-gateway-icon--{paypal,bank,stripe} and
.wpuf-gateway-card[data-gateway="..."] .wpuf-gateway-card__icon; hoist each SVG
into a CSS custom property (e.g. --wpuf-gateway-paypal, --wpuf-gateway-bank,
--wpuf-gateway-stripe) defined once (e.g. :root or a common wrapper) and replace
both background-image usages to reference the variable (background-image:
var(--wpuf-gateway-paypal)) for the matching selectors, leaving other properties
(background-repeat/position/size) intact so you only maintain each SVG in one
place.
- Around line 68-77: Stylelint flags use of `currentColor` in CSS value keyword
case; update both occurrences to lowercase `currentcolor` — specifically change
the `border: 1.5px solid currentColor;` and `background-color: currentColor;`
declarations (seen in the selector block containing
`.wpuf-gateway-icon::before`) to use `currentcolor` so they pass
`value-keyword-case`.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03d11a80-9ced-4b9a-8f21-533805937c91

📥 Commits

Reviewing files that changed from the base of the PR and between 24c49d9 and 175195d.

📒 Files selected for processing (4)
  • assets/css/admin/settings.css
  • assets/js/admin/settings.js
  • includes/Admin/Menu.php
  • includes/Assets.php
✅ Files skipped from review due to trivial changes (1)
  • includes/Admin/Menu.php

Comment thread assets/js/admin/settings.js Outdated
Comment on lines +163 to +167
// Stripe is disabled only when no stripe settings rows are registered in PHP
// (PRO off / stripe module off). If PRO active + stripe module on, rows > 0.
var isProFeatureDisabled = (key === 'stripe' && group.rows.length === 0);

if (isProFeatureDisabled) {
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 | 🟡 Minor

“PRO feature” detection mislabels a disabled-but-installed Stripe module.

isProFeatureDisabled = (key === 'stripe' && group.rows.length === 0) conflates two different states:

  1. WPUF PRO is not installed → Stripe truly is a PRO upsell.
  2. WPUF PRO is installed but the Stripe module is deactivated → no settings rows are emitted either, so the user gets a “Available with WPUF Pro” upsell pointing them to buy something they already own.

Consider checking a server-supplied flag (e.g., a wpufSettings.hasPro localized value) so the upsell only renders when PRO is genuinely absent; otherwise simply skip the group or show a "module disabled" hint.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 163 - 167, The current detection
using isProFeatureDisabled = (key === 'stripe' && group.rows.length === 0)
incorrectly treats an installed-but-disabled Stripe module as a PRO upsell;
update the logic in settings.js around isProFeatureDisabled to use a
server-localized flag (e.g., wpufSettings.hasPro) so the upsell only appears
when PRO is genuinely absent—i.e., set isProFeatureDisabled only when key ===
'stripe' AND wpufSettings.hasPro is false AND group.rows.length === 0; for cases
where wpufSettings.hasPro is true but group.rows.length === 0, instead skip
rendering the upsell and show a "module disabled" hint or no group at all
(adjust the branch that currently runs when isProFeatureDisabled is true).

@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad changed the title Fix/pro badge settings payment page Payment settings design changes Apr 29, 2026
@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad added needs: dev review This PR needs review by a developer and removed needs: author reply This PR needs author feedback or code changes labels Apr 29, 2026
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: 4

🧹 Nitpick comments (1)
wpuf-functions.php (1)

967-983: Harden preferred-order filter handling.

Line 970 assumes $preferred_order is iterable. If a third-party filter returns a scalar, this will emit warnings and skip ordering.

♻️ Suggested hardening
-        $preferred_order = apply_filters( 'wpuf_gateway_selector_order', [ 'bank', 'stripe', 'paypal' ] );
+        $preferred_order = apply_filters( 'wpuf_gateway_selector_order', [ 'bank', 'stripe', 'paypal' ] );
+        if ( ! is_array( $preferred_order ) ) {
+            $preferred_order = [];
+        }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@wpuf-functions.php` around lines 967 - 983, The code assumes $preferred_order
from apply_filters('wpuf_gateway_selector_order', ...) is iterable; harden it by
validating/coercing before the foreach: ensure $preferred_order is an
array/iterable (e.g., if ( ! is_array($preferred_order) && !
is_iterable($preferred_order) ) { $preferred_order = (array) $preferred_order; }
or simply cast with $preferred_order = (array) $preferred_order; ) so the
subsequent foreach loops over $preferred_order and the ordering logic using
$ordered, $return, and $gateway_id won't emit warnings if a scalar/null is
returned by the filter.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@assets/css/admin.css`:
- Around line 1522-1530: The active gateway card style is only applied on
:hover, so the saved "active" state disappears when focus moves; update the
stylesheet so .wpuf-gateway-card--active (in addition to
.wpuf-gateway-card--active:hover) receives the persistent styling (border-color:
`#059669` and the same box-shadow used by .wpuf-gateway-card--focused), and keep
the hover rule for visual consistency; modify the selectors for
.wpuf-gateway-card--active to include the non-:hover case and ensure
.wpuf-gateway-card--focused remains unchanged.

In `@assets/js/admin/settings.js`:
- Around line 330-334: The current logic picks the "bank" card as default even
if it's disabled; change it to pick the first enabled gateway card instead:
iterate gatewayCards to find the first card that is not disabled/hidden (e.g.,
no "disabled" class, aria-disabled !== "true", and dataset.disabled !== "true"
or contains an enabled input/checkbox) and set defaultCard to that; if none
found, fall back to the bank card or gatewayCards[0], then call
showGateway(defaultCard.getAttribute('data-gateway')) as before (refer to
variables container, gatewayCards, defaultCard and the showGateway function).

In `@assets/less/admin.less`:
- Around line 974-977: The hover background for the upgrade button selectors
(.wpuf-subscription-pack-settings nav .tab-current
a.wpuf-button.button-upgrade-to-pro:hover and
a.wpuf-button.button-upgrade-to-pro:hover) currently uses the same color as the
default, removing hover feedback; change the :hover background to a distinct
color (e.g., a darker or lighter hex such as `#047857` or a 10% darkened variant)
so it visibly differs from the base state, and optionally add a subtle
transition or border/box-shadow tweak to enhance the hover affordance.

In `@Lib/WeDevs_Settings_API.php`:
- Around line 384-395: The hidden gateway checkbox (input with class
"wpuf-gateway-card__checkbox" and id/name pattern using
$args['section']/$args['id']/$key inside the gateway card div) must be removed
from the tab order; update that input element to include tabindex="-1" (and
optionally aria-hidden="true") so the card (role="button" tabindex="0") remains
the sole keyboard target and the invisible checkbox does not create an extra tab
stop.

---

Nitpick comments:
In `@wpuf-functions.php`:
- Around line 967-983: The code assumes $preferred_order from
apply_filters('wpuf_gateway_selector_order', ...) is iterable; harden it by
validating/coercing before the foreach: ensure $preferred_order is an
array/iterable (e.g., if ( ! is_array($preferred_order) && !
is_iterable($preferred_order) ) { $preferred_order = (array) $preferred_order; }
or simply cast with $preferred_order = (array) $preferred_order; ) so the
subsequent foreach loops over $preferred_order and the ordering logic using
$ordered, $return, and $gateway_id won't emit warnings if a scalar/null is
returned by the filter.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 94d3fe1a-22a4-46a6-a08c-9f0f3e7ca381

📥 Commits

Reviewing files that changed from the base of the PR and between 175195d and 5f0280b.

📒 Files selected for processing (7)
  • Lib/WeDevs_Settings_API.php
  • assets/css/admin.css
  • assets/css/admin/settings.css
  • assets/js/admin/settings.js
  • assets/less/admin.less
  • includes/Admin/Menu.php
  • wpuf-functions.php
✅ Files skipped from review due to trivial changes (1)
  • assets/css/admin/settings.css
🚧 Files skipped from review as they are similar to previous changes (1)
  • includes/Admin/Menu.php

Comment thread assets/css/admin.css
Comment on lines 1522 to +1530
.wpuf-gateway-card--active:hover {
border-color: #10b981;
border-color: #059669;
}
.wpuf-gateway-card--focused {
border-color: #10b981;
box-shadow: 0 0 0 1px #10b981;
border-color: #059669;
box-shadow: 0 0 0 1px #059669;
}
.wpuf-gateway-card--focused:hover {
border-color: #10b981;
}
.wpuf-gateway-card--pro-locked {
opacity: 0.6;
cursor: not-allowed;
border-color: #059669;
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 | 🟡 Minor

Give enabled gateway cards a persistent active style.

wpuf-gateway-card--active is still applied from PHP and toggled from JS, but this sheet now only changes that modifier on :hover. Once focus moves to another card, enabled gateways look identical to disabled ones, so the saved state disappears from the grid.

🎨 Suggested patch
+.wpuf-gateway-card--active {
+  border-color: `#059669`;
+  box-shadow: 0 0 0 1px rgba(5, 150, 105, 0.2);
+}
+
 .wpuf-gateway-card--active:hover {
   border-color: `#059669`;
 }
📝 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
.wpuf-gateway-card--active:hover {
border-color: #10b981;
border-color: #059669;
}
.wpuf-gateway-card--focused {
border-color: #10b981;
box-shadow: 0 0 0 1px #10b981;
border-color: #059669;
box-shadow: 0 0 0 1px #059669;
}
.wpuf-gateway-card--focused:hover {
border-color: #10b981;
}
.wpuf-gateway-card--pro-locked {
opacity: 0.6;
cursor: not-allowed;
border-color: #059669;
.wpuf-gateway-card--active {
border-color: `#059669`;
box-shadow: 0 0 0 1px rgba(5, 150, 105, 0.2);
}
.wpuf-gateway-card--active:hover {
border-color: `#059669`;
}
.wpuf-gateway-card--focused {
border-color: `#059669`;
box-shadow: 0 0 0 1px `#059669`;
}
.wpuf-gateway-card--focused:hover {
border-color: `#059669`;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/css/admin.css` around lines 1522 - 1530, The active gateway card style
is only applied on :hover, so the saved "active" state disappears when focus
moves; update the stylesheet so .wpuf-gateway-card--active (in addition to
.wpuf-gateway-card--active:hover) receives the persistent styling (border-color:
`#059669` and the same box-shadow used by .wpuf-gateway-card--focused), and keep
the hover rule for visual consistency; modify the selectors for
.wpuf-gateway-card--active to include the non-:hover case and ensure
.wpuf-gateway-card--focused remains unchanged.

Comment on lines +330 to 334
// Default panel: Bank Payment if available, else first card.
var defaultCard = container.querySelector('.wpuf-gateway-card[data-gateway="bank"]') || gatewayCards[0];
if ( defaultCard ) {
showGateway(defaultCard.getAttribute('data-gateway'));
}
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 | 🟡 Minor

Prefer the first enabled gateway as the initial panel.

After reload, this always opens Bank when it exists, even if the saved state only has PayPal/Stripe enabled. The page then loads out of sync with persisted settings until the user clicks the active card manually.

🧭 Suggested patch
-        var defaultCard = container.querySelector('.wpuf-gateway-card[data-gateway="bank"]') || gatewayCards[0];
+        var defaultCard =
+            container.querySelector('.wpuf-gateway-card--active') ||
+            container.querySelector('.wpuf-gateway-card[data-gateway="bank"]') ||
+            gatewayCards[0];
         if ( defaultCard ) {
             showGateway(defaultCard.getAttribute('data-gateway'));
         }
📝 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
// Default panel: Bank Payment if available, else first card.
var defaultCard = container.querySelector('.wpuf-gateway-card[data-gateway="bank"]') || gatewayCards[0];
if ( defaultCard ) {
showGateway(defaultCard.getAttribute('data-gateway'));
}
// Default panel: Bank Payment if available, else first card.
var defaultCard =
container.querySelector('.wpuf-gateway-card--active') ||
container.querySelector('.wpuf-gateway-card[data-gateway="bank"]') ||
gatewayCards[0];
if ( defaultCard ) {
showGateway(defaultCard.getAttribute('data-gateway'));
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/js/admin/settings.js` around lines 330 - 334, The current logic picks
the "bank" card as default even if it's disabled; change it to pick the first
enabled gateway card instead: iterate gatewayCards to find the first card that
is not disabled/hidden (e.g., no "disabled" class, aria-disabled !== "true", and
dataset.disabled !== "true" or contains an enabled input/checkbox) and set
defaultCard to that; if none found, fall back to the bank card or
gatewayCards[0], then call showGateway(defaultCard.getAttribute('data-gateway'))
as before (refer to variables container, gatewayCards, defaultCard and the
showGateway function).

Comment thread assets/less/admin.less
Comment on lines 974 to 977
.wpuf-subscription-pack-settings nav .tab-current a.wpuf-button.button-upgrade-to-pro:hover,
a.wpuf-button.button-upgrade-to-pro:hover {
background: #10b981;
background: #059669;
}
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 | 🟡 Minor

Restore a distinct hover state for the upgrade button.

Line 976 now matches the default background (Line 949), so hover feedback is effectively gone.

♻️ Suggested tweak
 .wpuf-subscription-pack-settings nav .tab-current a.wpuf-button.button-upgrade-to-pro:hover,
 a.wpuf-button.button-upgrade-to-pro:hover {
-    background: `#059669`;
+    background: `#047857`;
 }
📝 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
.wpuf-subscription-pack-settings nav .tab-current a.wpuf-button.button-upgrade-to-pro:hover,
a.wpuf-button.button-upgrade-to-pro:hover {
background: #10b981;
background: #059669;
}
.wpuf-subscription-pack-settings nav .tab-current a.wpuf-button.button-upgrade-to-pro:hover,
a.wpuf-button.button-upgrade-to-pro:hover {
background: `#047857`;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@assets/less/admin.less` around lines 974 - 977, The hover background for the
upgrade button selectors (.wpuf-subscription-pack-settings nav .tab-current
a.wpuf-button.button-upgrade-to-pro:hover and
a.wpuf-button.button-upgrade-to-pro:hover) currently uses the same color as the
default, removing hover feedback; change the :hover background to a distinct
color (e.g., a darker or lighter hex such as `#047857` or a 10% darkened variant)
so it visibly differs from the base state, and optionally add a subtle
transition or border/box-shadow tweak to enhance the hover affordance.

Comment on lines +384 to +395
<div class="wpuf-gateway-card<?php echo esc_attr( $active_class ); ?>"
data-gateway="<?php echo esc_attr( $key ); ?>"
role="button"
tabindex="0"
aria-label="<?php echo esc_attr( $admin_label ); ?>">

<input type="checkbox"
class="wpuf-gateway-card__checkbox"
id="wpuf-<?php echo esc_attr( $args['section'] ); ?>[<?php echo esc_attr( $args['id'] ); ?>][<?php echo esc_attr( $key ); ?>]"
name="<?php echo esc_attr( $args['section'] ); ?>[<?php echo esc_attr( $args['id'] ); ?>][<?php echo esc_attr( $key ); ?>]"
value="<?php echo esc_attr( $key ); ?>"
<?php checked( $is_checked, true ); ?>
<?php echo esc_attr( $disabled ); ?> />

<label class="wpuf-gateway-card__toggle"
for="wpuf-<?php echo esc_attr( $args['section'] ); ?>[<?php echo esc_attr( $args['id'] ); ?>][<?php echo esc_attr( $key ); ?>]"
title="<?php echo esc_attr( sprintf( __( 'Enable %s', 'wp-user-frontend' ), $admin_label ) ); ?>">
<svg class="wpuf-gateway-card__check-on" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="22" height="22">
<circle cx="12" cy="12" r="12" fill="#00a32a"/>
<path d="M9 12l2 2 4-4" stroke="#fff" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg class="wpuf-gateway-card__check-off" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="22" height="22">
<circle cx="12" cy="12" r="11" fill="none" stroke="#c3c4c7" stroke-width="2"/>
</svg>
</label>
<?php checked( $is_checked, true ); ?> />
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

Make the hidden card checkbox non-tabbable.

The card itself is already the keyboard target (role="button" tabindex="0"), but this nested checkbox is still focusable even though the CSS reduces it to a 0×0 transparent control. That creates an invisible tab stop on every gateway card before users reach the visible enable toggle.

♿ Suggested patch
                         <input type="checkbox"
                                class="wpuf-gateway-card__checkbox"
+                               tabindex="-1"
+                               aria-hidden="true"
                                id="wpuf-<?php echo esc_attr( $args['section'] ); ?>[<?php echo esc_attr( $args['id'] ); ?>][<?php echo esc_attr( $key ); ?>]"
                                name="<?php echo esc_attr( $args['section'] ); ?>[<?php echo esc_attr( $args['id'] ); ?>][<?php echo esc_attr( $key ); ?>]"
                                value="<?php echo esc_attr( $key ); ?>"
                                <?php checked( $is_checked, true ); ?> />
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Lib/WeDevs_Settings_API.php` around lines 384 - 395, The hidden gateway
checkbox (input with class "wpuf-gateway-card__checkbox" and id/name pattern
using $args['section']/$args['id']/$key inside the gateway card div) must be
removed from the tab order; update that input element to include tabindex="-1"
(and optionally aria-hidden="true") so the card (role="button" tabindex="0")
remains the sole keyboard target and the invisible checkbox does not create an
extra tab stop.

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

Labels

needs: dev review This PR needs review by a developer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants