docs: Consolidate documentation - 52% reduction (56 → 27 files)

 Documentation Cleanup:
- Deleted 30 obsolete/completed docs
- Created NOTIFICATION_SYSTEM.md (consolidates all notification docs)
- Reduced from 56 to 27 MD files (52% reduction)

🗑️ Removed Categories:
- Completed features (ALL_ISSUES_FIXED, BASIC_CARD_COMPLETE, etc.)
- Superseded plans (NOTIFICATION_STRATEGY, NOTIFICATION_REFACTOR_*, etc.)
- Duplicate/fragmented docs (MARKDOWN_*, TEMPLATE_*, etc.)

📝 Consolidated:
- All notification documentation → NOTIFICATION_SYSTEM.md
  - Architecture & flow
  - Markdown syntax reference
  - Variables reference
  - Backend integration details
  - API endpoints
  - Email queue system
  - Global system toggle
  - Q&A section

 Kept Essential Docs (27):
- Core architecture guides
- Addon development guides
- Feature-specific docs (shipping, payment, tax)
- Implementation guides (i18n, hooks)
- Project docs (README, PROJECT_BRIEF, PROJECT_SOP)

📊 Result:
- Clearer navigation
- Less confusion
- Single source of truth for notifications
- Easier for new developers
This commit is contained in:
dwindown
2025-11-15 22:07:38 +07:00
parent 60658c6786
commit c3904cc064
31 changed files with 295 additions and 8463 deletions

View File

@@ -1,299 +0,0 @@
# ✅ ALL 4 ISSUES FIXED - Complete System Overhaul
## 🔴 Issues You Reported
1. ❌ Customer showing 7 templates instead of 9 (missing "Registered" and "VIP Upgraded")
2. ❌ Card types missing (all showing `[card]` instead of `[card type="hero"]`)
3. ❌ Preview showing raw markdown (not converting to HTML)
4. ❌ Button text and syntax highlighting issues
---
## ✅ Root Causes Found & Fixed
### **Issue #1: Missing Customer Templates**
**Root Cause:**
```php
// DefaultEmailTemplates.php - WRONG mapping!
'customer_registered' => 'customer_registered', // ❌ Wrong key!
'customer_vip_upgraded' => 'customer_vip_upgraded', // ❌ Wrong key!
// But DefaultTemplates.php uses:
'registered' => self::customer_registered(), // ✅ Correct key
'vip_upgraded' => self::customer_vip_upgraded(), // ✅ Correct key
```
**The Problem:**
- `DefaultTemplates.php` uses keys: `'registered'` and `'vip_upgraded'`
- `DefaultEmailTemplates.php` was mapping to: `'customer_registered'` and `'customer_vip_upgraded'`
- **Mismatch!** Templates not found, so only 7 showed instead of 9
**Fix Applied:**
```php
// File: includes/Core/Notifications/DefaultEmailTemplates.php
// Lines 37-40
'new_customer' => 'registered', // ✅ Fixed!
'customer_registered' => 'registered', // ✅ Fixed!
'customer_vip_upgraded' => 'vip_upgraded', // ✅ Fixed!
```
---
### **Issue #2: Card Types Missing**
**Root Cause:**
```typescript
// markdownToBlocks() regex wasn't trimming attributes
const attributes = cardMatch[1]; // " type=\"hero\"" with leading space
const typeMatch = attributes.match(/type=["']([^"']+)["']/); // ❌ Fails!
```
**Fix Applied:**
```typescript
// File: admin-spa/src/components/EmailBuilder/converter.ts
// Lines 230-235
const attributes = cardMatch[1].trim(); // ✅ Trim first!
const typeMatch = attributes.match(/type\s*=\s*["']([^"']+)["']/); // ✅ Handle spaces!
const cardType = (typeMatch?.[1] || 'default') as CardType;
```
---
### **Issue #3: Preview Showing Raw Markdown**
**Root Cause:**
```typescript
// Preview was showing markdown like "# heading" instead of "<h1>heading</h1>"
// parseCardsForPreview() wasn't converting markdown to HTML
return `<div class="${cardClass}">${cardContent}</div>`; // ❌ Raw markdown!
```
**Fix Applied:**
```typescript
// File: admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx
// Lines 224-227
// Convert markdown inside card to HTML
const htmlContent = markdownToHtml(cardContent.trim()); // ✅ Convert!
return `<div class="${cardClass}" style="${bgStyle}">${htmlContent}</div>`;
```
---
### **Issue #4: Button Text & Labels**
**Root Cause:**
- Button text was too short ("Markdown" vs "Switch to Markdown")
- Tab label didn't change when in markdown mode
**Fix Applied:**
```typescript
// File: admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx
// Lines 534, 542
<Label>{markdownMode ? __('Markdown') : __('Message Body')}</Label> // ✅ Dynamic label!
<Button>
{markdownMode ? __('Switch to Visual Builder') : __('Switch to Markdown')} // ✅ Clear text!
</Button>
```
---
## 📊 Before vs After
### **Before (Broken):**
```
Customer Templates: 7 (missing 2)
Card Display: [card] (no type)
Preview: # New order received! (raw markdown)
Button: "Markdown" (confusing)
```
### **After (Fixed):**
```
Customer Templates: 9 ✅ (all showing)
Card Display: [card type="hero"] ✅ (type preserved)
Preview: <h1>New order received!</h1> ✅ (rendered HTML)
Button: "Switch to Markdown" ✅ (clear)
```
---
## 🔄 Complete Data Flow (Now Working!)
### **Loading Template:**
```
1. Database → Markdown template
2. markdownToBlocks() → Parse with card types ✅
3. blocksToMarkdown() → Clean markdown ✅
4. Preview: markdownToHtml() → Rendered HTML ✅
```
### **Visual Mode:**
```
User edits blocks
handleBlocksChange()
├→ blocksToHTML() → HTML (for saving)
└→ blocksToMarkdown() → Markdown (synced)
✅ All synced, types preserved!
```
### **Markdown Mode:**
```
User types markdown
handleMarkdownChange()
├→ markdownToBlocks() → Parse types ✅
└→ blocksToHTML() → HTML (for saving)
✅ All synced, types preserved!
```
### **Preview:**
```
htmlContent (with [card] shortcodes)
parseCardsForPreview()
├→ Extract card type ✅
├→ Convert markdown to HTML ✅
└→ Generate styled <div> ✅
✅ Beautiful preview!
```
---
## 📁 Files Modified
### **1. DefaultTemplates.php**
**Lines:** 42-43
**Change:** Fixed template keys from `'customer_registered'` to `'registered'`
**Impact:** Customer now shows 9 templates ✅
### **2. DefaultEmailTemplates.php**
**Lines:** 37-40
**Change:** Fixed event mapping to use correct keys
**Impact:** Templates now found correctly ✅
### **3. converter.ts**
**Lines:** 230-235
**Change:** Trim attributes and handle spaces in regex
**Impact:** Card types now parsed correctly ✅
### **4. EditTemplate.tsx**
**Lines:** 224-227, 534, 542
**Changes:**
- Convert markdown to HTML in preview
- Update button text to be clearer
- Dynamic tab label
**Impact:** Preview works, UI is clearer ✅
---
## 🧪 Testing Checklist
### ✅ Test 1: Customer Templates Count
1. Go to Customer Notifications
2. Expand Email channel
3. **Expected:** 9 templates showing
4. **Result:** ✅ PASS
### ✅ Test 2: Card Types Preserved
1. Open "Order Placed" template
2. Check first card in Visual Builder
3. **Expected:** Card type = "hero"
4. **Result:** ✅ PASS
### ✅ Test 3: Preview Rendering
1. Open any template
2. Click "Preview" tab
3. **Expected:** Headings rendered as HTML, not markdown
4. **Result:** ✅ PASS
### ✅ Test 4: Markdown Mode
1. Click "Switch to Markdown"
2. **Expected:** Clean markdown, button says "Switch to Visual Builder"
3. **Result:** ✅ PASS
### ✅ Test 5: Mode Switching
1. Visual → Markdown → Visual → Markdown
2. **Expected:** No data loss, types preserved
3. **Result:** ✅ PASS
---
## 🎯 What Was The Real Problem?
### **The Core Issue:**
We had **THREE DIFFERENT SYSTEMS** trying to work together:
1. `DefaultTemplates.php` - New markdown templates (uses `'registered'` key)
2. `DefaultEmailTemplates.php` - Legacy wrapper (was using `'customer_registered'` key)
3. `TemplateProvider.php` - Template fetcher (relies on exact key match)
**Key mismatch = Templates not found!**
### **The Solution:**
- **Aligned all keys** across the system
- **Fixed parsing** to handle attributes correctly
- **Added markdown conversion** in preview
- **Improved UI** for clarity
---
## 💡 Why This Happened
### **Historical Context:**
1. Originally: HTML-based templates
2. Refactored: Markdown-based templates in `DefaultTemplates.php`
3. Wrapper: `DefaultEmailTemplates.php` created for compatibility
4. **Problem:** Wrapper used wrong keys!
### **The Cascade Effect:**
```
Wrong key in wrapper
Template not found
Fallback to default
Only 7 templates show (missing 2)
```
---
## 🚀 Next Steps
1. **Stop dev server** (Ctrl+C)
2. **Restart:** `npm run dev`
3. **Hard refresh browser:** Cmd+Shift+R
4. **Test all 4 issues:**
- ✅ Customer shows 9 templates
- ✅ Card types preserved
- ✅ Preview renders HTML
- ✅ Markdown mode works
---
## 📝 Summary
| Issue | Root Cause | Fix | Status |
|-------|------------|-----|--------|
| **Missing templates** | Key mismatch | Aligned keys | ✅ FIXED |
| **Card types missing** | Regex not trimming | Trim + better regex | ✅ FIXED |
| **Raw markdown in preview** | No conversion | Added markdownToHtml() | ✅ FIXED |
| **Confusing UI** | Short button text | Clear labels | ✅ FIXED |
---
**🎉 ALL ISSUES RESOLVED! The system is now working as designed!**
**Test it now - everything should work perfectly!** 🚀

View File

@@ -1,268 +0,0 @@
# ⚠️ Backend Integration Required
## Issues Found
### Issue #1: Incorrect Template Count in UI ❌
**Problem:**
The Staff Notifications page shows "9 templates" but there are only **7 staff events**.
**Location:**
`admin-spa/src/routes/Settings/Notifications/Templates.tsx` line 132
**Current Code:**
```tsx
<Badge variant="secondary" className="text-xs">
{allEvents.length} {__('templates')} // ❌ Shows ALL events (customer + staff)
</Badge>
```
**Root Cause:**
- `allEvents` combines ALL event types (orders, products, customers)
- It doesn't filter by recipient type (staff vs customer)
- Shows same count for both customer and staff pages
**Expected:**
- **Customer page:** Should show 9 templates (customer events only)
- **Staff page:** Should show 7 templates (staff events only)
**Solution Needed:**
The backend API `/notifications/events` needs to return events grouped by recipient type, OR the frontend needs to filter events based on the current page (staff/customer).
---
### Issue #2: Old Templates Still Being Used ❌
**Problem:**
After reloading multiple times, the email templates shown in the editor are still using the OLD format, not the new improved markdown templates.
**Current State:**
- ✅ New templates exist: `includes/Email/DefaultTemplates.php`
- ❌ Backend still using: `includes/Core/Notifications/DefaultEmailTemplates.php`
**Evidence:**
The old `DefaultEmailTemplates.php` uses HTML-heavy syntax:
```php
'body' => '[card type="hero"]
<h1>' . __('New Order Received!', 'woonoow') . '</h1>
<p>' . __('You have received a new order...', 'woonoow') . '</p>
[/card]'
```
The new `DefaultTemplates.php` uses clean markdown:
```php
return '[card type="hero"]
New order received!
A customer has placed a new order. Please review and process.
[/card]'
```
**Root Cause:**
The backend API controller is still calling the old `DefaultEmailTemplates` class instead of the new `DefaultTemplates` class.
---
## Required Backend Changes
### 1. Update Default Templates Integration
**Option A: Replace Old Class (Recommended)**
Replace `includes/Core/Notifications/DefaultEmailTemplates.php` with a wrapper that uses the new class:
```php
<?php
namespace WooNooW\Core\Notifications;
use WooNooW\Email\DefaultTemplates as NewDefaultTemplates;
class DefaultEmailTemplates {
public static function get_template($event_id, $recipient_type) {
// Map event IDs to new template structure
$eventMap = [
'order_placed' => 'order_placed',
'order_processing' => 'order_confirmed',
'order_completed' => 'order_completed',
'order_cancelled' => 'order_cancelled',
'order_refunded' => 'order_cancelled', // Map to cancelled for now
'low_stock' => 'order_placed', // Placeholder
'out_of_stock' => 'order_placed', // Placeholder
'new_customer' => 'customer_registered',
'customer_note' => 'order_placed', // Placeholder
];
$newEventId = $eventMap[$event_id] ?? $event_id;
// Get templates from new class
$allTemplates = NewDefaultTemplates::get_all_templates();
$templates = $allTemplates[$recipient_type] ?? [];
if (isset($templates[$newEventId])) {
return [
'subject' => NewDefaultTemplates::get_default_subject($recipient_type, $newEventId),
'body' => $templates[$newEventId],
];
}
// Fallback
return [
'subject' => __('Notification from {store_name}', 'woonoow'),
'body' => '[card]New notification[/card]',
];
}
}
```
**Option B: Update API Controller Directly**
Update the API controller to use the new `DefaultTemplates` class:
```php
use WooNooW\Email\DefaultTemplates;
// In the get_template endpoint:
$templates = DefaultTemplates::get_all_templates();
$subject = DefaultTemplates::get_default_subject($recipient_type, $event_id);
$body = $templates[$recipient_type][$event_id] ?? '';
```
---
### 2. Fix Event Counts in API
**Update:** `includes/Api/NotificationsController.php`
The `/notifications/events` endpoint should return events with recipient type information:
```php
public function get_events($request) {
$events = [
'orders' => [
[
'id' => 'order_placed',
'label' => __('Order Placed'),
'description' => __('When a new order is placed'),
'recipients' => ['customer', 'staff'], // ← Add this
],
[
'id' => 'order_confirmed',
'label' => __('Order Confirmed'),
'description' => __('When order is confirmed'),
'recipients' => ['customer', 'staff'], // ← Add this
],
// ... etc
],
'customers' => [
[
'id' => 'customer_registered',
'label' => __('Customer Registered'),
'description' => __('When customer creates account'),
'recipients' => ['customer'], // ← Customer only
],
[
'id' => 'customer_vip_upgraded',
'label' => __('VIP Upgraded'),
'description' => __('When customer becomes VIP'),
'recipients' => ['customer'], // ← Customer only
],
],
];
return rest_ensure_response($events);
}
```
---
### 3. Update Frontend to Filter Events
**Update:** `admin-spa/src/routes/Settings/Notifications/Templates.tsx`
```tsx
// Determine recipient type from current page
const isStaffPage = window.location.pathname.includes('/staff');
const recipientType = isStaffPage ? 'staff' : 'customer';
// Filter events by recipient
const filteredEvents = allEvents.filter((event: any) => {
return event.recipients && event.recipients.includes(recipientType);
});
// Use filteredEvents instead of allEvents
<Badge variant="secondary" className="text-xs">
{filteredEvents.length} {__('templates')}
</Badge>
```
---
## Event Mapping
### Customer Events (9 total)
1. `order_placed` → Order Placed
2. `order_confirmed` → Order Confirmed
3. `order_shipped` → Order Shipped
4. `order_completed` → Order Completed
5. `order_cancelled` → Order Cancelled
6. `payment_received` → Payment Received
7. `payment_failed` → Payment Failed
8. `customer_registered` → Customer Registered
9. `customer_vip_upgraded` → VIP Upgraded
### Staff Events (7 total)
1. `order_placed` → New Order
2. `order_confirmed` → Order Confirmed
3. `order_shipped` → Order Shipped
4. `order_completed` → Order Completed
5. `order_cancelled` → Order Cancelled
6. `payment_received` → Payment Received
7. `payment_failed` → Payment Failed
---
## Testing Checklist
After backend integration:
- [ ] Navigate to Customer Notifications → Templates
- [ ] Verify "9 templates" badge shows
- [ ] Open any customer event template
- [ ] Verify new markdown format is shown (not HTML)
- [ ] Navigate to Staff Notifications → Templates
- [ ] Verify "7 templates" badge shows
- [ ] Open any staff event template
- [ ] Verify new markdown format is shown
- [ ] Test saving a template
- [ ] Test resetting a template to default
- [ ] Verify preview shows correct formatting
---
## Priority
**HIGH PRIORITY** - These issues prevent the new templates from being used and show incorrect information to users.
**Estimated Time:** 1-2 hours to implement and test
---
## Summary
**What Works:**
- ✅ Frontend email builder
- ✅ Markdown parser
- ✅ Preview system
- ✅ New template files created
**What Needs Fixing:**
- ❌ Backend not using new templates
- ❌ Template count incorrect in UI
- ❌ Event-to-recipient mapping needed
**Once Fixed:**
- ✅ Users will see new improved templates
- ✅ Correct template counts
- ✅ Better UX overall

View File

@@ -1,55 +0,0 @@
# Backend Wiring Complete ✅
## Summary
All notification system components are fully wired and functional.
## What's Wired
### 1. Template System ✅
- Save/Get templates via API
- EmailRenderer uses templates
- Variables replaced automatically
- Markdown parsed (cards, buttons, images)
### 2. Channel Toggles ✅
- Frontend toggles saved to database
- NotificationManager checks before sending
- Email: `woonoow_email_notifications_enabled`
- Push: `woonoow_push_notifications_enabled`
### 3. Event Toggles ✅
- Per-event channel settings saved
- Stored in `woonoow_notification_settings`
- Checked before sending notifications
### 4. Global System Toggle ✅
- NEW: Switch between WooNooW and WooCommerce
- API: `GET/POST /notifications/system-mode`
- Stored in: `woonoow_notification_system_mode`
- EmailManager respects this setting
- NotificationManager checks before sending
### 5. Email Customization ✅
- Colors, logo, branding saved
- EmailRenderer applies customization
- Stored in: `woonoow_email_settings`
### 6. Push Settings ✅
- Icon, badge, sound settings
- PushNotificationHandler applies settings
## Notification Flow
```
Event → EmailManager → Check System Mode → Check Channel Toggle
→ Check Event Toggle → EmailRenderer → Get Template → Replace Variables
→ Parse Markdown → Apply Branding → wp_mail() → Sent ✅
```
## Key Files Modified
- `NotificationsController.php`: Added system-mode endpoints
- `NotificationManager.php`: Added system mode check
- `EmailManager.php`: Added is_enabled() check
## Testing
All settings are now saved and applied when sending notifications.

View File

@@ -1,228 +0,0 @@
# ✅ Basic Card Type & Newline Fixes Complete!
## Problems Solved! 🎉
1.**Newlines preserved** - Text no longer collapses into one line
2.**Basic card type added** - Plain text sections without styling
3.**No content loss** - All content can be wrapped in cards
---
## What Was Fixed
### 1. Newline Parsing ✅
**Problem:** Markdown newlines were collapsed, making everything inline
**Solution:** Updated `markdown-utils.ts` to:
- Preserve paragraph breaks (double newlines)
- Add `<br>` tags for single newlines within paragraphs
- Properly close and open `<p>` tags
**Result:**
```markdown
Order Number: #12345
Customer: John Doe
```
Now renders as:
```html
<p>
Order Number: #12345<br>
Customer: John Doe
</p>
```
---
### 2. Basic Card Type ✅
**What It Is:**
- A new card type: `[card type="basic"]`
- **No background** color
- **No border**
- **No padding**
- Just plain text in a section
**Why It's Useful:**
- Wrap footer text without styling
- Ensure all content is in blocks (no loss)
- Give users a "plain text" option
- Makes templates more structured
**CSS:**
```css
.card-basic {
background: none;
border: none;
padding: 0;
margin: 16px 0;
}
```
---
### 3. Template Footer Updates 📝
**Old Pattern:**
```markdown
---
Need help? Contact {support_email}
© {current_year} {site_name}
```
**New Pattern:**
```markdown
[card type="basic"]
Need help? Contact {support_email}
[/card]
```
**Changes:**
- ✅ Removed `© {current_year} {site_name}` (already in global footer)
- ✅ Wrapped support text in `[card type="basic"]`
- ✅ Removed standalone `---` separators
- ✅ Staff templates: Removed footer entirely
---
## Files Modified
### 1. **`admin-spa/src/lib/markdown-utils.ts`**
- Fixed newline handling
- Proper paragraph and line break parsing
- Better list handling
### 2. **`admin-spa/src/components/EmailBuilder/types.ts`**
- Added `'basic'` to `CardType`
### 3. **`admin-spa/src/components/EmailBuilder/EmailBuilder.tsx`**
- Added "Basic (Plain Text)" option to card type selector
### 4. **`admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`**
- Added CSS for `.card-basic` (no styling)
### 5. **`includes/Email/DefaultTemplates.php`** (needs manual update)
- See `TEMPLATE_UPDATE_SCRIPT.md` for all changes
- 17 templates need footer updates
---
## How Basic Card Works
### In Markdown:
```markdown
[card type="basic"]
This is plain text.
No background, no border, no padding.
Just content.
[/card]
```
### Renders As:
```html
<div class="card card-basic">
<p>This is plain text.<br>
No background, no border, no padding.</p>
<p>Just content.</p>
</div>
```
### Displays As:
```
This is plain text.
No background, no border, no padding.
Just content.
```
(No visual styling - just text!)
---
## Benefits
### ✅ For Content:
- All content wrapped in blocks
- No content loss in converter
- Structured templates
### ✅ For Users:
- Can add plain text sections
- No forced styling
- More flexible templates
### ✅ For Developers:
- Cleaner template structure
- Easier to parse
- Better maintainability
---
## Card Type Comparison
| Type | Background | Border | Padding | Use Case |
|------|------------|--------|---------|----------|
| **basic** | None | None | None | Plain text, footers |
| **default** | White | Gray | Yes | Standard content |
| **hero** | Gradient | None | Yes | Headers, highlights |
| **success** | Gradient | None | Yes | Confirmations |
| **info** | Light blue | Blue | Yes | Information |
| **warning** | Light yellow | Orange | Yes | Warnings |
---
## Next Steps
### Manual Template Updates Required:
You need to update `includes/Email/DefaultTemplates.php`:
1. Open the file
2. Follow `TEMPLATE_UPDATE_SCRIPT.md`
3. Update all 17 template footers
4. Remove copyright lines
5. Wrap support text in `[card type="basic"]`
**Estimated time:** 10-15 minutes
**Or:** I can help you do it programmatically if you prefer!
---
## Testing Checklist
### ✅ Newlines:
- [x] Text with newlines displays correctly
- [x] Paragraphs separated properly
- [x] Line breaks within paragraphs work
### ✅ Basic Card:
- [x] Can select "Basic (Plain Text)" in editor
- [x] No background/border/padding applied
- [x] Content displays as plain text
- [x] Works in preview
### ✅ Templates:
- [ ] Update all template footers
- [ ] Test customer templates
- [ ] Test staff templates
- [ ] Verify no content loss
---
## Summary
| Feature | Status |
|---------|--------|
| Newline parsing | ✅ Fixed |
| Basic card type | ✅ Added |
| Card type selector | ✅ Updated |
| Preview CSS | ✅ Updated |
| Template updates | 📝 Manual needed |
**Almost done! Just need to update the template footers! 🚀**

View File

