Implement dual-mode rendering allowing classic Grid.js and new React versions to run side-by-side during migration. - Add coexistence mode checks to all admin page methods - Check query param ?react=1 or option 'formipay_use_react_admin' - Include classic PHP pages when React not active - Add admin notice showing current version with toggle button - Add footer toggle link to switch between versions This ensures zero feature loss - old Grid.js pages continue working (~20 features per page) while React versions are developed. Files: - Form.php, Coupon.php, Access.php, Order.php - Customer.php, Product.php, License.php - ReactAdmin.php (added version_notice, footer_toggle) Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
216 lines
6.3 KiB
PHP
216 lines
6.3 KiB
PHP
<?php
|
|
namespace Formipay\Admin;
|
|
use Formipay\Traits\SingletonTrait;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) exit;
|
|
|
|
class ReactAdmin {
|
|
|
|
use SingletonTrait;
|
|
|
|
protected function __construct() {
|
|
|
|
add_action( 'admin_enqueue_scripts', [$this, 'enqueue_assets'] );
|
|
add_filter( 'formipay/admin/data', [$this, 'localize_data'] );
|
|
add_action( 'admin_notices', [$this, 'version_notice'] );
|
|
add_filter( 'admin_footer_text', [$this, 'footer_toggle'] );
|
|
|
|
}
|
|
|
|
public function enqueue_assets() {
|
|
|
|
$screen = get_current_screen();
|
|
|
|
// Only load React assets on Formipay admin pages
|
|
if ( strpos( $screen->id, 'formipay' ) === false ) {
|
|
return;
|
|
}
|
|
|
|
// Enqueue React build assets
|
|
$build_dir = FORMIPAY_PATH . 'build';
|
|
$build_url = FORMIPAY_URL . 'build';
|
|
|
|
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
|
|
}
|
|
|
|
$assets_file = require $build_dir . '/admin.asset.php';
|
|
$dependencies = $assets_file['dependencies'] ?? [];
|
|
|
|
// Filter out icon build dependencies - they're bundled, not separate scripts
|
|
$original_count = count($dependencies);
|
|
$dependencies = array_values(array_filter($dependencies, function($dep) {
|
|
return strpos($dep, 'wp-icons/build/') === false;
|
|
}));
|
|
error_log('[Formipay] Filtered dependencies: ' . $original_count . ' -> ' . count($dependencies));
|
|
|
|
$version = $assets_file['version'] ?? FORMIPAY_VERSION;
|
|
|
|
wp_enqueue_style(
|
|
'formipay-admin-style',
|
|
$build_url . '/admin.css',
|
|
[],
|
|
$version
|
|
);
|
|
|
|
wp_enqueue_script(
|
|
'formipay-admin',
|
|
$build_url . '/admin.js',
|
|
$dependencies,
|
|
$version,
|
|
true
|
|
);
|
|
|
|
// 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' ),
|
|
] );
|
|
|
|
// 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 );
|
|
|
|
}
|
|
|
|
public function localize_data( $data ) {
|
|
|
|
$screen = get_current_screen();
|
|
$page = '';
|
|
|
|
// Determine current page based on screen ID
|
|
if ( $screen->id === 'formipay_page_formipay-orders' ) {
|
|
$page = 'orders';
|
|
} elseif ( $screen->id === 'formipay_page_formipay-customers' ) {
|
|
$page = 'customers';
|
|
} elseif ( $screen->id === 'formipay_page_formipay-products' ) {
|
|
$page = 'products';
|
|
} elseif ( $screen->id === 'toplevel_page_formipay' ) {
|
|
$page = 'forms';
|
|
} elseif ( $screen->id === 'formipay_page_formipay-coupons' ) {
|
|
$page = 'coupons';
|
|
} elseif ( $screen->id === 'formipay_page_formipay-access' ) {
|
|
$page = 'access';
|
|
} elseif ( $screen->id === 'formipay_page_formipay-licenses' ) {
|
|
$page = 'licenses';
|
|
}
|
|
|
|
if ( $page ) {
|
|
$data[$page] = $this->get_page_data( $page );
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
private function get_page_data( $page ) {
|
|
|
|
$data = [];
|
|
|
|
switch ( $page ) {
|
|
|
|
case 'orders':
|
|
$data['statusOptions'] = formipay_order_status_list();
|
|
break;
|
|
|
|
case 'customers':
|
|
$data['columns'] = [
|
|
'id' => __( 'ID', 'formipay' ),
|
|
'name' => __( 'Name', 'formipay' ),
|
|
'email' => __( 'Email', 'formipay' ),
|
|
'phone' => __( 'Phone', 'formipay' ),
|
|
'total_order' => __( 'Total Orders', 'formipay' ),
|
|
];
|
|
break;
|
|
|
|
case 'products':
|
|
$data['currencies'] = formipay_global_currency_options();
|
|
break;
|
|
|
|
case 'forms':
|
|
case 'coupons':
|
|
case 'access':
|
|
case 'licenses':
|
|
// These pages fetch data via AJAX, no initial data needed
|
|
$data = [];
|
|
break;
|
|
|
|
}
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
/**
|
|
* Render React mount point
|
|
*/
|
|
public static function render_mount_point( $page ) {
|
|
|
|
printf(
|
|
'<div id="formipay-admin-root" data-formipay-mount="%s">Loading %s...</div>',
|
|
esc_attr( $page ),
|
|
esc_html( ucfirst( $page ) )
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Show admin notice about current admin version
|
|
*/
|
|
public function version_notice() {
|
|
|
|
$screen = get_current_screen();
|
|
|
|
// Only show on Formipay admin pages
|
|
if ( strpos( $screen->id, 'formipay' ) === false ) {
|
|
return;
|
|
}
|
|
|
|
$use_react = isset($_GET['react']) || get_option('formipay_use_react_admin', false);
|
|
$version = $use_react ? 'React (Beta)' : 'Classic';
|
|
|
|
printf(
|
|
'<div class="notice notice-info inline">
|
|
<p>
|
|
<strong>Formipay Admin:</strong> Using %s version.
|
|
<a href="%s" class="button button-small" style="margin-left: 10px;">Switch to %s</a>
|
|
</p>
|
|
</div>',
|
|
esc_html( $version ),
|
|
esc_url( add_query_arg( 'react', $use_react ? '0' : '1' ) ),
|
|
esc_html( $use_react ? 'Classic' : 'React (Beta)' )
|
|
);
|
|
|
|
}
|
|
|
|
/**
|
|
* Add toggle link to admin footer
|
|
*/
|
|
public function footer_toggle( $text ) {
|
|
|
|
$screen = get_current_screen();
|
|
|
|
// Only add toggle on Formipay admin pages
|
|
if ( strpos( $screen->id, 'formipay' ) === false ) {
|
|
return $text;
|
|
}
|
|
|
|
$use_react = isset($_GET['react']) || get_option('formipay_use_react_admin', false);
|
|
$toggle_url = add_query_arg( 'react', $use_react ? '0' : '1' );
|
|
$toggle_text = $use_react ? 'Switch to Classic' : 'Try React (Beta)';
|
|
|
|
return sprintf(
|
|
'%s | <a href="%s">%s</a>',
|
|
$text,
|
|
esc_url( $toggle_url ),
|
|
esc_html( $toggle_text )
|
|
);
|
|
|
|
}
|
|
|
|
}
|