feat: update design system to match WPCFTO architecture

- Update CSS tokens to match WPCFTO values (sidebar #2c3e50, content #f0f3f5)
- Update Field component to 40%/60% 2-column layout
- Update Checkbox component to toggle switch UI
- Add GroupTitle component for visual section dividers
- Update TabNav component to WPCFTO sidebar styling
- Add MetaboxLayout component for 2-column wrapper
- Update TabPanel styles to match WPCFTO tab content area
- Fix Coupons page to use native WordPress post.php editor instead of modal

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
dwindown
2026-04-19 07:05:14 +07:00
parent d8c81a4022
commit bde43d8c66
10 changed files with 527 additions and 101 deletions

View File

@@ -35,6 +35,8 @@ class Coupon {
add_action( 'wp_ajax_formipay-delete-coupon', [$this, 'formipay_delete_coupon'] );
add_action( 'wp_ajax_formipay-bulk-delete-coupon', [$this, 'formipay_bulk_delete_coupon'] );
add_action( 'wp_ajax_formipay-duplicate-coupon', [$this, 'formipay_duplicate_coupon'] );
add_action( 'wp_ajax_formipay-get-coupon', [$this, 'formipay_get_coupon'] );
add_action( 'wp_ajax_formipay-save-coupon', [$this, 'formipay_save_coupon'] );
// Order
add_filter( 'formipay/order/order-details', [$this, 'order_details'], 99, 3 );
@@ -888,4 +890,160 @@ class Coupon {
] );
}
/**
* Get coupon data for React editor
*/
public function formipay_get_coupon() {
check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
}
$post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
if ( empty($post_id) ) {
wp_send_json_error( [ 'message' => esc_html__( 'Coupon ID is required.', 'formipay' ) ] );
}
$post = get_post($post_id);
if ( ! $post || $post->post_type !== 'formipay-coupon' ) {
wp_send_json_error( [ 'message' => esc_html__( 'Coupon not found.', 'formipay' ) ] );
}
$global_currencies = get_global_currency_array();
// Build coupon data
$coupon_data = [
'ID' => $post_id,
'post_title' => $post->post_title,
'active' => formipay_get_post_meta($post_id, 'active'),
'type' => formipay_get_post_meta($post_id, 'type'),
'amount_percentage' => formipay_get_post_meta($post_id, 'amount_percentage'),
'case_sensitive' => formipay_get_post_meta($post_id, 'case_sensitive'),
'free_shipping' => formipay_get_post_meta($post_id, 'free_shipping'),
'quantity_active' => formipay_get_post_meta($post_id, 'quantity_active'),
'use_limit' => formipay_get_post_meta($post_id, 'use_limit'),
'date_limit' => formipay_get_post_meta($post_id, 'date_limit'),
'amounts_fixed' => [],
'max_amounts' => [],
'forms' => formipay_get_post_meta($post_id, 'forms') ?: [],
'products' => formipay_get_post_meta($post_id, 'products') ?: [],
'customers' => formipay_get_post_meta($post_id, 'customers') ?: [],
];
// Get fixed amounts for each currency
foreach ($global_currencies as $currency) {
$currency_raw = $currency['currency'];
$currency_parts = explode(':::', $currency_raw);
$currency_code = $currency_parts[0] ?? '';
$symbol = formipay_get_currency_data_by_value($currency_raw, 'symbol');
$amount_fixed = formipay_get_post_meta($post_id, 'amount_fixed_' . $symbol);
if ( $amount_fixed ) {
$coupon_data['amounts_fixed'][] = [
'currency' => $currency_code,
'symbol' => $symbol,
'amount' => $amount_fixed,
];
}
$max_amount = formipay_get_post_meta($post_id, 'max_amount_' . $symbol);
if ( $max_amount ) {
$coupon_data['max_amounts'][] = [
'currency' => $currency_code,
'symbol' => $symbol,
'amount' => $max_amount,
];
}
}
wp_send_json_success( $coupon_data );
}
/**
* Save coupon data from React editor
*/
public function formipay_save_coupon() {
check_ajax_referer( 'formipay-admin', '_wpnonce' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
}
$post_id = isset($_REQUEST['id']) ? intval($_REQUEST['id']) : 0;
$title = isset($_REQUEST['title']) ? sanitize_text_field(wp_unslash($_REQUEST['title'])) : '';
if ( empty($title) ) {
wp_send_json_error( [ 'message' => esc_html__( 'Coupon code is required.', 'formipay' ) ] );
}
$global_currencies = get_global_currency_array();
// Prepare post data
$post_data = [
'post_title' => $title,
'post_type' => 'formipay-coupon',
'post_status' => 'publish',
];
if ( $post_id > 0 ) {
$post_data['ID'] = $post_id;
$post_data['post_status'] = get_post_status($post_id);
$new_post_id = wp_update_post($post_data);
} else {
$new_post_id = wp_insert_post($post_data);
}
if ( is_wp_error($new_post_id) ) {
wp_send_json_error( [ 'message' => $new_post_id->get_error_message() ] );
}
// Save meta fields
$meta_fields = [
'active',
'type',
'amount_percentage',
'case_sensitive',
'free_shipping',
'quantity_active',
'use_limit',
'date_limit',
];
foreach ($meta_fields as $field) {
$value = isset($_REQUEST[$field]) ? wp_unslash($_REQUEST[$field]) : '';
update_post_meta($new_post_id, $field, $value);
}
// Save fixed amounts
foreach ($global_currencies as $currency) {
$symbol = formipay_get_currency_data_by_value($currency['currency'], 'symbol');
if ( isset($_REQUEST['amount_fixed_' . $symbol]) ) {
update_post_meta($new_post_id, 'amount_fixed_' . $symbol, wp_unslash($_REQUEST['amount_fixed_' . $symbol]));
}
if ( isset($_REQUEST['max_amount_' . $symbol]) ) {
update_post_meta($new_post_id, 'max_amount_' . $symbol, wp_unslash($_REQUEST['max_amount_' . $symbol]));
}
}
// Save relation fields
$relation_fields = ['forms', 'products', 'customers'];
foreach ($relation_fields as $field) {
if ( isset($_REQUEST[$field]) ) {
$values = is_array($_REQUEST[$field]) ? array_map('intval', $_REQUEST[$field]) : [];
update_post_meta($new_post_id, $field, $values);
}
}
wp_send_json_success( [
'message' => esc_html__( 'Coupon saved successfully.', 'formipay' ),
'id' => $new_post_id,
] );
}
}