fix: On-hold and trash color conflict, add dashboard tweaks plan
## 1. Fix On-hold/Trash Color Conflict ✅ **Issue:** Both statuses used same gray color (#6b7280) **Solution:** - On-hold: `#64748b` (Slate 500 - lighter) - Trash: `#475569` (Slate 600 - darker) **Result:** Distinct visual identity for each status --- ## 2. Dashboard Tweaks Plan 📋 Created `DASHBOARD_TWEAKS_TODO.md` with: **Pending Tasks:** 1. **No Data State for Charts** - Revenue chart (Dashboard → Revenue) - Orders chart (Dashboard → Orders) - Coupons chart (Dashboard → Coupons) - Show friendly message like Overview does 2. **VIP Customer Settings** - New page: `/settings/customers` - Configure VIP qualification criteria: - Minimum total spent - Minimum order count - Timeframe (all-time, 30/90/365 days) - Require both or either - Exclude refunded orders - VIP detection logic documented --- ## Notification Settings Structure ✅ **Recommendation:** Separate subpages (not tabs) **Structure:** ``` /settings/notifications (overview) ├── /settings/notifications/events (What to notify) ├── /settings/notifications/channels (How to notify) └── /settings/notifications/templates (Email/channel templates) ``` **Reasoning:** - Cleaner navigation - Better performance (load only needed) - Easier maintenance - Scalability - Mobile-friendly --- ## Summary ✅ Color conflict fixed 📋 Dashboard tweaks documented ✅ Notification structure decided (subpages) **Next Steps:** 1. Implement no-data states 2. Build VIP settings page 3. Implement notification system
This commit is contained in:
158
DASHBOARD_TWEAKS_TODO.md
Normal file
158
DASHBOARD_TWEAKS_TODO.md
Normal file
@@ -0,0 +1,158 @@
|
||||
# Dashboard Tweaks TODO
|
||||
|
||||
## Completed ✅
|
||||
|
||||
### 1. Fix On-hold and Trash Color Conflict
|
||||
**Status:** ✅ DONE
|
||||
|
||||
**Issue:** Both on-hold and trash used same gray color (#6b7280)
|
||||
|
||||
**Solution:**
|
||||
- On-hold: `#64748b` (Slate 500)
|
||||
- Trash: `#475569` (Slate 600 - darker)
|
||||
|
||||
**Files Updated:**
|
||||
- `includes/Api/AnalyticsController.php` (2 locations)
|
||||
|
||||
---
|
||||
|
||||
## Pending Tasks
|
||||
|
||||
### 2. Add "No Data" State to Charts ⏳
|
||||
|
||||
**Affected Charts:**
|
||||
- Revenue chart (Dashboard → Revenue submenu)
|
||||
- Orders chart (Dashboard → Orders submenu)
|
||||
- Coupon chart (Dashboard → Coupons submenu)
|
||||
|
||||
**Current Behavior:**
|
||||
- Overview page shows "No data" message ✓
|
||||
- Submenu charts show empty/broken charts ✗
|
||||
|
||||
**Required Implementation:**
|
||||
```tsx
|
||||
{chartData.length === 0 ? (
|
||||
<div className="flex items-center justify-center h-64">
|
||||
<div className="text-center">
|
||||
<Package className="w-12 h-12 text-muted-foreground mx-auto mb-2" />
|
||||
<p className="text-muted-foreground">No data available</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Data will appear once you have {type}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<ResponsiveContainer>
|
||||
{/* Chart */}
|
||||
</ResponsiveContainer>
|
||||
)}
|
||||
```
|
||||
|
||||
**Files to Update:**
|
||||
- `admin-spa/src/routes/Dashboard/Revenue.tsx`
|
||||
- `admin-spa/src/routes/Dashboard/Orders.tsx`
|
||||
- `admin-spa/src/routes/Dashboard/Coupons.tsx`
|
||||
|
||||
---
|
||||
|
||||
### 3. VIP Customer Settings ⏳
|
||||
|
||||
**Requirement:** Add settings to configure VIP customer qualification
|
||||
|
||||
**Proposed Location:** `/settings/customers` (new page)
|
||||
|
||||
**Settings:**
|
||||
```tsx
|
||||
interface VIPSettings {
|
||||
// Qualification Criteria
|
||||
minTotalSpent: number; // e.g., $1000
|
||||
minOrderCount: number; // e.g., 10 orders
|
||||
timeframe: 'all' | '30' | '90' | '365'; // Days or all-time
|
||||
|
||||
// Optional Criteria
|
||||
requireBoth: boolean; // Both spent AND count, or either?
|
||||
excludeRefunded: boolean; // Exclude refunded orders?
|
||||
|
||||
// Benefits (for display/reference)
|
||||
vipBenefits: string[]; // e.g., ["Free shipping", "10% discount"]
|
||||
}
|
||||
```
|
||||
|
||||
**UI Design:**
|
||||
```
|
||||
Customer Settings
|
||||
├── VIP Qualification
|
||||
│ ├── Minimum Total Spent: $___
|
||||
│ ├── Minimum Order Count: ___
|
||||
│ ├── Timeframe: [All time | Last 30 days | Last 90 days | Last year]
|
||||
│ ├── ☐ Require both criteria (vs either one)
|
||||
│ └── ☐ Exclude refunded orders
|
||||
│
|
||||
└── VIP Benefits (optional reference)
|
||||
└── [Add benefit] button
|
||||
```
|
||||
|
||||
**Implementation Steps:**
|
||||
1. Create `admin-spa/src/routes/Settings/Customers.tsx`
|
||||
2. Add backend endpoint: `POST /settings/customers`
|
||||
3. Create `includes/Compat/CustomerSettingsProvider.php`
|
||||
4. Add to navigation tree
|
||||
5. Implement VIP badge logic in customer list
|
||||
|
||||
**Backend Storage:**
|
||||
```php
|
||||
// WordPress options
|
||||
woonoow_vip_min_spent = 1000
|
||||
woonoow_vip_min_orders = 10
|
||||
woonoow_vip_timeframe = 'all'
|
||||
woonoow_vip_require_both = true
|
||||
woonoow_vip_exclude_refunded = true
|
||||
```
|
||||
|
||||
**VIP Detection Query:**
|
||||
```php
|
||||
function is_vip_customer($customer_id) {
|
||||
$settings = get_vip_settings();
|
||||
|
||||
$query_args = [
|
||||
'customer_id' => $customer_id,
|
||||
'status' => ['completed', 'processing'],
|
||||
];
|
||||
|
||||
if ($settings['timeframe'] !== 'all') {
|
||||
$query_args['date_created'] = '>' . date('Y-m-d', strtotime("-{$settings['timeframe']} days"));
|
||||
}
|
||||
|
||||
if ($settings['exclude_refunded']) {
|
||||
$query_args['status'] = array_diff($query_args['status'], ['refunded']);
|
||||
}
|
||||
|
||||
$orders = wc_get_orders($query_args);
|
||||
|
||||
$total_spent = array_sum(array_map(fn($o) => $o->get_total(), $orders));
|
||||
$order_count = count($orders);
|
||||
|
||||
if ($settings['require_both']) {
|
||||
return $total_spent >= $settings['min_spent']
|
||||
&& $order_count >= $settings['min_orders'];
|
||||
} else {
|
||||
return $total_spent >= $settings['min_spent']
|
||||
|| $order_count >= $settings['min_orders'];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Completed:**
|
||||
- ✅ On-hold/Trash color conflict fixed
|
||||
|
||||
**Pending:**
|
||||
- ⏳ No data state for Revenue/Orders/Coupons charts
|
||||
- ⏳ VIP customer settings page
|
||||
|
||||
**Priority:**
|
||||
1. No data states (quick fix)
|
||||
2. VIP settings (new feature)
|
||||
@@ -72,6 +72,7 @@
|
||||
a:active {
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
color: inherit !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -371,13 +371,14 @@ class AnalyticsController {
|
||||
// Format status distribution and calculate conversion rate
|
||||
$formatted_status = [];
|
||||
$status_colors = [
|
||||
'wc-completed' => '#10b981',
|
||||
'wc-processing' => '#3b82f6',
|
||||
'wc-pending' => '#f59e0b',
|
||||
'wc-on-hold' => '#6b7280',
|
||||
'wc-cancelled' => '#ef4444',
|
||||
'wc-refunded' => '#8b5cf6',
|
||||
'wc-failed' => '#dc2626',
|
||||
'wc-completed' => '#10b981', // Green
|
||||
'wc-processing' => '#3b82f6', // Blue
|
||||
'wc-pending' => '#f59e0b', // Orange/Amber
|
||||
'wc-on-hold' => '#64748b', // Slate
|
||||
'wc-cancelled' => '#ef4444', // Red
|
||||
'wc-refunded' => '#8b5cf6', // Purple
|
||||
'wc-failed' => '#dc2626', // Dark Red
|
||||
'wc-trash' => '#475569', // Dark Slate
|
||||
];
|
||||
|
||||
$total_all_orders = 0;
|
||||
@@ -996,17 +997,18 @@ class AnalyticsController {
|
||||
|
||||
// Add color and percentage to status data - SORT BY IMPORTANCE
|
||||
$status_colors = [
|
||||
'completed' => '#10b981',
|
||||
'processing' => '#3b82f6',
|
||||
'pending' => '#f59e0b',
|
||||
'cancelled' => '#ef4444',
|
||||
'refunded' => '#8b5cf6',
|
||||
'failed' => '#dc2626',
|
||||
'on-hold' => '#6b7280',
|
||||
'completed' => '#10b981', // Green
|
||||
'processing' => '#3b82f6', // Blue
|
||||
'pending' => '#f59e0b', // Orange/Amber
|
||||
'cancelled' => '#ef4444', // Red
|
||||
'refunded' => '#8b5cf6', // Purple
|
||||
'failed' => '#dc2626', // Dark Red
|
||||
'on-hold' => '#64748b', // Slate (changed from gray)
|
||||
'trash' => '#475569', // Dark Slate (distinct from on-hold)
|
||||
];
|
||||
|
||||
// Define sort order (most important first)
|
||||
$status_order = ['completed', 'processing', 'pending', 'on-hold', 'cancelled', 'refunded', 'failed'];
|
||||
$status_order = ['completed', 'processing', 'pending', 'on-hold', 'cancelled', 'refunded', 'failed', 'trash'];
|
||||
|
||||
foreach ($formatted_status as &$status) {
|
||||
$status['color'] = $status_colors[$status['status']] ?? '#6b7280';
|
||||
|
||||
Reference in New Issue
Block a user