feat: add React metabox island for coupon editor
- Create CouponMetabox React component with WPCFTO design system - Add MetaboxLayout with vertical tabs (Rules, Restrictions) - Implement Rules tab: active toggle, type radio, amount fields, multi-currency support - Implement Restrictions tab: usage limit, date limit, autocomplete for forms/products/customers - Add metabox registration in Coupon.php for formipay-coupon post type - Update ReactAdmin to load assets on post.php edit screens - Add autocomplete AJAX handler for relation fields - Disable old WPCFTO metabox in favor of React island
This commit is contained in:
@@ -19,8 +19,11 @@ class ReactAdmin {
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
// Only load React assets on Formipay admin pages
|
||||
if ( strpos( $screen->id, 'formipay' ) === false ) {
|
||||
// Load React assets on Formipay admin pages OR on post edit screens for our CPTs
|
||||
$is_formipay_admin = strpos($screen->id, 'formipay') !== false;
|
||||
$is_formipay_cpt = $screen->base === 'post' && in_array($screen->post_type, ['formipay-coupon', 'formipay-product', 'formipay-form']);
|
||||
|
||||
if (!$is_formipay_admin && !$is_formipay_cpt) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,7 +31,7 @@ class ReactAdmin {
|
||||
$build_dir = FORMIPAY_PATH . 'build';
|
||||
$build_url = FORMIPAY_URL . 'build';
|
||||
|
||||
if ( ! file_exists( $build_dir . '/admin.asset.php' ) ) {
|
||||
if (!file_exists($build_dir . '/admin.asset.php')) {
|
||||
error_log('[Formipay] Build files not found at: ' . $build_dir . '/admin.asset.php');
|
||||
return; // Build not generated yet
|
||||
}
|
||||
@@ -61,19 +64,19 @@ class ReactAdmin {
|
||||
);
|
||||
|
||||
// Localize script with required data
|
||||
$data = apply_filters( 'formipay/admin/data', [
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'restUrl' => rest_url( 'formipay/v1' ),
|
||||
'nonce' => wp_create_nonce( 'formipay-admin' ),
|
||||
$data = apply_filters('formipay/admin/data', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'restUrl' => rest_url('formipay/v1'),
|
||||
'nonce' => wp_create_nonce('formipay-admin'),
|
||||
'pluginUrl' => FORMIPAY_URL,
|
||||
'siteUrl' => site_url(),
|
||||
] );
|
||||
]);
|
||||
|
||||
// Debug logging
|
||||
error_log('[Formipay] Enqueuing React assets on screen: ' . $screen->id);
|
||||
error_log('[Formipay] Page data: ' . wp_json_encode($data));
|
||||
|
||||
wp_localize_script( 'formipay-admin', 'formipayAdmin', $data );
|
||||
wp_localize_script('formipay-admin', 'formipayAdmin', $data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ class 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'] );
|
||||
add_action( 'wp_ajax_formipay-autocomplete-search', [$this, 'formipay_autocomplete_search'] );
|
||||
|
||||
// React Metabox
|
||||
add_action( 'add_meta_boxes', [$this, 'add_react_metabox'] );
|
||||
add_action( 'admin_footer-post.php', [$this, 'render_react_metabox_template'] );
|
||||
|
||||
// Order
|
||||
add_filter( 'formipay/order/order-details', [$this, 'order_details'], 99, 3 );
|
||||
@@ -101,79 +106,29 @@ class Coupon {
|
||||
}
|
||||
|
||||
public function enqueue_admin() {
|
||||
// Assets now handled by ReactAdmin class
|
||||
return;
|
||||
|
||||
if($current_screen->id == 'formipay_page_formipay-coupons') {
|
||||
|
||||
wp_enqueue_style( 'page-coupons', FORMIPAY_URL . 'admin/assets/css/page-coupons.css', [], FORMIPAY_VERSION, 'all' );
|
||||
wp_enqueue_script( 'page-coupons', FORMIPAY_URL . 'admin/assets/js/page-coupons.js', ['jquery', 'gridjs'], FORMIPAY_VERSION, true );
|
||||
|
||||
wp_localize_script( 'page-coupons', 'formipay_coupons_page', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
'columns' => [
|
||||
'id' => esc_html__( 'ID', 'formipay' ),
|
||||
'code' => esc_html__( 'Coupon Code', 'formipay' ),
|
||||
'usages' => esc_html__( 'Usages', 'formipay' ),
|
||||
'date_limit' => esc_html__( 'Date Limit', 'formipay' ),
|
||||
'status' => esc_html__( 'Status', 'formipay' ),
|
||||
'type' => esc_html__( 'Type', 'formipay' ),
|
||||
'amount' => esc_html__( 'Amount', 'formipay' )
|
||||
],
|
||||
'filter_form' => [
|
||||
'products' => [
|
||||
'placeholder' => esc_html__( 'Filter by Product', 'formipay' ),
|
||||
'noresult_text' => esc_html__( 'No results found', 'formipay' )
|
||||
]
|
||||
],
|
||||
'modal' => [
|
||||
'add' => [
|
||||
'title' => esc_html__( 'Your New Coupon Code', 'formipay' ),
|
||||
'validation' => esc_html__( 'Coupon code is still empty. Please input the code before continue', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Create New Coupon', 'formipay' )
|
||||
],
|
||||
'delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the coupon?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Delete Permanently', 'formipay' )
|
||||
],
|
||||
'bulk_delete' => [
|
||||
'question' => esc_html__( 'Do you want to delete the selected the coupon(s)?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
'duplicate' => [
|
||||
'question' => esc_html__( 'Do you want to duplicate the coupon?', 'formipay' ),
|
||||
'cancelButton' => esc_html__( 'Cancel', 'formipay' ),
|
||||
'confirmButton' => esc_html__( 'Confirm', 'formipay' )
|
||||
],
|
||||
],
|
||||
'nonce' => wp_create_nonce('formipay-admin-coupon-page')
|
||||
] );
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( $screen->post_type === 'formipay-coupon' && $screen->base === 'post' ) {
|
||||
wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
|
||||
wp_localize_script( 'sweetalert2', 'formipay_admin', [
|
||||
'ajax_url' => admin_url('admin-ajax.php'),
|
||||
'site_url' => site_url(),
|
||||
] );
|
||||
// Enqueue SweetAlert2 for coupon post edit screen
|
||||
if ($screen && $screen->post_type === 'formipay-coupon' && $screen->base === 'post') {
|
||||
wp_enqueue_style('sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.4', 'all');
|
||||
wp_enqueue_script('sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.4', true);
|
||||
|
||||
// Localize admin data
|
||||
wp_localize_script('formipay-admin', 'formipayAdmin', [
|
||||
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||
'siteUrl' => site_url(),
|
||||
'nonce' => wp_create_nonce('formipay-admin'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
public function cpt_post_fields_box($boxes) {
|
||||
$boxes['formipay_coupon_settings'] = array(
|
||||
'post_type' => array('formipay-coupon'),
|
||||
'label' => __('Details', 'formipay'),
|
||||
);
|
||||
|
||||
// Disabled - using React metabox instead
|
||||
// $boxes['formipay_coupon_settings'] = array(
|
||||
// 'post_type' => array('formipay-coupon'),
|
||||
// 'label' => __('Details', 'formipay'),
|
||||
// );
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
@@ -1046,4 +1001,101 @@ class Coupon {
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add React metabox for coupon editor
|
||||
*/
|
||||
public function add_react_metabox() {
|
||||
add_meta_box(
|
||||
'formipay_coupon_reactor_metabox',
|
||||
__( 'Coupon Settings', 'formipay' ),
|
||||
[$this, 'render_react_metabox'],
|
||||
'formipay-coupon',
|
||||
'normal',
|
||||
'high'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render React metabox container
|
||||
*/
|
||||
public function render_react_metabox($post) {
|
||||
?>
|
||||
<div
|
||||
data-formipay-metabox="coupon"
|
||||
data-post-id="<?php echo esc_attr($post->ID); ?>"
|
||||
class="formipay-react-metabox-container"
|
||||
>
|
||||
<div class="formipay-loading">
|
||||
<div class="formipay-spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render React metabox template (hidden)
|
||||
*/
|
||||
public function render_react_metabox_template() {
|
||||
global $post;
|
||||
|
||||
if (!$post || $post->post_type !== 'formipay-coupon') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get global currencies
|
||||
$global_currencies = get_global_currency_array();
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
window.formipayGlobalCurrencies = <?php echo wp_json_encode($global_currencies); ?>;
|
||||
window.formipayGetFlag = function(currencyRaw) {
|
||||
<?php
|
||||
foreach ($global_currencies as $currency) {
|
||||
echo 'if (currencyRaw === "' . esc_js($currency['currency']) . '") return "' . esc_url(formipay_get_flag_by_currency($currency['currency'])) . '";';
|
||||
}
|
||||
?>
|
||||
return '';
|
||||
};
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Autocomplete search for relation fields
|
||||
*/
|
||||
public function formipay_autocomplete_search() {
|
||||
|
||||
check_ajax_referer( 'formipay-admin', '_wpnonce' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( [ 'message' => 'Unauthorized' ] );
|
||||
}
|
||||
|
||||
$post_type = isset($_REQUEST['post_type']) ? sanitize_text_field(wp_unslash($_REQUEST['post_type'])) : '';
|
||||
$search = isset($_REQUEST['search']) ? sanitize_text_field(wp_unslash($_REQUEST['search'])) : '';
|
||||
|
||||
if (empty($post_type) || strlen($search) < 2) {
|
||||
wp_send_json_error( [ 'message' => 'Invalid request' ] );
|
||||
}
|
||||
|
||||
$query = get_posts([
|
||||
'post_type' => $post_type,
|
||||
's' => $search,
|
||||
'posts_per_page' => 20,
|
||||
'post_status' => ['publish', 'draft'],
|
||||
]);
|
||||
|
||||
$results = [];
|
||||
if (!empty($query)) {
|
||||
foreach ($query as $post) {
|
||||
$results[] = [
|
||||
'value' => $post->ID,
|
||||
'label' => $post->post_title,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
wp_send_json_success($results);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user