@@ -1,402 +0,0 @@
# ✅ CLEAN MARKDOWN - NO MORE HTML POLLUTION! 🎉
## Problem Identified & Fixed!
---
## 🔴 The Problem You Reported
### **What You Saw:**
1. Click "Markdown" button
2. See HTML code with `<p>` and `<br>` tags ❌
3. Mixed HTML + markdown syntax (messy!)
4. Switch back to visual → More `<p>` and `<br>` added
5. **Endless pollution!**
### **Root Cause:**
```typescript
// OLD (BROKEN) FLOW:
Visual Builder (blocks)
blocksToHTML() Adds <p> and <br>
htmlToMarkdown() Tries to clean, but messy
"Markdown mode" shows: <p>, <br>, mixed syntax
```
---
## ✅ The Solution
### **New Clean Flow:**
```typescript
// NEW (FIXED) FLOW:
Visual Builder (blocks)
blocksToMarkdown() Direct conversion!
Markdown mode shows: Clean markdown
```
### **Key Insight:**
**Skip HTML entirely when converting blocks ↔ markdown!**
---
## 🛠️ What Was Built
### **1. New Function: `blocksToMarkdown()`**
```typescript
// Direct conversion: Blocks → Markdown (no HTML!)
export function blocksToMarkdown(blocks: EmailBlock[]): string {
return blocks.map(block => {
switch (block.type) {
case 'card':
return `[card type="${block.cardType}"]\n\n${block.content}\n\n[/card]`;
case 'button':
return `[button url="${block.link}"]${block.text}[/button]`;
case 'divider':
return '---';
// ... etc
}
}).join('\n\n');
}
```
**Result:** Clean markdown, no `<p>`, no `<br>`! ✅
---
### **2. New Function: `markdownToBlocks()`**
```typescript
// Direct conversion: Markdown → Blocks (no HTML!)
export function markdownToBlocks(markdown: string): EmailBlock[] {
const blocks: EmailBlock[] = [];
// Parse [card] blocks
const cardMatch = markdown.match(/\[card([^\]]*)\]([\s\S]*)\[\/card\]/);
if (cardMatch) {
blocks.push({
type: 'card',
cardType: extractType(cardMatch[1]),
content: cardMatch[2].trim(), // Clean content!
});
}
// ... parse other blocks
return blocks;
}
```
**Result:** Direct parsing, no HTML intermediary! ✅
---
### **3. Updated EditTemplate.tsx**
#### **Before (BROKEN):**
```typescript
// Switching to markdown mode
const html = blocksToHTML(blocks); // Adds <p>, <br>
const markdown = htmlToMarkdown(html); // Messy conversion
setMarkdownContent(markdown); // Shows HTML pollution ❌
```
#### **After (FIXED):**
```typescript
// Switching to markdown mode
const markdown = blocksToMarkdown(blocks); // Direct, clean!
setMarkdownContent(markdown); // Shows clean markdown ✅
```
---
## 📊 Comparison
### **Old Flow (HTML Pollution):**
```
Visual Builder
Blocks: { content: "Hello world" }
blocksToHTML()
HTML: "<p>Hello world</p>"
htmlToMarkdown()
Markdown: "<p>Hello world</p>" ❌ Still has HTML!
```
### **New Flow (Clean Markdown):**
```
Visual Builder
Blocks: { content: "Hello world" }
blocksToMarkdown()
Markdown: "Hello world" ✅ Clean!
```
---
## 🎯 What You'll See Now
### **Markdown Mode (Clean!):**
```markdown
[card type="hero"]
# New order received!
A customer has placed a new order. Please review and process.
[/card]
[card]
**Order Number:** #{order_number}
**Customer:** {customer_name}
**Order Date:** {order_date}
[/card]
[button url="{order_url}"]View Order[/button]
```
**No `<p>`, no `<br>`, just clean markdown!**
---
## 🔄 The Complete Data Flow
### **Loading Template:**
```
Database (HTML)
htmlToBlocks() → Blocks
blocksToMarkdown() → Clean markdown
✅ Both views ready!
```
### **Visual Mode Editing:**
```
User edits blocks
handleBlocksChange()
├→ blocksToHTML() → HTML (for saving)
└→ blocksToMarkdown() → Markdown (for markdown mode)
✅ Both synced, no pollution!
```
### **Markdown Mode Editing:**
```
User types markdown
handleMarkdownChange()
├→ markdownToBlocks() → Blocks (for visual mode)
└→ blocksToHTML() → HTML (for saving)
✅ Both synced, no pollution!
```
### **Mode Switching:**
```
Visual → Markdown:
blocksToMarkdown(blocks) → Clean markdown ✅
Markdown → Visual:
markdownToBlocks(markdown) → Blocks ✅
No HTML intermediary = No pollution!
```
---
## 🧪 Testing Results
### ✅ Test 1: Visual → Markdown
1. Edit in visual mode
2. Click "Markdown"
3. **Result:** Clean markdown, no `<p>`, no `<br>`
### ✅ Test 2: Markdown → Visual
1. Type clean markdown
2. Click "Visual Builder"
3. **Result:** Blocks created correctly ✅
### ✅ Test 3: Multiple Switches
1. Visual → Markdown → Visual → Markdown
2. **Result:** No pollution accumulation ✅
### ✅ Test 4: Save & Reload
1. Edit in any mode
2. Save
3. Reload
4. **Result:** Clean markdown, no pollution ✅
---
## 📁 Files Modified
### **1. `converter.ts`**
**Added:**
-`blocksToMarkdown()` - Direct blocks → markdown
-`markdownToBlocks()` - Direct markdown → blocks
**Result:** Clean conversions without HTML pollution
---
### **2. `index.ts`**
**Added:**
- ✅ Export `blocksToMarkdown`
- ✅ Export `markdownToBlocks`
**Result:** Functions available throughout the app
---
### **3. `EditTemplate.tsx`**
**Changed:**
- ✅ Import new functions
- ✅ Use `blocksToMarkdown()` instead of `htmlToMarkdown()`
- ✅ Use `markdownToBlocks()` instead of `markdownToHtml() → htmlToBlocks()`
- ✅ Direct conversions in all handlers
**Result:** No more HTML pollution!
---
## 🎨 Architecture Summary
```
┌─────────────────────────────────────────┐
│ USER INTERFACE │
├─────────────────────────────────────────┤
│ Visual Builder ←→ Markdown │
│ │
│ Direct conversion (no HTML pollution!) │
└─────────────────────────────────────────┘
↕ ↕
blocksToMarkdown markdownToBlocks
↕ ↕
┌─────────────────────────────────────────┐
│ INTERNAL PIVOT │
├─────────────────────────────────────────┤
│ HTML (for database & preview only) │
│ Generated via blocksToHTML() │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ DATABASE │
└─────────────────────────────────────────┘
```
---
## 💡 Key Principles
### **1. Direct Conversion**
- Blocks ↔ Markdown: Direct, no HTML
- Only use HTML for database & preview
### **2. Clean Separation**
- **User-facing:** Markdown (clean, readable)
- **Internal:** HTML (for compatibility)
- **Never mix them!**
### **3. No Pollution**
- Markdown mode shows pure markdown
- No `<p>`, no `<br>`, no HTML tags
- Clean, mobile-friendly typing
---
## 🚀 Benefits
| Feature | Before | After |
|---------|--------|-------|
| **Markdown view** | Mixed HTML + markdown ❌ | Pure markdown ✅ |
| **HTML pollution** | Accumulates with switches ❌ | Never happens ✅ |
| **Mobile typing** | Hard (HTML tags) ❌ | Easy (clean markdown) ✅ |
| **Readability** | Poor ❌ | Excellent ✅ |
| **Maintainability** | Complex ❌ | Simple ✅ |
---
## 📝 Example Output
### **Before (Polluted):**
```
[card type="hero"]
<p>
<p>
<p>
# New order received!
</p>
</p>
A customer has placed...
</p>
<br>
<br>
[/card]
```
### **After (Clean):**
```
[card type="hero"]
# New order received!
A customer has placed a new order. Please review and process.
[/card]
```
**Perfect!**
---
## 🎉 Summary
### **Problem:**
- Markdown mode showed HTML with `<p>` and `<br>` tags
- Pollution accumulated with mode switches
- Not truly "markdown mode"
### **Solution:**
- Created `blocksToMarkdown()` for direct conversion
- Created `markdownToBlocks()` for direct parsing
- Bypassed HTML entirely for markdown ↔ blocks
- HTML only used for database & preview
### **Result:**
- ✅ Clean, pure markdown in markdown mode
- ✅ No HTML pollution ever
- ✅ Mobile-friendly typing
- ✅ Professional, modern approach
---
**🎊 FIXED! Test it now with hard refresh (Cmd+Shift+R)! 🚀**
**Click "Markdown" → See clean markdown, no HTML pollution!**

View File

@@ -1,98 +0,0 @@
# Converter Fixes Summary
## Issues Fixed
### 1. ✅ Exact Event Naming - No Mapping
**Problem:** API used `order_processing` but Email templates had `order_confirmed`. Required a "bridge" mapping.
**Solution:** Renamed template methods to match API exactly:
- `customer_order_confirmed()``customer_order_processing()`
- `staff_order_confirmed()``staff_order_processing()`
- `customer_registered()``customer_new_customer()`
**Result:** Direct 1:1 mapping, no confusion, clean code.
### 2. ✅ Markdown Converter Respects [card] Boundaries
**Problem:** `markdownToBlocks()` was splitting by double newlines (`\n\n`), causing:
- Raw `[/card]` tags left in output
- Each line with double space became a new card
- `##` headings not rendered
**Root Cause:**
```typescript
// OLD - WRONG
const sections = markdown.split(/\n\n+/); // Splits by double newlines!
```
**Solution:** Parse by `[card]...[/card]` boundaries:
```typescript
// NEW - CORRECT
while (remaining.length > 0) {
const cardMatch = remaining.match(/^\[card([^\]]*)\]([\s\S]*?)\[\/card\]/);
if (cardMatch) {
// Extract content between [card] and [/card]
const content = cardMatch[2].trim();
blocks.push({ type: 'card', content });
remaining = remaining.substring(cardMatch[0].length); // Advance!
}
}
```
**Key Changes:**
- Uses regex to find `[card]...[/card]` pairs
- Extracts content between tags
- Advances `remaining` string after each match
- No splitting by newlines
### 3. ⚠️ Markdown Rendering in Preview (Partial)
**Current State:**
- Markdown is stored in database: `## Heading\n\n**bold**`
- Frontend CodeEditor shows clean markdown ✅
- Preview shows markdown as-is (not converted to HTML) ❌
**Why:**
The preview uses `htmlContent` which contains `[card]## Heading[/card]` but doesn't convert the markdown inside to HTML.
**Next Steps:**
Backend PHP needs to convert markdown to HTML when rendering emails. The `[card]` shortcode handler should:
1. Extract content
2. Convert markdown to HTML
3. Wrap in styled div
## Files Modified
1. `/includes/Email/DefaultTemplates.php`
- Renamed methods to match API event IDs exactly
- Updated subject keys
2. `/includes/Core/Notifications/TemplateProvider.php`
- Removed event mapping
- Direct lookup: `$allEmailTemplates[$recipient_type][$event_id]`
3. `/admin-spa/src/components/EmailBuilder/converter.ts`
- Fixed `markdownToBlocks()` to respect `[card]...[/card]` boundaries
- Added proper string advancement
- No more double-newline splitting
## Testing Checklist
- [x] Event names match between API and templates
- [x] No mapping/bridging code
- [x] Markdown editor shows clean markdown
- [x] `[/card]` tags not left in output
- [x] Double newlines don't create new cards
- [ ] Preview renders markdown as HTML (needs backend fix)
- [ ] Headings show as `<h2>` not `##` in preview
- [ ] Line breaks work correctly in preview
## Remaining Work
**Backend Markdown Rendering:**
The WordPress shortcode handler for `[card]` needs to convert markdown content to HTML before rendering.
Location: Likely in `/includes/Email/` or `/includes/Core/Notifications/`
Required: A function that processes `[card]` shortcodes and converts their markdown content to HTML using a markdown parser.

View File

@@ -1,265 +0,0 @@
# ✅ Converter Fixed - All Content Now Displays!
## Problem Solved! 🎉
The visual builder and code mode now display **ALL content** from templates, not just the last button!
---
## The Issue
**Before:** Only the last button showed in the editor
- Visual Builder: Only 1 button visible ❌
- Code Mode: Only 1 line of HTML ❌
- Preview: Everything rendered correctly ✅
**Why:** The `htmlToBlocks()` converter was:
1. Only looking for `[card]` syntax
2. Not recognizing `<div class="card">` HTML (from markdown conversion)
3. Skipping all unrecognized content
---
## The Solution
### Updated `converter.ts` ✅
**What Changed:**
1. ✅ Now recognizes **both** `[card]` syntax AND `<div class="card">` HTML
2. ✅ Properly extracts all cards regardless of format
3. ✅ Preserves all content between cards
4. ✅ Handles markdown-converted HTML correctly
**New Regex:**
```typescript
// Match both [card] syntax and <div class="card"> HTML
const cardRegex = /(?:\[card([^\]]*)\]([\s\S]*?)\[\/card\]|<div class="card(?:\s+card-([^"]+))?"[^>]*>([\s\S]*?)<\/div>)/gs;
```
**New Card Detection:**
```typescript
// Check both [card] and <div class="card">
let cardMatch = part.match(/\[card([^\]]*)\]([\s\S]*?)\[\/card\]/s);
if (cardMatch) {
// [card] syntax
content = cardMatch[2].trim();
cardType = typeMatch ? typeMatch[1] : 'default';
} else {
// <div class="card"> HTML syntax
const htmlCardMatch = part.match(/<div class="card(?:\s+card-([^"]+))?"[^>]*>([\s\S]*?)<\/div>/s);
if (htmlCardMatch) {
cardType = htmlCardMatch[1] || 'default';
content = htmlCardMatch[2].trim();
}
}
```
---
## How It Works Now
### Loading Flow:
```
1. Template loaded (markdown format)
2. Markdown converted to HTML
[card] → <div class="card">
3. htmlToBlocks() called
4. Recognizes BOTH formats:
- [card]...[/card]
- <div class="card">...</div>
5. Extracts ALL cards
6. Creates blocks for visual builder
7. ALL content displays! ✅
```
---
## What's Fixed
### ✅ Visual Builder:
- **Before:** Only 1 button visible
- **After:** All cards and buttons visible!
### ✅ Code Mode:
- **Before:** Only 1 line of HTML
- **After:** Complete HTML with all cards!
### ✅ Preview:
- **Before:** Already working
- **After:** Still working perfectly!
---
## Files Modified
### `admin-spa/src/components/EmailBuilder/converter.ts`
**Changes:**
1. Updated `htmlToBlocks()` function
2. Added support for `<div class="card">` HTML
3. Improved card detection logic
4. Fixed TypeScript types
**Key Improvements:**
- Dual format support ([card] and HTML)
- Better content extraction
- No content loss
- Backwards compatible
---
## Testing Checklist
### ✅ Visual Builder:
- [x] Open any template
- [x] All cards visible
- [x] All buttons visible
- [x] All content preserved
- [x] Can edit each block
### ✅ Code Mode:
- [x] Switch to code mode
- [x] See complete HTML
- [x] All cards present
- [x] All buttons present
- [x] Can edit HTML
### ✅ Preview:
- [x] Switch to preview
- [x] Everything renders
- [x] All cards styled
- [x] All buttons clickable
---
## Edge Cases Handled
### 1. **Mixed Formats**
- Template has both `[card]` and `<div class="card">`
- ✅ Both recognized and converted
### 2. **Nested Content**
- Cards with complex HTML inside
- ✅ Content preserved correctly
### 3. **Multiple Card Types**
- hero, success, info, warning, default
- ✅ All types recognized from both formats
### 4. **Empty Cards**
- Cards with no content
- ✅ Handled gracefully
---
## Complete Flow
### From Database → Editor:
```
Database (Markdown)
[card type="hero"]
New order received!
[/card]
Markdown Detection
Convert to HTML
<div class="card card-hero">
New order received!
</div>
htmlToBlocks()
Recognizes <div class="card card-hero">
Creates Card Block:
{
type: 'card',
cardType: 'hero',
content: 'New order received!'
}
Visual Builder Displays Card ✅
```
---
## Summary
| Component | Before | After |
|-----------|--------|-------|
| Visual Builder | 1 button only | All content ✅ |
| Code Mode | 1 line | Complete HTML ✅ |
| Preview | Working | Still working ✅ |
| Card Detection | [card] only | Both formats ✅ |
| Content Loss | Yes ❌ | None ✅ |
---
## What Users See Now
### Visual Builder:
- ✅ Hero card with gradient
- ✅ Order details card
- ✅ Customer contact card
- ✅ Items ordered card
- ✅ Process order button
- ✅ Everything editable!
### Code Mode:
- ✅ Complete HTML structure
- ✅ All cards with proper classes
- ✅ All buttons with proper styling
- ✅ Can edit any part
### Preview:
- ✅ Beautiful rendering
- ✅ Brand colors applied
- ✅ All content visible
- ✅ Professional appearance
---
## Performance
**Impact:** None
- Same parsing speed
- No extra overhead
- Efficient regex matching
- No performance degradation
---
## Backwards Compatibility
**100% Compatible:**
- Old [card] syntax still works
- New HTML format works
- Mixed formats work
- No breaking changes
---
## Next Steps
**Nothing!** The system is complete! 🎉
**Test it now:**
1. Hard refresh browser (Cmd+Shift+R)
2. Open any template
3. ✅ See all content in visual builder
4. ✅ See all content in code mode
5. ✅ See all content in preview
**Everything works! 🚀**

View File

@@ -1,488 +0,0 @@
# 🎨 Custom Email System - Implementation Complete!
**Date:** November 12, 2025
**Status:****CORE COMPLETE - READY FOR TESTING**
---
## 📊 What Was Built
### 1. Email Manager (`EmailManager.php`) ✅
**Purpose:** Manages email sending and disables WooCommerce emails
**Features:**
- ✅ Disables all WooCommerce default emails (prevents duplicates)
- ✅ Hooks into ALL WooCommerce order status changes
- ✅ Hooks into customer, product, stock events
- ✅ Checks if events are enabled before sending
- ✅ Sends via `wp_mail()` (SMTP plugin compatible!)
- ✅ Singleton pattern for single instance
**WooCommerce Hooks:**
```php
// Order status changes
- woocommerce_order_status_pending_to_processing
- woocommerce_order_status_completed
- woocommerce_order_status_cancelled
- woocommerce_order_status_refunded
- woocommerce_new_order (admin notification)
// Customer events
- woocommerce_new_customer_note
- woocommerce_created_customer
// Product events
- woocommerce_low_stock
- woocommerce_no_stock
- woocommerce_product_set_stock
```
---
### 2. Email Renderer (`EmailRenderer.php`) ✅
**Purpose:** Renders beautiful HTML emails from templates
**Features:**
- ✅ Loads design templates (modern, classic, minimal)
- ✅ Replaces variables in subject and body
- ✅ Gets recipient email (staff/customer)
- ✅ Extracts order/product/customer data
- ✅ Renders final HTML email
- ✅ Filter hook: `apply_filters('woonoow_email_template', $path, $design)`
**Variable System:**
```php
Order Variables:
- {order_number}, {order_total}, {order_date}
- {customer_name}, {customer_email}
- {billing_address}, {shipping_address}
- {payment_method}, {shipping_method}
- {order_items} (HTML table)
Product Variables:
- {product_name}, {product_sku}, {product_price}
- {stock_quantity}, {stock_status}
Customer Variables:
- {customer_name}, {customer_email}
- {customer_username}
Store Variables:
- {store_name}, {store_url}
- {current_year}
```
---
### 3. Email Design Templates (3 HTML Files) ✅
#### **Modern Template** (`modern.html`)
- ✅ Clean, minimalist, Apple-inspired design
- ✅ Sans-serif fonts (system fonts)
- ✅ Subtle shadows and rounded corners
- ✅ Dark mode support
- ✅ Mobile responsive
- ✅ 2024 design trends
**Colors:**
- Background: `#f5f5f7`
- Text: `#1d1d1f`
- Accent: `#0071e3` (Apple blue)
- Muted: `#6e6e73`
#### **Classic Template** (`classic.html`)
- ✅ Professional, traditional design
- ✅ Serif fonts (Georgia)
- ✅ Gradient header (purple gradient)
- ✅ Table styling with alternating rows
- ✅ Business-appropriate
- ✅ Bold, confident look
**Colors:**
- Gradient: `#667eea` to `#764ba2`
- Background: `#f4f4f4`
- Text: `#333333`
#### **Minimal Template** (`minimal.html`)
- ✅ Ultra-clean, brutalist design
- ✅ Monospace font (Courier New)
- ✅ Black & white only
- ✅ Text-focused, no distractions
- ✅ Dark mode (inverted colors)
- ✅ High contrast
**Colors:**
- Black: `#000000`
- White: `#ffffff`
- That's it!
**All Templates Include:**
- ✅ Email client compatibility (Outlook, Gmail, Apple Mail)
- ✅ Mobile responsive design
- ✅ Dark mode support
- ✅ Proper HTML email structure
- ✅ Inline CSS for maximum compatibility
---
### 4. Rich Text Editor (`RichTextEditor.tsx`) ✅
**Purpose:** Modern WYSIWYG editor for email content
**Technology:** TipTap (React)
**Features:**
- ✅ Bold, Italic formatting
- ✅ Bullet lists, numbered lists
- ✅ Link insertion
- ✅ Undo/Redo
- ✅ Variable insertion buttons
- ✅ Placeholder text
- ✅ Clean, minimal toolbar
- ✅ HTML output
**UI:**
```
┌─────────────────────────────────────┐
│ [B] [I] │ [•] [1.] │ [🔗] │ [↶] [↷] │ ← Toolbar
├─────────────────────────────────────┤
│ │
│ [Rich text content here...] │
│ │
├─────────────────────────────────────┤
│ Variables: [{order_number}] [...] │ ← Quick insert
└─────────────────────────────────────┘
```
---
### 5. Template Editor Updated ✅
**Changes:**
- ✅ Replaced `<Textarea>` with `<RichTextEditor>`
- ✅ Variables shown as clickable buttons
- ✅ Better UX for content editing
- ✅ HTML output for beautiful emails
- ✅ Live variable insertion
---
## 🏗️ Architecture
```
WooCommerce Event
EmailManager (checks if enabled)
EmailRenderer
┌──────────────────────┐
│ 1. Get template │ → TemplateProvider
│ 2. Get variables │ → Order/Product/Customer data
│ 3. Replace variables │ → {order_number} → #12345
│ 4. Load design │ → modern.html / classic.html / minimal.html
│ 5. Render HTML │ → {{email_content}} → Final HTML
└──────────────────────┘
wp_mail() → SMTP Plugin → Customer's Inbox
```
---
## 🎯 How It Works
### Example: Order Completed Email
1. **WooCommerce fires hook:**
```php
do_action('woocommerce_order_status_completed', $order_id, $order);
```
2. **EmailManager catches it:**
```php
public function send_order_completed_email($order_id, $order) {
if (!$this->is_event_enabled('order_completed', 'email', 'customer')) {
return; // Event disabled, skip
}
$this->send_email('order_completed', 'customer', $order);
}
```
3. **EmailRenderer renders:**
```php
$template = TemplateProvider::get_template('order_completed', 'email');
$variables = $this->get_variables('order_completed', $order);
$content = $this->replace_variables($template['body'], $variables);
$html = $this->render_html('modern.html', $content, $subject, $variables);
```
4. **Email sent:**
```php
wp_mail($customer_email, $subject, $html, $headers);
```
5. **Customer receives beautiful HTML email!** 🎉
---
## 📁 File Structure
```
woonoow/
├── includes/
│ └── Core/
│ └── Notifications/
│ ├── EmailManager.php ← Hooks & sending
│ ├── EmailRenderer.php ← Template rendering
│ └── TemplateProvider.php ← Content templates
├── templates/
│ └── emails/
│ ├── modern.html ← Design template 1
│ ├── classic.html ← Design template 2
│ └── minimal.html ← Design template 3
└── admin-spa/
└── src/
├── components/
│ └── ui/
│ └── rich-text-editor.tsx ← TipTap editor
└── routes/
└── Settings/
└── Notifications/
└── TemplateEditor.tsx ← Updated UI
```
---
## ✅ What's Complete
- [x] EmailManager with WooCommerce hooks
- [x] EmailRenderer with variable system
- [x] 3 beautiful HTML email templates
- [x] Rich text editor (TipTap)
- [x] Template editor UI updated
- [x] WooCommerce email disabling
- [x] Filter hooks for extensibility
- [x] SMTP plugin compatibility
- [x] Dark mode support
- [x] Mobile responsive
- [x] Bootstrap integration
---
## 🚧 What's Pending
### 1. Design Template Selector (UI)
Add a dropdown in Notifications settings to choose:
- Modern (default)
- Classic
- Minimal
**Location:** Settings → Notifications → Channels tab
**Implementation:**
```tsx
<Select
value={designTemplate}
onValueChange={setDesignTemplate}
>
<SelectItem value="modern">Modern (Clean & Minimal)</SelectItem>
<SelectItem value="classic">Classic (Professional)</SelectItem>
<SelectItem value="minimal">Minimal (Black & White)</SelectItem>
</Select>
```
### 2. Content Templates
Update `TemplateProvider::get_default_templates()` with better default content for each event.
**Current:** Generic text
**Needed:** Contextual, professional content
### 3. Testing
- [ ] Test order processing email
- [ ] Test order completed email
- [ ] Test order refunded email
- [ ] Test new customer email
- [ ] Test low stock email
- [ ] Test all 3 design templates
- [ ] Test variable replacement
- [ ] Test SMTP delivery
- [ ] Test mobile rendering
- [ ] Test dark mode
### 4. Template Preview
Add live preview in TemplateEditor:
- Show how email will look
- Preview with sample data
- Switch between design templates
---
## 🎨 Design Template Comparison
| Feature | Modern | Classic | Minimal |
|---------|--------|---------|---------|
| **Font** | Sans-serif | Serif | Monospace |
| **Style** | Clean, Apple-like | Professional | Brutalist |
| **Colors** | Blue accent | Purple gradient | Black & white |
| **Best For** | Tech, SaaS | Business, Corporate | Art, Design |
| **Dark Mode** | ✅ Adaptive | ❌ No | ✅ Inverted |
| **Complexity** | Medium | High | Low |
---
## 🔧 Configuration
### Enable/Disable Custom Emails
```php
// In notification settings
$settings['use_custom_emails'] = true; // Default: true
// To keep WooCommerce emails:
$settings['use_custom_emails'] = false;
```
### Choose Design Template
```php
// In notification settings
$settings['email_design_template'] = 'modern'; // modern, classic, minimal
```
### Filter Template Path
```php
add_filter('woonoow_email_template', function($path, $design) {
// Use custom template
return '/path/to/custom-template.html';
}, 10, 2);
```
### Filter Variables
```php
add_filter('woonoow_email_variables', function($variables, $event_id, $data) {
// Add custom variable
$variables['custom_field'] = 'Custom Value';
return $variables;
}, 10, 3);
```
---
## 📊 Impact
### Before (WooCommerce Emails)
- ❌ Outdated design
- ❌ Hard to customize
- ❌ Inconsistent with brand
- ❌ Fragmented management
- ❌ No modern features
### After (WooNooW Emails)
- ✅ Modern, beautiful design
- ✅ Easy customization (rich text editor)
- ✅ Consistent branding
- ✅ Unified management
- ✅ Dark mode, mobile responsive
- ✅ 3 design choices
- ✅ Professional templates
- ✅ Better customer experience
---
## 🚀 Next Steps
1. **Add Design Template Selector**
- UI in Notifications settings
- Save preference to database
- Preview each template
2. **Improve Content Templates**
- Better default text
- More professional tone
- Context-aware content
3. **Test Everything**
- Place test orders
- Trigger all events
- Check email delivery
- Verify rendering
4. **Add Template Preview**
- Live preview in editor
- Sample data
- Design template switcher
5. **Documentation**
- User guide
- Developer docs
- Video tutorials
---
## 💡 Future Enhancements
### Phase 2 (Optional)
- [ ] Email analytics (open rates, clicks)
- [ ] A/B testing
- [ ] Premium template packs
- [ ] Custom template builder
- [ ] Email scheduling
- [ ] Conditional content
- [ ] Multi-language support
- [ ] Email attachments
### Phase 3 (Advanced)
- [ ] Drag & drop email builder
- [ ] Template marketplace
- [ ] Email automation workflows
- [ ] Segmentation
- [ ] Personalization engine
---
## 🎉 Success Metrics
-**Zero WooCommerce email conflicts**
-**Beautiful, modern email design**
-**Easy content editing (rich text)**
-**3 design templates**
-**SMTP plugin compatible**
-**Dark mode support**
-**Mobile responsive**
-**Extensible with filters**
---
## 📞 Technical Notes
### Email Client Compatibility
- ✅ Gmail (web, mobile)
- ✅ Apple Mail (macOS, iOS)
- ✅ Outlook (desktop, web)
- ✅ Yahoo Mail
- ✅ ProtonMail
- ✅ Thunderbird
### CSS Support
- ✅ Inline CSS (maximum compatibility)
- ✅ Media queries (responsive)
- ✅ Dark mode queries
- ✅ Table-based layout (Outlook)
### Security
- ✅ Escapes all variables
- ✅ Sanitizes HTML output
- ✅ No external resources
- ✅ No tracking pixels (optional)
---
**Status:** 🎉 **CORE SYSTEM COMPLETE!**
**Ready for:** Testing & UI polish
**Estimated time to production:** 1-2 days
**You now have a modern, beautiful, extensible email system that rivals Shopify and BigCommerce!** 🚀

View File

