Skip to content

Conversation

@arifulhoque7
Copy link
Contributor

@arifulhoque7 arifulhoque7 commented Dec 29, 2025

Close issue, Related PR in PRO

What Changed:

1. New Tailwind CSS Integration

  • Added dedicated Tailwind CSS build system for frontend account pages
  • Created /src/css/frontend/account.css - comprehensive Tailwind component library
  • Updated Vite configuration to include account entry point
  • Implemented conditional CSS loading - only loads on pages with [wpuf_account] or [wpuf_editprofile] shortcodes

2. Modern Sidebar Navigation

  • Redesigned account navigation from horizontal tabs to vertical sidebar layout
  • Added custom SVG icons for each section (Dashboard, Subscription, Edit Profile, Billing Address, Posts)
  • Implemented profile card at top of sidebar with:
    • User avatar (96px rounded)
    • Display name
    • User role
    • Quick "Edit Profile" button with icon
  • Added dedicated logout section at bottom of sidebar with icon
  • Enhanced active state styling with background color and hover effects
  • Improved responsive behavior - sidebar collapses to full-width on mobile/tablet

3. Layout Architecture

  • Changed from single-column to two-column layout:
    • Left sidebar (260px) - navigation and profile
    • Right content area (flex-1) - section content
  • Added proper spacing and visual hierarchy with Tailwind utility classes
  • Implemented responsive breakpoints:
    • Mobile (<768px): Single column, stacked layout
    • Tablet (768-1023px): Single column with adjusted spacing
    • Desktop (1024px+): Two-column sidebar layout

4. Dashboard Section Redesign

  • Updated /templates/dashboard/dashboard.php with modern card-based design
  • Added welcome banner with blue background (bg-blue-50)
  • Created "Quick Links" card with proper typography and spacing
  • Improved readability with better font sizes and line heights

5. Subscription Page Enhancements

  • Redesigned subscription cards with modern rounded borders (24px radius)
  • Implemented 4-column grid layout for subscription features
  • Added expandable "Show Details" button in card header
  • Improved status badges with color-coded indicators
  • Enhanced pricing display with larger, bold typography
  • Added hover effects and transitions on cards
  • Implemented responsive grid:
    • 4 columns on desktop
    • 2 columns on tablet
    • 1 column on mobile

6. Edit Profile Form Styling

  • Modernized all form inputs with consistent styling:
    • Clean borders (border-gray-300)
    • Focus states with blue ring (focus:ring-primary)
    • Proper padding and height (42px)
    • Smooth transitions
  • Updated labels with better typography (14px, semibold)
  • Enhanced password fields with eye icon toggle positioning
  • Improved password strength indicators with color coding
  • Added file upload button styling
  • Updated submit button with primary color scheme (#99A7B2)

7. Form Builder Integration

  • Styled WPUF form builder generated forms to match Tailwind design
  • Removed legacy form styling (lists, old padding/margins)
  • Applied modern input styling to all field types
  • Enhanced form validation and error states
  • Improved help text and required field indicators

8. Posts Table Improvements

  • Added clean table styling with proper borders
  • Implemented status badges for post states (Published, Draft, Pending)
  • Enhanced link styling with hover states
  • Improved overall table typography

9. Color Scheme

  • Primary Brand Color: #99A7B2 (slate gray-blue)
  • Hover State: #7F8C96 (darker slate)
  • Active State Background: #E1E6EA (light gray)
  • Text Colors:
    • Primary: #2C3A41 (dark slate)
    • Secondary: #6C7A85 (medium gray)
  • Borders: #CBD2D9 (light gray)

10. Technical Implementation

  • Prefix: All Tailwind classes use wpuf- prefix to avoid conflicts
  • Build Process:
    • Entry: /assets/js/account.js → imports CSS
    • Output: /assets/css/frontend/account.css
    • Build command: npm run build:account
  • Loading: Conditional enqueue in Frontend.php (lines 183-185)
  • Compatibility: Maintains backward compatibility with existing CSS

Summary by CodeRabbit

  • New Features

    • Password visibility toggle and account script added; account assets now load on account pages
    • Redesigned account dashboard, sidebar navigation, profile, edit-profile, subscriptions, and posts views
    • Edit profile: live password strength indicator and improved validation
    • Subscription UI: card-based layout with expandable details
    • Rich post listing: thumbnails, status badges, action menus, improved pagination
  • Bug Fixes

    • Image uploader and field settings use safe defaults to prevent errors
  • Style

    • Comprehensive account-area UI overhaul with responsive layouts and refined form controls
  • Chores

    • Build/config updated to include account assets and produce minified CSS outputs; Tailwind watch paths extended

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

Warning

Rate limit exceeded

@arifulhoque7 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 5 seconds before requesting another review.

⌛ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between a6710b5 and b81ff7a.

📒 Files selected for processing (1)
  • src/css/frontend/account.css

Walkthrough

Adds an account UI with new frontend assets and styles, password visibility/strength interactions, rewritten account/dashboard templates (posts, subscription, billing, edit-profile), build/tooling updates for an account entry, and a few PHP/uploader/AJAX default adjustments.

Changes

Cohort / File(s) Summary
Build & config
Gruntfile.js, package.json, tailwind.config.js, vite.config.mjs
New account build entry (Vite + npm script), templates/**/*.php added to Tailwind content (duplicated entry), Grunt watch uses generic tailwind task and appends --minify.
Frontend assets
assets/js/account.js, src/css/frontend/account.css
Added assets/js/account.js (jQuery password visibility toggle) and comprehensive account.css for layout, sidebar, forms, password UI, subscription cards, posts table, and responsive rules.
Asset registration / enqueue
includes/Assets.php, includes/Frontend.php
Registered account script (depends on jquery, loads in footer); enqueue account stylesheet/script when wpuf_account or wpuf_editprofile shortcodes are present.
Account templates
templates/account.php, templates/dashboard/*.php
Major markup reworks: new sidebar+main account layout, profile/nav with icons, updated dashboard, grid/card billing, edit-profile with password strength & visibility, WP_Query-driven posts table with pagination/menu, card-based subscription UI with expand/cancel flows.
Utilities & PHP behaviors
includes/Fields/Form_Field_Image.php, wpuf-functions.php
Image uploader defaults added (count → 1, max_size → 1024); AJAX states builder uses sanitized dynamic field_name; publish status color updated to rgb(5,150,105).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • sapayth
  • Rubaiyat-E-Mohammad

Poem

🐰 I hopped through markup, tailwind in tow,
Sidebar flowers and forms in a row.
Eyes that blink for hidden keys,
Cards and posts sway in the breeze.
Build bells ring — the account garden grows. ✨

Pre-merge checks

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The PR title 'Feat/account page redesign new' is vague and incomplete, using 'new' as filler which diminishes clarity about the redesign scope. Revise the title to be more specific and descriptive, such as 'Feat: Account page redesign with Tailwind CSS and sidebar navigation' to clearly communicate the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

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

@arifulhoque7 arifulhoque7 requested a review from sapayth December 29, 2025 11:38
@arifulhoque7 arifulhoque7 self-assigned this Dec 29, 2025
@arifulhoque7 arifulhoque7 added needs: dev review This PR needs review by a developer needs: testing labels Dec 29, 2025
Copy link

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

🧹 Nitpick comments (13)
tailwind.config.js (1)

6-18: Deduplicate ./templates/**/*.php in Tailwind content array

'./templates/**/*.php' appears twice (lines 13 and 16). It’s harmless but redundant and slightly confusing when maintaining the config. You can safely keep a single entry.

includes/Fields/Form_Field_Image.php (1)

78-82: Good defaults for count/max_size, but harden inline JS escaping

Using fallbacks for count and max_size avoids undefined index notices and gives sensible defaults. However, both values are injected into unquoted JS as:

..., <?php echo esc_attr( isset( $field_settings['count'] ) ? $field_settings['count'] : 1 ); ?>, ...

esc_attr() HTML‑escapes but does not guarantee a numeric, and won’t neutralize characters like ) or ;. For defense‑in‑depth, especially if form settings are editable by more than full admins, cast to integers before output:

