Files
WooNooW/includes/Admin/StandaloneAdmin.php
dwindown 5a4e2bab06 fix: Polish UI/UX across all modes
## Issue 1: Submenu Hidden in WP-Admin Modes 

**Problem:** Tax and Customer submenus visible in standalone but hidden in wp-admin modes

**Root Cause:** Incorrect `top` positioning calculation
- Was: `top-[calc(7rem+32px)]` (112px + 32px = 144px)
- Should be: `top-16` (64px - header height)

**Fixed:**
- `DashboardSubmenuBar.tsx` - Updated positioning
- `SubmenuBar.tsx` - Updated positioning

**Result:** Submenus now visible in all modes 

---

## Issue 2: Inconsistent Title in Standalone 

**Problem:** Title should prioritize: Logo → Store Name → WooNooW

**Fixed:**
- `StandaloneAdmin.php` - Use `woonoow_store_name` option first
- Falls back to `blogname`, then "WooNooW"

---

## Issue 3: Dense Card Header on Mobile 

**Problem:** Card header with title, description, and button too cramped on mobile

**Solution:** Stack vertically on mobile, horizontal on desktop

**Fixed:**
- `SettingsCard.tsx` - Changed from `flex-row` to `flex-col sm:flex-row`
- Button now full width on mobile, auto on desktop

**Result:** Better mobile UX, readable spacing 

---

## Issue 4: Missing "Go to WP Admin" Link 

**Added:**
- New button in More page (wp-admin modes only)
- Positioned before Exit Fullscreen/Logout
- Uses `ExternalLink` icon
- Links to `/wp-admin/`

---

## Issue 5: Customer Settings 403 Error ⚠️

**Status:** Backend ready, needs testing
- `CustomerSettingsProvider.php` exists and is autoloaded
- REST endpoints registered in `StoreController.php`
- Permission callback uses `manage_woocommerce`

**Next:** Test endpoint directly to verify

---

## Issue 6: Dark Mode Logo Support 

**Added:**
- New field: `store_logo_dark`
- Stored in: `woonoow_store_logo_dark` option
- Added to `StoreSettingsProvider.php`:
  - `get_settings()` - Returns dark logo
  - `save_settings()` - Saves dark logo

**Frontend:** Ready for implementation (use `useTheme()` to switch)

---

## Issue 7: Consistent Dark Background 

**Problem:** Login and Dashboard use different dark backgrounds
- Login: `dark:from-gray-900 dark:to-gray-800` (pure gray)
- Dashboard: `--background: 222.2 84% 4.9%` (dark blue-gray)

**Solution:** Use design system variables consistently

**Fixed:**
- `Login.tsx` - Changed to `dark:from-background dark:to-background`
- Card background: `dark:bg-card` instead of `dark:bg-gray-800`

**Result:** Consistent dark mode across all screens 

---

## Summary

 **Fixed 6 issues:**
1. Submenu visibility in all modes
2. Standalone title logic
3. Mobile card header density
4. WP Admin link in More page
5. Dark mode logo backend support
6. Consistent dark background colors

⚠️ **Needs Testing:**
- Customer Settings 403 error (backend ready, verify endpoint)

**Files Modified:**
- `DashboardSubmenuBar.tsx`
- `SubmenuBar.tsx`
- `StandaloneAdmin.php`
- `SettingsCard.tsx`
- `More/index.tsx`
- `StoreSettingsProvider.php`
- `Login.tsx`

**All UI/UX polish complete!** 🎨
2025-11-11 09:26:06 +07:00

180 lines
5.7 KiB
PHP

