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:
dwindown
2025-11-11 16:21:15 +07:00
parent 3ef5087f09
commit 648be836ad

View File

@@ -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 WooCommerces 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