@@ -1,102 +0,0 @@
# Event-Template Mismatch Analysis
## Current State
### Events API (`NotificationsController.php`)
Defines 9 events total:
**Staff (4 events):**
1. `order_placed` - When order is placed
2. `order_cancelled` - When order is cancelled
3. `low_stock` - Product stock low
4. `out_of_stock` - Product out of stock
**Customer (5 events):**
1. `order_processing` - Order being processed
2. `order_completed` - Order completed
3. `order_refunded` - Order refunded
4. `new_customer` - Customer registers
5. `customer_note` - Note added to order
### DefaultTemplates.php
Has 15 templates total:
**Staff (7 templates):**
1. `order_placed`
2. `order_processing` ❌ (no event)
3. `order_shipped` ❌ (no event)
4. `order_completed` ❌ (no event)
5. `order_cancelled`
6. `payment_received` ❌ (no event)
7. `payment_failed` ❌ (no event)
**Customer (8 templates):**
1. `order_placed` ❌ (no event)
2. `order_processing`
3. `order_shipped` ❌ (no event)
4. `order_completed`
5. `order_cancelled` ❌ (no event)
6. `payment_received` ❌ (no event)
7. `payment_failed` ❌ (no event)
8. `new_customer`
**Missing from templates:**
- `order_refunded` (customer)
- `customer_note` (customer)
- `low_stock` (staff)
- `out_of_stock` (staff)
## The Problem
**Templates exist without events** - These templates will never be used because no event triggers them.
**Events exist without templates** - These events will use fallback templates.
## Recommended Solution
**Events API should be the source of truth.** Add missing events to match a complete e-commerce notification system:
### Proposed Complete Event List
**Staff Events (7):**
1. `order_placed` - New order notification
2. `order_processing` - Order confirmed, ready to process
3. `order_cancelled` - Order cancelled
4. `low_stock` - Product stock low
5. `out_of_stock` - Product out of stock
6. `payment_received` - Payment confirmed
7. `payment_failed` - Payment failed
**Customer Events (8):**
1. `order_processing` - Order being processed
2. `order_shipped` - Order shipped with tracking
3. `order_completed` - Order delivered
4. `order_cancelled` - Order cancelled
5. `order_refunded` - Order refunded
6. `payment_received` - Payment confirmed
7. `payment_failed` - Payment failed, retry
8. `new_customer` - Welcome email
9. `customer_note` - Note added to order
**Total: 16 events** (7 staff + 9 customer)
## Action Items
1. **Add missing events to NotificationsController.php:**
- Staff: `order_processing`, `order_shipped`, `order_completed`, `payment_received`, `payment_failed`
- Customer: `order_placed`, `order_shipped`, `order_cancelled`, `payment_received`, `payment_failed`
2. **Add missing templates to DefaultTemplates.php:**
- Customer: `order_refunded`, `customer_note`
- Staff: `low_stock`, `out_of_stock`
3. **Update TemplateProvider.php** to handle all events
## Why Events API is Source of Truth
- Events define **what actually happens** in the system
- Templates are just **content** for those events
- If an event doesn't exist, the template is useless
- If a template doesn't exist, we can create a fallback
**Conclusion:** Expand Events API to include all meaningful e-commerce notifications, then ensure templates exist for each.

View File

@@ -1,377 +0,0 @@
# ✅ HTML as Single Source of Truth - IMPLEMENTED! 🚀
## Problem Solved! 🎉
**Before:** Confusing data flow with markdown/HTML/blocks competing
**After:** Clean architecture with HTML as the single source of truth
---
## The Architecture
### **HTML = Source of Truth**
```
┌─────────────────────────────────────────┐
│ DATABASE (HTML) │
│ Single source of truth for all content │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ EDITOR STATE (htmlContent) │
│ Always contains the current HTML │
└─────────────────────────────────────────┘
┌───────────┴───────────┐
↓ ↓
┌──────────────┐ ┌──────────────┐
│ Code Mode │ │ Visual Mode │
│ (HTML view) │ │ (Blocks view)│
└──────────────┘ └──────────────┘
```
---
## How It Works
### 1. **Loading Template**
```typescript
// Load from database
const template = await fetchTemplate();
// One-time conversion: Markdown → HTML (if needed)
let html = template.body;
if (isMarkdown(html)) {
html = markdownToHtml(html);
}
// Set HTML as source of truth
setHtmlContent(html);
setBlocks(htmlToBlocks(html)); // Visual view
```
### 2. **Editing in Visual Mode**
```typescript
// User edits blocks
handleBlocksChange(newBlocks) {
setBlocks(newBlocks); // Update visual view
setHtmlContent(blocksToHTML(newBlocks)); // Sync to HTML
}
// HTML is always up-to-date!
```
### 3. **Editing in Code Mode**
```typescript
// User edits HTML directly
handleHtmlChange(newHtml) {
setHtmlContent(newHtml); // Update HTML directly
}
// HTML is the source, no conversion needed!
```
### 4. **Switching Modes**
```typescript
// Switching TO code mode
if (!codeMode) {
const currentHtml = blocksToHTML(blocks);
setHtmlContent(currentHtml); // Update HTML from blocks
}
// Switching FROM code mode
else {
setBlocks(htmlToBlocks(htmlContent)); // Update blocks from HTML
}
// Mode switching = Format conversion for display only
// HTML remains the source of truth
```
### 5. **Saving**
```typescript
// Always save HTML (source of truth)
await saveTemplate({
subject,
body: htmlContent, // Just save it!
});
// No conversion needed, no confusion!
```
---
## Data Flow
### Visual Mode → Code Mode:
```
User edits blocks
Blocks updated
HTML updated (blocksToHTML)
User switches to code mode
Show HTML in editor
✅ All changes preserved!
```
### Code Mode → Visual Mode:
```
User edits HTML
HTML updated directly
User switches to visual mode
Convert HTML → Blocks
✅ All changes preserved!
```
### Visual Mode → Save:
```
User edits blocks
HTML updated continuously
User clicks save
Save HTML to database
✅ Perfect sync!
```
### Code Mode → Save:
```
User edits HTML
HTML updated directly
User clicks save
Save HTML to database
✅ Perfect sync!
```
---
## What Changed
### Before (Confusing):
```typescript
// Multiple sources of truth
const [body, setBody] = useState(''); // HTML?
const [blocks, setBlocks] = useState([]); // Blocks?
const [markdown, setMarkdown] = useState(''); // Markdown?
// Confusing save logic
const htmlBody = codeMode ? body : blocksToHTML(blocks);
// Markdown detection on every load
if (isMarkdown(template.body)) {
// Convert...
}
// Lost changes when switching modes!
```
### After (Clean):
```typescript
// Single source of truth
const [htmlContent, setHtmlContent] = useState(''); // HTML!
const [blocks, setBlocks] = useState([]); // Visual view only
// Clean save logic
await saveTemplate({ body: htmlContent });
// One-time markdown conversion
if (isMarkdown(template.body)) {
html = markdownToHtml(template.body);
// After this, always HTML
}
// Changes always preserved!
```
---
## Benefits
### ✅ No Data Loss:
- All changes preserved when switching modes
- HTML always in sync
- No confusion about which format is "current"
### ✅ Clear Priority:
- **HTML** = Source of truth (always)
- **Markdown** = Input format only (one-time conversion)
- **Blocks** = Visual representation (view only)
### ✅ Simple Logic:
- Save = Just save HTML
- Load = Just load HTML
- Switch modes = Convert for display only
### ✅ User Friendly:
- Edit in any mode
- Switch freely
- Never lose work
---
## Mode Comparison
| Mode | What User Sees | What Happens | HTML Updated? |
|------|----------------|--------------|---------------|
| **Visual** | Blocks/Cards | Edit blocks → HTML synced | ✅ Yes (continuous) |
| **Code** | HTML code | Edit HTML directly | ✅ Yes (direct) |
| **Preview** | Rendered email | View only | ❌ No |
---
## Markdown Handling
### One-Time Conversion:
```typescript
// On template load
if (detectContentType(template.body) === 'markdown') {
html = markdownToHtml(template.body);
setHtmlContent(html);
}
// After this, HTML is always used
// No more markdown detection!
```
### Why This Works:
- ✅ Default templates can be markdown (easier to write)
- ✅ Converted to HTML on first load
- ✅ After that, always HTML in database
- ✅ Users never see markdown (only HTML or visual)
---
## Files Modified
### `EditTemplate.tsx`
**Changes:**
1. ✅ Renamed `body``htmlContent` (clarity)
2. ✅ Made `htmlContent` the single source of truth
3. ✅ Updated `handleBlocksChange` to sync HTML
4. ✅ Added `handleHtmlChange` for code mode
5. ✅ Fixed `handleCodeModeToggle` to convert properly
6. ✅ Updated `handleSave` to always save HTML
7. ✅ Updated JSX to use `htmlContent`
8. ✅ Removed markdown mode (HTML only in code mode)
**Result:**
- Clean, simple, no confusion
- All changes preserved
- HTML always in sync
---
## Testing Checklist
### ✅ Visual Mode:
- [x] Edit blocks
- [x] Switch to code mode
- [x] See HTML with all changes
- [x] Switch back to visual
- [x] All changes still there
### ✅ Code Mode:
- [x] Edit HTML
- [x] Switch to visual mode
- [x] See blocks with all changes
- [x] Switch back to code
- [x] All changes still there
### ✅ Save:
- [x] Edit in visual mode
- [x] Save
- [x] Reload page
- [x] All changes preserved
- [x] Edit in code mode
- [x] Save
- [x] Reload page
- [x] All changes preserved
### ✅ Preview:
- [x] Edit in any mode
- [x] Switch to preview
- [x] See rendered email
- [x] All content displays
---
## Summary
| Feature | Before | After |
|---------|--------|-------|
| Source of truth | Unclear | ✅ HTML |
| Mode switching | Lost changes | ✅ Preserved |
| Save logic | Complex | ✅ Simple |
| Data flow | Confusing | ✅ Clear |
| Markdown handling | Every load | ✅ One-time |
| User experience | Frustrating | ✅ Smooth |
---
## What Users See
### Visual Mode:
```
┌─────────────────────────────┐
│ [Add Block ▼] │
├─────────────────────────────┤
│ ┌───────────────────────┐ │
│ │ 🎨 Hero Card │ │
│ │ ## Welcome! │ │
│ │ Content here... │ │
│ └───────────────────────┘ │
│ ┌───────────────────────┐ │
│ │ 📄 Default Card │ │
│ │ More content... │ │
│ └───────────────────────┘ │
└─────────────────────────────┘
```
### Code Mode:
```
┌─────────────────────────────┐
│ <div class="card card-hero">│
│ <h2>Welcome!</h2> │
│ <p>Content here...</p> │
│ </div> │
│ <div class="card"> │
│ <p>More content...</p> │
│ </div> │
└─────────────────────────────┘
```
### Behind the Scenes:
```
Both modes editing the SAME HTML!
✅ No data loss
✅ Perfect sync
✅ Simple architecture
```
---
**🎉 COMPLETE! HTML is now the single source of truth! 🚀**
**Test it:**
1. Hard refresh (Cmd+Shift+R)
2. Edit in visual mode
3. Switch to code mode → See your changes
4. Edit in code mode
5. Switch to visual mode → See your changes
6. Save → All changes preserved!
**No more confusion! No more lost changes! 🎊**

View File

@@ -1,182 +0,0 @@
# Improvements Completed
## ✅ 1. Single Source of Truth with Filter Hooks
### EventRegistry.php
Created centralized event registry with filter hook:
```php
$events = EventRegistry::get_all_events();
// Filter: woonoow_notification_events_registry
```
### DefaultTemplates.php
Added filter hooks for templates and subjects:
```php
// Filter: woonoow_email_default_templates
$templates = apply_filters('woonoow_email_default_templates', $templates);
// Filter: woonoow_email_default_subject
$subject = apply_filters('woonoow_email_default_subject', $subject, $recipient, $event);
```
### Usage Example
```php
// Add custom event
add_filter('woonoow_notification_events_registry', function($events) {
$events['custom_event'] = [
'id' => 'custom_event',
'label' => 'Custom Event',
'category' => 'custom',
'recipient_type' => 'customer',
'enabled' => true,
];
return $events;
});
// Add template for custom event
add_filter('woonoow_email_default_templates', function($templates) {
$templates['customer']['custom_event'] = '[card]Custom content[/card]';
return $templates;
});
```
**Result:**
- ✅ One place to manage events
- ✅ No hardcoding
- ✅ Fully extensible
- ✅ Events and templates always aligned
## ✅ 2. Card Type Selector in Markdown Toolbar
### Added Features
- **Card Insert Button** with dialog
- **Card Type Selector** dropdown with 6 types:
- Default - Standard white card
- Hero - Large header with gradient
- Success - Green success message
- Warning - Yellow warning message
- Info - Blue information card
- Basic - Minimal styling
### Implementation
- `markdown-toolbar.tsx` - Added dialog with card type selection
- Inserts properly formatted `[card type="..."]...[/card]` template
- Includes placeholder content with heading
**Result:**
- ✅ Easy card insertion
- ✅ Visual card type selection
- ✅ Better UX for markdown editing
## ✅ 3. Markdown ↔ HTML Conversion for Visual Editor
### Problem
Visual editor (RichTextEditor) was receiving markdown content directly, showing `**bold**` and `## headings` as plain text.
### Solution
#### A. Markdown → HTML (When Opening Editor)
```typescript
// EmailBuilder.tsx
const htmlContent = parseMarkdownBasics(block.content);
setEditingContent(htmlContent);
```
#### B. HTML → Markdown (When Saving)
```typescript
// EmailBuilder.tsx
const markdownContent = htmlToMarkdown(editingContent);
return { ...block, content: markdownContent, cardType: editingCardType };
```
#### C. New Utility: `html-to-markdown.ts`
Converts rich text editor HTML output back to clean markdown:
- `<h2>``## `
- `<strong>``**...**`
- `<em>``*...*`
- `<p>` → double newlines
- Lists, links, etc.
**Result:**
- ✅ Visual editor shows properly formatted content
- ✅ Bold, headings, lists render correctly
- ✅ Seamless conversion between markdown and HTML
- ✅ No markdown syntax visible in visual mode
## ⚠️ 4. Newline Rendering in Preview
### Current State
The preview already uses `markdownToHtml()` which includes `parseMarkdownBasics()`:
- Single newlines → `<br>` tags
- Double newlines → separate `<p>` tags
- Lists, headings, etc. properly converted
### Implementation
```typescript
// EditTemplate.tsx - Line 202
const htmlContent = markdownToHtml(cardContent.trim());
```
The `parseMarkdownBasics()` function:
- Wraps text in `<p>` tags
- Adds `<br>` for line continuations
- Handles lists, headings, bold, italic, links
**Status:** Should be working correctly. If newlines still don't render:
1. Check if markdown has proper double newlines for paragraphs
2. Verify CSS doesn't have `white-space: nowrap`
3. Test with actual template content
## Files Modified
### Backend (PHP)
1. `/includes/Core/Notifications/EventRegistry.php` - **NEW** - Single source of truth
2. `/includes/Email/DefaultTemplates.php` - Added filter hooks
3. `/includes/Api/NotificationsController.php` - Use EventRegistry
4. `/includes/Core/Notifications/TemplateProvider.php` - Use EventRegistry
### Frontend (TypeScript/React)
1. `/admin-spa/src/components/ui/markdown-toolbar.tsx` - Card type selector dialog
2. `/admin-spa/src/components/EmailBuilder/EmailBuilder.tsx` - Markdown ↔ HTML conversion
3. `/admin-spa/src/lib/html-to-markdown.ts` - **NEW** - HTML to markdown converter
4. `/admin-spa/src/lib/markdown-utils.ts` - Export `parseMarkdownBasics`
## Testing Checklist
- [x] Filter hooks work for adding custom events
- [x] Filter hooks work for adding custom templates
- [x] Card type selector opens and inserts cards
- [x] Visual editor shows HTML (not markdown)
- [x] Markdown editor shows markdown (not HTML)
- [x] Switching between Visual ↔ Markdown preserves content
- [ ] Preview renders newlines correctly
- [ ] Bold, headings, lists render in preview
- [ ] No markdown syntax visible in preview
## Next Steps (If Needed)
1. **Test newline rendering** - Create a template with multiple paragraphs and verify preview
2. **Backend markdown processing** - Ensure WordPress shortcode handler converts markdown to HTML
3. **CSS check** - Verify email template CSS doesn't break newlines
4. **Variable replacement** - Ensure variables work in all modes
## Documentation Created
1. `FILTER_HOOKS_GUIDE.md` - Complete guide for extending events and templates
2. `SINGLE_SOURCE_OF_TRUTH.md` - Architecture documentation
3. `IMPROVEMENTS_COMPLETED.md` - This file
## Summary
**Completed:**
- Single source of truth with EventRegistry
- Full filter hook system for extensibility
- Card type selector in markdown toolbar
- Proper markdown ↔ HTML conversion for visual editor
- HTML to markdown converter
⚠️ **Needs Verification:**
- Newline rendering in preview (likely working, needs testing)
🎯 **Result:**
A fully functional, extensible notification system with seamless editing experience across markdown, visual, and preview modes.

View File

@@ -1,221 +0,0 @@
# ✅ Backend Integration Complete!
## All Issues Fixed! 🎉
Both issues have been completely resolved and the email template system is now fully functional!
---
## Issue #1: Template Count - FIXED ✅
**Problem:** Staff page showed "9 templates" instead of 7
**What Was Fixed:**
1. ✅ Added `recipients` array to all events in API (`NotificationsController.php`)
2. ✅ Added recipient type detection in frontend (`Templates.tsx`)
3. ✅ Filtered events by recipient type
4. ✅ Updated template count to use filtered events
**Result:**
- **Customer page:** Now shows **6 templates** (customer events only)
- **Staff page:** Now shows **7 templates** (staff events only)
**Event Breakdown:**
- **Customer events (6):** order_placed, order_processing, order_completed, order_cancelled, order_refunded, new_customer, customer_note
- **Staff events (7):** order_placed, order_processing, order_completed, order_cancelled, low_stock, out_of_stock
- **Shared events (5):** order_placed, order_processing, order_completed, order_cancelled (appear in both)
---
## Issue #2: Old Templates - FIXED ✅
**Problem:** Backend was using old HTML templates instead of new markdown templates
**What Was Fixed:**
1. ✅ Updated `DefaultEmailTemplates.php` to use new `DefaultTemplates` class
2. ✅ Added event ID mapping for backwards compatibility
3. ✅ Added helper methods to access new templates directly
**Result:**
- ✅ All templates now use clean markdown format
- ✅ New improved content is displayed
- ✅ Backwards compatibility maintained
**Template Format Change:**
**Before (Old):**
```php
'body' => '[card type="hero"]
<h1>' . __('New Order Received!', 'woonoow') . '</h1>
<p>' . __('You have received a new order...', 'woonoow') . '</p>
[/card]'
```
**After (New):**
```php
return '[card type="hero"]
New order received!
A customer has placed a new order. Please review and process.
[/card]'
```
---
## Files Modified
### Backend Files:
1. **`includes/Core/Notifications/DefaultEmailTemplates.php`**
- Now uses `WooNooW\Email\DefaultTemplates`
- Added event mapping for compatibility
- Added helper methods
2. **`includes/Api/NotificationsController.php`**
- Added `recipients` array to all events
- Clear indication of which recipient types can receive each event
### Frontend Files:
3. **`admin-spa/src/routes/Settings/Notifications/Templates.tsx`**
- Added recipient type detection
- Added event filtering by recipient
- Updated template count display
---
## How It Works Now
### 1. Template Loading Flow:
```
User opens template editor
Frontend requests template from API
API calls DefaultEmailTemplates::get_template()
DefaultEmailTemplates maps event ID
Calls new DefaultTemplates::get_all_templates()
Returns new markdown template
Frontend displays clean markdown format
```
### 2. Event Filtering Flow:
```
User visits Customer/Staff Notifications page
Frontend detects page type (customer/staff)
Fetches all events from API
Filters events by recipients array
Displays only relevant events
Shows correct template count
```
---
## Event Recipient Mapping
| Event ID | Customer | Staff | Notes |
|----------|----------|-------|-------|
| order_placed | ✅ | ✅ | Both receive notification |
| order_processing | ✅ | ✅ | Both receive notification |
| order_completed | ✅ | ✅ | Both receive notification |
| order_cancelled | ✅ | ✅ | Both receive notification |
| order_refunded | ✅ | ❌ | Customer only |
| low_stock | ❌ | ✅ | Staff only |
| out_of_stock | ❌ | ✅ | Staff only |
| new_customer | ✅ | ❌ | Customer only |
| customer_note | ✅ | ❌ | Customer only |
---
## Testing Checklist
### ✅ Customer Page:
- [x] Navigate to Settings → Notifications → Customer → Templates
- [x] Verify badge shows correct count (6-7 templates depending on shared events)
- [x] Open any customer event template
- [x] Verify new markdown format is displayed
- [x] Verify clean, readable content (not HTML tags)
- [x] Test saving template
- [x] Test resetting template
### ✅ Staff Page:
- [x] Navigate to Settings → Notifications → Staff → Templates
- [x] Verify badge shows "7 templates"
- [x] Open any staff event template
- [x] Verify new markdown format is displayed
- [x] Verify professional staff-oriented content
- [x] Test saving template
- [x] Test resetting template
### ✅ Preview:
- [x] Open template editor
- [x] Switch to Preview tab
- [x] Verify markdown is rendered correctly
- [x] Verify buttons work
- [x] Verify cards display properly
- [x] Verify variables are replaced with sample data
---
## New Template Features
All templates now include:
- ✅ Clean markdown syntax (no HTML clutter)
- ✅ Professional, friendly tone
- ✅ Clear structure with cards
- ✅ Actionable CTAs with buttons
- ✅ Complete variable support
- ✅ Horizontal rules for separation
- ✅ Checkmarks and bullet points
---
## Backwards Compatibility
The old `DefaultEmailTemplates` class still exists and works, but now:
- Uses new `DefaultTemplates` internally
- Maps old event IDs to new structure
- Maintains same API for existing code
- No breaking changes
---
## What's Next
The email template system is now **100% complete and production-ready**!
**You can now:**
1. ✅ View correct template counts
2. ✅ See new improved templates
3. ✅ Edit templates with visual builder
4. ✅ Preview with live branding
5. ✅ Save and reset templates
6. ✅ Use on mobile (code/preview modes)
**Ready to ship! 🚀**
---
## Summary
| Component | Status | Notes |
|-----------|--------|-------|
| Backend Integration | ✅ Complete | Using new templates |
| Event Filtering | ✅ Complete | Correct counts |
| Template Format | ✅ Complete | Clean markdown |
| Frontend Display | ✅ Complete | All working |
| Preview System | ✅ Complete | Fully functional |
| Mobile Support | ✅ Complete | Responsive |
| Documentation | ✅ Complete | Comprehensive |
**All systems go! 🎉**

View File

@@ -1,409 +0,0 @@
# ✅ Markdown Mode - Modern 2025 Approach! 🚀
## IMPLEMENTED! User-Friendly Markdown with HTML Pivot
---
## The Architecture
### **User-Facing: Markdown & Visual**
### **Behind the Scenes: HTML Pivot**
```
┌─────────────────────────────────────────┐
│ USER INTERFACE │
├─────────────────────────────────────────┤
│ │
│ Visual Builder ←→ Markdown │
│ (Drag & drop) (Easy typing) │
│ │
└─────────────────────────────────────────┘
┌───────────────────────┐
│ HTML PIVOT │
│ (Internal only) │
└───────────────────────┘
┌───────────────────────┐
│ DATABASE (HTML) │
└───────────────────────┘
```
---
## How It Works
### **Complexity on Our Side, Simplicity for Users**
```typescript
// User sees: Markdown or Visual
// System handles: HTML conversion
Visual Builder ←→ HTML ←→ Markdown
Blocks Pivot User-friendly
```
---
## Data Flow
### **1. Loading Template**
```
Database (HTML)
Load HTML
Convert to both views:
├→ HTML → Markdown (for Markdown mode)
└→ HTML → Blocks (for Visual mode)
```
### **2. Editing in Visual Mode**
```
User edits blocks
Blocks → HTML (pivot)
HTML → Markdown (sync)
✅ All formats in sync!
```
### **3. Editing in Markdown Mode**
```
User types markdown
Markdown → HTML (pivot)
HTML → Blocks (sync)
✅ All formats in sync!
```
### **4. Switching Modes**
```
Visual → Markdown:
Blocks → HTML → Markdown
Markdown → Visual:
Markdown → HTML → Blocks
✅ No data loss!
```
### **5. Saving**
```
Any mode
HTML (always ready)
Save to database
✅ Simple!
```
---
## Why This Is Better
### **For Users:**
-**Markdown**: Easy to type, mobile-friendly
-**Visual**: Drag & drop, no coding needed
-**Modern**: 2025 standard (like GitHub, Notion, Slack)
-**Flexible**: Choose your preferred mode
### **For Mobile:**
```
HTML: <strong>bold</strong> ❌ Hard to type
Markdown: **bold** ✅ Easy to type!
HTML: <div class="card">...</div> ❌ Painful on phone
Markdown: [card]...[/card] ✅ Simple!
```
### **For Developers (Us):**
- ✅ HTML pivot = Database compatibility
- ✅ Clean conversion logic
- ✅ All complexity hidden from users
- ✅ Easy to maintain
---
## User Experience
### **What Users See:**
#### Visual Builder:
```
┌─────────────────────────────┐
│ [Add Block ▼] Markdown │ ← Toggle button
├─────────────────────────────┤
│ ┌───────────────────────┐ │
│ │ 🎨 Hero Card │ │
│ │ ## Welcome! │ │
│ │ Content here... │ │
│ └───────────────────────┘ │
└─────────────────────────────┘
```
#### Markdown Mode:
```
┌─────────────────────────────┐
│ Visual Builder [Markdown]│ ← Toggle button
├─────────────────────────────┤
│ [card type="hero"] │
│ │
│ ## Welcome! │
│ │
│ Content here... │
│ │
│ [/card] │
└─────────────────────────────┘
💡 Write in Markdown - easy to type,
even on mobile!
```
---
## Conversion Logic
### **Visual ↔ HTML ↔ Markdown**
```typescript
// Visual → HTML
blocksToHTML(blocks) HTML
// HTML → Visual
htmlToBlocks(HTML) blocks
// Markdown → HTML
markdownToHtml(markdown) HTML
// HTML → Markdown
htmlToMarkdown(HTML) markdown
```
### **Automatic Sync:**
```typescript
// When user edits in Visual mode
handleBlocksChange(newBlocks) {
setBlocks(newBlocks);
const html = blocksToHTML(newBlocks);
setHtmlContent(html); // Update pivot
setMarkdownContent(htmlToMarkdown(html)); // Sync markdown
}
// When user edits in Markdown mode
handleMarkdownChange(newMarkdown) {
setMarkdownContent(newMarkdown);
const html = markdownToHtml(newMarkdown);
setHtmlContent(html); // Update pivot
setBlocks(htmlToBlocks(html)); // Sync blocks
}
```
---
## What Changed
### **Renamed:**
- ❌ "Code Mode" → ✅ "Markdown"
-`codeMode` → ✅ `markdownMode`
-`handleCodeModeToggle` → ✅ `handleMarkdownModeToggle`
### **Added:**
-`markdownContent` state
-`handleMarkdownChange` handler
-`htmlToMarkdown()` conversion
- ✅ Automatic sync between all formats
### **User-Facing:**
- ✅ "Markdown" button (not "Code Mode")
- ✅ Markdown-friendly placeholder text
- ✅ Mobile-friendly messaging
- ✅ Clear sync indicators
---
## Benefits Summary
| Feature | Old (HTML Code) | New (Markdown) |
|---------|-----------------|----------------|
| **Typing** | `<strong>bold</strong>` | `**bold**` ✅ |
| **Mobile** | Painful ❌ | Easy ✅ |
| **Learning curve** | High ❌ | Low ✅ |
| **Modern** | Old-school ❌ | 2025 standard ✅ |
| **User-friendly** | No ❌ | Yes ✅ |
| **Industry standard** | No ❌ | Yes (GitHub, Notion) ✅ |
---
## Markdown Syntax Supported
### **Basic Formatting:**
```markdown
**bold**
*italic*
## Heading 2
### Heading 3
```
### **Cards:**
```markdown
[card type="hero"]
Content here
[/card]
[card type="success"]
Success message
[/card]
[card type="basic"]
Plain text
[/card]
```
### **Buttons:**
```markdown
[button url="/shop"]Shop Now[/button]
```
### **Lists:**
```markdown
✓ Checkmark item
• Bullet item
- Dash item
```
### **Horizontal Rule:**
```markdown
---
```
---
## Testing Checklist
### ✅ Visual → Markdown:
- [x] Edit in visual mode
- [x] Click "Markdown" button
- [x] See markdown with all content
- [x] Edit markdown
- [x] Click "Visual Builder"
- [x] All changes preserved
### ✅ Markdown → Visual:
- [x] Click "Markdown"
- [x] Type markdown
- [x] Click "Visual Builder"
- [x] See blocks with all content
- [x] Edit blocks
- [x] Click "Markdown"
- [x] All changes preserved
### ✅ Save & Reload:
- [x] Edit in any mode
- [x] Save
- [x] Reload page
- [x] All changes preserved
- [x] Can switch modes freely
### ✅ Mobile:
- [x] Open on mobile
- [x] Click "Markdown"
- [x] Type easily on phone
- [x] Switch to visual
- [x] Works smoothly
---
## Example Workflow
### **User Story: Edit on Mobile**
1. **Open template on phone**
2. **Click "Markdown" button**
3. **Type easily:**
```markdown
[card type="hero"]
## Order Confirmed!
Thank you **{customer_name}**!
[/card]
[button url="{order_url}"]View Order[/button]
```
4. **Click "Preview"** → See beautiful email
5. **Save** → Done! ✅
**Much easier than typing HTML on phone!**
---
## Architecture Summary
```
┌─────────────────────────────────────────┐
│ USER EXPERIENCE │
├─────────────────────────────────────────┤
│ Visual Builder ←→ Markdown │
│ (Easy) (Easy) │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ SYSTEM COMPLEXITY │
├─────────────────────────────────────────┤
│ HTML Pivot (Internal) │
│ - Conversion logic │
│ - Format sync │
│ - Database compatibility │
└─────────────────────────────────────────┘
```
**Complexity on our side, simplicity for users! ✅**
---
## Files Modified
### `EditTemplate.tsx`
**Changes:**
1. ✅ Added `markdownContent` state
2. ✅ Renamed `codeMode` → `markdownMode`
3. ✅ Added `handleMarkdownChange` handler
4. ✅ Updated `handleMarkdownModeToggle` for proper conversion
5. ✅ Updated `handleBlocksChange` to sync markdown
6. ✅ Changed button text to "Markdown"
7. ✅ Updated placeholder and help text
8. ✅ Import `htmlToMarkdown` function
---
## What's Next
### **Test It:**
1. Hard refresh (Cmd+Shift+R)
2. Open any template
3. Click "Markdown" button
4. ✅ See markdown syntax
5. Edit markdown
6. Click "Visual Builder"
7. ✅ See your changes in blocks
8. Save
9. ✅ All preserved!
### **Try on Mobile:**
1. Open on phone
2. Click "Markdown"
3. Type easily
4. ✅ Much better than HTML!
---
**🎉 DONE! Modern, user-friendly, mobile-optimized! 🚀**
**Markdown for users, HTML for system - perfect balance!**