var uploader = new WPUF_Uploader(
    'wpuf-<?php echo esc_attr( $unique_id ); ?>-pickfiles',
    'wpuf-<?php echo esc_attr( $unique_id ); ?>-upload-container',
    <?php echo absint( isset( $field_settings['count'] ) ? $field_settings['count'] : 1 ); ?>,
    '<?php echo esc_attr( $field_settings['name'] ); ?>',
    'jpg,jpeg,gif,png,bmp,webp',
    <?php echo absint( isset( $field_settings['max_size'] ) ? $field_settings['max_size'] : 1024 ); ?>
);

No need for esc_attr() on these numeric slots once cast.

templates/dashboard/billing-address.php (1)

47-93: Address form logic/escaping look solid; PHPCS warnings are purely formatting

The billing form correctly:

  • Normalizes $address_fields via wpuf_map_address_fields.
  • Derives $states from Country_State::getStates( $selected['country'] ).
  • Escapes the generated <select> via wp_kses( wpuf_select( ... ), ... ) with a tight whitelist.

The PHPCS failures called out in CI here are about multi‑line function‑call and array formatting for the wpuf_select(...) call and allowed‑tags array (alignment, one value per line). If your pipeline is red on these, you’ll need to reflow the call/array per your coding standard, but there’s no functional issue.

wpuf-functions.php (1)

3897-3923: Harden wpuf_ajax_get_states_field against bad input

The dynamic field name support is useful, but a couple of small hardening tweaks would make this more robust:

  • Guard access to $countries[ $country ] before calling getStates() to avoid notices if $_POST['country'] is invalid/tampered:
if ( empty( $country ) || ! isset( $countries[ $country ] ) ) {
    wp_send_json( 'nostates' );
}
$states = $cs->getStates( $countries[ $country ] );
  • Likewise, if field_name comes through empty after sanitize_text_field, you currently emit <select name="" id="">..., which is hard to use. Consider bailing early or defaulting to a known safe name in that case.

These are small changes but will avoid edge‑case warnings and odd markup if the AJAX request is malformed.

templates/dashboard/dashboard.php (1)

26-50: Use strict comparisons and pre‑increment for consistency / PHPCS

The quick‑links logic is fine, but PHPCS is flagging a couple of small style points:

  • Prefer strict comparisons for options:
if ( 'off' === wpuf_get_option( 'show_subscriptions', 'wpuf_my_account', 'on' ) ) {
    unset( $tabs['subscription'] );
}
  • Likewise, inside the loop:
if ( $total_tabs === $count ) {
    // last item
    ...
} else {
    ...
    ++$count;
}

This keeps things consistent with the rest of the codebase and quiets the CS warnings.

templates/dashboard/subscription.php (2)

179-255: Align expired card pricing text with actual billing configuration

In the expired‑subscription branch you render:

<span class="wpuf-price"><?php echo esc_html( $billing_amount ); ?></span>
<span class="wpuf-price-period">/year</span>

while in the active card you correctly show $recurring_des when available. For non‑yearly packs (e.g. monthly), the expired card will misrepresent the billing period.

Reusing $recurring_des (when set) and only falling back to /year as a default would keep the display consistent with the actual pack config.


415-454: Inline toggle JS assumes a single subscription card

The toggle script targets fixed IDs/selectors:

  • document.getElementById('wpuf-toggle-details')
  • document.querySelector('.wpuf-show-details-btn')
  • document.getElementById('subscription-details-1')

This works as long as there’s exactly one subscription card, but will break or behave unpredictably if you ever support multiple subscriptions per user.

If you plan to expand to multiple cards later, consider delegating events per card (e.g. data-target attributes and closest('.wpuf-subscription-card') scopes) instead of global IDs.

templates/dashboard/edit-profile.php (1)

162-211: Localize password strength messages and clean up the JS check

The password strength script works but has a couple of rough edges:

  • pwsL10n is defined inline with hard‑coded English strings. WordPress already provides localized messages for the password meter; overriding them this way makes the UI non‑translatable.
  • The typeof pass2 === undefined check is incorrect JS (it should be compared to the string 'undefined') and is redundant here since pass2 is always defined via jQuery.

Consider:

  • Using the existing window.pwsL10n if available, and only falling back to your own defaults:
var pwsL10n = window.pwsL10n || {
    empty: '<?php echo esc_js( __( 'Strength indicator', 'wp-user-frontend' ) ); ?>',
    short: '<?php echo esc_js( __( 'Very weak', 'wp-user-frontend' ) ); ?>',
    // ...
};
  • Dropping the unused typeof pass2 check altogether, since you already initialize pass2 from #pass2.

This keeps the strength meter fully localized and simplifies the code.

templates/dashboard/posts.php (1)

11-35: Harden delete flow: strict compares, null‑check, and safer redirect