<?php
namespace WooNooW\Admin;
/**
* Standalone Admin Handler
*
* Handles /admin requests without requiring .htaccess modifications.
* Uses WordPress template_redirect hook to catch requests early.
*
* @package WooNooW\Admin
*/
class StandaloneAdmin {
/**
* Initialize standalone admin handler
*/
public static function init() {
// Catch /admin requests very early (before WordPress routing)
add_action( 'parse_request', [ __CLASS__, 'handle_admin_request' ], 1 );
}
/**
* Handle /admin requests
*/
public static function handle_admin_request() {
// Check if this is an /admin request
$request_uri = $_SERVER['REQUEST_URI'] ?? '';
// Remove query string
$path = strtok( $request_uri, '?' );
// Only handle exact /admin or /admin/ paths (not asset files)
if ( $path !== '/admin' && $path !== '/admin/' ) {
return;
}
// This is a standalone admin request
self::render_standalone_admin();
exit;
}
/**
* Render standalone admin interface
*/
private static function render_standalone_admin() {
// Check if user is logged in and has permissions
$is_logged_in = is_user_logged_in();
$has_permission = $is_logged_in && current_user_can( 'manage_woocommerce' );
$is_authenticated = $is_logged_in && $has_permission;
// Debug logging (only in WP_DEBUG mode)
if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
error_log( '[StandaloneAdmin] is_user_logged_in: ' . ( $is_logged_in ? 'true' : 'false' ) );
error_log( '[StandaloneAdmin] has manage_woocommerce: ' . ( $has_permission ? 'true' : 'false' ) );
error_log( '[StandaloneAdmin] is_authenticated: ' . ( $is_authenticated ? 'true' : 'false' ) );
}
// Get nonce for REST API
$nonce = wp_create_nonce( 'wp_rest' );
$rest_url = rest_url( 'woonoow/v1' );
$wp_admin_url = admin_url( 'admin.php?page=woonoow' );
// Get current user data if authenticated
$current_user = null;
if ( $is_authenticated ) {
$user = wp_get_current_user();
$current_user = [
'id' => $user->ID,
'name' => $user->display_name,
'email' => $user->user_email,
'avatar' => get_avatar_url( $user->ID ),
];
}
// Get WooCommerce store settings
$store_settings = self::get_store_settings();
// Get asset URLs
$plugin_url = plugins_url( '', dirname( dirname( __FILE__ ) ) );
$asset_url = $plugin_url . '/admin-spa/dist';
// Cache busting
$version = defined( 'WP_DEBUG' ) && WP_DEBUG ? time() : '1.0.0';
$css_url = $asset_url . '/app.css?ver=' . $version;
$js_url = $asset_url . '/app.js?ver=' . $version;
// Render HTML
?>
<!DOCTYPE html>
<html lang="<?php echo esc_attr( get_locale() ); ?>">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex, nofollow">
<title><?php
// Priority: Store Name > WooNooW
$store_name = get_option( 'woonoow_store_name', '' );
if ( empty( $store_name ) ) {
$store_name = get_option( 'blogname', 'WooNooW' );
}
echo esc_html( $store_name );
?></title>
<?php
// Favicon
$icon = get_option( 'woonoow_store_icon', '' );
if ( ! empty( $icon ) ) {
?>
<link rel="icon" type="image/png" href="<?php echo esc_url( $icon ); ?>" />
<link rel="apple-touch-icon" href="<?php echo esc_url( $icon ); ?>" />
<?php
}
?>
<!-- WooNooW Assets Only - NO wp_head() -->
<link rel="stylesheet" href="<?php echo esc_url( $css_url ); ?>">
</head>
<body class="woonoow-standalone">
<div id="woonoow-admin-app"></div>
<script>
// Minimal config - no WordPress bloat
window.WNW_CONFIG = {
restUrl: <?php echo wp_json_encode( $rest_url ); ?>,
nonce: <?php echo wp_json_encode( $nonce ); ?>,
standaloneMode: true,
wpAdminUrl: <?php echo wp_json_encode( $wp_admin_url ); ?>,
isAuthenticated: <?php echo $is_authenticated ? 'true' : 'false'; ?>,
currentUser: <?php echo wp_json_encode( $current_user ); ?>,
locale: <?php echo wp_json_encode( get_locale() ); ?>,
siteUrl: <?php echo wp_json_encode( home_url() ); ?>,
siteName: <?php echo wp_json_encode( get_bloginfo( 'name' ) ); ?>
};
// Also set WNW_API for API compatibility
window.WNW_API = {
root: <?php echo wp_json_encode( $rest_url ); ?>,
nonce: <?php echo wp_json_encode( $nonce ); ?>,
isDev: <?php echo ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'true' : 'false'; ?>
};
// WooCommerce store settings (currency, formatting, etc.)
window.WNW_STORE = <?php echo wp_json_encode( $store_settings ); ?>;
</script>
<script type="module" src="<?php echo esc_url( $js_url ); ?>"></script>
<?php
// NO wp_footer() - we don't want theme/plugin scripts
?>
</body>
</html>
<?php
}
/**
* Get WooCommerce store settings for frontend
*
* @return array Store settings (currency, decimals, separators, etc.)
*/
private static function get_store_settings(): array {
// Get WooCommerce settings with fallbacks
$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 = get_option( 'woocommerce_currency_pos', '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,
];
}
}