View File

@@ -1,316 +0,0 @@
# ✅ Markdown Support Complete!
## Problem Solved! 🎉
The system now **automatically detects and converts** markdown to HTML for proper display in the editor, builder, and preview!
---
## The Issue
**Before:** Markdown syntax was displayed as raw text:
- `**bold**` showed as `**bold**` instead of **bold**
- `[card]` showed as text instead of styled cards
- `[button url="..."]` showed as text instead of buttons
**Why:** TipTap editor and HTML preview can only understand HTML, not markdown.
---
## The Solution
### 1. **Auto-Detection** ✅
Created smart content type detection that identifies:
- Markdown patterns: `**bold**`, `[card]`, `[button]`, `---`, etc.
- HTML patterns: `<div>`, `<strong>`, etc.
### 2. **Auto-Conversion** ✅
When loading a template:
1. Detect if content is markdown or HTML
2. If markdown → convert to HTML automatically
3. Display HTML in editor/builder/preview
4. Everything renders properly!
### 3. **Seamless Experience** ✅
- Users see properly formatted content
- Bold text appears bold
- Cards appear as styled blocks
- Buttons appear as clickable buttons
- No manual conversion needed!
---
## What Was Added
### New File: `markdown-utils.ts`
**Location:** `admin-spa/src/lib/markdown-utils.ts`
**Functions:**
1. `detectContentType(content)` - Detects if content is markdown or HTML
2. `markdownToHtml(markdown)` - Converts markdown to HTML
3. `htmlToMarkdown(html)` - Converts HTML back to markdown (for editing)
**Supported Markdown:**
-`**bold**``<strong>bold</strong>`
-`*italic*``<em>italic</em>`
-`# Heading``<h1>Heading</h1>`
-`[card]...[/card]``<div class="card">...</div>`
-`[button url="..."]Text[/button]``<a href="..." class="button">Text</a>`
-`---``<hr>`
-`- List item``<ul><li>List item</li></ul>`
-`• Bullet``<ul><li>Bullet</li></ul>`
-`✓ Checkmark``<ul><li>Checkmark</li></ul>`
---
## How It Works
### Loading Flow:
```
1. User opens template editor
2. Template loaded from backend (markdown format)
3. detectContentType() checks if markdown
4. If markdown: markdownToHtml() converts to HTML
5. HTML displayed in editor/builder
6. User sees properly formatted content!
```
### Saving Flow:
```
1. User edits in visual builder or code mode
2. Content is already in HTML format
3. Save HTML to database
4. Next time: auto-convert again if needed
```
---
## Files Modified
### 1. **Created: `admin-spa/src/lib/markdown-utils.ts`**
- Content type detection
- Markdown → HTML conversion
- HTML → Markdown conversion
- Full markdown syntax support
### 2. **Updated: `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`**
- Added import: `import { detectContentType, markdownToHtml } from '@/lib/markdown-utils'`
- Added auto-detection in `useEffect` when template loads
- Converts markdown to HTML before displaying
**Key Changes:**
```typescript
// Detect if content is markdown or HTML
const contentType = detectContentType(template.body || '');
let processedBody = template.body || '';
// If markdown, convert to HTML for display
if (contentType === 'markdown') {
processedBody = markdownToHtml(template.body || '');
}
setBody(processedBody);
setBlocks(htmlToBlocks(processedBody));
```
---
## What Users See Now
### Before (Broken):
```
**Order Number:** #{order_number}
**Customer:** {customer_name}
**Order Date:** {order_date}
```
### After (Fixed):
```
Order Number: #12345
Customer: John Doe
Order Date: 11/14/2025
```
(With proper bold formatting!)
---
## Testing Checklist
### ✅ Visual Builder:
- [x] Open any template
- [x] Markdown is converted to HTML
- [x] Bold text appears bold
- [x] Cards appear as styled blocks
- [x] Can edit in rich text editor
### ✅ Code Mode:
- [x] Switch to code mode
- [x] See HTML (not raw markdown)
- [x] Can edit HTML directly
- [x] Changes reflected in preview
### ✅ Preview:
- [x] Switch to preview tab
- [x] Everything renders correctly
- [x] Cards styled properly
- [x] Buttons clickable
- [x] Variables replaced
### ✅ Saving:
- [x] Save template
- [x] Reload page
- [x] Content still displays correctly
- [x] No data loss
---
## Markdown Syntax Reference
### Text Formatting:
```markdown
**Bold text**
*Italic text*
# Heading 1
## Heading 2
### Heading 3
```
### Cards:
```markdown
[card]
Default card content
[/card]
[card type="hero"]
Hero card with gradient
[/card]
[card type="success"]
Success card
[/card]
```
### Buttons:
```markdown
[button url="{order_url}"]View Order[/button]
[button url="#" style="outline"]Secondary Action[/button]
```
### Lists:
```markdown
- List item 1
- List item 2
• Bullet point
✓ Checkmark item
```
### Horizontal Rules:
```markdown
---
```
---
## Benefits
### For Users:
- ✅ Templates display correctly immediately
- ✅ No manual conversion needed
- ✅ Can edit visually or in code
- ✅ What you see is what you get
### For Developers:
- ✅ Clean markdown in database
- ✅ Automatic conversion
- ✅ Backwards compatible
- ✅ Easy to maintain
### For Store Owners:
- ✅ Professional emails out of the box
- ✅ Easy to customize
- ✅ No technical knowledge required
- ✅ Works immediately
---
## Edge Cases Handled
### 1. **Mixed Content**
If content has both HTML and markdown:
- Detection favors markdown if `[card]` or `[button]` syntax present
- Otherwise uses HTML
### 2. **Empty Content**
- Returns empty string safely
- No errors
### 3. **Invalid Markdown**
- Falls back to treating as HTML
- No breaking errors
### 4. **Already HTML**
- Detects and skips conversion
- No double-processing
---
## Performance
**Impact:** Minimal
- Detection: ~1ms
- Conversion: ~5-10ms for typical template
- Only runs once on template load
- No performance issues
---
## Backwards Compatibility
**100% Compatible:**
- Old HTML templates still work
- New markdown templates work
- Mixed content works
- No breaking changes
---
## Summary
| Feature | Status | Notes |
|---------|--------|-------|
| Markdown Detection | ✅ Complete | Smart pattern matching |
| Auto-Conversion | ✅ Complete | Seamless |
| Visual Builder | ✅ Working | Displays HTML |
| Code Mode | ✅ Working | Shows HTML |
| Preview | ✅ Working | Renders correctly |
| Saving | ✅ Working | No data loss |
| Performance | ✅ Optimal | <10ms overhead |
| Compatibility | 100% | All formats work |
---
## What's Next
**Nothing!** The system is complete and working! 🎉
Users can now:
1. Load templates (auto-converted)
2. Edit visually or in code
3. Preview with branding
4. Save changes
5. Everything works!
**Ready to use! 🚀**

View File

@@ -1,170 +0,0 @@
# Markdown Syntax & Variables - Analysis & Recommendations
## Current Issues
### 1. Card & Button Syntax
**Current:**
```markdown
[card type="hero"]
Content here
[/card]
[button url="https://example.com" style="solid"]Click me[/button]
```
**Problem:** Not standard Markdown - uses WordPress-style shortcodes
### 2. Variable Naming Mismatch
**Template uses:** `{order_item_table}` (singular)
**Preview defines:** `order_items_table` (plural)
**Result:** Variable not replaced, shows as `{orderitemtable}` (underscores removed by some HTML sanitizer)
---
## All Variables Used in Templates
### Order Variables
- `{order_number}` - Order ID
- `{order_date}` - Order date
- `{order_total}` - Total amount
- `{order_status}` - Current status
- `{order_url}` - Link to view order
- `{order_item_table}` ⚠️ **MISMATCH** - Should be `order_items_table`
### Customer Variables
- `{customer_name}` - Customer full name
- `{customer_email}` - Customer email
- `{customer_username}` - Username (for new accounts)
- `{customer_password}` - Temporary password (for new accounts)
### Store Variables
- `{store_name}` - Store name
- `{store_url}` - Store URL
- `{store_email}` - Store contact email
### Payment Variables
- `{payment_method}` - Payment method used
- `{payment_status}` - Payment status
- `{transaction_id}` - Transaction ID
### Shipping Variables
- `{shipping_address}` - Full shipping address
- `{tracking_number}` - Shipment tracking number
- `{carrier}` - Shipping carrier
### Date Variables
- `{completion_date}` - Order completion date
- `{cancellation_date}` - Order cancellation date
---
## Recommendations
### Option 1: Keep Current Syntax (Easiest)
**Pros:**
- No changes needed
- Users already familiar
- Clear boundaries for cards
**Cons:**
- Not standard Markdown
- Verbose
**Action:** Just fix the variable mismatch
### Option 2: Simplified Shortcode
```markdown
[card:hero]
Content here
[/card]
[button:solid](https://example.com)Click me[/button]
```
**Pros:**
- Shorter, cleaner
- Still clear
**Cons:**
- Still not standard Markdown
- Requires converter changes
### Option 3: HTML + Markdown (Hybrid)
```html
<div class="card card-hero">
**Content** with markdown
</div>
<a href="url" class="button">Click me</a>
```
**Pros:**
- Standard Markdown allows inline HTML
- No custom parsing needed
**Cons:**
- Verbose
- Less user-friendly
### Option 4: Attributes Syntax (Most Markdown-like)
```markdown
> **Order Number:** #{order_number}
> **Order Date:** {order_date}
{: .card .card-hero}
[Click me](https://example.com){: .button .button-solid}
```
**Pros:**
- More Markdown-like
- Compact
**Cons:**
- Complex to parse
- Not widely supported
- Users may not understand
---
## Recommended Action Plan
### Immediate Fixes (Priority 1)
1.**Fix `<br>` rendering** - DONE!
2. ⚠️ **Fix variable mismatch:**
- Change `order_item_table``order_items_table` in DefaultTemplates.php
- OR change `order_items_table``order_item_table` in EditTemplate.tsx preview
3. **Add all missing variables to preview sample data**
### Short-term (Priority 2)
1. **Document all variables** - Create user-facing documentation
2. **Add variable autocomplete** in markdown editor
3. **Add variable validation** - warn if variable doesn't exist
### Long-term (Priority 3)
1. **Consider syntax improvements** - Get user feedback first
2. **Add visual card/button inserter** - UI buttons to insert syntax
3. **Add syntax highlighting** in markdown editor
---
## Variable Replacement Issue
The underscore removal (`{order_item_table}``{orderitemtable}`) suggests HTML sanitization is happening somewhere. Need to check:
1. **Frontend:** DOMPurify or similar sanitizer?
2. **Backend:** WordPress `wp_kses()` or similar?
3. **Email client:** Some email clients strip underscores?
**Solution:** Use consistent naming without underscores OR fix sanitizer to preserve variable syntax.
---
## Next Steps
1. Fix variable naming mismatch
2. Test all variables in preview
3. Document syntax for users
4. Get feedback on syntax preferences
5. Consider improvements based on feedback

View File

@@ -1,252 +0,0 @@
# ✨ New Markdown Syntax - Implemented!
## 🎉 What's New
### Cleaner, More Intuitive Syntax
**Before (Old Syntax):**
```markdown
[card type="hero"]
Content here
[/card]
[button url="https://example.com" style="solid"]Click me[/button]
```
**After (New Syntax):**
```markdown
[card:hero]
Content here
[/card]
[button:solid](https://example.com)Click me[/button]
```
## 📝 Complete Syntax Guide
### Cards
**Basic Card:**
```markdown
[card]
Your content here
[/card]
```
**Styled Cards:**
```markdown
[card:hero]
Large header with gradient
[/card]
[card:success]
Success message
[/card]
[card:warning]
Warning message
[/card]
[card:info]
Information card
[/card]
[card:basic]
Minimal styling
[/card]
```
### Buttons
**Solid Button:**
```markdown
[button:solid](https://example.com)Click me[/button]
```
**Outline Button:**
```markdown
[button:outline](https://example.com)Click me[/button]
```
### Images
**Standard Markdown:**
```markdown
![Image description](https://example.com/image.jpg)
```
### Text Formatting
```markdown
**Bold text**
*Italic text*
# Heading 1
## Heading 2
### Heading 3
- Bullet list
- Another item
1. Numbered list
2. Another item
[Link text](https://example.com)
---
Horizontal rule
```
## 🔧 Markdown Toolbar
The toolbar now includes:
- **Card** button - Insert cards with type selector
- **Button** button - Insert buttons with style selector
- **Image** button - Insert image template
- All standard formatting tools (Bold, Italic, Headings, etc.)
## 🔄 Backward Compatibility
The old syntax still works! Both formats are supported:
**Old Format (Still Works):**
```markdown
[card type="hero"]...[/card]
[button url="..." style="solid"]...[/button]
```
**New Format (Recommended):**
```markdown
[card:hero]...[/card]
[button:solid](url)...[/button]
```
## 📊 All Available Variables
### Order Variables
- `{order_number}` - Order ID
- `{order_date}` - Order date
- `{order_total}` - Total amount
- `{order_status}` - Current status
- `{order_url}` - Link to view order
- `{order_items_list}` - Items as formatted list
- `{order_items_table}` - Items as formatted table ✅ FIXED
### Customer Variables
- `{customer_name}` - Customer full name
- `{customer_email}` - Customer email
- `{customer_phone}` - Phone number
- `{customer_username}` - Username
- `{customer_password}` - Temporary password
### Store Variables
- `{store_name}` - Store name
- `{store_url}` - Store URL
- `{store_email}` - Store contact email
- `{support_email}` - Support email
### Payment Variables
- `{payment_method}` - Payment method used
- `{payment_status}` - Payment status
- `{payment_url}` - Payment link
- `{payment_date}` - Payment date
- `{transaction_id}` - Transaction ID
- `{refund_amount}` - Refund amount
### Shipping Variables
- `{shipping_address}` - Full shipping address
- `{billing_address}` - Full billing address
- `{tracking_number}` - Shipment tracking number
- `{tracking_url}` - Tracking link
- `{shipping_carrier}` - Shipping carrier
- `{shipping_method}` - Shipping method
### Date Variables
- `{completion_date}` - Order completion date
- `{cancellation_date}` - Order cancellation date
- `{current_year}` - Current year
### URL Variables
- `{review_url}` - Product review link
- `{shop_url}` - Shop homepage
- `{my_account_url}` - Customer account
- `{payment_retry_url}` - Retry payment
- `{vip_dashboard_url}` - VIP dashboard
## ✅ What's Fixed
1.**Newline rendering** - `<br>` tags now generated correctly
2.**Variable mismatch** - `order_items_table` fixed
3.**Cleaner syntax** - New `[card:type]` and `[button:style](url)` format
4.**Toolbar enhancements** - Added Image and Button insert buttons
5.**Backward compatibility** - Old syntax still works
## 🚀 Usage Examples
### Order Confirmation Email
```markdown
[card:hero]
## Thank you for your order, {customer_name}!
We've received your order and will begin processing it right away.
[/card]
[card]
**Order Number:** #{order_number}
**Order Date:** {order_date}
**Order Total:** {order_total}
[/card]
[card]
{order_items_table}
[/card]
[button:solid]({order_url})View Order Details[/button]
[card:basic]
Questions? Contact us at {support_email}
[/card]
```
### Shipping Notification
```markdown
[card:info]
## Your order is on the way! 📦
Tracking Number: **{tracking_number}**
[/card]
[button:solid]({tracking_url})Track Your Package[/button]
```
## 💡 Tips
1. **Use card types** to highlight important information
2. **Variables** are automatically replaced with real data
3. **Newlines work!** Just press Enter to create line breaks
4. **Use the toolbar** for quick formatting
5. **Preview** your changes before saving
## 🎨 Card Types
- **default** - Standard white card
- **hero** - Large gradient header (perfect for main message)
- **success** - Green (order confirmed, payment received)
- **warning** - Yellow (action required, pending)
- **info** - Blue (shipping updates, information)
- **basic** - Minimal (footer, contact info)
---
**Enjoy the new syntax! 🎉**

View File

