fix: WP-Admin CSS conflicts and add-to-cart redirect
- Fix CSS conflicts between WP-Admin and SPA (radio buttons, chart text) - Add Tailwind important selector scoped to #woonoow-admin-app - Remove overly aggressive inline SVG styles from Assets.php - Add targeted WordPress admin CSS overrides in index.css - Fix add-to-cart redirect to use woocommerce_add_to_cart_redirect filter - Let WooCommerce handle cart operations natively for proper session management - Remove duplicate tailwind.config.cjs
This commit is contained in:
@@ -6,17 +6,20 @@ use WooNooW\Compat\AddonRegistry;
|
||||
use WooNooW\Compat\RouteRegistry;
|
||||
use WooNooW\Compat\NavigationRegistry;
|
||||
|
||||
class Assets {
|
||||
public static function init() {
|
||||
class Assets
|
||||
{
|
||||
public static function init()
|
||||
{
|
||||
add_action('admin_enqueue_scripts', [__CLASS__, 'enqueue']);
|
||||
}
|
||||
|
||||
public static function enqueue($hook) {
|
||||
public static function enqueue($hook)
|
||||
{
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('[WooNooW Assets] Hook: ' . $hook);
|
||||
}
|
||||
|
||||
|
||||
if ($hook !== 'toplevel_page_woonoow') {
|
||||
return;
|
||||
}
|
||||
@@ -26,12 +29,12 @@ class Assets {
|
||||
|
||||
// Decide dev vs prod
|
||||
$is_dev = self::is_dev_mode();
|
||||
|
||||
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
error_log('[WooNooW Assets] Dev mode: ' . ($is_dev ? 'true' : 'false'));
|
||||
}
|
||||
|
||||
|
||||
if ($is_dev) {
|
||||
self::enqueue_dev();
|
||||
} else {
|
||||
@@ -42,49 +45,50 @@ class Assets {
|
||||
/** ----------------------------------------
|
||||
* DEV MODE (Vite dev server)
|
||||
* -------------------------------------- */
|
||||
private static function enqueue_dev(): void {
|
||||
private static function enqueue_dev(): void
|
||||
{
|
||||
$dev_url = self::dev_server_url(); // e.g. http://localhost:5173
|
||||
|
||||
|
||||
// 1) Create a small handle to attach config (window.WNW_API)
|
||||
$handle = 'wnw-admin-dev-config';
|
||||
wp_register_script($handle, '', [], null, true);
|
||||
wp_enqueue_script($handle);
|
||||
|
||||
|
||||
// Attach runtime config (before module loader runs)
|
||||
// If you prefer, keep using self::localize_runtime($handle)
|
||||
wp_localize_script($handle, 'WNW_API', [
|
||||
'root' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'isDev' => true,
|
||||
'devServer' => $dev_url,
|
||||
'root' => 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'),
|
||||
'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'),
|
||||
'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__))),
|
||||
'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())),
|
||||
'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,
|
||||
'isDev' => true,
|
||||
'devServer' => $dev_url,
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
'siteTitle' => get_bloginfo('name') ?: 'WooNooW',
|
||||
]);
|
||||
wp_add_inline_script($handle, 'window.wnw = window.wnw || wnw;', 'after');
|
||||
@@ -97,37 +101,37 @@ class Assets {
|
||||
$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)
|
||||
?>
|
||||
<script type="module">
|
||||
import RefreshRuntime from "<?php echo esc_url( $dev_url ); ?>/@react-refresh";
|
||||
RefreshRuntime.injectIntoGlobalHook(window);
|
||||
window.$RefreshReg$ = () => {};
|
||||
window.$RefreshSig$ = () => (type) => type;
|
||||
window.__vite_plugin_react_preamble_installed__ = true;
|
||||
import RefreshRuntime from "<?php echo esc_url($dev_url); ?>/@react-refresh";
|
||||
RefreshRuntime.injectIntoGlobalHook(window);
|
||||
window.$RefreshReg$ = () => { };
|
||||
window.$RefreshSig$ = () => (type) => type;
|
||||
window.__vite_plugin_react_preamble_installed__ = true;
|
||||
</script>
|
||||
<?php
|
||||
|
||||
|
||||
// 2) Vite client (HMR)
|
||||
printf('<script type="module" src="%s/@vite/client"></script>' . "\n", esc_url($dev_url));
|
||||
|
||||
|
||||
// 3) Your app entry
|
||||
printf('<script type="module">import "%s/src/main.tsx";</script>' . "\n", esc_url($dev_url));
|
||||
}, 1);
|
||||
@@ -136,17 +140,18 @@ class Assets {
|
||||
/** ----------------------------------------
|
||||
* PROD MODE (built assets in admin-spa/dist)
|
||||
* -------------------------------------- */
|
||||
private static function enqueue_prod(): void {
|
||||
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';
|
||||
$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();
|
||||
$ver_js = file_exists($dist_dir . $js) ? (string) filemtime($dist_dir . $js) : self::asset_version();
|
||||
|
||||
// Debug logging
|
||||
if (defined('WP_DEBUG') && WP_DEBUG) {
|
||||
@@ -159,71 +164,60 @@ class Assets {
|
||||
|
||||
if (file_exists($dist_dir . $css)) {
|
||||
wp_enqueue_style('wnw-admin', $base_url . $css, [], $ver_css);
|
||||
|
||||
// Fix icon rendering in WP-Admin (prevent WordPress admin styles from overriding)
|
||||
$icon_fix_css = '
|
||||
/* Fix Lucide icons in WP-Admin - force outlined style */
|
||||
#woonoow-admin-app svg {
|
||||
fill: none !important;
|
||||
stroke: currentColor !important;
|
||||
stroke-width: 2 !important;
|
||||
stroke-linecap: round !important;
|
||||
stroke-linejoin: round !important;
|
||||
}
|
||||
';
|
||||
wp_add_inline_style('wnw-admin', $icon_fix_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) {
|
||||
add_filter('script_loader_tag', function ($tag, $handle, $src) {
|
||||
if ($handle === 'wnw-admin') {
|
||||
$tag = str_replace('<script ', '<script type="module" ', $tag);
|
||||
}
|
||||
return $tag;
|
||||
}, 10, 3);
|
||||
|
||||
|
||||
self::localize_runtime('wnw-admin');
|
||||
}
|
||||
}
|
||||
|
||||
/** Attach runtime config to a handle */
|
||||
private static function localize_runtime(string $handle): void {
|
||||
private static function localize_runtime(string $handle): void
|
||||
{
|
||||
wp_localize_script($handle, 'WNW_API', [
|
||||
'root' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'isDev' => self::is_dev_mode(),
|
||||
'devServer' => self::dev_server_url(),
|
||||
'root' => untrailingslashit(esc_url_raw(rest_url('woonoow/v1'))),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
'isDev' => self::is_dev_mode(),
|
||||
'devServer' => self::dev_server_url(),
|
||||
'adminScreen' => 'woonoow',
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
]);
|
||||
|
||||
|
||||
// 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'),
|
||||
'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__))),
|
||||
'pluginUrl' => trailingslashit(plugins_url('/', dirname(__DIR__))),
|
||||
]);
|
||||
|
||||
|
||||
// WordPress REST API settings (for media upload compatibility)
|
||||
wp_localize_script($handle, 'wpApiSettings', [
|
||||
'root' => untrailingslashit(esc_url_raw(rest_url())),
|
||||
'root' => untrailingslashit(esc_url_raw(rest_url())),
|
||||
'nonce' => wp_create_nonce('wp_rest'),
|
||||
]);
|
||||
|
||||
|
||||
wp_localize_script($handle, 'WNW_STORE', self::store_runtime());
|
||||
wp_add_inline_script($handle, 'window.WNW_STORE = window.WNW_STORE || WNW_STORE;', 'after');
|
||||
|
||||
// Compact global (prod)
|
||||
wp_localize_script($handle, 'wnw', [
|
||||
'isDev' => (bool) self::is_dev_mode(),
|
||||
'isDev' => (bool) self::is_dev_mode(),
|
||||
'devServer' => (string) self::dev_server_url(),
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
'adminUrl' => admin_url('admin.php'),
|
||||
'siteTitle' => get_bloginfo('name') ?: 'WooNooW',
|
||||
]);
|
||||
wp_add_inline_script($handle, 'window.wnw = window.wnw || wnw;', 'after');
|
||||
@@ -232,39 +226,40 @@ class Assets {
|
||||
$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 (prod)
|
||||
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');
|
||||
}
|
||||
|
||||
/** Runtime store meta for frontend (currency, decimals, separators, position). */
|
||||
private static function store_runtime(): array {
|
||||
private static function store_runtime(): array
|
||||
{
|
||||
// WooCommerce helpers may not exist in some contexts; guard with defaults
|
||||
$currency = function_exists('get_woocommerce_currency') ? get_woocommerce_currency() : 'USD';
|
||||
$currency_sym = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol($currency) : '$';
|
||||
$decimals = function_exists('wc_get_price_decimals') ? wc_get_price_decimals() : 2;
|
||||
$thousand_sep = function_exists('wc_get_price_thousand_separator') ? wc_get_price_thousand_separator() : ',';
|
||||
$decimal_sep = function_exists('wc_get_price_decimal_separator') ? wc_get_price_decimal_separator() : '.';
|
||||
$currency_pos = function_exists('get_option') ? get_option('woocommerce_currency_pos', 'left') : 'left';
|
||||
$currency = function_exists('get_woocommerce_currency') ? get_woocommerce_currency() : 'USD';
|
||||
$currency_sym = function_exists('get_woocommerce_currency_symbol') ? get_woocommerce_currency_symbol($currency) : '$';
|
||||
$decimals = function_exists('wc_get_price_decimals') ? wc_get_price_decimals() : 2;
|
||||
$thousand_sep = function_exists('wc_get_price_thousand_separator') ? wc_get_price_thousand_separator() : ',';
|
||||
$decimal_sep = function_exists('wc_get_price_decimal_separator') ? wc_get_price_decimal_separator() : '.';
|
||||
$currency_pos = function_exists('get_option') ? get_option('woocommerce_currency_pos', 'left') : 'left';
|
||||
|
||||
return [
|
||||
'currency' => $currency,
|
||||
'currency_symbol' => $currency_sym,
|
||||
'decimals' => (int) $decimals,
|
||||
'thousand_sep' => (string) $thousand_sep,
|
||||
'decimal_sep' => (string) $decimal_sep,
|
||||
'currency_pos' => (string) $currency_pos,
|
||||
'currency' => $currency,
|
||||
'currency_symbol' => $currency_sym,
|
||||
'decimals' => (int) $decimals,
|
||||
'thousand_sep' => (string) $thousand_sep,
|
||||
'decimal_sep' => (string) $decimal_sep,
|
||||
'currency_pos' => (string) $currency_pos,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -275,9 +270,10 @@ class Assets {
|
||||
* Note: We don't check WP_ENV to avoid accidentally enabling dev mode
|
||||
* in Local by Flywheel or other local dev environments.
|
||||
*/
|
||||
private static function is_dev_mode(): bool {
|
||||
private static function is_dev_mode(): bool
|
||||
{
|
||||
// Only enable dev mode if explicitly set via constant
|
||||
$const_dev = defined('WOONOOW_ADMIN_DEV') && WOONOOW_ADMIN_DEV === true;
|
||||
$const_dev = defined('WOONOOW_ADMIN_DEV') && WOONOOW_ADMIN_DEV === true;
|
||||
|
||||
/**
|
||||
* Filter: force dev/prod mode for WooNooW admin assets.
|
||||
@@ -287,34 +283,36 @@ class Assets {
|
||||
* Only use it during development.
|
||||
*/
|
||||
$filtered = apply_filters('woonoow/admin_is_dev', $const_dev);
|
||||
|
||||
|
||||
// Debug logging (only if WP_DEBUG is enabled)
|
||||
if (defined('WP_DEBUG') && WP_DEBUG && $filtered !== $const_dev) {
|
||||
error_log('[WooNooW Assets] Dev mode changed by filter: ' . ($filtered ? 'true' : 'false'));
|
||||
}
|
||||
|
||||
|
||||
return (bool) $filtered;
|
||||
}
|
||||
|
||||
/** Dev server URL (filterable) */
|
||||
private static function dev_server_url(): string {
|
||||
private static function dev_server_url(): string
|
||||
{
|
||||
// Auto-detect based on current host (for Local by Flywheel compatibility)
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
$protocol = is_ssl() ? 'https' : 'http';
|
||||
|
||||
|
||||
// If using *.local domain (Local by Flywheel), use HTTPS
|
||||
if (strpos($host, '.local') !== false) {
|
||||
$protocol = 'https';
|
||||
}
|
||||
|
||||
|
||||
$default = $protocol . '://' . $host . ':5173';
|
||||
|
||||
|
||||
/** Filter: change dev server URL if needed */
|
||||
return (string) apply_filters('woonoow/admin_dev_server', $default);
|
||||
}
|
||||
|
||||
/** Basic asset versioning */
|
||||
private static function asset_version(): string {
|
||||
private static function asset_version(): string
|
||||
{
|
||||
// Bump when releasing; in dev we don't cache-bust
|
||||
return defined('WOONOOW_VERSION') ? WOONOOW_VERSION : '0.1.0';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user