docs: Update PROGRESS_NOTE with notification system refinement
## 📝 Documentation Update Added comprehensive progress note for notification system work completed on November 11, 2025. ### Documented: **Phase 1: UI/UX Refinements** - Channels page simplification - Events page density reduction - Visual improvements **Phase 2: Critical Bug Fixes** - Toggle not saving (get_json_params fix) - Multiple API calls (optimistic update removal) - Wrong event defaults (data structure fix) - Events cannot be enabled (path fix) **Phase 3: Push URL Strategy** - Dynamic URLs recommendation - Event-specific deep linking - Template variables support - Implementation plan ### Testing Results: - All toggles working correctly - State persistence verified - Network optimization confirmed ### Next Steps: - Dynamic push notification URLs - Per-event URL configuration - Rich notification content --- **Status:** ✅ All issues resolved and documented
This commit is contained in:
271
PROGRESS_NOTE.md
271
PROGRESS_NOTE.md
@@ -1,6 +1,6 @@
|
||||
# WooNooW Project Progress Note
|
||||
|
||||
**Last Updated:** November 8, 2025, 7:30 PM (GMT+7)
|
||||
**Last Updated:** November 11, 2025, 4:10 PM (GMT+7)
|
||||
|
||||
## Overview
|
||||
WooNooW is a hybrid WordPress + React SPA replacement for WooCommerce Admin. It focuses on performance, UX consistency, and extensibility with SSR-safe endpoints and REST-first design. The plugin integrates deeply with WooCommerce’s data store (HPOS ready) and provides a modern React-based dashboard and order management system.
|
||||
@@ -2451,3 +2451,272 @@ const actions = (
|
||||
**Implementation Date:** November 8, 2025
|
||||
**Status:** ✅ Production Ready
|
||||
**Next Milestone:** Apply mobile patterns to other modules
|
||||
|
||||
---
|
||||
|
||||
## 🔔 Notification System Refinement — November 11, 2025
|
||||
|
||||
### ✅ COMPLETE - UI/UX Improvements & Toggle Logic Fixes
|
||||
|
||||
**Goal:** Simplify notification settings UI and fix critical toggle bugs.
|
||||
|
||||
### 🎯 Phase 1: UI/UX Refinements
|
||||
|
||||
#### **Channels Page Improvements**
|
||||
|
||||
**Changes Made:**
|
||||
1. ✅ Removed redundant "Active/Inactive" badge (color indicates state)
|
||||
2. ✅ Renamed "Built-in Channels" → "Channels" (unified card)
|
||||
3. ✅ Moved "Built-in" badge inline with channel title
|
||||
4. ✅ Removed redundant "Subscribe" toggle for push notifications
|
||||
5. ✅ Unified enable/disable toggle for all channels
|
||||
6. ✅ Auto-subscribe when enabling push channel
|
||||
7. ✅ Green icon when enabled, gray when disabled
|
||||
|
||||
**Layout:**
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Channels │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 📧 Email [Built-in] │
|
||||
│ Email notifications powered by... │
|
||||
│ [Enabled ●] [Configure] │
|
||||
├─────────────────────────────────────────┤
|
||||
│ 🔔 Push Notifications [Built-in] │
|
||||
│ Browser push notifications... │
|
||||
│ [Disabled ○] [Configure] │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### **Events Page Improvements**
|
||||
|
||||
**Changes Made:**
|
||||
1. ✅ Removed event-level toggle (reduced visual density)
|
||||
2. ✅ Cleaner header layout
|
||||
3. ✅ Focus on per-channel toggles only
|
||||
|
||||
**Before:**
|
||||
```
|
||||
Order Placed [Toggle]
|
||||
├─ Email [Toggle] Admin
|
||||
└─ Push [Toggle] Admin
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
Order Placed
|
||||
├─ Email [Toggle] Admin
|
||||
└─ Push [Toggle] Admin
|
||||
```
|
||||
|
||||
### 🐛 Phase 2: Critical Bug Fixes
|
||||
|
||||
#### **Issue 1: Toggle Not Saving**
|
||||
|
||||
**Problem:** Channel toggle always returned `enabled: true`, changes weren't saved
|
||||
|
||||
**Root Cause:** Backend using `get_param()` instead of `get_json_params()`
|
||||
|
||||
**Fix:**
|
||||
```php
|
||||
// Before
|
||||
$channel_id = $request->get_param('channelId');
|
||||
$enabled = $request->get_param('enabled');
|
||||
|
||||
// After
|
||||
$params = $request->get_json_params();
|
||||
$channel_id = isset($params['channelId']) ? $params['channelId'] : null;
|
||||
$enabled = isset($params['enabled']) ? $params['enabled'] : null;
|
||||
```
|
||||
|
||||
**Result:** Toggle state now persists correctly ✅
|
||||
|
||||
---
|
||||
|
||||
#### **Issue 2: Multiple API Calls**
|
||||
|
||||
**Problem:** Single toggle triggered 3 network requests
|
||||
|
||||
**Root Cause:** Optimistic update + `onSettled` refetch caused race condition
|
||||
|
||||
**Fix:**
|
||||
```typescript
|
||||
// Removed optimistic update
|
||||
// Now uses server response directly
|
||||
onSuccess: (data, variables) => {
|
||||
queryClient.setQueryData(['notification-channels'], (old) =>
|
||||
old.map(channel =>
|
||||
channel.id === variables.channelId
|
||||
? { ...channel, enabled: data.enabled }
|
||||
: channel
|
||||
)
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**Result:** Only 1 request per toggle ✅
|
||||
|
||||
---
|
||||
|
||||
#### **Issue 3: Wrong Event Channel Defaults**
|
||||
|
||||
**Problem:**
|
||||
- Email showing as enabled by default (should be disabled)
|
||||
- Push showing as disabled (inconsistent)
|
||||
- Backend path was wrong
|
||||
|
||||
**Root Cause:**
|
||||
1. Wrong path: `$settings['event_id']` instead of `$settings['event_id']['channels']`
|
||||
2. Defaults set to `true` instead of `false`
|
||||
|
||||
**Fix:**
|
||||
```php
|
||||
// Before
|
||||
'channels' => $settings['order_placed'] ?? ['email' => ['enabled' => true, ...]]
|
||||
|
||||
// After
|
||||
'channels' => $settings['order_placed']['channels'] ?? [
|
||||
'email' => ['enabled' => false, 'recipient' => 'admin'],
|
||||
'push' => ['enabled' => false, 'recipient' => 'admin']
|
||||
]
|
||||
```
|
||||
|
||||
**Result:** Events page shows correct defaults ✅
|
||||
|
||||
---
|
||||
|
||||
#### **Issue 4: Events Cannot Be Enabled**
|
||||
|
||||
**Problem:** All event channels disabled and cannot be enabled
|
||||
|
||||
**Root Cause:** Wrong data structure in `update_event()`
|
||||
|
||||
**Fix:**
|
||||
```php
|
||||
// Before
|
||||
$settings[$event_id][$channel_id] = [...];
|
||||
// Saved as: { "order_placed": { "email": {...} } }
|
||||
|
||||
// After
|
||||
$settings[$event_id]['channels'][$channel_id] = [...];
|
||||
// Saves as: { "order_placed": { "channels": { "email": {...} } } }
|
||||
```
|
||||
|
||||
**Result:** Event toggles save correctly ✅
|
||||
|
||||
### 📊 Data Structure
|
||||
|
||||
**Correct Structure:**
|
||||
```php
|
||||
[
|
||||
'order_placed' => [
|
||||
'channels' => [
|
||||
'email' => ['enabled' => true, 'recipient' => 'admin'],
|
||||
'push' => ['enabled' => false, 'recipient' => 'admin']
|
||||
]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
### 🎯 Phase 3: Push Notification URL Strategy
|
||||
|
||||
**Question:** Should push notification URL be static or dynamic?
|
||||
|
||||
**Answer:** **Dynamic based on context** for better UX
|
||||
|
||||
**Recommended Approach:**
|
||||
|
||||
```php
|
||||
// Event-specific URLs
|
||||
$notification_urls = [
|
||||
'order_placed' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
|
||||
'order_completed' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
|
||||
'low_stock' => '/wp-admin/admin.php?page=woonoow#/products/{product_id}',
|
||||
'out_of_stock' => '/wp-admin/admin.php?page=woonoow#/products/{product_id}',
|
||||
'new_customer' => '/wp-admin/admin.php?page=woonoow#/customers/{customer_id}',
|
||||
];
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- ✅ Better UX - Direct navigation to relevant page
|
||||
- ✅ Context-aware - Order notification → Order detail
|
||||
- ✅ Actionable - User can immediately take action
|
||||
- ✅ Professional - Industry standard (Gmail, Slack, etc.)
|
||||
|
||||
**Implementation Plan:**
|
||||
1. Add `notification_url` field to push settings
|
||||
2. Support template variables: `{order_id}`, `{product_id}`, `{customer_id}`
|
||||
3. Per-event URL configuration in Templates page
|
||||
4. Default fallback: `/wp-admin/admin.php?page=woonoow#/orders`
|
||||
|
||||
**Current State:**
|
||||
- Global URL in push configuration: `/wp-admin/admin.php?page=woonoow#/orders`
|
||||
- **Recommendation:** Keep as default, add per-event override in Templates
|
||||
|
||||
### 📚 Documentation Created
|
||||
|
||||
1. **NOTIFICATION_LOGIC.md** - Complete logic explanation
|
||||
- Toggle hierarchy
|
||||
- Decision logic with examples
|
||||
- Implementation details
|
||||
- Usage examples
|
||||
- Testing checklist
|
||||
|
||||
2. **NotificationManager.php** - Backend validation class
|
||||
- `is_channel_enabled()` - Global state
|
||||
- `is_event_channel_enabled()` - Event state
|
||||
- `should_send_notification()` - Combined validation
|
||||
- `send()` - Notification sending
|
||||
|
||||
### ✅ Testing Results
|
||||
|
||||
**Channels Page:**
|
||||
- [x] Toggle email off → Stays off ✅
|
||||
- [x] Toggle email on → Stays on ✅
|
||||
- [x] Toggle push off → Does NOT affect email ✅
|
||||
- [x] Toggle push on → Does NOT affect email ✅
|
||||
- [x] Reload page → States persist ✅
|
||||
|
||||
**Events Page:**
|
||||
- [x] Enable email for "Order Placed" → Saves ✅
|
||||
- [x] Enable push for "Order Placed" → Saves ✅
|
||||
- [x] Disable email → Does NOT affect push ✅
|
||||
- [x] Reload page → States persist ✅
|
||||
- [x] Enable multiple events → All save independently ✅
|
||||
|
||||
**Network Tab:**
|
||||
- [x] Each toggle = 1 request only ✅
|
||||
- [x] Response includes correct `enabled` value ✅
|
||||
- [x] No race conditions ✅
|
||||
|
||||
### 📊 Files Changed
|
||||
|
||||
**Backend:**
|
||||
- `includes/Api/NotificationsController.php` - 3 methods fixed
|
||||
- `includes/Core/Notifications/NotificationManager.php` - New class
|
||||
|
||||
**Frontend:**
|
||||
- `admin-spa/src/routes/Settings/Notifications/Channels.tsx` - UI simplified, mutation fixed
|
||||
- `admin-spa/src/routes/Settings/Notifications/Events.tsx` - Event-level toggle removed
|
||||
|
||||
**Documentation:**
|
||||
- `NOTIFICATION_LOGIC.md` - Complete logic documentation
|
||||
|
||||
### 🎯 Next Steps
|
||||
|
||||
**Immediate:**
|
||||
- [ ] Implement dynamic push notification URLs per event
|
||||
- [ ] Add URL template variables support
|
||||
- [ ] Add per-event URL configuration in Templates page
|
||||
|
||||
**Future:**
|
||||
- [ ] Push notification icon per event type
|
||||
- [ ] Push notification image per event (product image, customer avatar)
|
||||
- [ ] Rich notification content (order items, product details)
|
||||
- [ ] Notification actions (Mark as read, Quick reply)
|
||||
|
||||
---
|
||||
|
||||
**Implementation Date:** November 11, 2025
|
||||
**Status:** ✅ Production Ready
|
||||
**Next Milestone:** Dynamic push notification URLs
|
||||
|
||||
Reference in New Issue
Block a user