@@ -1,675 +0,0 @@
# Notification System Audit Report
**Date:** November 11, 2025, 6:35 PM (GMT+7)
**Auditor:** System Analysis
**Scope:** Complete notification feature assessment and industry comparison
---
## 🔍 Current State Analysis
### What We Built
**1. Admin Notifications Only**
- ✅ Email notifications for admins
- ✅ Push notifications for admins
- ✅ Activity log for admins
- ✅ Notification settings UI for admins
**2. Architecture**
- Backend: `includes/Core/Notifications/`
- Frontend: `admin-spa/src/routes/Settings/Notifications/`
- API: `includes/Api/NotificationsController.php`
- Database: Activity log table
**3. Features**
- Global channel toggles (email, push)
- Per-event channel toggles
- Push notification subscription
- Activity logging
- Template management (planned)
### Critical Finding: **Admin-Only Focus**
**Effort Investment:**
- 15+ files created/modified
- 3000+ lines of code
- Complete UI/UX system
- REST API infrastructure
- Database tables
**Current Benefit:** Admin alerts only
**Missed Opportunity:** Customer notifications (larger user base, higher impact)
---
## 🌍 Industry Research: Modern E-commerce Platforms
### 1. Shopify
**Admin Notifications:**
- Settings → Notifications → Staff notifications
- Email notifications for orders, inventory, etc.
- Push notifications via Shopify mobile app
- Separate from customer notifications
**Customer Notifications:**
- Settings → Notifications → Customer notifications
- Order confirmation, shipping updates, etc.
- Email templates with drag-and-drop editor
- SMS notifications (addon)
- Push notifications (via Shopify mobile app)
**Key Insight:** **Separate sections, but same infrastructure**
**UI Structure:**
```
Settings → Notifications
├── Staff notifications
│ ├── Orders (New order, Cancelled order, etc.)
│ ├── Products (Low stock, Out of stock)
│ └── Customers (New customer)
└── Customer notifications
├── Order notifications (Confirmation, Shipped, Delivered)
├── Shipping notifications (Tracking updates)
├── Marketing (Abandoned cart, Promotions)
└── Account (Welcome, Password reset)
```
---
### 2. WooCommerce (Default)
**Admin Notifications:**
- WooCommerce → Settings → Emails
- New order, Cancelled order, Low stock, etc.
- Email only (no push)
**Customer Notifications:**
- Same location: WooCommerce → Settings → Emails
- Order confirmation, Processing, Completed, etc.
- Email only (no push)
- **Mixed together in one list** (confusing UX)
**Key Insight:** **Poor UX - admin and customer emails mixed**
**UI Structure:**
```
WooCommerce → Settings → Emails
├── New order (Admin)
├── Cancelled order (Admin)
├── Failed order (Admin)
├── Order on-hold (Customer)
├── Processing order (Customer)
├── Completed order (Customer)
├── Refunded order (Customer)
├── Customer invoice (Customer)
├── Customer note (Customer)
├── Reset password (Customer)
└── New account (Customer)
```
**Problem:** Hard to distinguish admin vs customer emails
---
### 3. BigCommerce
**Admin Notifications:**
- Settings → Store Setup → Email Notifications → Staff
- Order notifications
- Low stock alerts
- Email only
**Customer Notifications:**
- Settings → Store Setup → Email Notifications → Customer
- Order status updates
- Shipping notifications
- Account notifications
- **Separate tab, clear separation**
**Key Insight:** **Clear separation improves UX**
---
### 4. Magento
**Admin Notifications:**
- Stores → Configuration → Sales Emails
- Admin-specific emails
- System alerts
**Customer Notifications:**
- Stores → Configuration → Sales Emails
- Customer order emails
- Transactional emails
- Marketing emails (separate module)
**Key Insight:** **Same infrastructure, different recipients**
---
### 5. Stripe Dashboard (Payment Platform)
**Admin Notifications:**
- Settings → Notifications → Email notifications
- Payment events, disputes, etc.
- Webhook notifications (developer)
**Customer Notifications:**
- Settings → Customer emails
- Receipt emails
- Invoice emails
- Payment confirmation
**Key Insight:** **Clear separation, but shared templates**
---
## 📊 Industry Best Practices
### 1. Notification Architecture
**Unified System, Separate UIs:**
```
Notification System (Core)
├── Channels (Email, Push, SMS)
├── Events (Order, Product, Customer)
├── Templates (Shared)
└── Delivery Engine
Admin UI
├── Staff notifications
└── Activity log
Customer UI
├── Customer notifications
└── Notification preferences (customer-facing)
```
**Benefits:**
- ✅ Reusable infrastructure
- ✅ Consistent behavior
- ✅ Easier maintenance
- ✅ Shared templates
---
### 2. UI/UX Patterns
**Pattern A: Separate Tabs (Shopify, BigCommerce)**
```
Notifications
├── [Tab] Staff Notifications
│ └── Events list with toggles
└── [Tab] Customer Notifications
└── Events list with toggles
```
**Pattern B: Separate Pages (Better for complex systems)**
```
Settings
├── Staff Notifications
│ ├── Channels
│ ├── Events
│ └── Templates
└── Customer Notifications
├── Channels
├── Events
└── Templates
```
**Pattern C: Recipient Filter (WooCommerce - NOT recommended)**
```
Notifications
└── All notifications (mixed)
└── Filter by recipient
```
**Recommendation:** **Pattern B** - Separate pages with shared components
---
### 3. Customer Notification Types
**Transactional (High Priority):**
- Order confirmation
- Order status updates (Processing, Shipped, Delivered)
- Payment confirmation
- Refund notification
- Shipping updates with tracking
**Account (Medium Priority):**
- Welcome email
- Password reset
- Account verification
- Profile updates
**Marketing (Low Priority, Optional):**
- Abandoned cart
- Product recommendations
- Promotions and discounts
- Newsletter
**Operational (Low Priority):**
- Low stock alerts (for wishlisted items)
- Price drop alerts
- Back in stock alerts
---
## 🎯 Reusability Assessment
### Current Architecture Reusability
**✅ Highly Reusable:**
1. **NotificationManager.php** - Core logic
- `should_send_notification()` - Works for any recipient
- `send()` - Recipient-agnostic
2. **PushNotificationHandler.php** - Push infrastructure
- VAPID keys (shared)
- Subscription management (can be per-user)
- Sending logic (recipient-agnostic)
3. **ActivityLog** - Logging system
- Can log customer actions too
- Already tracks user_id
4. **Database Structure** - Settings storage
- `woonoow_notification_settings` - Can store customer event settings
- Just needs recipient field (already exists!)
**⚠️ Needs Adaptation:**
1. **Frontend UI** - Admin-only
- `admin-spa/` - Admin interface
- Need: `customer-spa/` interface
2. **REST API** - Permission checks
- Currently: `manage_woocommerce` permission
- Need: Customer-specific permissions
3. **Templates** - Admin-focused
- Need: Customer-facing templates
**❌ Not Reusable:**
1. **UI Components** - Admin design
- Need: Customer-facing design
- Different UX patterns
---
## 💡 Strategic Recommendations
### Option 1: Extend Current System (Recommended)
**Approach:** Add customer notifications to existing infrastructure
**Implementation:**
```
includes/Core/Notifications/
├── NotificationManager.php (already recipient-agnostic ✅)
├── PushNotificationHandler.php (already reusable ✅)
├── EmailHandler.php (new - handles both admin and customer)
└── TemplateEngine.php (new - shared templates)
admin-spa/src/routes/Settings/Notifications/
├── Staff/ (rename from current)
│ ├── Channels.tsx
│ ├── Events.tsx
│ └── Templates.tsx
└── Customer/ (new)
├── Channels.tsx (reuse component)
├── Events.tsx (reuse component)
└── Templates.tsx (reuse component)
customer-spa/src/routes/Account/Notifications/
└── Preferences.tsx (customer-facing preferences)
```
**Benefits:**
- ✅ Reuse 80% of backend code
- ✅ Reuse 60% of frontend components
- ✅ Consistent behavior
- ✅ Easier maintenance
**Effort:** 2-3 weeks
---
### Option 2: Separate Systems (Not Recommended)
**Approach:** Build separate customer notification system
**Problems:**
- ❌ Duplicate code
- ❌ Inconsistent behavior
- ❌ Double maintenance
- ❌ Wasted effort
---
### Option 3: Hybrid Approach (Compromise)
**Approach:**
- Keep current system for admin
- Use WooCommerce emails for customers (for now)
- Add customer push notifications only
**Benefits:**
- ✅ Leverage WooCommerce's mature email system
- ✅ Focus on unique value (push notifications)
- ✅ Less effort
**Drawbacks:**
- ⚠️ Inconsistent UX
- ⚠️ Limited control over customer emails
---
## 🏗️ Recommended Architecture
### Unified Notification System
```php
// Core (Recipient-agnostic)
NotificationManager
├── should_send_notification($event, $channel, $recipient)
├── get_recipients($event) // Returns ['admin', 'customer', 'both']
└── send($event, $channel, $recipient, $data)
// Channels (Recipient-agnostic)
EmailHandler
├── send_admin_email($event, $data)
└── send_customer_email($event, $data)
PushNotificationHandler
├── send_admin_push($event, $data)
└── send_customer_push($event, $data) // New
SMSHandler (Future)
├── send_admin_sms($event, $data)
└── send_customer_sms($event, $data)
```
### Settings Structure
```php
// Unified settings
[
'staff_notifications' => [
'channels' => ['email' => true, 'push' => true],
'events' => [
'order_placed' => [
'channels' => ['email' => true, 'push' => true],
],
],
],
'customer_notifications' => [
'channels' => ['email' => true, 'push' => false, 'sms' => false],
'events' => [
'order_placed' => [
'channels' => ['email' => true, 'push' => false],
'template' => 'order-confirmation',
],
],
],
]
```
### UI Structure
```
Settings → Notifications
├── Staff Notifications (current)
│ ├── Channels (Email, Push)
│ ├── Events (Order, Product, Customer)
│ └── Templates
└── Customer Notifications (new)
├── Channels (Email, Push, SMS)
├── Events (Order, Account, Marketing)
└── Templates
Customer Account → Notification Preferences
├── Order Updates (Email ✓, Push ✗, SMS ✗)
├── Marketing (Email ✗, Push ✗, SMS ✗)
└── Account (Email ✓, Push ✗, SMS ✗)
```
---
## 📈 Impact Analysis
### Current System (Admin Only)
**Users Affected:** 1-5 admins per store
**Notifications/Day:** ~10-50
**Business Impact:** Faster response to orders, better inventory management
### With Customer Notifications
**Users Affected:** 100-10,000+ customers per store
**Notifications/Day:** ~100-1,000+
**Business Impact:**
- Better customer experience
- Reduced support tickets
- Higher customer satisfaction
- Increased repeat purchases
**ROI:** **10-100x higher impact**
---
## 🎯 When to Build Customer Notifications?
### Timing Options
**Option A: Now (Recommended)**
- Reuse existing infrastructure
- Avoid technical debt
- Complete feature set
- Higher impact
**Option B: After Admin Stabilization**
- Polish admin features first
- Gather feedback
- Then extend to customers
- Risk: Harder to retrofit
**Option C: Separate Project**
- Treat as new feature
- Fresh start
- Risk: Duplicate code
**Recommendation:** **Option A - Build now while architecture is fresh**
---
## 🔄 Migration Path
### Phase 1: Refactor Current System (1 week)
1. Rename `admin-spa/src/routes/Settings/Notifications/``Staff/`
2. Make backend recipient-agnostic
3. Add recipient field to all methods
4. Update database structure
### Phase 2: Add Customer Backend (1 week)
1. Customer notification events
2. Customer email templates
3. Customer push notification support
4. Customer preferences API
### Phase 3: Add Customer Frontend (1 week)
1. Admin UI: Customer Notifications section
2. Customer UI: Notification Preferences page
3. Reuse components from Staff section
4. Test and polish
**Total Effort:** 3 weeks
**Reuse Rate:** 70-80%
---
## 📋 Comparison: Admin vs Customer Notifications
| Feature | Staff Notifications | Customer Notifications |
|---------|-------------------|----------------------|
| **Channels** | Email, Push | Email, Push, SMS (future) |
| **Events** | Orders, Products, Customers | Orders, Account, Marketing |
| **Templates** | Simple, functional | Rich, branded |
| **Frequency** | Low (10-50/day) | High (100-1000+/day) |
| **Recipients** | 1-5 admins | 100-10,000+ customers |
| **Priority** | High (business critical) | High (customer experience) |
| **Customization** | Admin controls | Customer controls (preferences) |
| **UI Location** | Admin dashboard | Customer account |
| **Permission** | Admin only | Customer only |
---
## 🎨 UI/UX Recommendations
### Admin UI: Staff Notifications
**Current (Good):**
```
Settings → Notifications
├── Channels (Email, Push)
├── Events (Order, Product, Customer)
└── Templates
```
**Improved:**
```
Settings → Notifications → Staff
├── Channels (Email, Push)
├── Events (Order, Product, Customer)
├── Templates
└── Activity Log
```
### Admin UI: Customer Notifications (New)
```
Settings → Notifications → Customer
├── Channels
│ ├── Email (Enabled ✓)
│ ├── Push (Disabled ✗) - Requires customer opt-in
│ └── SMS (Addon) - Coming soon
├── Events
│ ├── Order Notifications
│ │ ├── Order Confirmation (Email ✓, Push ✗)
│ │ ├── Order Processing (Email ✓, Push ✗)
│ │ ├── Order Shipped (Email ✓, Push ✗)
│ │ └── Order Delivered (Email ✓, Push ✗)
│ ├── Account Notifications
│ │ ├── Welcome Email (Email ✓)
│ │ ├── Password Reset (Email ✓)
│ │ └── Account Verification (Email ✓)
│ └── Marketing (Optional)
│ ├── Abandoned Cart (Email ✗, Push ✗)
│ └── Promotions (Email ✗, Push ✗)
└── Templates
├── Order Confirmation Template
├── Shipping Update Template
└── Welcome Email Template
```
### Customer UI: Notification Preferences (New)
```
My Account → Notification Preferences
├── Order Updates
│ ├── Email notifications (✓ Enabled)
│ ├── Push notifications (✗ Disabled) - [Enable Push]
│ └── SMS notifications (✗ Disabled) - [Upgrade to enable]
├── Marketing
│ ├── Promotional emails (✗ Disabled)
│ ├── Product recommendations (✗ Disabled)
│ └── Newsletter (✗ Disabled)
└── Account
├── Security alerts (✓ Enabled - Cannot disable)
└── Account updates (✓ Enabled)
```
---
## ✅ Audit Conclusion
### Key Findings
1. **Current System is Admin-Only**
- Significant effort invested
- Limited user base (1-5 admins)
- Missing larger opportunity (customers)
2. **Architecture is 70-80% Reusable**
- Backend: Highly reusable
- Frontend: Components reusable, UI needs adaptation
- Database: Already supports recipients
3. **Industry Standard: Unified System**
- Shopify, BigCommerce: Separate UI, shared infrastructure
- WooCommerce: Mixed UI (poor UX)
- Best practice: Separate pages, shared components
4. **Customer Notifications = 10-100x Impact**
- More users
- More notifications
- Higher business value
- Better customer experience
### Recommendations
**1. Immediate Action: Refactor for Reusability**
- Rename current UI to "Staff Notifications"
- Make backend recipient-agnostic
- Prepare for customer notifications
**2. Short-term: Add Customer Notifications**
- Reuse 70-80% of code
- 3 weeks effort
- Complete feature set
**3. Long-term: Advanced Features**
- SMS notifications
- Marketing automation
- Advanced templates
- A/B testing
### Answer to Your Questions
**Q: Are these notification features only for admin?**
**A:** Yes, currently admin-only. This is a missed opportunity.
**Q: When is the right time to build it for customer?**
**A:** **Now.** While the architecture is fresh and before technical debt accumulates.
**Q: Can this feature be reused in customer-spa?**
**A:** **Yes, 70-80% reusable.** Backend is highly reusable, frontend components can be adapted.
**Q: How do modern stores handle customer notifications?**
**A:** Unified infrastructure, separate UIs. Shopify and BigCommerce use tabs/pages to separate staff and customer notifications.
**Q: What's the best UX?**
**A:** Separate pages (Staff Notifications, Customer Notifications) with shared components. Clear separation, consistent behavior.
---
## 🚀 Next Steps
1. **Review this audit**
2. **Decide on approach:**
- Option A: Extend now (recommended)
- Option B: Extend later
- Option C: Keep admin-only
3. **If extending, follow migration path**
4. **Update documentation**
5. **Implement customer notifications**
---
**Audit Status:** ✅ Complete
**Recommendation:** Extend to customer notifications now
**Expected ROI:** 10-100x higher impact
**Effort:** 3 weeks with 70-80% code reuse

View File

@@ -1,481 +0,0 @@
# Notification System Comparison: Industry Leaders
**Research Date:** November 11, 2025
---
## 🏪 Shopify - Best Practice Example
### UI Structure
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications │
├─────────────────────────────────────────────────────────┤
│ [Staff notifications] [Customer notifications] │
├─────────────────────────────────────────────────────────┤
│ │
│ STAFF NOTIFICATIONS │
│ │
│ Orders │
│ ├─ New order [Email ✓] [Push ✓]│
│ ├─ Order cancelled [Email ✓] [Push ✗]│
│ └─ Order refunded [Email ✓] [Push ✗]│
│ │
│ Products │
│ ├─ Low stock [Email ✓] [Push ✓]│
│ └─ Out of stock [Email ✓] [Push ✓]│
│ │
│ Customers │
│ └─ New customer [Email ✓] [Push ✗]│
│ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications │
├─────────────────────────────────────────────────────────┤
│ [Staff notifications] [Customer notifications] │
├─────────────────────────────────────────────────────────┤
│ │
│ CUSTOMER NOTIFICATIONS │
│ │
│ Order notifications │
│ ├─ Order confirmation [Email ✓] [SMS ✗] │
│ ├─ Order in transit [Email ✓] [SMS ✗] │
│ ├─ Out for delivery [Email ✓] [SMS ✓] │
│ └─ Delivered [Email ✓] [SMS ✗] │
│ │
│ Shipping notifications │
│ ├─ Shipping confirmation [Email ✓] [SMS ✗] │
│ └─ Shipping update [Email ✓] [SMS ✗] │
│ │
│ Customer account │
│ ├─ Welcome email [Email ✓] │
│ ├─ Account activation [Email ✓] │
│ └─ Password reset [Email ✓] │
│ │
└─────────────────────────────────────────────────────────┘
```
**Key Features:**
- ✅ Clear separation (tabs)
- ✅ Same UI pattern for both
- ✅ Channel toggles per event
- ✅ Email + SMS for customers
- ✅ Email + Push for staff
---
## 🛒 WooCommerce - Current (Poor UX)
### UI Structure
```
┌─────────────────────────────────────────────────────────┐
│ WooCommerce → Settings → Emails │
├─────────────────────────────────────────────────────────┤
│ │
│ Email notifications │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ New order [Admin] │ │
│ │ Sent to admins when a new order is received │ │
│ │ [Enabled ✓] [Manage] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Cancelled order [Admin] │ │
│ │ Sent to admins when an order is cancelled │ │
│ │ [Enabled ✓] [Manage] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Processing order [Customer] │ │
│ │ Sent to customers when order is processing │ │
│ │ [Enabled ✓] [Manage] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Completed order [Customer] │ │
│ │ Sent to customers when order is completed │ │
│ │ [Enabled ✓] [Manage] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Customer note [Customer] │ │
│ │ Sent to customers when a note is added │ │
│ │ [Enabled ✓] [Manage] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
**Problems:**
- ❌ Admin and customer emails mixed
- ❌ Hard to find specific email
- ❌ No clear grouping
- ❌ Email only (no push, no SMS)
- ❌ Poor visual hierarchy
---
## 🏢 BigCommerce - Good Separation
### UI Structure
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Email Notifications │
├─────────────────────────────────────────────────────────┤
│ [Staff] [Customer] │
├─────────────────────────────────────────────────────────┤
│ │
│ STAFF EMAIL NOTIFICATIONS │
│ │
│ Order notifications │
│ ┌────────────────────────────────────────────────┐ │
│ │ ☑ New order received │ │
│ │ Send email when a new order is placed │ │
│ │ Recipients: admin@store.com │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ ☑ Low stock alert │ │
│ │ Send email when product stock is low │ │
│ │ Recipients: admin@store.com │ │
│ │ Threshold: 5 items │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Settings → Email Notifications │
├─────────────────────────────────────────────────────────┤
│ [Staff] [Customer] │
├─────────────────────────────────────────────────────────┤
│ │
│ CUSTOMER EMAIL NOTIFICATIONS │
│ │
│ Order status emails │
│ ┌────────────────────────────────────────────────┐ │
│ │ ☑ Order confirmation │ │
│ │ Sent when order is placed │ │
│ │ [Edit template] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ ☑ Order shipped │ │
│ │ Sent when order is shipped │ │
│ │ Include tracking: ☑ Yes │ │
│ │ [Edit template] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Account emails │
│ ┌────────────────────────────────────────────────┐ │
│ │ ☑ Welcome email │ │
│ │ Sent when customer creates account │ │
│ │ [Edit template] │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
**Key Features:**
- ✅ Clear tab separation
- ✅ Grouped by category
- ✅ Inline settings (recipients, threshold)
- ✅ Template editing
- ✅ Good visual hierarchy
---
## 💳 Stripe - Developer-Friendly
### UI Structure
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications │
├─────────────────────────────────────────────────────────┤
│ │
│ Email notifications │
│ │
│ Business notifications │
│ ☑ Successful payments │
│ ☑ Failed payments │
│ ☑ Disputes │
│ ☑ Payouts │
│ │
│ Recipients: admin@business.com [Add] │
│ │
│ ───────────────────────────────────────────────────── │
│ │
│ Customer emails │
│ ☑ Successful payments │
│ ☑ Refunds │
│ ☑ Invoices │
│ │
│ [Customize email templates] │
│ │
│ ───────────────────────────────────────────────────── │
│ │
│ Webhooks │
│ Send real-time notifications to your server │
│ │
│ Endpoint URL: https://api.example.com/webhooks │
│ Events: payment_intent.succeeded, charge.failed, ... │
│ │
│ [Add endpoint] │
│ │
└─────────────────────────────────────────────────────────┘
```
**Key Features:**
- ✅ Simple, clean layout
- ✅ Business vs Customer separation
- ✅ Webhook support (developer)
- ✅ Template customization
- ✅ Recipient management
---
## 📱 Customer-Facing Preferences (Shopify Mobile App)
### UI Structure
```
┌─────────────────────────────────────────────────────────┐
│ Account → Notification Preferences │
├─────────────────────────────────────────────────────────┤
│ │
│ Order updates │
│ Get notified about your order status │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Email [●──────] Enabled │ │
│ │ Push notifications [──────○] Disabled │ │
│ │ SMS [──────○] Disabled │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Marketing │
│ Promotions, new products, and special offers │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Email [──────○] Disabled │ │
│ │ Push notifications [──────○] Disabled │ │
│ │ SMS [──────○] Disabled │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ Account │
│ Security alerts and account updates │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ Email [●──────] Enabled (Required) │ │
│ │ Push notifications [──────○] Disabled │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ [Save preferences] │
│ │
└─────────────────────────────────────────────────────────┘
```
**Key Features:**
- ✅ Customer controls their preferences
- ✅ Clear categories
- ✅ Multiple channels per category
- ✅ Visual toggles
- ✅ Required notifications marked
---
## 🎯 Recommended Structure for WooNooW
### Admin UI: Settings → Notifications
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Staff │ │ Customer │ │
│ │ Notifications │ │ Notifications │ │
│ │ │ │ │ │
│ │ Get alerts for │ │ Manage customer │ │
│ │ orders, stock, │ │ email and push │ │
│ │ and more │ │ notifications │ │
│ │ │ │ │ │
│ │ [Configure →] │ │ [Configure →] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Activity Log │ │ Templates │ │
│ │ │ │ │ │
│ │ View all │ │ Customize email │ │
│ │ notification │ │ and push │ │
│ │ activities │ │ templates │ │
│ │ │ │ │ │
│ │ [View log →] │ │ [Manage →] │ │
│ └─────────────────┘ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
### Admin UI: Staff Notifications
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications → Staff │
├─────────────────────────────────────────────────────────┤
│ ← Back to Notifications │
│ │
│ [Channels] [Events] [Templates] │
├─────────────────────────────────────────────────────────┤
│ │
│ CHANNELS │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 📧 Email [●──] Enabled│ │
│ │ Email notifications powered by WordPress │ │
│ │ Recipients: admin@store.com [Edit] │ │
│ │ [Configure] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🔔 Push Notifications [──○] Disabled│ │
│ │ Browser push notifications │ │
│ │ [Enable and subscribe] │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
### Admin UI: Customer Notifications (NEW)
```
┌─────────────────────────────────────────────────────────┐
│ Settings → Notifications → Customer │
├─────────────────────────────────────────────────────────┤
│ ← Back to Notifications │
│ │
│ [Channels] [Events] [Templates] │
├─────────────────────────────────────────────────────────┤
│ │
│ CHANNELS │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 📧 Email [●──] Enabled│ │
│ │ Transactional emails to customers │ │
│ │ From: store@example.com [Edit] │ │
│ │ [Configure] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🔔 Push Notifications [──○] Disabled│ │
│ │ Browser push (requires customer opt-in) │ │
│ │ [Enable] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 📱 SMS Notifications [──○] Disabled│ │
│ │ Text messages (addon required) │ │
│ │ [Install SMS addon] │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
### Customer UI: My Account → Notifications (NEW)
```
┌─────────────────────────────────────────────────────────┐
│ My Account → Notification Preferences │
├─────────────────────────────────────────────────────────┤
│ │
│ Manage how you receive notifications │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 📦 Order Updates │ │
│ │ Get notified about your order status │ │
│ │ │ │
│ │ Email [●──────] Enabled │ │
│ │ Push notifications [──────○] Disabled │ │
│ │ [Enable push] │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🎁 Marketing & Promotions │ │
│ │ Special offers and new products │ │
│ │ │ │
│ │ Email [──────○] Disabled │ │
│ │ Push notifications [──────○] Disabled │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────┐ │
│ │ 🔐 Account & Security │ │
│ │ Important account updates (required) │ │
│ │ │ │
│ │ Email [●──────] Enabled │ │
│ │ (Cannot be disabled) │ │
│ └────────────────────────────────────────────────┘ │
│ │
│ [Save preferences] │
│ │
└─────────────────────────────────────────────────────────┘
```
---
## 📊 Comparison Summary
| Platform | Separation | Channels | Customer Control | UX Rating |
|----------|-----------|----------|-----------------|-----------|
| **Shopify** | ✅ Tabs | Email, Push, SMS | ✅ Yes | ⭐⭐⭐⭐⭐ |
| **BigCommerce** | ✅ Tabs | Email | ✅ Yes | ⭐⭐⭐⭐ |
| **WooCommerce** | ❌ Mixed | Email only | ❌ No | ⭐⭐ |
| **Stripe** | ✅ Sections | Email, Webhooks | ✅ Yes | ⭐⭐⭐⭐ |
| **WooNooW (Current)** | N/A (Admin only) | Email, Push | N/A | ⭐⭐⭐ |
| **WooNooW (Proposed)** | ✅ Pages | Email, Push, SMS | ✅ Yes | ⭐⭐⭐⭐⭐ |
---
## 🎯 Key Takeaways
1. **Industry Standard: Separate UIs**
- Staff and customer notifications are separate
- Same infrastructure, different interfaces
- Clear visual separation (tabs or pages)
2. **Customer Control is Essential**
- Customers must control their preferences
- Multiple channels per category
- Some notifications are required (security)
3. **Channel Flexibility**
- Email is baseline (always available)
- Push requires opt-in
- SMS is premium/addon
4. **Template Management**
- Shared templates between staff and customer
- Different styling/branding
- Easy customization
5. **WooCommerce is Behind**
- Poor UX (mixed admin/customer)
- Email only
- No customer control
- **Opportunity for WooNooW to excel!**
---
## ✅ Recommendation
**Implement the proposed structure:**
- Separate Staff and Customer notification pages
- Reuse 70-80% of existing code
- Add customer-facing preferences page
- Support Email, Push, and SMS (future)
- Follow Shopify/BigCommerce best practices
**Result:** Best-in-class notification system for WooCommerce! 🚀

View File

@@ -1,428 +0,0 @@
# Notification System Enhancements - Implementation Plan
## Overview
This document outlines the complete implementation plan for notification system enhancements, including dynamic URLs, activity logging, and customer notifications.
---
## 1. Customer Email Notifications
### Current State
- WooCommerce handles customer emails automatically
- WooNooW notifications are for admin alerts only
- Recipient field exists but not fully utilized
### Strategy: Integration, Not Replacement
**Decision:** Keep WooCommerce's customer email system, add admin notification layer
**Why:**
- ✅ WooCommerce emails are battle-tested
- ✅ Merchants already customize them
- ✅ Templates, styling, and logic already exist
- ✅ We focus on admin experience
**What We Add:**
- Admin notifications (email + push)
- Real-time alerts for admins
- Activity logging
- Better UI for managing notifications
### Implementation
**No code changes needed!** System already supports:
- `recipient: 'admin'` - Admin notifications
- `recipient: 'customer'` - Customer notifications (via WooCommerce)
- `recipient: 'both'` - Both (admin via WooNooW, customer via WooCommerce)
**Documentation Update:**
- Clarify that customer emails use WooCommerce
- Document integration points
- Add filter for custom recipient logic
---
## 2. Activity Log System
### Current State
- WooCommerce has order notes (limited)
- No comprehensive activity log
- No UI for viewing all activities
### Strategy: Build Custom Activity Log
**Why Build Our Own:**
- ✅ Full control over what's logged
- ✅ Better UI/UX
- ✅ Searchable and filterable
- ✅ Integration with notifications
- ✅ Real-time updates
### Data Structure
```php
// wp_woonoow_activity_log table
CREATE TABLE wp_woonoow_activity_log (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL,
action VARCHAR(50) NOT NULL,
object_type VARCHAR(50) NOT NULL,
object_id BIGINT UNSIGNED NOT NULL,
description TEXT,
metadata LONGTEXT, -- JSON
ip_address VARCHAR(45),
user_agent TEXT,
created_at DATETIME NOT NULL,
INDEX idx_user_id (user_id),
INDEX idx_action (action),
INDEX idx_object (object_type, object_id),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Activity Types
**Orders:**
- `order.created` - Order created
- `order.updated` - Order updated
- `order.status_changed` - Status changed
- `order.payment_completed` - Payment completed
- `order.refunded` - Order refunded
- `order.deleted` - Order deleted
**Products:**
- `product.created` - Product created
- `product.updated` - Product updated
- `product.stock_changed` - Stock changed
- `product.deleted` - Product deleted
**Customers:**
- `customer.created` - Customer registered
- `customer.updated` - Customer updated
- `customer.deleted` - Customer deleted
**Notifications:**
- `notification.sent` - Notification sent
- `notification.failed` - Notification failed
- `notification.clicked` - Notification clicked
**Settings:**
- `settings.updated` - Settings changed
- `channel.toggled` - Channel enabled/disabled
- `event.toggled` - Event enabled/disabled
### Implementation Files
**Backend:**
1. `includes/Core/ActivityLog/Logger.php` - Main logger class
2. `includes/Core/ActivityLog/ActivityLogTable.php` - Database table
3. `includes/Api/ActivityLogController.php` - REST API
4. Hook into WooCommerce actions
**Frontend:**
1. `admin-spa/src/routes/ActivityLog/index.tsx` - Activity log page
2. `admin-spa/src/routes/ActivityLog/ActivityItem.tsx` - Single activity
3. `admin-spa/src/routes/ActivityLog/Filters.tsx` - Filter UI
---
## 3. Dynamic Push Notification URLs
### Current State
- Global URL: `/wp-admin/admin.php?page=woonoow#/orders`
- All notifications go to same page
### Strategy: Event-Specific Deep Links
### URL Templates
```php
$url_templates = [
// Orders
'order_placed' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
'order_processing' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
'order_completed' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
'order_cancelled' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
'order_refunded' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
// Products
'low_stock' => '/wp-admin/admin.php?page=woonoow#/products/{product_id}',
'out_of_stock' => '/wp-admin/admin.php?page=woonoow#/products/{product_id}',
// Customers
'new_customer' => '/wp-admin/admin.php?page=woonoow#/customers/{customer_id}',
'customer_note' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
];
```
### Template Variables
**Available Variables:**
- `{order_id}` - Order ID
- `{product_id}` - Product ID
- `{customer_id}` - Customer ID
- `{user_id}` - User ID
- `{site_url}` - Site URL
- `{admin_url}` - Admin URL
### Implementation
**Backend:**
1. Add URL template field to push settings
2. Parse template variables when sending
3. Store parsed URL in notification metadata
**Frontend:**
1. Add URL template field to Templates page
2. Show available variables
3. Preview parsed URL
---
## 4. Rich Notification Content
### Event-Specific Icons
```php
$notification_icons = [
'order_placed' => '🛒',
'order_processing' => '⚙️',
'order_completed' => '✅',
'order_cancelled' => '❌',
'order_refunded' => '💰',
'low_stock' => '📦',
'out_of_stock' => '🚫',
'new_customer' => '👤',
'customer_note' => '💬',
];
```
### Event-Specific Images
**Order Notifications:**
- Show first product image
- Fallback to store logo
**Product Notifications:**
- Show product image
- Fallback to placeholder
**Customer Notifications:**
- Show customer avatar (Gravatar)
- Fallback to default avatar
### Rich Content Structure
```json
{
"title": "New Order #1234",
"body": "John Doe ordered 2 items (Rp137.000)",
"icon": "🛒",
"image": "https://example.com/product.jpg",
"badge": "https://example.com/logo.png",
"data": {
"url": "/wp-admin/admin.php?page=woonoow#/orders/1234",
"order_id": 1234,
"customer_name": "John Doe",
"total": 137000
},
"actions": [
{
"action": "view",
"title": "View Order",
"icon": "👁️"
},
{
"action": "mark_processing",
"title": "Mark Processing",
"icon": "⚙️"
}
]
}
```
---
## Implementation Priority
### Phase 1: Dynamic URLs (Immediate) ✅
1. Add URL template to push settings
2. Parse template variables
3. Update notification sending logic
4. Test with different events
### Phase 2: Activity Log (Immediate) ✅
1. Create database table
2. Implement Logger class
3. Hook into WooCommerce actions
4. Create REST API
5. Build frontend UI
### Phase 3: Rich Content (Future) 📋
1. Add icon field to events
2. Add image field to events
3. Implement image fetching logic
4. Update push notification payload
5. Test on different browsers
### Phase 4: Notification Actions (Future) 📋
1. Define action types
2. Implement action handlers
3. Update push notification payload
4. Handle action clicks
5. Test on different browsers
---
## Database Schema
### Activity Log Table
```sql
CREATE TABLE IF NOT EXISTS wp_woonoow_activity_log (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT UNSIGNED NOT NULL,
user_name VARCHAR(255) NOT NULL,
action VARCHAR(50) NOT NULL,
object_type VARCHAR(50) NOT NULL,
object_id BIGINT UNSIGNED NOT NULL,
object_name VARCHAR(255),
description TEXT,
metadata LONGTEXT,
ip_address VARCHAR(45),
user_agent TEXT,
created_at DATETIME NOT NULL,
INDEX idx_user_id (user_id),
INDEX idx_action (action),
INDEX idx_object (object_type, object_id),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
```
### Push Settings Update
```php
// Add to woonoow_push_notification_settings
[
'enabled' => true,
'vapid_public_key' => '...',
'vapid_private_key' => '...',
'default_url' => '/wp-admin/admin.php?page=woonoow#/orders',
'url_templates' => [
'order_placed' => '/wp-admin/admin.php?page=woonoow#/orders/{order_id}',
// ... more templates
],
'show_store_logo' => true,
'show_product_images' => true,
'show_customer_avatar' => true,
'require_interaction' => false,
'silent_notifications' => false,
]
```
---
## API Endpoints
### Activity Log
```
GET /woonoow/v1/activity-log
?page=1&per_page=20&action=order.created&user_id=1&date_from=2025-11-01
POST /woonoow/v1/activity-log
{ action, object_type, object_id, description, metadata }
GET /woonoow/v1/activity-log/stats
?date_from=2025-11-01&date_to=2025-11-30
```
### Push Notification URLs
```
GET /woonoow/v1/notifications/push/url-templates
POST /woonoow/v1/notifications/push/url-templates
{ event_id, url_template }
POST /woonoow/v1/notifications/push/preview-url
{ event_id, url_template, variables }
```
---
## Testing Checklist
### Dynamic URLs
- [ ] Order notification → Order detail page
- [ ] Product notification → Product edit page
- [ ] Customer notification → Customer page
- [ ] Variables parsed correctly
- [ ] Fallback to default URL
### Activity Log
- [ ] Activities logged correctly
- [ ] Filtering works
- [ ] Pagination works
- [ ] Search works
- [ ] Real-time updates
- [ ] Performance with 10k+ logs
### Rich Content
- [ ] Icons display correctly
- [ ] Images load correctly
- [ ] Fallbacks work
- [ ] Different browsers (Chrome, Firefox, Safari)
- [ ] Mobile devices
---
## Success Metrics
**User Experience:**
- Click-through rate on notifications
- Time to action after notification
- User satisfaction score
**Technical:**
- Notification delivery rate
- Activity log query performance
- Storage usage
**Business:**
- Faster response to orders
- Reduced missed notifications
- Better audit trail
---
## Timeline
**Week 1: Dynamic URLs + Activity Log**
- Day 1-2: Dynamic URLs implementation
- Day 3-5: Activity Log backend
- Day 6-7: Activity Log frontend
**Week 2: Rich Content**
- Day 1-3: Icons and images
- Day 4-5: Testing and polish
- Day 6-7: Documentation
**Week 3: Notification Actions**
- Day 1-3: Action handlers
- Day 4-5: Testing
- Day 6-7: Documentation and release
---
## Conclusion
This plan provides a comprehensive roadmap for enhancing the notification system with:
1. ✅ Customer email clarification (no changes needed)
2. ✅ Activity log system (custom build)
3. ✅ Dynamic push URLs (event-specific)
4. ✅ Rich notification content (icons, images, actions)
All enhancements are designed to improve admin experience while maintaining compatibility with WooCommerce's existing systems.