The delete logic is functionally correct, but a few small tweaks will make it more robust:

  • Use strict comparison for the action check to avoid surprises:
if ( 'del' === $action ) {
    ...
}
  • Guard against an invalid pid before dereferencing:
$maybe_delete = get_post( $pid );

if ( ! $maybe_delete ) {
    return;
}

if ( ( (int) $maybe_delete->post_author === (int) $userdata->ID ) || current_user_can( 'delete_others_pages' ) ) {
    ...
}
  • Prefer wp_safe_redirect( $redirect ); over wp_redirect( $redirect ); when redirecting to a URL derived from get_permalink() plus query args.

These are all low‑impact changes but help with general hardening and alignment with WP best practices.

Gruntfile.js (1)

281-283: Note: shell:tailwind now always minifies output.

The --minify flag was added to the tailwind command (line 282), making it produce minified output by default. This matches shell:tailwind_minify behavior. Consider whether you still need tailwind_minify as a separate task, or if this duplication is intentional for different use cases.

assets/js/account.js (1)

11-22: Consider improving accessibility for the password toggle.

The toggle functionality works but lacks accessibility attributes. Consider adding aria-pressed or aria-label to indicate the toggle state for screen reader users.

🔎 Suggested improvement
         // Password toggle functionality
         $('.wpuf-password-toggle').on('click', function() {
             const input = $(this).siblings('input[type="password"], input[type="text"]');
 
             if (input.attr('type') === 'password') {
                 input.attr('type', 'text');
                 $(this).addClass('active');
+                $(this).attr('aria-label', 'Hide password');
             } else {
                 input.attr('type', 'password');
                 $(this).removeClass('active');
+                $(this).attr('aria-label', 'Show password');
             }
         });
templates/account.php (1)

88-94: Escape or sanitize the $icon SVG output.

While the SVG content is hardcoded and safe in this context, WordPress coding standards recommend using wp_kses with allowed SVG tags for HTML output. This also prevents issues if the icon source changes in the future.

🔎 Suggested approach

Consider using wp_kses with an SVG-safe allowed tags array:

$allowed_svg = [
    'svg' => ['class' => [], 'width' => [], 'height' => [], 'viewBox' => [], 'fill' => [], 'xmlns' => []],
    'path' => ['d' => [], 'stroke' => [], 'stroke-width' => [], 'stroke-linecap' => [], 'stroke-linejoin' => [], 'fill' => []],
];

echo sprintf(
    '<li><a href="%s" class="%s">%s<span>%s</span></a></li>',
    esc_url( add_query_arg( [ 'section' => $section ], get_permalink() ) ),
    esc_attr( $active_class ),
    wp_kses( $icon, $allowed_svg ),
    esc_html( $label )
);
src/css/frontend/account.css (1)

1-893: Heavy use of !important throughout the stylesheet.

The extensive use of !important declarations suggests conflicts with existing styles. While this may be necessary for overriding legacy CSS, consider documenting why these overrides are needed. For future maintainability, you might explore increasing CSS specificity instead of relying on !important.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7d7e76 and 5257185.

⛔ Files ignored due to path filters (1)
  • assets/js/account.min.js is excluded by !**/*.min.js
📒 Files selected for processing (18)
  • Gruntfile.js
  • assets/css/account.min.css
  • assets/css/frontend/account.css
  • assets/js/account.js
  • includes/Assets.php
  • includes/Fields/Form_Field_Image.php
  • includes/Frontend.php
  • package.json
  • src/css/frontend/account.css
  • tailwind.config.js
  • templates/account.php
  • templates/dashboard/billing-address.php
  • templates/dashboard/dashboard.php
  • templates/dashboard/edit-profile.php
  • templates/dashboard/posts.php
  • templates/dashboard/subscription.php
  • vite.config.mjs
  • wpuf-functions.php
🧰 Additional context used
🧬 Code graph analysis (7)
includes/Frontend.php (1)
wpuf-functions.php (1)
  • wpuf_has_shortcode (1562-1584)
templates/dashboard/dashboard.php (1)
wpuf-functions.php (2)
  • wpuf_get_account_sections (2215-2243)
  • wpuf_get_option (1543-1551)
templates/dashboard/posts.php (6)
wpuf-functions.php (3)
  • wpuf_get_option (1543-1551)
  • wpuf_show_post_status (30-50)
  • wpuf_is_post_editable (4625-4658)
Lib/WeDevs_Settings_API.php (1)
  • get_option (649-658)
assets/vendor/sweetalert2/sweetalert2.js (1)
  • title (1309-1309)
includes/Render_Form.php (1)
  • url (1134-1152)
class/render-form.php (1)
  • url (1272-1290)
tests/e2e/utils/generate-summary.js (1)
  • total (217-217)
templates/account.php (2)
class/render-form.php (1)
  • label (880-892)
wpuf-functions.php (1)
  • wpuf_get_option (1543-1551)
templates/dashboard/subscription.php (1)
wpuf-functions.php (3)
  • wpuf_get_date (1767-1789)
  • wpuf_date2mysql (1801-1808)
  • wpuf_is_checkbox_or_toggle_on (5651-5653)
assets/js/account.js (1)
vite.config.mjs (1)
  • input (14-14)
templates/dashboard/billing-address.php (2)
wpuf-functions.php (2)
  • wpuf_map_address_fields (4534-4543)
  • wpuf_select (3679-3777)
includes/Data/Country_State.php (3)
  • states (278-291)
  • getStates (294-316)
  • countries (265-275)
🪛 GitHub Actions: Inspections
Gruntfile.js

[error] 1-1: PHPCS check failed. Error: 'If control structure block found as the only statement within an "else" block. Use elseif instead.' Reproduce with: vendor/bin/phpcs Gruntfile.js assets/css/account.min.css assets/css/frontend/account.css assets/js/account.js assets/js/account.min.js includes/Assets.php includes/Fields/Form_Field_Image.php includes/Frontend.php package.json src/css/frontend/account.css tailwind.config.js templates/account.php templates/dashboard/billing-address.php templates/dashboard/dashboard.php templates/dashboard/edit-profile.php templates/dashboard/posts.php templates/dashboard/subscription.php vite.config.mjs wpuf-functions.php -q --report=checkstyle | cs2pr --graceful-warnings

🪛 GitHub Check: Run PHPCS inspection
templates/dashboard/dashboard.php

[warning] 57-57:
Found precision alignment of 1 spaces.


[warning] 56-56:
When a multi-item array uses associative keys, each value should start on a new line.


[warning] 49-49:
Stand-alone post-increment statement found. Use pre-increment instead: ++$count.


[warning] 43-43:
Loose comparisons are not allowed. Expected: "==="; Found: "=="


[warning] 28-28:
Loose comparisons are not allowed. Expected: "==="; Found: "=="


[warning] 14-14:
Found precision alignment of 1 spaces.

templates/dashboard/billing-address.php

[warning] 112-112:
When a multi-item array uses associative keys, each value should start on a new line.


[warning] 75-75:
When a multi-item array uses associative keys, each value should start on a new line.


[failure] 70-70:
Array item not aligned correctly; expected 16 spaces but found 20


[failure] 69-69:
Array item not aligned correctly; expected 16 spaces but found 20


[failure] 68-68:
Array item not aligned correctly; expected 16 spaces but found 20


[failure] 67-67:
Array item not aligned correctly; expected 16 spaces but found 20


[failure] 66-66:
Array item not aligned correctly; expected 16 spaces but found 20


[failure] 65-65:
Opening parenthesis of a multi-line function call must be the last content on the line


[failure] 65-65:
Opening parenthesis of a multi-line function call must be the last content on the line

🔇 Additional comments (7)
templates/dashboard/posts.php (1)

70-215: Dashboard table implementation looks solid; only minor style nits from CS

The rebuilt posts table:

  • Uses WP_Query scoped to the current user and allowed statuses.
  • Escapes titles, URLs, and attributes appropriately (esc_html, esc_attr, esc_url[_raw]).
  • Delegates status rendering to wpuf_show_post_status.
  • Respects existing dashboard/payment options and hooks (wpuf_account_posts_head_col, wpuf_account_posts_row_col).

The remaining PHPCS hints here (e.g., loose comparisons like 'on' == $featured_img) are stylistic; if you want a clean CS run, convert those to strict comparisons and normalize spacing, but there are no obvious functional issues in this block.

vite.config.mjs (1)

8-8: LGTM!

The new account entry point is correctly added and follows the existing pattern for other entry points in the configuration.

Gruntfile.js (2)

7-8: LGTM!

The new mapping for templates/account.php to frontend/account.css is correctly added. The Tailwind task will process src/css/frontend/account.css and output to assets/css/frontend/account.css.


144-148: Good addition for template watching.

Adding templates/**/*.php to watch paths ensures Tailwind rebuilds when template files change, which is necessary since Tailwind scans these files for class usage.

