fix: consolidate backend changes and fix icon imports
- Add standard .gitignore patterns (node_modules, .env, IDE files) - Coupon.php: fix data structure for DataTable, add status filter - Order.php: fix data structure to match OrderListItem expectations - Product.php: add multi-currency prices array, unify nonce to 'formipay-admin' - client.js: fix AJAX action names to match PHP (underscores → hyphens) - OrderList.js: fix icon import (Icons.list), add response handling - OrderListItem.js: fix icon import (Icons.seen)
This commit is contained in:
11
.gitignore
vendored
11
.gitignore
vendored
@@ -1 +1,12 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
coverage
|
||||||
|
.env
|
||||||
|
*.log
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
@@ -612,6 +612,9 @@ class Coupon {
|
|||||||
$args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
|
$args['s'] = sanitize_text_field( wp_unslash($_REQUEST['search']) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle status filtering (active/inactive)
|
||||||
|
$status_filter = isset($_REQUEST['status']) ? sanitize_text_field($_REQUEST['status']) : 'all';
|
||||||
|
|
||||||
$get_coupons = get_posts($args);
|
$get_coupons = get_posts($args);
|
||||||
$global_currencies = get_global_currency_array();
|
$global_currencies = get_global_currency_array();
|
||||||
|
|
||||||
@@ -619,7 +622,13 @@ class Coupon {
|
|||||||
if(!empty($get_coupons)){
|
if(!empty($get_coupons)){
|
||||||
foreach($get_coupons as $key => $coupon){
|
foreach($get_coupons as $key => $coupon){
|
||||||
|
|
||||||
$active = true;
|
$is_active = formipay_get_post_meta($coupon->ID, 'active') == 'on';
|
||||||
|
|
||||||
|
// Apply status filter
|
||||||
|
if ($status_filter !== 'all') {
|
||||||
|
if ($status_filter === 'active' && !$is_active) continue;
|
||||||
|
if ($status_filter === 'inactive' && $is_active) continue;
|
||||||
|
}
|
||||||
|
|
||||||
$date_limit = formipay_get_post_meta($coupon->ID, 'date_limit');
|
$date_limit = formipay_get_post_meta($coupon->ID, 'date_limit');
|
||||||
|
|
||||||
@@ -648,23 +657,21 @@ class Coupon {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if($active){
|
|
||||||
$coupons[] = [
|
$coupons[] = [
|
||||||
'ID' => $coupon->ID,
|
'ID' => $coupon->ID,
|
||||||
'code' => get_the_title($coupon->ID),
|
'code' => get_the_title($coupon->ID),
|
||||||
'value' => $amount_value,
|
'amount' => $amount_value,
|
||||||
'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')),
|
'type' => ucfirst(formipay_get_post_meta($coupon->ID, 'type')),
|
||||||
'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'),
|
'case_sensitive' => formipay_get_post_meta($coupon->ID, 'case_sensitive'),
|
||||||
'usages' => [
|
'usage_count' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
|
||||||
'used' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
|
'usages' => $this->count_order_by_coupon_code(get_the_title($coupon->ID)),
|
||||||
'limit' => (intval(formipay_get_post_meta($coupon->ID, 'use_limit')) > 0) ? formipay_get_post_meta($coupon->ID, 'use_limit') : '∞'
|
|
||||||
],
|
|
||||||
'date_limit' => false !== $date_limit ? formipay_date('Y-m-d', intval(formipay_get_post_meta($coupon->ID, 'date_limit')) / 1000) : 'none',
|
'date_limit' => false !== $date_limit ? formipay_date('Y-m-d', intval(formipay_get_post_meta($coupon->ID, 'date_limit')) / 1000) : 'none',
|
||||||
'status' => (formipay_get_post_meta($coupon->ID, 'active') == 'on') ? 'Active' : 'Inactive'
|
'active' => $is_active ? 'on' : 'off',
|
||||||
|
'post_status' => $is_active ? 'active' : 'inactive',
|
||||||
|
'status' => $is_active ? 'active' : 'inactive'
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$response = [
|
$response = [
|
||||||
'results' => $coupons,
|
'results' => $coupons,
|
||||||
|
|||||||
@@ -646,7 +646,7 @@ class Order {
|
|||||||
|
|
||||||
// React admin
|
// React admin
|
||||||
printf(
|
printf(
|
||||||
'<div id="formipay-admin-root" data-formipay-mount="%s"></div>',
|
'<div class="wrap"><div id="formipay-admin-root" data-formipay-mount="%s"></div></div>',
|
||||||
esc_attr($page)
|
esc_attr($page)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -936,18 +936,28 @@ class Order {
|
|||||||
foreach ($get_filtered_orders as $key => $order) {
|
foreach ($get_filtered_orders as $key => $order) {
|
||||||
$currency = explode(':::', formipay_get_post_meta($order->form_id, 'product_currency'));
|
$currency = explode(':::', formipay_get_post_meta($order->form_id, 'product_currency'));
|
||||||
$code = !empty($currency[0]) ? $currency[0] : '';
|
$code = !empty($currency[0]) ? $currency[0] : '';
|
||||||
// Prepare order data
|
|
||||||
|
// Keep status as-is (with hyphens) to match STATUS_COLORS keys
|
||||||
|
$status = $order->status;
|
||||||
|
|
||||||
|
// Transform form_data to the structure expected by OrderListItem
|
||||||
|
$raw_form_data = maybe_unserialize($order->form_data);
|
||||||
|
$transformed_form_data = [];
|
||||||
|
if (is_array($raw_form_data)) {
|
||||||
|
foreach ($raw_form_data as $field_key => $field_value) {
|
||||||
|
$transformed_form_data[] = [
|
||||||
|
'name' => $field_key,
|
||||||
|
'value' => is_array($field_value) && isset($field_value['value']) ? $field_value['value'] : $field_value,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$orders[] = [
|
$orders[] = [
|
||||||
'ID' => $order->id,
|
'id' => $order->id,
|
||||||
'form' => get_the_title($order->form_id),
|
'created_date' => $order->created_date,
|
||||||
'date' => $order->created_date,
|
'form_data' => $transformed_form_data,
|
||||||
'payment_gateway' => ucwords(str_replace('_', ' ', $order->payment_gateway)),
|
'total_formatted' => formipay_price_format($order->total, $order->form_id),
|
||||||
'status' => ucwords(str_replace('-', ' ', $order->status)),
|
'status' => $status,
|
||||||
'total' => [
|
|
||||||
'flag' => formipay_get_flag_by_currency($code),
|
|
||||||
'name' => $code,
|
|
||||||
'value' => formipay_price_format($order->total, $order->form_id),
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ class Product {
|
|||||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'nonce' => wp_create_nonce('formipay-admin-product-page')
|
'nonce' => wp_create_nonce('formipay-admin')
|
||||||
] );
|
] );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +590,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_tabledata_products() {
|
public function formipay_tabledata_products() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
@@ -668,6 +668,7 @@ class Product {
|
|||||||
$total_products = $query->found_posts;
|
$total_products = $query->found_posts;
|
||||||
|
|
||||||
// Process results
|
// Process results
|
||||||
|
$global_currencies = get_global_currency_array();
|
||||||
$products = [];
|
$products = [];
|
||||||
foreach ($product_ids as $product_id) {
|
foreach ($product_ids as $product_id) {
|
||||||
$product = get_post($product_id);
|
$product = get_post($product_id);
|
||||||
@@ -675,19 +676,58 @@ class Product {
|
|||||||
$currency = explode(':::', get_post_meta($product_id, 'product_currency', true));
|
$currency = explode(':::', get_post_meta($product_id, 'product_currency', true));
|
||||||
$categories = wp_get_post_terms($product_id, 'formipay-product-category', ['fields' => 'names']);
|
$categories = wp_get_post_terms($product_id, 'formipay-product-category', ['fields' => 'names']);
|
||||||
|
|
||||||
|
// Build multi-currency prices array
|
||||||
|
$prices = [];
|
||||||
|
foreach ($global_currencies as $curr) {
|
||||||
|
$curr_raw = $curr['currency'];
|
||||||
|
$curr_parts = explode(':::', $curr_raw);
|
||||||
|
$curr_code = $curr_parts[0] ?? '';
|
||||||
|
$symbol = formipay_get_currency_data_by_value($curr_raw, 'symbol');
|
||||||
|
|
||||||
|
$regular_price = get_post_meta($product_id, 'setting_product_price_regular_' . $symbol, true);
|
||||||
|
$sale_price = get_post_meta($product_id, 'setting_product_price_sale_' . $symbol, true);
|
||||||
|
|
||||||
|
// Only add if we have at least a regular price
|
||||||
|
if (!empty($regular_price)) {
|
||||||
|
// Format price using this currency's own formatting rules
|
||||||
|
$decimal_digits = intval($curr['decimal_digits'] ?? 2);
|
||||||
|
$decimal_symbol = $curr['decimal_symbol'] ?? '.';
|
||||||
|
$thousand_separator = $curr['thousand_separator'] ?? ',';
|
||||||
|
|
||||||
|
$formatted_regular = $symbol . ' ' . number_format(floatval($regular_price), $decimal_digits, $decimal_symbol, $thousand_separator);
|
||||||
|
$formatted_sale = !empty($sale_price) ? $symbol . ' ' . number_format(floatval($sale_price), $decimal_digits, $decimal_symbol, $thousand_separator) : '';
|
||||||
|
|
||||||
|
$prices[] = [
|
||||||
|
'currency' => $curr_code,
|
||||||
|
'symbol' => $symbol,
|
||||||
|
'flag' => formipay_get_flag_by_currency($curr_raw),
|
||||||
|
'regular_price' => $formatted_regular,
|
||||||
|
'sale_price' => $formatted_sale,
|
||||||
|
'has_sale' => !empty($sale_price),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback to single price if no multi-currency prices set
|
||||||
|
if (empty($prices)) {
|
||||||
|
$fallback_price = get_post_meta($product_id, 'price', true);
|
||||||
|
$prices[] = [
|
||||||
|
'currency' => $currency[0] ?? 'USD',
|
||||||
|
'symbol' => $currency[2] ?? '$',
|
||||||
|
'flag' => formipay_get_flag_by_currency($currency[0] ?? ''),
|
||||||
|
'regular_price' => formipay_price_format($fallback_price, $product_id),
|
||||||
|
'sale_price' => '',
|
||||||
|
'has_sale' => false,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
$products[] = [
|
$products[] = [
|
||||||
'ID' => $product_id,
|
'ID' => $product_id,
|
||||||
'title' => $product->post_title,
|
'title' => $product->post_title,
|
||||||
'category' => implode(', ', $categories),
|
'category' => implode(', ', $categories),
|
||||||
'type' => formipay_get_post_meta($product_id, 'product_type'),
|
'type' => formipay_get_post_meta($product_id, 'product_type'),
|
||||||
'stock' => formipay_get_post_meta($product_id, 'stock') ?: '∞',
|
'stock' => formipay_get_post_meta($product_id, 'stock') ?: '∞',
|
||||||
'price' => [
|
'prices' => $prices,
|
||||||
'flag' => formipay_get_flag_by_currency($currency[0] ?? ''),
|
|
||||||
'name' => formipay_price_format(
|
|
||||||
get_post_meta($product_id, 'price', true),
|
|
||||||
$product_id
|
|
||||||
)
|
|
||||||
],
|
|
||||||
'status' => $product->post_status,
|
'status' => $product->post_status,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -710,7 +750,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_create_product_post() {
|
public function formipay_create_product_post() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
@@ -745,7 +785,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_product_get_currencies() {
|
public function formipay_product_get_currencies() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
@@ -773,7 +813,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_delete_product() {
|
public function formipay_delete_product() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
@@ -801,7 +841,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_bulk_delete_product() {
|
public function formipay_bulk_delete_product() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
@@ -847,7 +887,7 @@ class Product {
|
|||||||
|
|
||||||
public function formipay_duplicate_product() {
|
public function formipay_duplicate_product() {
|
||||||
|
|
||||||
check_ajax_referer( 'formipay-admin-product-page', '_wpnonce' );
|
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||||
|
|
||||||
if ( ! current_user_can( 'manage_options' ) ) {
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ export const customersApi = {
|
|||||||
* Products API
|
* Products API
|
||||||
*/
|
*/
|
||||||
export const productsApi = {
|
export const productsApi = {
|
||||||
list: (params = {}) => ajaxRequest('formipay_tabledata_products', params),
|
list: (params = {}) => ajaxRequest('formipay-tabledata-products', params),
|
||||||
get: (productId) => ajaxRequest('formipay_get_product', { post_id: productId }),
|
get: (productId) => ajaxRequest('formipay-get-product', { post_id: productId }),
|
||||||
getVariables: (productId) => ajaxRequest('get_product_variables', { post_id: productId }),
|
getVariables: (productId) => ajaxRequest('get_product_variables', { post_id: productId }),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { __ } from '@wordpress/i18n';
|
|||||||
import { useState, useCallback, useEffect } from '@wordpress/element';
|
import { useState, useCallback, useEffect } from '@wordpress/element';
|
||||||
import { SearchControl, SelectControl, Button } from '@wordpress/components';
|
import { SearchControl, SelectControl, Button } from '@wordpress/components';
|
||||||
import { Icon } from '@wordpress/icons';
|
import { Icon } from '@wordpress/icons';
|
||||||
import list from '@wordpress/icons/build/list';
|
import * as Icons from '@wordpress/icons';
|
||||||
import { ordersApi } from '../../api/client';
|
import { ordersApi } from '../../api/client';
|
||||||
import OrderListItem from './OrderListItem';
|
import OrderListItem from './OrderListItem';
|
||||||
import './OrderList.css';
|
import './OrderList.css';
|
||||||
@@ -37,9 +37,14 @@ export default function OrderList({ onSelectOrder }) {
|
|||||||
offset: pagination.offset,
|
offset: pagination.offset,
|
||||||
})
|
})
|
||||||
.then(result => {
|
.then(result => {
|
||||||
if (result.data) {
|
console.log('Orders API response:', result);
|
||||||
setOrders(result.data.results || []);
|
// Handle both response formats: with or without data wrapper
|
||||||
setTotal(result.data.total || 0);
|
const data = result.data || result;
|
||||||
|
if (data) {
|
||||||
|
setOrders(data.results || []);
|
||||||
|
setTotal(data.total || 0);
|
||||||
|
} else {
|
||||||
|
console.error('Unexpected response structure:', result);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@@ -86,7 +91,7 @@ export default function OrderList({ onSelectOrder }) {
|
|||||||
<div className="formipay-order-list">
|
<div className="formipay-order-list">
|
||||||
<div className="formipay-orders-header">
|
<div className="formipay-orders-header">
|
||||||
<h2>
|
<h2>
|
||||||
<Icon icon={list()} />
|
<Icon icon={Icons.list} />
|
||||||
{ __('Orders', 'formipay') }
|
{ __('Orders', 'formipay') }
|
||||||
</h2>
|
</h2>
|
||||||
<span className="order-count">
|
<span className="order-count">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { Icon } from '@wordpress/icons';
|
import { Icon } from '@wordpress/icons';
|
||||||
import seen from '@wordpress/icons/build/visible';
|
import * as Icons from '@wordpress/icons';
|
||||||
import './OrderListItem.css';
|
import './OrderListItem.css';
|
||||||
|
|
||||||
const STATUS_COLORS = {
|
const STATUS_COLORS = {
|
||||||
@@ -79,7 +79,7 @@ export default function OrderListItem({ order, onSelect }) {
|
|||||||
className="button button-small"
|
className="button button-small"
|
||||||
onClick={onSelect}
|
onClick={onSelect}
|
||||||
>
|
>
|
||||||
<Icon icon={seen()} size={16} />
|
<Icon icon={Icons.seen} size={16} />
|
||||||
{ __('View', 'formipay') }
|
{ __('View', 'formipay') }
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user