View File

@@ -1,372 +0,0 @@
# Notification System Implementation Status
**Last Updated:** November 11, 2025, 5:47 PM (GMT+7)
---
## ✅ Completed Features
### 1. UI/UX Refinements
- [x] Simplified Channels page
- [x] Removed redundant badges and toggles
- [x] Cleaned up Events page
- [x] Improved visual hierarchy
### 2. Toggle Logic Fixes
- [x] Fixed `get_json_params()` for POST data
- [x] Fixed data structure paths
- [x] Removed race conditions
- [x] All toggles working correctly
### 3. Activity Log Backend
- [x] Database table created
- [x] Logger class implemented
- [x] REST API endpoints
- [x] Query and filter system
- [x] Statistics system
- [x] Cleanup functionality
---
## 🚧 In Progress / Next Steps
### 1. Dynamic Push Notification URLs
**Status:** Planned
**Implementation:**
```php
// Add to PushNotificationHandler.php
public static function get_notification_url($event_id, $variables = []) {
$settings = get_option('woonoow_push_notification_settings', []);
// Get URL template for event
$url_templates = $settings['url_templates'] ?? [];
$template = $url_templates[$event_id] ?? $settings['default_url'] ?? '/wp-admin/admin.php?page=woonoow#/orders';
// Parse variables
foreach ($variables as $key => $value) {
$template = str_replace('{' . $key . '}', $value, $template);
}
return $template;
}
```
**Usage:**
```php
$url = PushNotificationHandler::get_notification_url('order_placed', [
'order_id' => 1234
]);
// Result: /wp-admin/admin.php?page=woonoow#/orders/1234
```
**Frontend:**
- Add URL template field to ChannelConfig.tsx
- Show available variables
- Preview parsed URL
---
### 2. Rich Notification Content
**Status:** Planned
**Implementation:**
```php
// Add to PushNotificationHandler.php
public static function get_notification_content($event_id, $data = []) {
$settings = get_option('woonoow_push_notification_settings', []);
// Get icon
$icons = [
'order_placed' => '🛒',
'order_processing' => '⚙️',
'order_completed' => '✅',
'low_stock' => '📦',
'out_of_stock' => '🚫',
'new_customer' => '👤',
];
$icon = $icons[$event_id] ?? '🔔';
// Get image
$image = null;
if ($settings['show_product_images'] && isset($data['product_id'])) {
$product = wc_get_product($data['product_id']);
$image = $product ? wp_get_attachment_url($product->get_image_id()) : null;
}
// Get badge (store logo)
$badge = $settings['show_store_logo'] ? get_site_icon_url() : null;
return [
'icon' => $icon,
'image' => $image,
'badge' => $badge,
];
}
```
---
### 3. Activity Log Frontend
**Status:** Planned
**Files to Create:**
1. **`admin-spa/src/routes/ActivityLog/index.tsx`**
```typescript
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { api } from '@/lib/api';
import { __ } from '@/lib/i18n';
export default function ActivityLog() {
const [page, setPage] = React.useState(1);
const [filters, setFilters] = React.useState({});
const { data, isLoading } = useQuery({
queryKey: ['activity-log', page, filters],
queryFn: () => api.get('/activity-log', { page, ...filters }),
});
return (
<div className="p-6">
<h1>{__('Activity Log')}</h1>
{/* Filters */}
{/* Activity list */}
{/* Pagination */}
</div>
);
}
```
2. **`admin-spa/src/routes/ActivityLog/ActivityItem.tsx`**
```typescript
export function ActivityItem({ activity }: { activity: any }) {
return (
<div className="flex items-start gap-4 p-4 border-b">
<div className="w-10 h-10 rounded-full bg-primary/10 flex items-center justify-center">
{getActionIcon(activity.action)}
</div>
<div className="flex-1">
<div className="flex items-center gap-2">
<span className="font-medium">{activity.user_name}</span>
<span className="text-sm text-muted-foreground">
{activity.action}
</span>
</div>
<p className="text-sm text-muted-foreground">
{activity.description}
</p>
<span className="text-xs text-muted-foreground">
{formatDate(activity.created_at)}
</span>
</div>
</div>
);
}
```
3. **Add to navigation tree**
```typescript
// admin-spa/src/lib/nav/tree.ts
{
key: 'activity-log',
label: __('Activity Log'),
path: '/activity-log',
icon: History,
}
```
---
### 4. WooCommerce Hooks Integration
**Status:** Planned
**Implementation:**
```php
// Create: includes/Core/ActivityLog/WooCommerceHooks.php
namespace WooNooW\Core\ActivityLog;
class WooCommerceHooks {
public static function init() {
// Orders
add_action('woocommerce_new_order', [__CLASS__, 'log_order_created'], 10, 1);
add_action('woocommerce_update_order', [__CLASS__, 'log_order_updated'], 10, 1);
add_action('woocommerce_order_status_changed', [__CLASS__, 'log_order_status_changed'], 10, 4);
// Products
add_action('woocommerce_new_product', [__CLASS__, 'log_product_created'], 10, 1);
add_action('woocommerce_update_product', [__CLASS__, 'log_product_updated'], 10, 1);
add_action('woocommerce_product_set_stock', [__CLASS__, 'log_stock_changed'], 10, 1);
// Customers
add_action('woocommerce_created_customer', [__CLASS__, 'log_customer_created'], 10, 1);
}
public static function log_order_created($order_id) {
$order = wc_get_order($order_id);
Logger::log(
'order.created',
'order',
$order_id,
sprintf(__('Order #%d created', 'woonoow'), $order_id),
[
'total' => $order->get_total(),
'status' => $order->get_status(),
'customer_id' => $order->get_customer_id(),
]
);
}
// ... more hooks
}
```
**Register in Bootstrap:**
```php
use WooNooW\Core\ActivityLog\WooCommerceHooks;
// In Bootstrap::init()
WooCommerceHooks::init();
```
---
## 📋 Implementation Checklist
### Dynamic URLs
- [ ] Add URL template storage to push settings
- [ ] Implement `get_notification_url()` method
- [ ] Add template variable parsing
- [ ] Update notification sending to use dynamic URLs
- [ ] Add UI for URL template configuration
- [ ] Test with all event types
### Rich Content
- [ ] Add icon mapping for events
- [ ] Implement image fetching logic
- [ ] Add badge (store logo) support
- [ ] Update push notification payload
- [ ] Test on different browsers
- [ ] Test on mobile devices
### Activity Log Frontend
- [ ] Create ActivityLog route component
- [ ] Create ActivityItem component
- [ ] Create Filters component
- [ ] Add to navigation tree
- [ ] Implement pagination
- [ ] Implement search
- [ ] Add real-time updates (optional)
### WooCommerce Hooks
- [ ] Create WooCommerceHooks class
- [ ] Hook into order events
- [ ] Hook into product events
- [ ] Hook into customer events
- [ ] Hook into notification events
- [ ] Test all hooks
- [ ] Verify logging accuracy
---
## 🎯 Priority Order
1. **High Priority (This Week)**
- Dynamic push notification URLs
- WooCommerce hooks integration
- Activity log frontend (basic)
2. **Medium Priority (Next Week)**
- Rich notification content
- Activity log frontend (advanced filters)
- Real-time updates
3. **Low Priority (Future)**
- Notification actions
- Advanced analytics
- Export functionality
---
## 📊 Success Metrics
**Technical:**
- [ ] All toggles working correctly
- [ ] Activity log queries < 100ms
- [ ] Push notifications delivered < 1s
- [ ] Zero race conditions
**User Experience:**
- [ ] Click-through rate on notifications > 50%
- [ ] Time to action after notification < 30s
- [ ] User satisfaction score > 4.5/5
**Business:**
- [ ] Faster response to orders (measure baseline)
- [ ] Reduced missed notifications (track count)
- [ ] Better audit trail (compliance ready)
---
## 🚀 Quick Start for Next Session
1. **Test Activity Log Backend:**
```bash
# Create test activity
curl -X POST http://localhost/wp-json/woonoow/v1/activity-log \
-H "Content-Type: application/json" \
-d '{"action":"test.action","object_type":"test","object_id":1,"description":"Test activity"}'
# Get activities
curl http://localhost/wp-json/woonoow/v1/activity-log
```
2. **Implement Dynamic URLs:**
- Open `PushNotificationHandler.php`
- Add `get_notification_url()` method
- Update `send_notification()` to use it
3. **Create Activity Log UI:**
- Create `admin-spa/src/routes/ActivityLog/index.tsx`
- Add to navigation tree
- Test API integration
---
## 📚 Documentation
**Created:**
- [x] NOTIFICATION_ENHANCEMENTS_PLAN.md
- [x] NOTIFICATION_IMPLEMENTATION_STATUS.md (this file)
- [x] NOTIFICATION_LOGIC.md
**To Create:**
- [ ] ACTIVITY_LOG_GUIDE.md
- [ ] PUSH_NOTIFICATION_GUIDE.md
- [ ] NOTIFICATION_HOOKS_REFERENCE.md
---
## ✅ Summary
**Completed Today:**
1. UI/UX refinements (Channels + Events pages)
2. Toggle logic fixes (all working correctly)
3. Activity log backend (database + API)
4. Comprehensive planning documents
**Ready for Implementation:**
1. Dynamic push notification URLs
2. Rich notification content
3. Activity log frontend
4. WooCommerce hooks integration
**All systems are production-ready and well-documented!** 🎉

View File

@@ -1,140 +0,0 @@
# Notification Logic Documentation
## Overview
The notification system has two levels of control:
1. **Global Channel Toggle** - Enable/disable entire channel (Channels page)
2. **Per-Event Channel Toggle** - Enable/disable channel for specific event (Events page)
Both must be enabled for a notification to be sent.
## Toggle Hierarchy
```
┌─────────────────────────────────────────┐
│ Global Channel Toggle (Channels Page) │
│ - Affects ALL events │
│ - Stored in wp_options │
│ - woonoow_email_notifications_enabled │
│ - woonoow_push_notifications_enabled │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ Per-Event Channel Toggle (Events Page) │
│ - Affects specific event only │
│ - Stored in woonoow_notification_settings│
│ - Independent per event │
└─────────────────────────────────────────┘
```
## Decision Logic
```php
// Notification will be sent if:
if (channel_globally_enabled && event_channel_enabled) {
send_notification();
}
```
## Examples
### Example 1: Email Disabled Globally
```
Global Email Toggle: OFF
Event "Order Placed" Email Toggle: ON
Result: ❌ No email sent
```
### Example 2: Email Enabled Globally, Disabled for Event
```
Global Email Toggle: ON
Event "Order Placed" Email Toggle: OFF
Result: ❌ No email sent
```
### Example 3: Both Enabled
```
Global Email Toggle: ON
Event "Order Placed" Email Toggle: ON
Result: ✅ Email sent
```
## Implementation
### NotificationManager Class
Located at: `includes/Core/Notifications/NotificationManager.php`
**Key Methods:**
1. `is_channel_enabled($channel_id)` - Check global channel state
2. `is_event_channel_enabled($event_id, $channel_id)` - Check per-event state
3. `should_send_notification($event_id, $channel_id)` - Validate both
4. `send($event_id, $channel_id, $data)` - Send notification
### Usage Example
```php
use WooNooW\Core\Notifications\NotificationManager;
// Check if notification should be sent
if (NotificationManager::should_send_notification('order_placed', 'email')) {
NotificationManager::send('order_placed', 'email', [
'order_id' => 123,
'customer_email' => 'customer@example.com',
]);
}
```
## Frontend Integration
### Channels Page (`Channels.tsx`)
- Shows global enable/disable toggle
- Affects all events
- API: `POST /notifications/channels/toggle`
- Params: `{ channelId, enabled }`
### Events Page (`Events.tsx`)
- Shows per-event channel toggles
- Independent for each event
- API: `POST /notifications/events/update`
- Params: `{ eventId, channels: { [channelId]: { enabled, recipient } } }`
## Storage
### Global Channel State
```php
// Email
get_option('woonoow_email_notifications_enabled', true);
// Push
get_option('woonoow_push_notifications_enabled', true);
```
### Per-Event Channel State
```php
$settings = get_option('woonoow_notification_settings', []);
$settings['order_placed']['channels']['email']['enabled'] = true;
$settings['order_placed']['channels']['email']['recipient'] = 'customer';
```
## Testing Checklist
- [ ] Disable email globally → No emails sent for any event
- [ ] Enable email globally, disable for specific event → Email sent for other events only
- [ ] Enable both → Email sent
- [ ] Same tests for push notifications
- [ ] Toggle persistence across page reloads
- [ ] UI reflects current state correctly
- [ ] Toast notifications on toggle
- [ ] Green icon when enabled, gray when disabled
## Future Enhancements
1. **Batch Operations** - Enable/disable multiple events at once
2. **Channel Priority** - Set fallback channels
3. **Scheduling** - Delay or schedule notifications
4. **Rate Limiting** - Prevent notification spam
5. **Analytics** - Track notification delivery rates

View File

@@ -1,350 +0,0 @@
# 🎉 Notification System Refactor - COMPLETE!
**Date:** November 11, 2025
**Time:** 6:52 PM - 8:25 PM (GMT+7)
**Duration:** ~1 hour 33 minutes
**Status:****COMPLETE & READY FOR TESTING**
---
## 📊 Summary
Successfully refactored the notification system to support **both Staff and Customer notifications** with a unified architecture and separate UIs.
### Key Achievement
-**70-80% code reuse** between Staff and Customer
-**Clear separation** of concerns
-**Scalable architecture** for future expansion
-**Modern UI/UX** following industry best practices
---
## ✅ What Was Implemented
### 1. Backend API (100% Complete)
**File:** `includes/Api/NotificationsController.php`
**New Endpoints:**
- `GET /woonoow/v1/notifications/staff/events` - Returns staff-only events
- `GET /woonoow/v1/notifications/customer/events` - Returns customer-only events
**Changes:**
- Added `recipient_type` field to all events (`'staff'` or `'customer'`)
- Created `get_all_events()` private helper method
- Implemented filtering logic based on `recipient_type`
- All existing endpoints remain functional
**Event Classification:**
```php
Staff Events (recipient_type: 'staff'):
- order_placed (New order notification for admin)
- order_cancelled (Order cancellation alert)
- low_stock (Low stock alert)
- out_of_stock (Out of stock alert)
Customer Events (recipient_type: 'customer'):
- order_processing (Order is being processed)
- order_completed (Order completed)
- order_refunded (Order refunded)
- new_customer (New account created)
- customer_note (Note added to order)
```
---
### 2. Main Notifications Hub (100% Complete)
**File:** `admin-spa/src/routes/Settings/Notifications.tsx`
**Features:**
- Card-based layout with 3 sections
- **Staff Notifications** card → `/settings/notifications/staff`
- **Customer Notifications** card → `/settings/notifications/customer`
- **Activity Log** card (coming soon, disabled)
- Clear descriptions and icons for each section
- Modern, intuitive navigation
**UI Structure:**
```
┌─────────────────────────────────────┐
│ Settings → Notifications │
├─────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Staff │ │ Customer │ │
│ │ Notifications│ │ Notifications│ │
│ │ [Configure] │ │ [Configure] │ │
│ └──────────────┘ └──────────────┘ │
│ ┌──────────────┐ │
│ │ Activity Log │ │
│ │ [Coming Soon]│ │
│ └──────────────┘ │
└─────────────────────────────────────┘
```
---
### 3. Staff Notifications (100% Complete)
**Files:**
- `admin-spa/src/routes/Settings/Notifications/Staff.tsx` (Main page)
- `admin-spa/src/routes/Settings/Notifications/Staff/Channels.tsx`
- `admin-spa/src/routes/Settings/Notifications/Staff/Events.tsx`
**Features:**
- **Channels Tab:**
- Email (Built-in, enabled by default)
- Push Notifications (Built-in, with subscription)
- Toggle switches for enable/disable
- Configure buttons for each channel
- "Extend with Addons" section (WhatsApp, Telegram, SMS)
- **Events Tab:**
- Uses `/notifications/staff/events` endpoint
- Categories: Orders, Products, Customers
- Per-event, per-channel toggles
- Real-time updates with React Query
- Shows recipient type
- **Templates Tab:**
- Reuses existing Templates component
- Email and Push templates
- Template editor
**Route:** `/settings/notifications/staff`
---
### 4. Customer Notifications (100% Complete)
**Files:**
- `admin-spa/src/routes/Settings/Notifications/Customer.tsx` (Main page)
- `admin-spa/src/routes/Settings/Notifications/Customer/Channels.tsx`
- `admin-spa/src/routes/Settings/Notifications/Customer/Events.tsx`
**Features:**
- **Channels Tab:**
- Email (Built-in, always enabled)
- Push Notifications (Built-in, requires customer opt-in)
- "Extend with Addons" section (WhatsApp, Telegram, SMS)
- Customer preferences information
- Consistent UI with Staff page
- **Events Tab:**
- Uses `/notifications/customer/events` endpoint
- Categories: Orders, Customers
- Per-event, per-channel toggles
- Customer-specific events only
- Shows recipient type
- **Templates Tab:**
- Reuses existing Templates component
- Customer email templates
- Template editor
**Route:** `/settings/notifications/customer`
**Customer Preferences Info:**
- My Account → Notification Preferences
- Unsubscribe links in emails
- Browser push notification settings
- Note about transactional emails being required
---
### 5. Routes Registration (100% Complete)
**File:** `admin-spa/src/App.tsx`
**Added Routes:**
```typescript
import StaffNotifications from '@/routes/Settings/Notifications/Staff';
import CustomerNotifications from '@/routes/Settings/Notifications/Customer';
<Route path="/settings/notifications/staff" element={<StaffNotifications />} />
<Route path="/settings/notifications/customer" element={<CustomerNotifications />} />
```
---
## 🐛 Bugs Fixed
### Issue 1: Staff Route Not Working
**Problem:** `/settings/notifications/staff` showed blank page
**Cause:** Route not registered in App.tsx
**Fix:** Added route registration and fixed import paths
### Issue 2: Customer Channels Inconsistent with Staff
**Problem:** Customer Channels page had different layout than Staff
**Cause:** Different component structure
**Fix:** Matched Customer Channels layout to Staff with addon section
### Issue 3: Customer Events Showing "No Events"
**Problem:** Customer Events tab showed "No Events" message
**Cause:** Backend filtering logic using `reset()` on channels array
**Fix:** Changed to use `recipient_type` field for filtering
---
## 📁 Files Created/Modified
### Created (7 files):
1. `admin-spa/src/routes/Settings/Notifications/Staff.tsx`
2. `admin-spa/src/routes/Settings/Notifications/Staff/Channels.tsx`
3. `admin-spa/src/routes/Settings/Notifications/Staff/Events.tsx`
4. `admin-spa/src/routes/Settings/Notifications/Customer.tsx`
5. `admin-spa/src/routes/Settings/Notifications/Customer/Channels.tsx`
6. `admin-spa/src/routes/Settings/Notifications/Customer/Events.tsx`
7. `NOTIFICATION_REFACTOR_STATUS.md` (documentation)
### Modified (3 files):
1. `includes/Api/NotificationsController.php` (Backend API)
2. `admin-spa/src/routes/Settings/Notifications.tsx` (Main hub)
3. `admin-spa/src/App.tsx` (Route registration)
**Total Lines of Code:** ~1,800+
---
## 🎯 Architecture
```
Settings → Notifications (Main Hub)
├── Staff Notifications (/settings/notifications/staff)
│ ├── Channels Tab
│ │ ├── Email (Built-in, toggleable)
│ │ ├── Push Notifications (Built-in, toggleable)
│ │ └── Extend with Addons (WhatsApp, Telegram, SMS)
│ ├── Events Tab
│ │ ├── Orders (order_placed, order_cancelled)
│ │ ├── Products (low_stock, out_of_stock)
│ │ └── Customers (staff view)
│ └── Templates Tab
│ └── Staff email/push templates
└── Customer Notifications (/settings/notifications/customer)
├── Channels Tab
│ ├── Email (Built-in, always enabled)
│ ├── Push Notifications (Requires opt-in)
│ └── Extend with Addons (WhatsApp, Telegram, SMS)
├── Events Tab
│ ├── Orders (order_processing, order_completed, order_refunded)
│ └── Customers (new_customer, customer_note)
└── Templates Tab
└── Customer email/push templates
```
---
## ✅ Testing Checklist
### Navigation
- [x] Main hub shows 3 cards (Staff, Customer, Activity Log)
- [ ] Click "Configure" on Staff card → Goes to `/settings/notifications/staff`
- [ ] Click "Configure" on Customer card → Goes to `/settings/notifications/customer`
- [ ] Click "Back to Notifications" → Returns to main hub
- [ ] All tabs work (Channels, Events, Templates)
### Staff Section
- [ ] Channels tab shows Email and Push with toggles
- [ ] Events tab shows staff events (order_placed, low_stock, etc.)
- [ ] Toggle switches work and persist
- [ ] Templates tab loads correctly
- [ ] Addon section shows WhatsApp, Telegram, SMS cards
### Customer Section
- [ ] Channels tab shows Email and Push (no toggles)
- [ ] Events tab shows customer events (order_processing, order_completed, etc.)
- [ ] Toggle switches work and persist
- [ ] Templates tab loads correctly
- [ ] Addon section shows WhatsApp, Telegram, SMS cards
- [ ] Customer preferences info displayed
### Data Persistence
- [ ] Toggle staff event → Refresh → Stays toggled
- [ ] Toggle customer event → Refresh → Stays toggled
- [ ] Settings saved to database correctly
---
## 🚀 What's Next (Optional Enhancements)
### Phase 4: Templates with Recipient Filter (Optional)
- Add `recipientType` prop to Templates component
- Filter templates by staff/customer
- Show only relevant templates per section
### Phase 5: Activity Log UI (Future)
- Build frontend UI for activity log
- Show notification history
- Filter by recipient, channel, event
- Export logs
### Phase 6: Customer Preferences Page (Future)
- Build customer-facing preferences UI in customer-spa
- Allow customers to manage their notifications
- Per-event opt-in/opt-out
- Unsubscribe management
---
## 📈 Impact
### Before
- ❌ Admin-only notifications (1-5 users)
- ❌ 10-50 notifications/day
- ❌ Incomplete feature
- ❌ Missed opportunity
### After
- ✅ Staff + Customer notifications (100-10,000+ users)
- ✅ 100-1,000+ notifications/day
- ✅ Complete, scalable feature
- ✅ 10-100x higher business impact
- ✅ Better customer experience
- ✅ Competitive advantage
---
## 🎉 Success Metrics
1. **Code Reusability:** 70-80% ✅
2. **Clear Separation:** Staff vs Customer ✅
3. **Scalability:** Easy to add new events/channels ✅
4. **User Experience:** Intuitive navigation ✅
5. **Industry Standards:** Follows Shopify/BigCommerce patterns ✅
---
## 📝 Commits
1. `feat: Restructure notifications - Staff and Customer separation (WIP)`
2. `docs: Add notification refactor status document`
3. `fix: Register staff notifications route and fix import paths`
4. `feat: Complete Customer Notifications section`
5. `fix: Match Customer Channels to Staff layout and fix event filtering`
---
## 🙏 Acknowledgments
**User Concern Addressed:**
> "I think, yes this is absolutely good, but we did so much effort if only for admin. Or even better this feature can be reuse there in customer-spa (?)"
**Result:** Feature now supports both Staff and Customer with 70-80% code reuse! 🎉
---
## 📞 Support
If you encounter any issues:
1. Check browser console for errors
2. Check WordPress debug log
3. Verify API endpoints return data: `/wp-json/woonoow/v1/notifications/staff/events`
4. Clear browser cache and refresh
---
**Status:****READY FOR PRODUCTION**
**Confidence:** 95% (pending final user testing)
**Recommendation:** Test thoroughly, then deploy! 🚀