includes/Assets.php (1)

384-388: LGTM!

The account script registration follows the established patterns in the codebase with appropriate jQuery dependency and footer loading configuration.

package.json (1)

10-16: LGTM!

The build pipeline correctly includes the new build:account step before build:css, ensuring account assets are compiled in the proper sequence.

includes/Frontend.php (1)

183-187: The wpuf_editprofile shortcode is properly registered in includes/Frontend/Shortcode.php and will function as intended. No action needed.

Likely an incorrect or invalid review comment.

Comment on lines +125 to +142
.wpuf-form-add .wpuf-label {
margin-bottom: 0 !important;
}

.wpuf-form-add .wpuf-label label {
display: block !important;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important;
font-size: 14px !important;
line-height: 20px !important;
font-weight: 500 !important;
color: #334155 !important;
margin-bottom: 8px !important;
letter-spacing: 0 !important;
}

.wpuf-form-add .wpuf-fields {
margin-bottom: 0 !important;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Duplicate CSS rule block detected.

The styles for .wpuf-form-add .wpuf-label and .wpuf-form-add .wpuf-label label (lines 125-138) are duplicated later in the file (lines 287-300). Consider removing one of the duplicate blocks.

🤖 Prompt for AI Agents
In src/css/frontend/account.css around lines 125 to 142, the rule blocks for
".wpuf-form-add .wpuf-label" and ".wpuf-form-add .wpuf-label label" are
duplicated later in the file (lines 287-300); remove the later duplicate block
(or the earlier one if preferred) and consolidate any unique declarations so
only one authoritative rule remains, keeping specificity and existing !important
declarations intact to avoid changing behavior.

Comment on lines +144 to +163
.wpuf-form-add .wpuf-fields input[type="text"],
.wpuf-form-add .wpuf-fields input[type="email"],
.wpuf-form-add .wpuf-fields input[type="password"],
.wpuf-form-add .wpuf-fields input.textfield,
.wpuf-form-add .wpuf-fields input.password {
width: 100% !important;
max-width: 772px !important;
height: 42px !important;
padding: 9px 13px !important;
font-size: 0.875rem !important;
line-height: 1.25rem !important;
color: rgb(17, 24, 39) !important;
background-color: rgb(255, 255, 255) !important;
border: 1px solid rgb(203, 213, 225) !important;
border-radius: 0.375rem !important;
opacity: 1 !important;
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1) !important;
box-shadow: none !important;
margin-bottom: 0 !important;
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Duplicate input styling rules.

The form input styles defined here (lines 144-163) are duplicated at lines 306-325. Consolidate these into a single rule block to improve maintainability.

🤖 Prompt for AI Agents
In src/css/frontend/account.css around lines 144-163 (and duplicated at
306-325), the same .wpuf-form-add .wpuf-fields input... rule block is defined
twice; remove the duplicate by keeping a single consolidated rule block and
delete the redundant copy (choose the preferred location — e.g., the earlier
occurrence or the later based on cascade needs), ensure any unique declarations
from either block are merged into the retained block, and run a quick browser
check to confirm styling remains unchanged.

Comment on lines +14 to +19
<p class="wpuf-profile-role">
<?php
$user_roles = $current_user->roles;
echo esc_html( ucfirst( $user_roles[0] ) );
?>
</p>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add defensive check for empty roles array.

Accessing $user_roles[0] without checking if the array is empty could cause an undefined index notice if a user has no roles assigned.

🔎 Suggested fix
             <p class="wpuf-profile-role">
                 <?php
                 $user_roles = $current_user->roles;
-                echo esc_html( ucfirst( $user_roles[0] ) );
+                echo esc_html( ! empty( $user_roles ) ? ucfirst( $user_roles[0] ) : '' );
                 ?>
             </p>
📝 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
<p class="wpuf-profile-role">
<?php
$user_roles = $current_user->roles;
echo esc_html( ucfirst( $user_roles[0] ) );
?>
</p>
<p class="wpuf-profile-role">
<?php
$user_roles = $current_user->roles;
echo esc_html( ! empty( $user_roles ) ? ucfirst( $user_roles[0] ) : '' );
?>
</p>
🤖 Prompt for AI Agents
In templates/account.php around lines 14 to 19, the code directly accesses
$user_roles[0] which can trigger an undefined index notice if the roles array is
empty; update the output to first check that $user_roles is a non-empty array
(e.g. isset($user_roles[0]) or !empty($user_roles)) and only echo the
ucfirst-escaped role when present, otherwise echo a safe fallback string (like
'No role' or an empty string) so there is no undefined index access.

Comment on lines +57 to +59
if ( ( isset( $_GET['section'] ) && $_GET['section'] == $section ) || ( !isset( $_GET['section'] ) && $default_active_tab == $section ) ) {
$active_tab = true;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Sanitize $_GET['section'] input.

The $_GET['section'] value should be sanitized before use to follow WordPress coding standards and security best practices.

🔎 Suggested fix
-                            if ( ( isset( $_GET['section'] ) && $_GET['section'] == $section ) || ( !isset( $_GET['section'] ) && $default_active_tab == $section ) ) {
+                            $current_section_param = isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '';
+                            if ( ( $current_section_param && $current_section_param == $section ) || ( ! $current_section_param && $default_active_tab == $section ) ) {
                                 $active_tab = true;
                             }
🤖 Prompt for AI Agents
In templates/account.php around lines 57 to 59, the code reads $_GET['section']
directly; sanitize the input before use by retrieving it once with
$section_param = isset($_GET['section']) ? sanitize_text_field( wp_unslash(
$_GET['section'] ) ) : null; then use $section_param in the conditional (compare
to $section) instead of raw $_GET access, ensuring you handle the null case
consistently.

Comment on lines +19 to +23
<div class="wpuf-bg-transparent wpuf-mb-[48px]">
<p class="wpuf-text-gray-400 wpuf-font-normal wpuf-text-[18px] wpuf-leading-[24px] wpuf-tracking-[0.13px] wpuf-m-0">
<?php esc_html_e( 'The following addresses will be used on the checkout page by default.', 'wp-user-frontend' ); ?>
</p>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate the edit-profile.php file
fd "edit-profile.php" -t f

Repository: weDevsOfficial/wp-user-frontend

Length of output: 111


🏁 Script executed:

# Check if the file exists and read the relevant lines
if [ -f "templates/dashboard/edit-profile.php" ]; then
  echo "=== Lines 19-23 of edit-profile.php ==="
  sed -n '19,23p' "templates/dashboard/edit-profile.php"
  echo ""
  echo "=== Full file context (first 50 lines) ==="
  head -n 50 "templates/dashboard/edit-profile.php"
fi

Repository: weDevsOfficial/wp-user-frontend

Length of output: 2822


🏁 Script executed:

# Search for the phrase about addresses to see if it appears elsewhere in the codebase
rg "addresses will be used on the checkout page" -t php

Repository: weDevsOfficial/wp-user-frontend

Length of output: 400


🏁 Script executed:

# Check the subscription.php file context
head -n 50 "templates/dashboard/subscription.php" | tail -n 35

Repository: weDevsOfficial/wp-user-frontend

Length of output: 1140


🏁 Script executed:

# Get more of edit-profile.php to see all form fields
sed -n '1,100p' "templates/dashboard/edit-profile.php" | tail -n 60

Repository: weDevsOfficial/wp-user-frontend

Length of output: 2390


🏁 Script executed:

# Find the line with address text in subscription.php and show context
grep -n "addresses will be used on the checkout page" "templates/dashboard/subscription.php" -B 10 -A 10

Repository: weDevsOfficial/wp-user-frontend

Length of output: 1250


🏁 Script executed:

# Check what the subscription.php page is about by looking at its title/header
head -n 80 "templates/dashboard/subscription.php"

Repository: weDevsOfficial/wp-user-frontend

Length of output: 2473


Replace account details description text

The page title is "Account details" and the form manages personal information (first/last name, email, password), but the description text says "The following addresses will be used on the checkout page by default." This mismatches the form's purpose. Replace with text explaining that users can update their account details and change their password here.

🤖 Prompt for AI Agents
In templates/dashboard/edit-profile.php around lines 19 to 23, the description
text incorrectly references checkout addresses; replace that string with a
sentence appropriate for the "Account details" form. Update the esc_html_e call
to a new translatable message such as "Update your personal information and
change your password here." (keeping the same text domain 'wp-user-frontend') so
the UI matches the form's purpose.

Comment on lines +167 to +177
<div class="wpuf-bg-transparent wpuf-rounded-t-lg wpuf-mb-3">
<h2 class="wpuf-text-gray-700 wpuf-font-bold wpuf-text-[32px] wpuf-leading-[48px] wpuf-tracking-[0.13px] wpuf-m-0">
<?php esc_html_e( 'Subscription', 'wp-user-frontend' ); ?>
</h2>
</div>

<div class="wpuf-bg-transparent wpuf-mb-[48px]">
<p class="wpuf-text-gray-400 wpuf-font-normal wpuf-text-[18px] wpuf-leading-[24px] wpuf-tracking-[0.13px] wpuf-m-0">
<?php esc_html_e( 'The following addresses will be used on the checkout page by default.', 'wp-user-frontend' ); ?>
</p>
</div>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the subscription.php file
find . -path "*templates/dashboard/subscription.php" -type f

Repository: weDevsOfficial/wp-user-frontend

Length of output: 113


🏁 Script executed:

# Search for billing-address related templates
find . -path "*templates/dashboard/*" -type f | grep -i "address\|billing"

Repository: weDevsOfficial/wp-user-frontend

Length of output: 116


🏁 Script executed:

# Get file info and examine the specific lines mentioned
if [ -f "templates/dashboard/subscription.php" ]; then
  echo "=== File: templates/dashboard/subscription.php ===" 
  wc -l templates/dashboard/subscription.php
  echo -e "\n=== Lines 160-185 ===" 
  sed -n '160,185p' templates/dashboard/subscription.php
fi

Repository: weDevsOfficial/wp-user-frontend

Length of output: 1417


🏁 Script executed:

# Check the billing-address.php file for similar copy
cat -n templates/dashboard/billing-address.php | head -200

Repository: weDevsOfficial/wp-user-frontend

Length of output: 10769


🏁 Script executed:

# Search for the exact copy in all template files
rg "The following addresses will be used on the checkout page" templates/

Repository: weDevsOfficial/wp-user-frontend

Length of output: 400


🏁 Script executed:

# Check if edit-profile.php also contains this string and in what context
grep -n "The following addresses will be used on the checkout page" templates/dashboard/edit-profile.php -B 5 -A 5

Repository: weDevsOfficial/wp-user-frontend

Length of output: 600


🏁 Script executed:

# Let's verify what edit-profile.php is actually about - what comes before this text?
head -30 templates/dashboard/edit-profile.php

Repository: weDevsOfficial/wp-user-frontend

Length of output: 1689


🏁 Script executed:

# Check what fields edit-profile.php actually contains - look for address-related inputs
grep -n "address\|billing" templates/dashboard/edit-profile.php | head -20

Repository: weDevsOfficial/wp-user-frontend

Length of output: 205


Subscription page copy incorrectly references checkout addresses

The subscription details section displays:

<?php esc_html_e( 'The following addresses will be used on the checkout page by default.', 'wp-user-frontend' ); ?>

This text is confusing on a subscription page where it should describe subscription status, renewal, and billing information—not checkout addresses. Replace with subscription-specific copy (e.g., describing the user's current subscription status, next billing date, or renewal terms).

Note: This same misplaced text also appears in templates/dashboard/edit-profile.php, which contains no address fields.

Comment on lines +256 to +407
<!-- Compact Features List (Initial View - shows first row of 4) -->
<ul class="wpuf-subscription-features wpuf-features-compact">
<?php
$feature_count = 0;
$max_initial_features = 4; // Show 4 features (1 row)
$compact_displayed_features = []; // Track features shown in compact view

// Remaining posts
if ( ! empty( $user_sub['posts'] ) ) {
foreach ( $user_sub['posts'] as $key => $value ) {
if ( $feature_count >= $max_initial_features ) {
break;
}
$value = intval( $value );
if ( 0 === $value ) {
continue;
}
$post_type_obj = get_post_type_object( $key );
if ( ! $post_type_obj ) {
continue;
}
$value_display = ( -1 === intval( $value ) ) ? __( 'Unlimited', 'wp-user-frontend' ) : $value;
// Track this feature as displayed in compact view
$compact_displayed_features[] = strtolower( trim( $post_type_obj->labels->name ) );
?>
<li>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.75 10.5L9 12.75L12.75 7.5M18.75 9.75C18.75 14.7206 14.7206 18.75 9.75 18.75C4.77944 18.75 0.75 14.7206 0.75 9.75C0.75 4.77944 4.77944 0.75 9.75 0.75C14.7206 0.75 18.75 4.77944 18.75 9.75Z" stroke="#99A7B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span><?php echo esc_html( $post_type_obj->labels->name ); ?>: <strong><?php echo esc_html( $value_display ); ?></strong></span>
</li>
<?php
$feature_count++;
}
$value = ( -1 === intval( $value ) ) ? __( 'Unlimited', 'wp-user-frontend' ) : $value;
$hidden_class = ( $i >= 3 ) ? 'wpuf-remaining-post-hidden' : '';
}

// Add other features to reach 4
$basic_features = [
[ 'label' => __( 'Template Parts', 'wp-user-frontend' ), 'value' => __( 'Unlimited', 'wp-user-frontend' ) ],
[ 'label' => __( 'User Requests', 'wp-user-frontend' ), 'value' => __( 'Unlimited', 'wp-user-frontend' ) ],
[ 'label' => __( 'Global Styles', 'wp-user-frontend' ), 'value' => __( 'Unlimited', 'wp-user-frontend' ) ],
[ 'label' => __( 'Pages', 'wp-user-frontend' ), 'value' => __( 'Unlimited', 'wp-user-frontend' ) ],
];

for ( $i = $feature_count; $i < $max_initial_features && $i < count( $basic_features ); $i++ ) {
// Track this feature as displayed in compact view
$compact_displayed_features[] = strtolower( trim( $basic_features[ $i ]['label'] ) );
?>
<div class="<?php echo esc_attr( $hidden_class ); ?>"><?php echo esc_html( $post_type_obj->labels->name ) . ': ' . esc_html( $value ); ?></div>
<li>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.75 10.5L9 12.75L12.75 7.5M18.75 9.75C18.75 14.7206 14.7206 18.75 9.75 18.75C4.77944 18.75 0.75 14.7206 0.75 9.75C0.75 4.77944 4.77944 0.75 9.75 0.75C14.7206 0.75 18.75 4.77944 18.75 9.75Z" stroke="#99A7B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span><?php echo esc_html( $basic_features[ $i ]['label'] ); ?>: <strong><?php echo esc_html( $basic_features[ $i ]['value'] ); ?></strong></span>
</li>
<?php
++$i;
}
}
echo $i ? '' : esc_attr( $i );
?>
?>
</ul>

<!-- Expandable Detailed Features (Hidden Initially) -->
<div class="wpuf-subscription-details" id="subscription-details-1" style="display: none;">
<ul class="wpuf-subscription-features-detailed">
<?php
// Start with features already displayed in compact view
$displayed_features = $compact_displayed_features;

// All remaining posts (skip those already shown in compact view)
if ( ! empty( $user_sub['posts'] ) ) {
foreach ( $user_sub['posts'] as $key => $value ) {
$value = intval( $value );
if ( 0 === $value ) {
continue;
}
$post_type_obj = get_post_type_object( $key );
if ( ! $post_type_obj ) {
continue;
}

// Check if already displayed in compact view
$normalized_label = strtolower( trim( $post_type_obj->labels->name ) );
if ( in_array( $normalized_label, $displayed_features, true ) ) {
continue; // Skip this one, already shown
}

$value_display = ( -1 === intval( $value ) ) ? __( 'Unlimited', 'wp-user-frontend' ) : $value;
// Store normalized label for matching
$displayed_features[] = $normalized_label;
?>
<li>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.75 10.5L9 12.75L12.75 7.5M18.75 9.75C18.75 14.7206 14.7206 18.75 9.75 18.75C4.77944 18.75 0.75 14.7206 0.75 9.75C0.75 4.77944 4.77944 0.75 9.75 0.75C14.7206 0.75 18.75 4.77944 18.75 9.75Z" stroke="#99A7B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span><?php echo esc_html( $post_type_obj->labels->name ); ?>: <strong><?php echo esc_html( $value_display ); ?></strong></span>
</li>
<?php
}
}

// Featured items (only if not already shown as posts)
$user_requests_normalized = strtolower( __( 'User Requests', 'wp-user-frontend' ) );
if ( ! empty( $user_sub['total_feature_item'] ) && ! in_array( $user_requests_normalized, $displayed_features, true ) ) {
$feature_value = ( -1 === intval( $user_sub['total_feature_item'] ) ) ? __( 'Unlimited', 'wp-user-frontend' ) : $user_sub['total_feature_item'];
$displayed_features[] = $user_requests_normalized;
?>
<li>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.75 10.5L9 12.75L12.75 7.5M18.75 9.75C18.75 14.7206 14.7206 18.75 9.75 18.75C4.77944 18.75 0.75 14.7206 0.75 9.75C0.75 4.77944 4.77944 0.75 9.75 0.75C14.7206 0.75 18.75 4.77944 18.75 9.75Z" stroke="#99A7B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span><?php esc_html_e( 'User Requests', 'wp-user-frontend' ); ?>: <strong><?php echo esc_html( $feature_value ); ?></strong></span>
</li>
<?php
}

// Additional features (only if not already displayed)
$all_features = [
'Template Parts' => __( 'Template Parts', 'wp-user-frontend' ),
'Global Styles' => __( 'Global Styles', 'wp-user-frontend' ),
'Templates' => __( 'Templates', 'wp-user-frontend' ),
'Navigation Menus' => __( 'Navigation Menus', 'wp-user-frontend' ),
'Pages' => __( 'Pages', 'wp-user-frontend' ),
'Patterns' => __( 'Patterns', 'wp-user-frontend' ),
'Font Families' => __( 'Font Families', 'wp-user-frontend' ),
'Font Faces' => __( 'Font Faces', 'wp-user-frontend' ),
'Products' => __( 'Products', 'wp-user-frontend' ),
'Variations' => __( 'Variations', 'wp-user-frontend' ),
'Orders' => __( 'Orders', 'wp-user-frontend' ),
'Refunds' => __( 'Refunds', 'wp-user-frontend' ),
'Coupons' => __( 'Coupons', 'wp-user-frontend' ),
];

foreach ( $all_features as $feature_key => $feature_label ) :
// Normalize and check if already displayed
$normalized_label = strtolower( trim( $feature_label ) );

if ( in_array( $normalized_label, $displayed_features, true ) ) {
continue;
}

// Add to displayed features to avoid future duplicates
$displayed_features[] = $normalized_label;

// Get the value - always "Unlimited" for these additional features
$feature_value = __( 'Unlimited', 'wp-user-frontend' );
?>
<li>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M6.75 10.5L9 12.75L12.75 7.5M18.75 9.75C18.75 14.7206 14.7206 18.75 9.75 18.75C4.77944 18.75 0.75 14.7206 0.75 9.75C0.75 4.77944 4.77944 0.75 9.75 0.75C14.7206 0.75 18.75 4.77944 18.75 9.75Z" stroke="#99A7B2" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span><?php echo esc_html( $feature_label ); ?>: <strong><?php echo esc_html( $feature_value ); ?></strong></span>
</li>
<?php endforeach; ?>
</ul>
Copy link

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:

head -n 430 templates/dashboard/subscription.php | tail -n +256 | cat -n

Repository: weDevsOfficial/wp-user-frontend

Length of output: 13299


🏁 Script executed:

fd subscription.php -x wc -l {}

Repository: weDevsOfficial/wp-user-frontend

Length of output: 304


Update "User Requests" to display the actual total_feature_item quota instead of hardcoded "Unlimited"

The compact and detailed feature lists use $basic_features to fill the initial 4-feature display. However, "User Requests" is hardcoded to always show "Unlimited" in the compact view (line 40), even when it should reflect $user_sub['total_feature_item'].

In the detailed view, "User Requests" is only rendered if not already shown in the compact view. Because $basic_features includes "User Requests", when there are few posts (0–3), this entry fills the compact list and gets tracked in $compact_displayed_features. Later, the detailed view's condition at line 101 skips the total_feature_item block since "user requests" is already in $displayed_features. This means the actual quota is never shown to the user.

Update $basic_features at line 40 to use the actual total_feature_item value (or keep "Unlimited" only if it is -1), ensuring the configured quota is always visible.

🤖 Prompt for AI Agents
In templates/dashboard/subscription.php around lines 256–407, the basic_features
array currently hardcodes "User Requests" as "Unlimited", so when that label
fills the compact view the actual quota ($user_sub['total_feature_item']) is
never shown in the detailed list; compute a display value for user requests
before the $basic_features declaration (e.g. set $user_requests_display = (
isset($user_sub['total_feature_item']) && -1 ===
intval($user_sub['total_feature_item']) ) ? __( 'Unlimited', 'wp-user-frontend'
) : ( isset($user_sub['total_feature_item']) ?
intval($user_sub['total_feature_item']) : __( 'Unlimited', 'wp-user-frontend' )
); then update the $basic_features entry for "User Requests" to use that
$user_requests_display variable instead of the hardcoded "Unlimited", keeping
the rest of the logic (tracking displayed features) unchanged.

@Rubaiyat-E-Mohammad
Copy link
Contributor

Rubaiyat-E-Mohammad commented Dec 30, 2025

Bad design for invoice list. Also, no space between list title @arifulhoque7 vai
image

Please do a hard recheck. In my case, it is not working after multiple hard refresh. @arifulhoque7 vai

Copy link

@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 (1)
tailwind.config.js (1)

14-17: Remove duplicate path from content array.

The path './templates/**/*.php' appears twice in the content array (lines 14 and 17). While Tailwind handles duplicates gracefully, this is redundant and causes unnecessary scanning during builds.

🔎 Proposed fix
         './admin/form-builder/views/*.php',
         './admin/form-builder/assets/js/**/*.php',
         './templates/**/*.php',
         'wpuf-functions.php',
-        // New paths from upstream (for subscription templates)
-        './templates/**/*.php',
+        // New paths from upstream
         './src/**/*.{js,css}',
     ],
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5257185 and 86298f3.

📒 Files selected for processing (3)
  • Gruntfile.js
  • tailwind.config.js
  • wpuf-functions.php
🚧 Files skipped from review as they are similar to previous changes (1)
  • Gruntfile.js
🔇 Additional comments (1)
wpuf-functions.php (1)

33-33: Approve color change for "publish" status, but verify design consistency.

The status color has been updated from #33CC33 (bright green) to rgb(5, 150, 105) (emerald green) as part of the redesign. This aligns with the PR's visual system updates.

Please verify that this specific green shade (rgb(5, 150, 105)) is part of the approved design system and matches the status badge colors used in other redesigned components (subscription cards, posts table, etc.).

Comment on lines +3881 to +3886
$field_name = isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '';

$args = [
'name' => isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '',
'id' => isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '',
'class' => isset( $_POST['field_name'] ) ? sanitize_text_field( wp_unslash( $_POST['field_name'] ) ) : '',
'name' => $field_name,
'id' => $field_name,
'class' => "{$field_name} wpuf-w-full wpuf-rounded-md wpuf-border-gray-300 focus:wpuf-border-primary focus:wpuf-ring-primary",
Copy link

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

# Find AJAX action registration for address-related AJAX handlers
echo "=== AJAX Action Registration ==="
rg -n "add_action.*wp_ajax.*address|add_action.*wp_ajax.*state" --type=php -A 2 -B 2

# Search for JavaScript files that trigger AJAX calls to wpuf_ajax_get_states_field
echo -e "\n=== JavaScript AJAX Calls (searching for address/state AJAX) ==="
rg -n "wpuf_ajax_get_states_field|wpuf.*address.*field|action.*address|action.*state" --type=js --type=ts -B 2 -A 2

# Search for where account.css is enqueued
echo -e "\n=== Account CSS Enqueue Location ==="
rg -n "account\.css|enqueue.*account" --type=php -B 5 -A 5

# Check for any form shortcode usage that might load address fields
echo -e "\n=== Form Shortcode and Address Field Usage ==="
rg -n "wpuf_account|wpuf_editprofile|address.*field|get_states_field" --type=php | head -30

Repository: weDevsOfficial/wp-user-frontend

Length of output: 50388


🏁 Script executed:

#!/bin/bash

# Search specifically for the AJAX handler function in non-minified PHP
echo "=== Search for wpuf_ajax_get_states_field or similar address AJAX handlers ==="
rg -n "wpuf_ajax_get_states_field|wpuf_ajax_address|add_action.*address" --type=php -A 5 -B 1 | head -50

# Search for add_action calls in main functions file
echo -e "\n=== AJAX add_action registration ==="
rg -n "add_action.*wp_ajax" --type=php | grep -i "address\|state" | head -20

# Specifically look in wpuf-functions.php for the function definition
echo -e "\n=== Check wpuf-functions.php for address/state functions ==="
rg -n "function.*address|function.*state" wpuf-functions.php | head -20

# Look for account.css enqueue
echo -e "\n=== Account CSS enqueue conditions ==="
rg -n "account.*\.css|wp_enqueue_style.*account" --type=php -B 3 -A 3 | head -50

Repository: weDevsOfficial/wp-user-frontend

Length of output: 4709


🏁 Script executed:

#!/bin/bash

# Find where billing-address.js is enqueued
echo "=== Where is billing-address.js enqueued? ==="
rg -n "billing.*address|billing-address\.js" --type=php -B 3 -A 3

# Look for when wpuf_account or wpuf_editprofile is displayed
echo -e "\n=== Check if address form is used only on account pages ==="
rg -n "wpuf_ajax_address_form|Address_Form_Ajax" --type=php -B 2 -A 2 | head -40

# Search for where wpuf_account shortcode is defined/used
echo -e "\n=== Where wpuf_account shortcode is used/registered ==="
rg -n "shortcode_.*wpuf_account|wpuf_account.*shortcode" --type=php -B 2 -A 2 | head -40

# Check if address form/fields appear anywhere else besides account pages
echo -e "\n=== Address field HTML template usage ==="
rg -n "wpuf-address|wpuf_biiling_country|wpuf_biiling_state" --type=php --type=js | grep -v ".min.js" | head -30

Repository: weDevsOfficial/wp-user-frontend

Length of output: 27261


🏁 Script executed:

#!/bin/bash

# Check what CSS is enqueued for payment pages
echo "=== Frontend CSS enqueue (check for payment page CSS) ==="
rg -n "wp_enqueue_style" includes/Frontend.php -A 2 -B 1 | head -60

# Look for any other Tailwind CSS files or payment-specific CSS
echo -e "\n=== Check if there's payment page CSS with Tailwind ==="
fd -e css | grep -i "payment\|checkout\|frontend" | head -20

# Verify the exact context where billing-address.js is enqueued
echo -e "\n=== Context of billing-address.js enqueue in Frontend.php ==="
sed -n '50,80p' includes/Frontend.php

Repository: weDevsOfficial/wp-user-frontend

Length of output: 3074


Refactor improves code quality, but Tailwind CSS unavailable on payment pages using this AJAX handler.

The refactoring at lines 3881–3886 properly sanitizes $_POST['field_name'] once into a local variable, which is a good practice. However, the Tailwind utility classes (wpuf-w-full, wpuf-rounded-md, wpuf-border-gray-300, focus:wpuf-border-primary, focus:wpuf-ring-primary) in the dynamically generated select field will lack styling on payment checkout pages.

The wpuf_ajax_address AJAX handler is triggered from both account pages and payment checkout pages (via includes/Frontend/Payment.php), but account.css is conditionally loaded only when [wpuf_account] or [wpuf_editprofile] shortcodes are present. On payment pages, only wpuf-layout1 and wpuf-frontend-forms CSS files are loaded—neither contains the Tailwind classes.

Either load account.css on payment pages (where the address form is used), or use fallback styling that doesn't depend on conditional Tailwind CSS loading.

🤖 Prompt for AI Agents
In wpuf-functions.php around lines 3881–3886, the sanitized $field_name is used
to build a select field with Tailwind utility classes that are only present in
account.css (which is conditionally loaded for account/editprofile shortcodes),
causing the select to be unstyled on payment checkout pages; fix by either (A)
replacing those Tailwind-only classes with CSS classes already shipped in
wpuf-layout1 or wpuf-frontend-forms so the field has fallback styling on payment
pages, or (B) enqueue/account.css when the payment pages render the address form
(detect via the same condition used in includes/Frontend/Payment.php or when the
ajax handler is used) so the Tailwind utilities are available—choose one
approach and implement consistently for all places that call wpuf_ajax_address.

arifulhoque7 and others added 2 commits January 1, 2026 16:37
Changed the font size utility from wpuf-text-md to wpuf-text-base for the active account navigation item to ensure consistent typography.
@Rubaiyat-E-Mohammad Rubaiyat-E-Mohammad added the QA Approved This PR is approved by the QA team label Jan 1, 2026
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 QA Approved This PR is approved by the QA team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants