untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), 'nonce' => wp_create_nonce('wp_rest'), 'isDev' => true, 'devServer' => $dev_url, 'adminScreen' => 'woonoow', 'adminUrl' => admin_url('admin.php'), ]); wp_add_inline_script($handle, 'window.WNW_API = window.WNW_API || WNW_API;', 'after'); // WNW_CONFIG for compatibility with standalone mode code wp_localize_script($handle, 'WNW_CONFIG', [ 'restUrl' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))), 'nonce' => wp_create_nonce('wp_rest'), 'standaloneMode' => false, 'wpAdminUrl' => admin_url('admin.php?page=woonoow'), 'isAuthenticated' => is_user_logged_in(), 'pluginUrl' => trailingslashit(plugins_url('/', dirname(__DIR__))), ]); wp_add_inline_script($handle, 'window.WNW_CONFIG = window.WNW_CONFIG || WNW_CONFIG;', 'after'); // WordPress REST API settings (for media upload compatibility) wp_localize_script($handle, 'wpApiSettings', [ 'root' => untrailingslashit(esc_url_raw(rest_url())), 'nonce' => wp_create_nonce('wp_rest'), ]); wp_add_inline_script($handle, 'window.wpApiSettings = window.wpApiSettings || wpApiSettings;', 'after'); // Also expose compact global for convenience wp_localize_script($handle, 'wnw', [ 'isDev' => true, 'devServer' => $dev_url, 'adminUrl' => admin_url('admin.php'), 'siteTitle' => get_bloginfo('name') ?: 'WooNooW', ]); wp_add_inline_script($handle, 'window.wnw = window.wnw || wnw;', 'after'); // Localize store currency data (same as prod) wp_localize_script($handle, 'WNW_STORE', self::store_runtime()); wp_add_inline_script($handle, 'window.WNW_STORE = window.WNW_STORE || WNW_STORE;', 'after'); // Localize Woo menus snapshot for instant render $menus_snapshot = class_exists(MenuProvider::class) ? MenuProvider::get_snapshot() : []; wp_localize_script($handle, 'WNW_WC_MENUS', ['items' => $menus_snapshot]); wp_add_inline_script($handle, 'window.WNW_WC_MENUS = window.WNW_WC_MENUS || WNW_WC_MENUS;', 'after'); // Addon system data wp_localize_script($handle, 'WNW_ADDONS', AddonRegistry::get_frontend_registry()); wp_add_inline_script($handle, 'window.WNW_ADDONS = window.WNW_ADDONS || WNW_ADDONS;', 'after'); wp_localize_script($handle, 'WNW_ADDON_ROUTES', RouteRegistry::get_frontend_routes()); wp_add_inline_script($handle, 'window.WNW_ADDON_ROUTES = window.WNW_ADDON_ROUTES || WNW_ADDON_ROUTES;', 'after'); wp_localize_script($handle, 'WNW_NAV_TREE', NavigationRegistry::get_frontend_nav_tree()); wp_add_inline_script($handle, 'window.WNW_NAV_TREE = window.WNW_NAV_TREE || WNW_NAV_TREE;', 'after'); // Temporary compat aliases for old WNM_* wp_add_inline_script($handle, 'window.WNM_API = window.WNM_API || window.WNW_API;', 'after'); wp_add_inline_script($handle, 'window.WNM_WC_MENUS = window.WNM_WC_MENUS || window.WNW_WC_MENUS;', 'after'); // 2) Print a real module tag in the footer to load Vite client + app add_action('admin_print_footer_scripts', function () use ($dev_url) { // 1) React Refresh preamble (required by @vitejs/plugin-react) ?> ' . "\n", esc_url($dev_url)); // 3) Your app entry printf('' . "\n", esc_url($dev_url)); }, 1); } /** ---------------------------------------- * PROD MODE (built assets in admin-spa/dist) * -------------------------------------- */ private static function enqueue_prod(): void { // Get plugin root directory (2 levels up from includes/Admin/) $plugin_dir = dirname(dirname(__DIR__)); $dist_dir = $plugin_dir . '/admin-spa/dist/'; $base_url = plugins_url('admin-spa/dist/', $plugin_dir . '/woonoow.php'); $css = 'app.css'; $js = 'app.js'; $ver_css = file_exists($dist_dir . $css) ? (string) filemtime($dist_dir . $css) : self::asset_version(); $ver_js = file_exists($dist_dir . $js) ? (string) filemtime($dist_dir . $js) : self::asset_version(); // Debug logging if (defined('WP_DEBUG') && WP_DEBUG) { } if (file_exists($dist_dir . $css)) { wp_enqueue_style('wnw-admin', $base_url . $css, [], $ver_css); // Note: Icon fixes are now in index.css with proper specificity } if (file_exists($dist_dir . $js)) { wp_enqueue_script('wnw-admin', $base_url . $js, ['wp-element'], $ver_js, true); // Add type="module" attribute for Vite build add_filter('script_loader_tag', function ($tag, $handle, $src) { if ($handle === 'wnw-admin') { $tag = str_replace('