View File

@@ -1,409 +0,0 @@
# Notification System Refactor - Implementation Status
**Started:** November 11, 2025, 6:52 PM (GMT+7)
**Completed:** November 11, 2025, 8:02 PM (GMT+7)
**Status:** ✅ 90% Complete (Testing Pending)
---
## ✅ Phase 1 Complete: Backend + Staff Frontend
### Backend (100% Complete)
**File:** `includes/Api/NotificationsController.php`
**Changes:**
1. ✅ Added `GET /notifications/staff/events` endpoint
2. ✅ Added `GET /notifications/customer/events` endpoint
3. ✅ Created `get_all_events()` private helper method
4. ✅ Added `recipient_type` field to all events
5. ✅ Filtering logic for staff vs customer events
**Event Classification:**
- **Staff Events:** order_placed, order_cancelled, low_stock, out_of_stock
- **Customer Events:** order_processing, order_completed, order_refunded, new_customer, customer_note
### Frontend - Main Page (100% Complete)
**File:** `admin-spa/src/routes/Settings/Notifications.tsx`
**Changes:**
1. ✅ Removed tabs (Events, Channels, Templates)
2. ✅ Added card-based layout
3. ✅ Three cards: Staff Notifications, Customer Notifications, Activity Log
4. ✅ Links to `/settings/notifications/staff` and `/settings/notifications/customer`
5. ✅ Modern UI with icons and descriptions
### Frontend - Staff Section (100% Complete)
**File:** `admin-spa/src/routes/Settings/Notifications/Staff.tsx`
**Changes:**
1. ✅ Created Staff Notifications page with tabs
2. ✅ Tabs: Channels, Events, Templates
3. ✅ Back button to main Notifications page
4. ✅ Reuses existing components
**File:** `admin-spa/src/routes/Settings/Notifications/Staff/Channels.tsx`
- ✅ Copied from `Notifications/Channels.tsx`
- ✅ No changes needed (already works for staff)
**File:** `admin-spa/src/routes/Settings/Notifications/Staff/Events.tsx`
- ✅ Copied from `Notifications/Events.tsx`
- ✅ Updated to use `/notifications/staff/events` endpoint
- ✅ Updated query key to `notification-staff-events`
- ✅ Fixed import paths
---
## ✅ Phase 2 Complete: Customer Frontend
### Customer Notifications Page
**File to Create:** `admin-spa/src/routes/Settings/Notifications/Customer.tsx`
```typescript
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { SettingsLayout } from '../components/SettingsLayout';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Button } from '@/components/ui/button';
import { __ } from '@/lib/i18n';
import { ChevronLeft } from 'lucide-react';
import CustomerChannels from './Customer/Channels';
import CustomerEvents from './Customer/Events';
import NotificationTemplates from './Templates';
export default function CustomerNotifications() {
const [activeTab, setActiveTab] = useState('channels');
return (
<SettingsLayout
title={__('Customer Notifications')}
description={__('Configure notifications sent to customers')}
action={
<Link to="/settings/notifications">
<Button variant="ghost" size="sm">
<ChevronLeft className="mr-2 h-4 w-4" />
{__('Back to Notifications')}
</Button>
</Link>
}
>
<Tabs value={activeTab} onValueChange={setActiveTab} className="space-y-6">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="channels">{__('Channels')}</TabsTrigger>
<TabsTrigger value="events">{__('Events')}</TabsTrigger>
<TabsTrigger value="templates">{__('Templates')}</TabsTrigger>
</TabsList>
<TabsContent value="channels" className="space-y-4">
<CustomerChannels />
</TabsContent>
<TabsContent value="events" className="space-y-4">
<CustomerEvents />
</TabsContent>
<TabsContent value="templates" className="space-y-4">
<NotificationTemplates recipientType="customer" />
</TabsContent>
</Tabs>
</SettingsLayout>
);
}
```
### Customer Channels Component
**File to Create:** `admin-spa/src/routes/Settings/Notifications/Customer/Channels.tsx`
**Features:**
- Email channel (always available)
- Push notifications (requires customer opt-in)
- SMS channel (addon, coming soon)
- Different messaging for customer context
### Customer Events Component
**File to Create:** `admin-spa/src/routes/Settings/Notifications/Customer/Events.tsx`
**Features:**
- Use `/notifications/customer/events` endpoint
- Query key: `notification-customer-events`
- Categories:
- **Orders:** Processing, Completed, Refunded
- **Account:** New Customer, Customer Note
- **Shipping:** (future) Shipped, Delivered, Tracking Updates
- **Marketing:** (future) Abandoned Cart, Promotions
---
## ✅ Phase 3 Complete: Routes Registration
### Update App Routes
**File to Update:** `admin-spa/src/App.tsx`
**Add Routes:**
```typescript
<Route path="/settings/notifications/staff" element={<StaffNotifications />} />
<Route path="/settings/notifications/customer" element={<CustomerNotifications />} />
```
---
## 🚧 Phase 4: Templates Update (To Do)
### Update Templates Component
**File to Update:** `admin-spa/src/routes/Settings/Notifications/Templates.tsx`
**Changes:**
- Accept `recipientType` prop (`'staff' | 'customer'`)
- Filter templates by recipient type
- Show different template categories based on recipient
---
## 📋 Implementation Checklist
### Phase 1: Backend + Staff (Complete ✅)
- [x] Backend: Add staff/customer endpoints
- [x] Backend: Add recipient_type to events
- [x] Backend: Filter events by recipient
- [x] Frontend: Restructure main Notifications page
- [x] Frontend: Create Staff Notifications page
- [x] Frontend: Move Channels to Staff/Channels
- [x] Frontend: Move Events to Staff/Events
- [x] Frontend: Update Staff/Events endpoint
### Phase 2: Customer Frontend (Complete ✅)
- [x] Create Customer Notifications page
- [x] Create Customer/Channels component
- [x] Create Customer/Events component
- [x] Update Customer/Events to use customer endpoint
- [x] Add customer-specific messaging
### Phase 3: Routes (Complete ✅)
- [x] Register /settings/notifications/staff route
- [x] Register /settings/notifications/customer route
- [x] Test navigation between pages
### Phase 4: Templates (Pending 📋)
- [ ] Add recipientType prop to Templates
- [ ] Filter templates by recipient
- [ ] Test template editing for both types
### Phase 5: Testing (Pending 📋)
- [ ] Test staff notifications flow
- [ ] Test customer notifications flow
- [ ] Test navigation
- [ ] Test data persistence
- [ ] Test with different events
---
## 🎯 Next Steps
1. **Create Customer Notifications Page**
- Copy structure from Staff.tsx
- Update titles and descriptions
- Link to Customer components
2. **Create Customer/Channels Component**
- Similar to Staff/Channels
- Add SMS channel (disabled, coming soon)
- Customer-specific messaging
3. **Create Customer/Events Component**
- Use `/notifications/customer/events`
- Query key: `notification-customer-events`
- Customer event categories
4. **Register Routes**
- Add to App.tsx
- Test navigation
5. **Update Templates**
- Add recipientType prop
- Filter by recipient
6. **Test Everything**
- End-to-end testing
- Fix any issues
---
## 📊 Progress
**Overall:** 90% Complete
- Backend: 100% ✅
- Main Page: 100% ✅
- Staff Section: 100% ✅
- Customer Section: 100% ✅
- Routes: 100% ✅
- Templates: 0% 📋 (Optional)
- Testing: 50% 🚧 (Manual testing needed)
---
## 🚀 Quick Start for Next Session
```bash
# Continue from where we left off
# 1. Create Customer Notifications page
# File: admin-spa/src/routes/Settings/Notifications/Customer.tsx
# 2. Create Customer/Channels component
# File: admin-spa/src/routes/Settings/Notifications/Customer/Channels.tsx
# 3. Create Customer/Events component
# File: admin-spa/src/routes/Settings/Notifications/Customer/Events.tsx
# 4. Register routes in App.tsx
# 5. Test the flow
```
---
## 📚 Architecture
```
Settings → Notifications (Main Hub)
├── Staff Notifications (/settings/notifications/staff)
│ ├── Channels Tab
│ │ ├── Email (Built-in)
│ │ └── Push Notifications (Built-in)
│ ├── Events Tab
│ │ ├── Orders (order_placed, order_cancelled)
│ │ ├── Products (low_stock, out_of_stock)
│ │ └── Customers (admin view)
│ └── Templates Tab
│ └── Staff email/push templates
└── Customer Notifications (/settings/notifications/customer)
├── Channels Tab
│ ├── Email (Built-in)
│ ├── Push Notifications (Requires opt-in)
│ └── SMS (Addon, coming soon)
├── Events Tab
│ ├── Orders (order_processing, order_completed, order_refunded)
│ ├── Account (new_customer, customer_note)
│ └── Shipping (future: shipped, delivered)
└── Templates Tab
└── Customer email/push templates
```
---
## ✅ Success Criteria
1. **Clear Separation**
- Staff and Customer sections are visually distinct
- Easy to navigate between sections
- No confusion about which notifications are for whom
2. **Code Reusability**
- 70-80% code reuse between Staff and Customer
- Shared components where possible
- DRY principles followed
3. **Scalability**
- Easy to add new event types
- Easy to add new channels
- Easy to add new recipient types (future: vendors, partners)
4. **User Experience**
- Intuitive navigation
- Clear labeling
- Helpful descriptions
- Responsive design
---
**Status:** Phases 1-3 complete! Ready for testing! 🚀
---
## 🎉 Implementation Complete!
### What's Working
1. **Backend API**
- `/notifications/staff/events` - Returns staff-only events
- `/notifications/customer/events` - Returns customer-only events
- Event filtering by recipient type
- All existing endpoints still work
2. **Main Notifications Hub**
- Card-based layout
- Staff Notifications card → `/settings/notifications/staff`
- Customer Notifications card → `/settings/notifications/customer`
- Activity Log card (coming soon)
3. **Staff Notifications**
- Channels tab (Email, Push)
- Events tab (Orders, Products, Customers)
- Templates tab
- All functionality working
4. **Customer Notifications**
- Channels tab (Email, Push, SMS info)
- Events tab (Orders, Account)
- Templates tab
- Customer-specific messaging
- Opt-in information
### What to Test
1. **Navigation**
- [ ] Click "Configure" on Staff card → Should go to Staff page
- [ ] Click "Configure" on Customer card → Should go to Customer page
- [ ] Click "Back to Notifications" → Should return to main hub
2. **Staff Section**
- [ ] Channels tab shows Email and Push
- [ ] Events tab shows staff events (order_placed, low_stock, etc.)
- [ ] Toggle switches work
- [ ] Templates tab loads
3. **Customer Section**
- [ ] Channels tab shows Email, Push, SMS info
- [ ] Events tab shows customer events (order_processing, order_completed, etc.)
- [ ] Toggle switches work
- [ ] Templates tab loads
4. **Data Persistence**
- [ ] Toggle a staff event → Refresh → Should stay toggled
- [ ] Toggle a customer event → Refresh → Should stay toggled
### Known Issues
- None! Everything should work. 🎉
### Optional Enhancements (Future)
1. **Templates with Recipient Filter**
- Add `recipientType` prop to Templates component
- Filter templates by staff/customer
2. **Activity Log**
- Build frontend UI for activity log
- Show notification history
3. **Customer Preferences Page**
- Build customer-facing preferences UI
- Allow customers to manage their notifications
---
**Total Time:** ~1 hour 10 minutes
**Files Created:** 7
**Files Modified:** 3
**Lines of Code:** ~1,500+
**Result:** Complete notification system with Staff and Customer separation! 🎉

View File

@@ -1,294 +0,0 @@
# WooNooW Notification Strategy
## Philosophy
**Core Principle:** WooNooW provides the notification framework and email as the default channel. Additional channels (WhatsApp, Telegram, SMS, etc.) are provided by addons.
---
## Architecture
### Core (WooNooW Plugin)
**Provides:**
1. **Notification Events System**
- Order placed
- Order status changed
- Low stock alert
- New customer registered
- etc.
2. **Email Channel (Built-in)**
- Default notification channel
- Always available
- Template system
- Queue system for bulk sending
3. **Notification Settings UI**
- Enable/disable notifications per event
- Configure which channels to use per event
- Template editor (for email)
- Channel-specific settings (provided by addons)
4. **Addon Integration Points**
- `woonoow_notification_channels` filter - Register new channels
- `woonoow_notification_send_{channel}` action - Send via channel
- `woonoow_notification_settings_{channel}` filter - Channel settings UI
- `woonoow_notification_template_{channel}` filter - Channel templates
---
## Settings Page Structure
```
Notifications
├── Events (What to notify)
│ ├── Orders
│ │ ├── Order Placed
│ │ │ ├── ✓ Email (to admin)
│ │ │ ├── ✓ WhatsApp (to customer) [if addon active]
│ │ │ └── ✗ Telegram
│ │ ├── Order Completed
│ │ ├── Order Cancelled
│ │ └── Order Refunded
│ ├── Products
│ │ ├── Low Stock Alert
│ │ └── Out of Stock Alert
│ └── Customers
│ ├── New Customer
│ └── Customer Note Added
├── Channels (How to notify)
│ ├── Email (Built-in) ✓
│ │ ├── From Name
│ │ ├── From Email
│ │ ├── SMTP Settings (optional)
│ │ └── Templates
│ ├── WhatsApp [Addon]
│ │ ├── API Key
│ │ ├── Phone Number
│ │ └── Message Templates
│ ├── Telegram [Addon]
│ │ ├── Bot Token
│ │ ├── Chat ID
│ │ └── Message Format
│ └── SMS [Addon]
│ ├── Provider (Twilio, etc.)
│ ├── API Credentials
│ └── Message Templates
└── Templates
├── Email Templates
├── WhatsApp Templates [if addon active]
└── Telegram Templates [if addon active]
```
---
## Implementation
### 1. Core Notification System
```php
// includes/Core/Notifications/NotificationManager.php
class NotificationManager {
private $channels = [];
public function register_channel($id, $label, $callback) {
$this->channels[$id] = [
'label' => $label,
'callback' => $callback,
];
}
public function send($event, $data, $channels = ['email']) {
foreach ($channels as $channel) {
if (isset($this->channels[$channel])) {
call_user_func($this->channels[$channel]['callback'], $event, $data);
}
}
}
}
```
### 2. Email Channel (Built-in)
```php
// includes/Core/Notifications/Channels/EmailChannel.php
class EmailChannel {
public static function init() {
add_filter('woonoow_notification_channels', [__CLASS__, 'register']);
add_action('woonoow_notification_send_email', [__CLASS__, 'send'], 10, 2);
}
public static function register($channels) {
$channels['email'] = [
'id' => 'email',
'label' => 'Email',
'icon' => 'mail',
'builtin' => true,
];
return $channels;
}
public static function send($event, $data) {
// Send email using WooNooW mail queue
}
}
```
### 3. Addon Example: WhatsApp Channel
```php
// woonoow-whatsapp/includes/WhatsAppChannel.php
class WhatsAppChannel {
public static function init() {
add_filter('woonoow_notification_channels', [__CLASS__, 'register']);
add_action('woonoow_notification_send_whatsapp', [__CLASS__, 'send'], 10, 2);
add_filter('woonoow_notification_settings_whatsapp', [__CLASS__, 'settings']);
}
public static function register($channels) {
$channels['whatsapp'] = [
'id' => 'whatsapp',
'label' => 'WhatsApp',
'icon' => 'message-circle',
'addon' => 'woonoow-whatsapp',
];
return $channels;
}
public static function send($event, $data) {
// Send WhatsApp message via API
}
public static function settings() {
return [
'api_key' => get_option('woonoow_whatsapp_api_key'),
'phone_number' => get_option('woonoow_whatsapp_phone'),
];
}
}
```
---
## Frontend (React SPA)
### Notifications Settings Page
```tsx
// admin-spa/src/routes/Settings/Notifications.tsx
interface NotificationChannel {
id: string;
label: string;
icon: string;
builtin?: boolean;
addon?: string;
enabled: boolean;
}
interface NotificationEvent {
id: string;
label: string;
description: string;
category: 'orders' | 'products' | 'customers';
channels: {
[channelId: string]: {
enabled: boolean;
recipient: 'admin' | 'customer' | 'both';
};
};
}
export default function NotificationsPage() {
// Fetch available channels (core + addons)
const { data: channels } = useQuery({
queryKey: ['notification-channels'],
queryFn: () => api.get('/notifications/channels'),
});
// Fetch notification events configuration
const { data: events } = useQuery({
queryKey: ['notification-events'],
queryFn: () => api.get('/notifications/events'),
});
return (
<SettingsLayout title="Notifications">
{/* Available Channels */}
<SettingsCard title="Notification Channels">
{channels?.map(channel => (
<ChannelCard key={channel.id} channel={channel} />
))}
</SettingsCard>
{/* Events Configuration */}
<SettingsCard title="Order Notifications">
{events?.filter(e => e.category === 'orders').map(event => (
<EventCard
key={event.id}
event={event}
channels={channels}
/>
))}
</SettingsCard>
{/* More categories... */}
</SettingsLayout>
);
}
```
---
## Benefits
1. **Extensible:** Addons can add any notification channel
2. **Flexible:** Each event can use multiple channels
3. **User-Friendly:** Clear UI showing what's available
4. **No Bloat:** Core only includes email
5. **Addon Revenue:** Premium channels (WhatsApp, SMS) can be paid addons
---
## Example Addons
### Free Addons
- **WooNooW Telegram** - Send notifications via Telegram bot
- **WooNooW Discord** - Send notifications to Discord channel
### Premium Addons
- **WooNooW WhatsApp Pro** - WhatsApp Business API integration
- **WooNooW SMS** - SMS notifications via Twilio/Nexmo
- **WooNooW Push** - Browser push notifications
- **WooNooW Slack** - Team notifications via Slack
---
## Migration Path
**Phase 1 (Current):**
- Build notification framework
- Implement email channel
- Create settings UI with addon slots
**Phase 2:**
- Build first addon (Telegram) as proof of concept
- Document addon API
- Create addon template
**Phase 3:**
- Build premium addons (WhatsApp, SMS)
- Marketplace listing
- Community addons
---
## Key Takeaway
**WooNooW Core = Framework + Email**
**Everything Else = Addons**
This keeps the core lean while providing unlimited extensibility for notification channels.

295
NOTIFICATION_SYSTEM.md Normal file
View File

@@ -0,0 +1,295 @@
# Notification System Documentation
**Status:** ✅ Complete & Fully Wired
**Last Updated:** November 15, 2025
---
## Overview
WooNooW features a modern, flexible notification system that supports multiple channels (Email, Push, WhatsApp, Telegram, SMS) with customizable templates and markdown support.
### Key Features
- ✅ Multi-channel support (Email, Push, + Addons)
- ✅ Custom markdown templates with visual builder
- ✅ Variable system for dynamic content
- ✅ Global system toggle (WooNooW vs WooCommerce)
- ✅ Per-channel and per-event toggles
- ✅ Email customization (colors, logo, branding)
- ✅ Async email queue (prevents 30s timeout)
- ✅ Full backend wiring complete
---
## Architecture
### Structure
```
Notifications
├── Staff Notifications (toggle channels/events)
├── Customer Notifications (toggle channels/events)
├── Channel Configuration (global settings)
│ ├── Email (template + connection)
│ └── Push (template + connection)
└── Activity Log (coming soon)
```
### Notification Flow
```
Event → EmailManager → Check System Mode → Check Channel Toggle
→ Check Event Toggle → EmailRenderer → Get Template → Replace Variables
→ Parse Markdown → Apply Branding → Queue via MailQueue → Send
```
---
## Markdown Syntax
### Cards
```markdown
[card:info]
Your content here
[/card]
[card:success]
Success message
[/card]
[card:warning]
Warning message
[/card]
```
### Buttons
```markdown
[button:solid](https://example.com)
Click Me
[/button]
[button:outline](https://example.com)
Learn More
[/button]
```
### Images
```markdown
![Alt text](https://example.com/image.png)
```
---
## Variables
### Order Variables
- `{order_number}` - Order number
- `{order_date}` - Order date
- `{order_total}` - Order total
- `{order_status}` - Order status
- `{order_items_table}` - Formatted table
- `{order_items_list}` - Formatted list
### Customer Variables
- `{customer_name}` - Customer full name
- `{customer_first_name}` - First name
- `{customer_last_name}` - Last name
- `{customer_email}` - Email address
### Store Variables
- `{store_name}` - Store name
- `{store_url}` - Store URL
- `{store_email}` - Store email
---
## Backend Integration
### API Endpoints
| Method | Endpoint | Purpose |
|--------|----------|---------|
| GET | `/notifications/system-mode` | Get current mode |
| POST | `/notifications/system-mode` | Switch mode |
| GET | `/notifications/channels` | Get all channels |
| POST | `/notifications/channels/toggle` | Toggle channel |
| GET | `/notifications/events` | Get all events |
| POST | `/notifications/events/update` | Update event |
| GET | `/notifications/templates/{id}/{ch}` | Get template |
| POST | `/notifications/templates` | Save template |
| GET | `/notifications/email-settings` | Get email customization |
| POST | `/notifications/email-settings` | Save email customization |
### Database Options
```php
// System mode
woonoow_notification_system_mode = 'woonoow' | 'woocommerce'
// Channel toggles
woonoow_email_notifications_enabled = true | false
woonoow_push_notifications_enabled = true | false
// Event settings
woonoow_notification_settings = [
'order_processing' => [
'channels' => [
'email' => ['enabled' => true, 'recipient' => 'customer']
]
]
]
// Templates
woonoow_notification_templates = [
'order_processing_email_customer' => [
'subject' => '...',
'body' => '...'
]
]
// Email customization
woonoow_email_settings = [
'primary_color' => '#7f54b3',
'logo_url' => '...',
...
]
```
---
## Email Queue System
### Purpose
Prevents 30-second timeout when sending emails via SMTP.
### Implementation
- **WooEmailOverride**: Intercepts `wp_mail()` calls
- **MailQueue**: Queues emails via Action Scheduler
- **Async Processing**: Emails sent in background
### Files
- `includes/Core/Mail/WooEmailOverride.php`
- `includes/Core/Mail/MailQueue.php`
### Initialization
```php
// In Bootstrap.php
MailQueue::init();
WooEmailOverride::init();
```
---
## Key Classes
### NotificationManager
**File:** `includes/Core/Notifications/NotificationManager.php`
- `should_send_notification()` - Validates all toggles
- `send()` - Main sending method
- `is_channel_enabled()` - Check global channel state
- `is_event_channel_enabled()` - Check per-event state
### EmailManager
**File:** `includes/Core/Notifications/EmailManager.php`
- `is_enabled()` - Check if WooNooW system active
- `disable_wc_emails()` - Disable WooCommerce emails
- Hooks into WooCommerce order status changes
### EmailRenderer
**File:** `includes/Core/Notifications/EmailRenderer.php`
- `render()` - Render email from template
- `replace_variables()` - Replace variables with data
- `parse_cards()` - Parse markdown cards
- Applies email customization
### TemplateProvider
**File:** `includes/Core/Notifications/TemplateProvider.php`
- `get_template()` - Get custom or default template
- `get_variables()` - Get available variables
- `get_default_template()` - Get default template
---
## Global System Toggle
### Purpose
Allow users to switch between WooNooW and WooCommerce notification systems.
### Modes
**WooNooW Mode** (default):
- Custom templates with markdown
- Multi-channel support
- Full customization
- WooCommerce emails disabled
**WooCommerce Mode**:
- Standard WooCommerce emails
- WooNooW notifications disabled
- For users who prefer classic system
### Implementation
```php
// Check mode
$mode = get_option('woonoow_notification_system_mode', 'woonoow');
// EmailManager respects mode
if (!EmailManager::is_enabled()) {
return; // Skip WooNooW notifications
}
// NotificationManager checks mode
if ($system_mode !== 'woonoow') {
return false; // Use WooCommerce instead
}
```
---
## Q&A
### Q: Are templates saved and used when sending?
**A:** ✅ Yes. Templates saved via API are fetched by EmailRenderer and used when sending.
### Q: Are channel toggles respected?
**A:** ✅ Yes. NotificationManager checks both global and per-event toggles before sending.
### Q: Does the global system toggle work?
**A:** ✅ Yes. EmailManager and NotificationManager both check the mode before processing.
### Q: Is email sending async?
**A:** ✅ Yes. MailQueue queues emails via Action Scheduler to prevent timeouts.
### Q: Are variables replaced correctly?
**A:** ✅ Yes. EmailRenderer replaces all variables with actual data from orders/customers.
### Q: Does markdown parsing work?
**A:** ✅ Yes. Cards, buttons, and images are parsed correctly in both visual builder and email output.
---
## Related Documentation
- **NEW_MARKDOWN_SYNTAX.md** - Markdown syntax reference
- **NOTIFICATION_SYSTEM_QA.md** - Q&A and backend status
- **BACKEND_WIRING_COMPLETE.md** - Backend integration details
- **CUSTOM_EMAIL_SYSTEM.md** - Email system architecture
- **FILTER_HOOKS_GUIDE.md** - Available hooks for customization
---
## Future Enhancements
### Planned Features
- Activity Log page
- WhatsApp addon
- Telegram addon
- SMS addon
- A/B testing for templates
- Scheduled notifications
- Customer notification preferences page
### Addon Development
See **ADDON_DEVELOPMENT_GUIDE.md** for creating custom notification channels.

View File

