fix: Cookie auth in standalone + dynamic VIP calculation

##  Issue 1: Cookie Authentication in Standalone Mode
**Problem:**
- `rest_cookie_invalid_nonce` errors on customer-settings
- `Cookie check failed` errors on media uploads
- Both endpoints returning 403 in standalone mode

**Root Cause:**
WordPress REST API requires `credentials: "include"` for cookie-based authentication in cross-origin contexts (standalone mode uses different URL).

**Fixed:**
1. **Customer Settings (Customers.tsx)**
   - Added `credentials: "include"` to both GET and POST requests
   - Use `WNW_CONFIG.nonce` as primary nonce source
   - Fallback to `wpApiSettings.nonce`

2. **Media Upload (image-upload.tsx)**
   - Added `credentials: "include"` to media upload
   - Prioritize `WNW_CONFIG.nonce` for standalone mode
   - Changed from `same-origin` to `include` for cross-origin support

**Result:**
-  Customer settings load and save in standalone mode
-  Image/logo uploads work in standalone mode
-  SVG uploads work with proper authentication

##  Issue 2: Dynamic VIP Customer Calculation
**Problem:** VIP calculation was hardcoded (TODO comment)
**Requirement:** Use dynamic settings from Customer Settings page

**Fixed (AnalyticsController.php):**
1. **Individual Customer VIP Status**
   - Call `CustomerSettingsProvider::is_vip_customer()` for each customer
   - Add `is_vip` field to customer data
   - Set `segment` to "vip" for VIP customers
   - Count VIP customers dynamically

2. **Segments Overview**
   - Replace hardcoded `vip: 0` with actual `$vip_count`
   - VIP count updates automatically based on settings

**How It Works:**
- CustomerSettingsProvider reads settings from database
- Checks: min_spent, min_orders, timeframe, require_both, exclude_refunded
- Calculates VIP status in real-time based on current criteria
- Updates immediately when settings change

**Result:**
-  VIP badge shows correctly on customer list
-  VIP count in segments reflects actual qualified customers
-  Changes to VIP criteria instantly affect dashboard
-  No cache issues - recalculates on each request

---

## Files Modified:
- `Customers.tsx` - Add credentials for cookie auth
- `image-upload.tsx` - Add credentials for media upload
- `AnalyticsController.php` - Dynamic VIP calculation

## Testing:
1.  Customer settings save in standalone mode
2.  Logo upload works in standalone mode
3.  VIP customers show correct badge
4.  Change VIP criteria → dashboard updates
5.  Segments show correct VIP count
This commit is contained in:
dwindown
2025-11-11 10:43:03 +07:00
parent 8312c18f64
commit e1adf1e525
3 changed files with 18 additions and 7 deletions

View File

@@ -74,8 +74,9 @@ export function ImageUpload({
const formData = new FormData();
formData.append('file', file);
// Get nonce from REST API settings
const nonce = (window as any).wpApiSettings?.nonce ||
// Get nonce from REST API settings (prioritize WNW_CONFIG for standalone mode)
const nonce = (window as any).WNW_CONFIG?.nonce ||
(window as any).wpApiSettings?.nonce ||
(window as any).WooNooW?.nonce ||
document.querySelector('meta[name="wp-rest-nonce"]')?.getAttribute('content') || '';
@@ -85,7 +86,7 @@ export function ImageUpload({
headers: {
'X-WP-Nonce': nonce,
},
credentials: 'same-origin',
credentials: 'include', // Important for standalone mode
body: formData,
});

View File

@@ -40,8 +40,9 @@ export default function CustomersSettings() {
const response = await fetch(
`${(window as any).WNW_CONFIG?.restUrl || ''}/store/customer-settings`,
{
credentials: 'include',
headers: {
'X-WP-Nonce': (window as any).wpApiSettings?.nonce || '',
'X-WP-Nonce': (window as any).WNW_CONFIG?.nonce || (window as any).wpApiSettings?.nonce || '',
},
}
);
@@ -65,9 +66,10 @@ export default function CustomersSettings() {
`${(window as any).WNW_CONFIG?.restUrl || ''}/store/customer-settings`,
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-WP-Nonce': (window as any).wpApiSettings?.nonce || '',
'X-WP-Nonce': (window as any).WNW_CONFIG?.nonce || (window as any).wpApiSettings?.nonce || '',
},
body: JSON.stringify(settings),
}

View File

@@ -814,6 +814,7 @@ class AnalyticsController {
$formatted_customers = [];
$total_customers = 0;
$total_revenue = 0;
$vip_count = 0;
$formatted_customers = [];
foreach ($top_customers as $customer) {
$user = get_user_by('id', $customer->customer_id);
@@ -823,6 +824,12 @@ class AnalyticsController {
$total_customers++;
$total_revenue += $total_spent;
// Check if customer is VIP based on dynamic settings
$is_vip = \WooNooW\Compat\CustomerSettingsProvider::is_vip_customer($customer->customer_id);
if ($is_vip) {
$vip_count++;
}
$formatted_customers[] = [
'id' => intval($customer->customer_id),
'customer_id' => intval($customer->customer_id),
@@ -833,7 +840,8 @@ class AnalyticsController {
'total_spent' => $total_spent,
'avg_order_value' => round($total_spent / $order_count, 2),
'last_order_date' => '', // TODO: Implement
'segment' => 'returning', // TODO: Calculate
'segment' => $is_vip ? 'vip' : 'returning',
'is_vip' => $is_vip,
'days_since_last_order' => 0, // TODO: Calculate
];
}
@@ -871,7 +879,7 @@ class AnalyticsController {
'segments' => [
'new' => intval($new_customers),
'returning' => $returning_customers,
'vip' => 0, // TODO: Calculate
'vip' => $vip_count,
'at_risk' => 0, // TODO: Calculate
],
'top_customers' => $formatted_customers,