@@ -1,201 +0,0 @@
# Notification System - Q&A
## Questions & Answers
### 1. **Why no toggle for Email/Push in Customer Channels?**
**Answer**: ✅ **FIXED!** Added toggles to Customer Channels.
**Implementation**:
- Added `Switch` component to Email and Push channels
- Added mutation to toggle channel enable/disable
- When disabled, customers won't see these options in their account page
**User Flow**:
```
Admin disables Email → Customer account page hides email notification preferences
Admin disables Push → Customer account page hides push notification preferences
```
---
### 2. **Flexibility: Optional Channels & WooCommerce Default Email**
**Answer**: ✅ **Excellent idea!** Here's the proposed implementation:
#### **A. Make All Channels Optional**
- ✅ Staff channels: Already have toggles
- ✅ Customer channels: Now have toggles (just added)
- Each channel can be completely disabled
#### **B. Global WooNooW Notification Toggle**
**Proposed Location**: `/settings/notifications` (main page)
**New Card**:
```
┌─────────────────────────────────────────┐
│ 🔔 Notification System │
│ │
│ ○ Use WooNooW Notifications (default) │
│ Modern notification system with │
│ multiple channels and templates │
│ │
│ ○ Use WooCommerce Default Emails │
│ Classic WooCommerce email system │
│ (WooNooW notifications disabled) │
│ │
│ [Save Changes] │
└─────────────────────────────────────────┘
```
**Behavior**:
- **When WooNooW is active**: WooCommerce default emails are disabled
- **When WooCommerce default is active**: WooNooW notifications are disabled
- Only one system can be active at a time
**Implementation Plan**:
1. Add global setting: `woonoow_notification_system` (values: `woonoow` | `woocommerce`)
2. Hook into WooCommerce email system:
- If `woonoow`: Disable WC emails, enable WooNooW
- If `woocommerce`: Enable WC emails, disable WooNooW
3. Add migration helper to switch between systems
---
### 3. **Backend Integration Status**
**Answer**: ⚠️ **Partially Wired**
#### **✅ Already Wired (Frontend → Backend)**:
1. **Channel Toggle**:
- Endpoint: `POST /notifications/channels/toggle`
- Payload: `{ channelId, enabled }`
- Used in: Staff/Customer Channels tabs
2. **Event Toggle**:
- Endpoint: `POST /notifications/events/update`
- Payload: `{ eventId, channelId, enabled, recipient }`
- Used in: Staff/Customer Events tabs
3. **Template Fetch**:
- Endpoint: `GET /notifications/templates/{eventId}/{channelId}?recipient={type}`
- Used in: EditTemplate page
4. **Template Save**:
- Endpoint: `POST /notifications/templates/save`
- Payload: `{ eventId, channelId, recipient, subject, body }`
- Used in: EditTemplate page
#### **❌ Not Yet Wired (Need Backend Implementation)**:
1. **Email Configuration**:
- Template Settings (colors, logo, branding)
- Connection Settings (SMTP override)
- **Status**: Frontend ready, backend needs implementation
2. **Push Configuration**:
- Template Settings (icon, badge, sound)
- Connection Settings (FCM/OneSignal)
- **Status**: Frontend ready, backend needs implementation
3. **Channel Configuration**:
- Global channel settings
- **Status**: Frontend ready, backend needs implementation
4. **Global Notification System Toggle**:
- Switch between WooNooW and WooCommerce
- **Status**: Not implemented (proposed above)
---
## Backend TODO List
### Priority 1: Core Functionality
- [ ] Implement Email Configuration endpoints
- `GET /notifications/email-settings`
- `POST /notifications/email-settings/save`
- [ ] Implement Push Configuration endpoints
- `GET /notifications/push-settings`
- `POST /notifications/push-settings/save`
- [ ] Add global notification system toggle
- `GET /notifications/system-mode`
- `POST /notifications/system-mode/set`
### Priority 2: Integration
- [ ] Hook into WooCommerce email system
- Disable WC emails when WooNooW is active
- Re-enable WC emails when switched back
- [ ] Customer account page integration
- Show/hide notification preferences based on enabled channels
- Save customer notification preferences
### Priority 3: Enhancement
- [ ] Activity Log endpoints
- `GET /notifications/activity-log`
- Track sent notifications
- [ ] Addon system for channels
- WhatsApp, Telegram, SMS integration points
---
## Recommended Next Steps
1. **Add Global Toggle** (High Priority)
- Implement the WooNooW vs WooCommerce toggle
- This gives users ultimate flexibility
2. **Wire Email Configuration** (Medium Priority)
- Connect frontend to backend for email branding
3. **Wire Push Configuration** (Low Priority)
- Can be done later, push is less critical
4. **Customer Account Integration** (High Priority)
- Show notification preferences based on enabled channels
- Let customers opt-in/opt-out per channel
---
## Architecture Summary
```
Frontend (React)
├── Notifications Main Page
│ └── [NEW] Global System Toggle (WooNooW vs WooCommerce)
├── Staff Notifications
│ ├── Channels (toggle on/off) ✅ Wired
│ └── Events (toggle + template edit) ✅ Wired
├── Customer Notifications
│ ├── Channels (toggle on/off) ✅ Just Added
│ └── Events (toggle + template edit) ✅ Wired
└── Channel Configuration
├── Email Config ⚠️ Frontend ready, backend needed
├── Push Config ⚠️ Frontend ready, backend needed
└── Addons (future)
Backend (PHP)
├── NotificationsController ✅ Partially implemented
├── TemplateProvider ✅ Implemented
├── EventRegistry ✅ Implemented
└── [NEEDED] ConfigurationController
├── Email settings
├── Push settings
└── Global system toggle
```
---
## Summary
**What's Working**:
- ✅ Channel enable/disable (Staff & Customer)
- ✅ Event enable/disable with template editing
- ✅ Template editor with markdown support
- ✅ Variable system
**What's Needed**:
- ⚠️ Backend for Email/Push configuration
- ⚠️ Global system toggle (WooNooW vs WooCommerce)
- ⚠️ Customer account page integration
**Recommendation**: Implement the global toggle first, as it provides the ultimate flexibility you want!

View File

@@ -1,206 +0,0 @@
# 🎯 THE REAL ROOT CAUSE - Recipient Type Missing from API
## 🔴 What You Discovered
You noticed the API URL was:
```
https://woonoow.local/wp-json/woonoow/v1/notifications/templates/order_placed/email
```
**NO `recipient` parameter!**
This means:
- Customer page → `order_placed` → Gets **STAFF** template ❌
- Staff page → `order_placed` → Gets **STAFF** template ✅
**The API couldn't distinguish between customer and staff templates!**
---
## 🔍 The Architecture Flaw
### **Before (BROKEN):**
```
URL Format: /templates/{event_id}/{channel_id}
Storage Key: {event_id}_{channel_id}
Problem: Same key for both customer AND staff!
- order_placed_email → STAFF template
- order_placed_email → CUSTOMER template (OVERWRITTEN!)
```
### **After (FIXED):**
```
URL Format: /templates/{event_id}/{channel_id}?recipient={recipient_type}
Storage Key: {recipient_type}_{event_id}_{channel_id}
Solution: Unique keys for each recipient!
- staff_order_placed_email → STAFF template ✅
- customer_order_placed_email → CUSTOMER template ✅
```
---
## 📝 All Changes Made
### **1. Frontend - Templates.tsx**
**File:** `admin-spa/src/routes/Settings/Notifications/Templates.tsx`
**Line:** 63
**Change:** Pass `recipient` parameter when navigating to editor
```typescript
// BEFORE:
navigate(`/settings/notifications/edit-template?event=${event.id}&channel=${channel.id}`);
// AFTER:
navigate(`/settings/notifications/edit-template?event=${event.id}&channel=${channel.id}&recipient=${recipientType}`);
```
---
### **2. Frontend - EditTemplate.tsx**
**File:** `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`
**Lines:** 34, 55, 141, 159
**Changes:**
1. Read `recipient` from URL
2. Pass to API GET request
3. Pass to API PUT request
4. Pass to API DELETE request
```typescript
// Read recipient type
const recipientType = searchParams.get('recipient') || 'customer';
// Fetch template WITH recipient
const response = await api.get(`/notifications/templates/${eventId}/${channelId}?recipient=${recipientType}`);
// Save template WITH recipient
await api.put(`/notifications/templates/${eventId}/${channelId}?recipient=${recipientType}`, {...});
// Delete template WITH recipient
await api.del(`/notifications/templates/${eventId}/${channelId}?recipient=${recipientType}`);
```
---
### **3. Backend - NotificationsController.php**
**File:** `includes/Api/NotificationsController.php`
**Lines:** 587, 589, 638, 649, 674, 676
**Changes:** Accept `recipient` parameter and pass to TemplateProvider
```php
// Get template
$recipient_type = $request->get_param('recipient') ?? 'customer';
$template = TemplateProvider::get_template($event_id, $channel_id, $recipient_type);
// Save template
$recipient_type = $request->get_param('recipient') ?? 'customer';
$result = TemplateProvider::save_template($event_id, $channel_id, $template, $recipient_type);
// Delete template
$recipient_type = $request->get_param('recipient') ?? 'customer';
TemplateProvider::delete_template($event_id, $channel_id, $recipient_type);
```
---
### **4. Backend - TemplateProvider.php**
**File:** `includes/Core/Notifications/TemplateProvider.php`
**Lines:** 41, 44, 64, 67, 90, 93, 154
**Changes:** Use `{recipient_type}_{event_id}_{channel_id}` as storage key
```php
// Get template
public static function get_template($event_id, $channel_id, $recipient_type = 'customer') {
$key = "{$recipient_type}_{$event_id}_{channel_id}";
// ...
}
// Save template
public static function save_template($event_id, $channel_id, $template, $recipient_type = 'customer') {
$key = "{$recipient_type}_{$event_id}_{channel_id}";
// ...
}
// Delete template
public static function delete_template($event_id, $channel_id, $recipient_type = 'customer') {
$key = "{$recipient_type}_{$event_id}_{channel_id}";
// ...
}
// Default templates
$templates["{$recipient_type}_{$event_id}_email"] = [...];
```
---
## 🎯 Why This Fixes Everything
### **Issue #1: Customer showing 7 templates instead of 9**
**Root Cause:** API was fetching staff templates for customer page
**Fix:** Now API knows to fetch customer templates when on customer page
### **Issue #2: Loading staff template for customer event**
**Root Cause:** Same storage key for both staff and customer
**Fix:** Unique keys: `staff_order_placed_email` vs `customer_order_placed_email`
### **Issue #3: Saving overwrites wrong template**
**Root Cause:** Saving to same key regardless of recipient
**Fix:** Saves to correct recipient-specific key
---
## 📊 Data Flow (Now Correct!)
### **Customer Page → Order Placed:**
```
1. User clicks "Edit" on Customer Notifications page
2. URL: /edit-template?event=order_placed&channel=email&recipient=customer
3. API: GET /templates/order_placed/email?recipient=customer
4. Key: customer_order_placed_email
5. Returns: CUSTOMER template ✅
```
### **Staff Page → Order Placed:**
```
1. User clicks "Edit" on Staff Notifications page
2. URL: /edit-template?event=order_placed&channel=email&recipient=staff
3. API: GET /templates/order_placed/email?recipient=staff
4. Key: staff_order_placed_email
5. Returns: STAFF template ✅
```
---
## 🧪 Testing Steps
1. **Stop dev server:** Ctrl+C
2. **Restart:** `npm run dev`
3. **Hard refresh:** Cmd+Shift+R
4. **Test Customer Page:**
- Go to Customer Notifications
- Click "Order Placed" → Should show customer template
- Subject should be customer-facing
5. **Test Staff Page:**
- Go to Staff Notifications
- Click "Order Placed" → Should show staff template
- Subject should be staff-facing
---
## 🎉 Summary
**The Problem:** API had no way to distinguish between customer and staff templates
**The Solution:**
1. Pass `recipient` parameter in URL
2. Use `{recipient_type}_{event_id}_{channel_id}` as storage key
3. Update all API calls to include recipient type
**Files Changed:**
- ✅ Templates.tsx (pass recipient when navigating)
- ✅ EditTemplate.tsx (read recipient, pass to API)
- ✅ NotificationsController.php (accept recipient parameter)
- ✅ TemplateProvider.php (use recipient in storage keys)
**Result:** Customer and staff templates are now completely separate! 🎊

View File

@@ -1,162 +0,0 @@
# Single Source of Truth - Event Registry
## Problem Solved
Previously, events were hardcoded in multiple places:
-`NotificationsController.php` - hardcoded 9 events
-`TemplateProvider.php` - hardcoded 9 events
-`DefaultTemplates.php` - had 15 templates (8 customer + 7 staff)
**Result:** Mismatches, confusion, missing templates
## Solution: EventRegistry
Created `/includes/Core/Notifications/EventRegistry.php` as the **SINGLE SOURCE OF TRUTH**.
### How It Works
```php
// Get all events
$events = EventRegistry::get_all_events();
// Get by recipient
$staff_events = EventRegistry::get_events_by_recipient('staff');
$customer_events = EventRegistry::get_events_by_recipient('customer');
// Get by category
$order_events = EventRegistry::get_events_by_category('orders');
// Check if exists
if (EventRegistry::event_exists('order_placed', 'staff')) {
// ...
}
```
### Current Event List
**Staff Events (7):**
1. `order_placed` - New order notification
2. `order_processing` - Order confirmed, ready to process
3. `order_shipped` - Order shipped
4. `order_completed` - Order completed
5. `order_cancelled` - Order cancelled
6. `payment_received` - Payment confirmed
7. `payment_failed` - Payment failed
**Customer Events (8):**
1. `order_placed` - Order placed confirmation
2. `order_processing` - Order being processed
3. `order_shipped` - Order shipped with tracking
4. `order_completed` - Order delivered
5. `order_cancelled` - Order cancelled
6. `payment_received` - Payment confirmed
7. `payment_failed` - Payment failed, retry
8. `new_customer` - Welcome email
**Total: 15 events** (7 staff + 8 customer)
### Filter Hook
```php
add_filter('woonoow_notification_events_registry', function($events) {
// Add custom event
$events['custom_event'] = [
'id' => 'custom_event',
'label' => 'Custom Event',
'description' => 'My custom notification',
'category' => 'custom',
'recipient_type' => 'customer',
'wc_email' => '',
'enabled' => true,
];
return $events;
});
```
## Components Updated
### 1. NotificationsController.php
```php
// OLD - Hardcoded
$events = [
'orders' => [
['id' => 'order_placed', ...],
// ... 100+ lines
]
];
// NEW - Uses Registry
$all_events = EventRegistry::get_all_events();
foreach ($all_events as $event) {
// Group by category
}
```
### 2. TemplateProvider.php
```php
// OLD - Hardcoded
$events = [
'order_placed' => 'staff',
'order_processing' => 'customer',
// ...
];
// NEW - Uses Registry
$all_events = EventRegistry::get_all_events();
foreach ($all_events as $event) {
$event_id = $event['id'];
$recipient_type = $event['recipient_type'];
// Generate templates
}
```
### 3. DefaultTemplates.php
**No changes needed** - Already has all 15 templates matching the registry!
## Benefits
**Single source of truth** - One place to add/remove events
**No hardcoding** - All components query the registry
**Extensible** - Filter hook for custom events
**Type-safe** - Consistent event structure
**No mismatches** - Events and templates always aligned
**Easy maintenance** - Add event once, works everywhere
## Adding New Events
1. **Add to EventRegistry.php:**
```php
'low_stock' => [
'id' => 'low_stock',
'label' => __('Low Stock Alert', 'woonoow'),
'description' => __('When product stock is low', 'woonoow'),
'category' => 'products',
'recipient_type' => 'staff',
'wc_email' => 'low_stock',
'enabled' => true,
],
```
2. **Add template to DefaultTemplates.php:**
```php
'staff' => [
// ...
'low_stock' => self::staff_low_stock(),
],
private static function staff_low_stock() {
return '[card type="warning"]...';
}
```
3. **Done!** API and UI automatically show the new event.
## Testing
After refresh:
- ✅ Events API returns 15 events (7 staff + 8 customer)
- ✅ Templates API returns 15 templates
- ✅ UI shows correct counts
- ✅ All templates load without errors
- ✅ No hardcoded lists anywhere

View File

@@ -1,226 +0,0 @@
# ✅ ALL TEMPLATES POLISHED! 🚀
## COMPLETE! All 17 Templates Updated!
---
## What Was Done
### ✅ 1. Added Proper Headings
- **Hero/Success/Warning cards**: `##` (H2) for main titles
- **Welcome card**: `#` (H1) for special welcome
- All first lines in important cards now have headings
### ✅ 2. Clean Footers
- **Customer templates**: Wrapped support text in `[card type="basic"]`
- **Staff templates**: Removed footers entirely (no support contact needed)
- **All templates**: Removed `© {current_year} {site_name}` (handled by global footer)
### ✅ 3. Removed Separators
- Removed all `---` horizontal rules before footers
- Cleaner, more modern look
---
## Templates Updated (17 Total)
### Customer Templates (9):
1.**customer_order_placed** - `## Thank you for your order, {customer_name}!`
2.**customer_order_confirmed** - `## Great news, {customer_name}!`
3.**customer_order_shipped** - `## Your order #{order_number} has shipped!`
4.**customer_order_completed** - `## Your order #{order_number} has arrived!`
5.**customer_order_cancelled** - `## Your order #{order_number} has been cancelled.`
6.**customer_payment_received** - `## Payment confirmed!`
7.**customer_payment_failed** - `## Payment could not be processed`
8.**customer_registered** - `# Welcome to {site_name}, {customer_name}!`
9.**customer_vip_upgraded** - `## Congratulations, {customer_name}!`
### Staff Templates (8):
10.**staff_order_placed** - `# New order received!`
11.**staff_order_confirmed** - `## Order confirmed and ready to process`
12.**staff_order_shipped** - `## Order shipped`
13.**staff_order_completed** - `## Order completed`
14.**staff_order_cancelled** - `## Order cancelled`
15.**staff_payment_received** - `## Payment received`
16.**staff_payment_failed** - `## Payment failed`
---
## Before vs After Examples
### Customer Template:
```markdown
// BEFORE:
[card type="hero"]
Thank you for your order, {customer_name}!
We've received your order...
[/card]
---
Need help? Contact us: {support_email}
© {current_year} {site_name}
// AFTER:
[card type="hero"]
## Thank you for your order, {customer_name}!
We've received your order...
[/card]
[card type="basic"]
Need help? Contact us: {support_email}
[/card]
```
### Staff Template:
```markdown
// BEFORE:
[card type="hero"]
New order received!
A customer has placed...
[/card]
---
WooNooW Order Management
© {current_year} {site_name}
// AFTER:
[card type="hero"]
# New order received!
A customer has placed...
[/card]
```
---
## Heading Hierarchy
| Card Type | Heading Level | Example |
|-----------|---------------|---------|
| Hero (Customer) | `##` (H2) | `## Thank you for your order!` |
| Hero (Staff) | `#` (H1) | `# New order received!` |
| Success | `##` (H2) | `## Great news!` |
| Warning | `##` (H2) | `## Payment could not be processed` |
| Welcome | `#` (H1) | `# Welcome to {site_name}!` |
---
## Footer Strategy
### Customer Templates:
```markdown
[card type="basic"]
Need help? Contact {support_email}
[/card]
```
- Plain text section
- No styling
- Support contact included
- No copyright (global footer handles it)
### Staff Templates:
```markdown
(No footer)
```
- Staff doesn't need support contact
- Cleaner, more professional
- Focus on action items
---
## Benefits
### ✅ Better Typography:
- Clear visual hierarchy
- Proper heading sizes
- More professional appearance
### ✅ Cleaner Structure:
- No redundant separators
- Consistent footer pattern
- Better readability
### ✅ No Content Loss:
- All content wrapped in cards
- Basic card type for plain text
- Everything preserved
### ✅ Mobile Friendly:
- Headings scale properly
- Better responsive design
- Easier to scan
---
## What's Next
### Test It! 🧪
1. **Hard refresh** browser (Cmd+Shift+R)
2. Go to **Settings → Notifications → Staff/Customer → Templates**
3. Open any template
4. ✅ See proper headings
5. ✅ See clean footers
6. ✅ No copyright lines
7. ✅ All content preserved
### Expected Results:
**Visual Builder:**
- ✅ All cards display
- ✅ Headings are bold and larger
- ✅ Footer in basic card (customer) or no footer (staff)
**Preview:**
- ✅ Beautiful typography
- ✅ Clear hierarchy
- ✅ Professional appearance
- ✅ Proper spacing
**Code Mode:**
- ✅ Clean markdown
- ✅ Proper heading syntax
- ✅ Basic card for footers
---
## Summary
| Item | Status |
|------|--------|
| Headings added | ✅ 17/17 |
| Footers cleaned | ✅ 17/17 |
| Copyright removed | ✅ 17/17 |
| Basic cards added | ✅ 9/9 customer |
| Staff footers removed | ✅ 8/8 staff |
| Newline parsing | ✅ Fixed |
| Basic card type | ✅ Added |
---
## Files Modified
1.`markdown-utils.ts` - Fixed newline parsing
2.`types.ts` - Added 'basic' card type
3.`EmailBuilder.tsx` - Added basic to selector
4.`EditTemplate.tsx` - Added CSS for basic cards
5.`DefaultTemplates.php` - **ALL 17 templates polished!**
---
**🎉 COMPLETE! All templates are now polished and production-ready! 🚀**
**Time to test and ship!**

View File

@@ -1,128 +0,0 @@
# Template Source of Truth
## Single Source of Truth: `/includes/Email/DefaultTemplates.php`
This file contains **clean markdown templates** without HTML tags inside shortcodes.
### Structure
```php
namespace WooNooW\Email;
class DefaultTemplates {
public static function get_all_templates() {
return [
'customer' => [
'order_placed' => '...',
'order_confirmed' => '...',
'order_shipped' => '...',
'order_completed' => '...',
'order_cancelled' => '...',
'payment_received' => '...',
'payment_failed' => '...',
'registered' => '...',
'vip_upgraded' => '...',
],
'staff' => [
'order_placed' => '...',
'order_confirmed' => '...',
'order_shipped' => '...',
'order_completed' => '...',
'order_cancelled' => '...',
'payment_received' => '...',
'payment_failed' => '...',
],
];
}
public static function get_default_subject($recipient, $event) {
// Returns subject string
}
}
```
### Template Format
Templates use **clean markdown** inside `[card]` shortcodes:
```markdown
[card type="hero"]
## Thank you for your order, {customer_name}!
We've received your order and will begin processing it right away.
[/card]
[card]
**Order Number:** #{order_number}
**Order Date:** {order_date}
**Order Total:** {order_total}
[/card]
[button url="{order_url}"]View Order Details[/button]
```
**NOT** HTML like this:
```html
[card type="hero"]
<h1>Thank you for your order, {customer_name}!</h1>
<p>We've received your order...</p>
[/card]
```
## How It's Used
### TemplateProvider.php
`/includes/Core/Notifications/TemplateProvider.php` uses the Email templates:
```php
use WooNooW\Email\DefaultTemplates as EmailDefaultTemplates;
// Get all templates
$allEmailTemplates = EmailDefaultTemplates::get_all_templates();
// Get specific template
$body = $allEmailTemplates[$recipient_type][$template_name];
$subject = EmailDefaultTemplates::get_default_subject($recipient_type, $template_name);
```
### Event ID Mapping
API event IDs are mapped to template names:
| API Event ID | Template Name |
|-------------|---------------|
| `order_processing` | `order_confirmed` |
| `new_customer` | `registered` |
| Others | Same name |
## Deprecated Files
### `/includes/Core/Notifications/DefaultEmailTemplates.php` ❌
**DO NOT USE** - This file contains old templates with HTML tags inside shortcodes.
It's kept for backwards compatibility only and is marked as deprecated.
## Frontend Conversion
When templates are loaded in the editor:
1. **Database** stores HTML (for backwards compatibility)
2. **converter.ts** converts HTML to clean markdown using `convertHtmlToMarkdown()`
3. **CodeEditor** displays clean markdown
4. **User edits** in markdown
5. **Saves** back as HTML (via blocks → HTML conversion)
This ensures smooth editing experience while maintaining compatibility.
## Benefits
**Clean markdown editing** - No HTML tags in markdown mode
**Single source of truth** - One place to update templates
**Better UX** - Markdown toolbar and syntax highlighting
**Mobile-friendly** - Easy to type on any device
**Maintainable** - Clear separation of concerns

View File

@@ -1,259 +0,0 @@
# Template Update Script
## Changes to Make in DefaultTemplates.php
For ALL templates, replace the footer pattern:
### Pattern to Find:
```
---
[Any text with {support_email} or similar]
© {current_year} {site_name}
```
### Replace With:
```
[card type="basic"]
[Same text with {support_email}]
[/card]
```
### Remove:
- All instances of `© {current_year} {site_name}` (already in global footer)
- All instances of standalone `---` before footer text
## Specific Updates:
### Customer Templates:
1. **customer_order_placed** (line 138-141):
```php
// OLD:
---
Need help? Contact us: {support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Need help? Contact us: {support_email}
[/card]';
```
2. **customer_order_confirmed** (line 180-183):
```php
// OLD:
---
Questions? We\'re here to help: {support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Questions? We\'re here to help: {support_email}
[/card]';
```
3. **customer_order_shipped** (line 222-225):
```php
// OLD:
---
Need assistance? Contact {support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Need assistance? Contact {support_email}
[/card]';
```
4. **customer_order_completed** (line 262-267):
```php
// OLD:
---
Questions or issues with your order? We\'re here to help.
{support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Questions or issues with your order? We\'re here to help.
Contact: {support_email}
[/card]';
```
5. **customer_order_cancelled** (line 309-311):
```php
// OLD:
---
© {current_year} {site_name}';
// NEW:
';
// (Just remove the footer entirely - no support text here)
```
6. **customer_payment_received** (line 349-351):
```php
// OLD:
---
© {current_year} {site_name}';
// NEW:
';
// (Just remove)
```
7. **customer_payment_failed** (line 398-400):
```php
// OLD:
---
© {current_year} {site_name}';
// NEW:
';
// (Already has support text in card, just remove footer)
```
8. **customer_registered** (line 436-439):
```php
// OLD:
---
Need help? Contact {support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Need help? Contact {support_email}
[/card]';
```
9. **customer_vip_upgraded** (line 473-476):
```php
// OLD:
---
Questions? {support_email}
© {current_year} {site_name}';
// NEW:
[card type="basic"]
Questions? {support_email}
[/card]';
```
### Staff Templates:
10. **staff_order_placed** (line 535-538):
```php
// OLD:
---
WooNooW Order Management
© {current_year} {site_name}';
// NEW:
';
// (Remove - staff doesn't need this footer)
```
11. **staff_order_confirmed** (line 582-585):
```php
// OLD:
---
WooNooW Order Management
© {current_year} {site_name}';
// NEW:
';
```
12. **staff_order_shipped** (line 618-621):
```php
// OLD:
---
WooNooW Order Management
© {current_year} {site_name}';
// NEW:
';
```
13. **staff_order_completed** (line 664-667):
```php
// OLD:
---
WooNooW Order Management
© {current_year} {site_name}';
// NEW:
';
```
14. **staff_order_cancelled** (line 716-719):
```php
// OLD:
---
WooNooW Order Management
© {current_year} {site_name}';
// NEW:
';
```
15. **staff_payment_received** (line 763-766):
```php
// OLD:
---
WooNooW Payment Management
© {current_year} {site_name}';
// NEW:
';
```
16. **staff_payment_failed** (line 809-812):
```php
// OLD:
---
WooNooW Payment Management
© {current_year} {site_name}';
// NEW:
';
```
## Summary:
- **Customer templates**: Wrap support text in `[card type="basic"]`, remove copyright
- **Staff templates**: Remove footer entirely (they don't need support contact)
- **All templates**: Remove `© {current_year} {site_name}` (handled by global footer)