-```
-
-#### Trust Badges:
-```tsx
-// BEFORE:
-
-
Free Shipping
-
On orders over $50
-
-
-// AFTER:
-
-
Free Shipping
-
On orders over $50
-
-```
-
-**Benefits:**
-- โ
No horizontal scroll on mobile
-- โ
Text truncates gracefully
-- โ
Proper flex layout
-- โ
Smaller text on mobile (text-xs)
-
----
-
-### 4. โ
Image Height Override (!h-full)
-
-**What Was Required:**
-- Override WooCommerce default image styles
-- Ensure consistent image heights
-
-**What Was Fixed:**
-```tsx
-// Applied to ALL images:
-className="w-full !h-full object-cover"
-
-// Locations:
-1. Main product image
-2. Thumbnail images
-3. Empty state placeholder
-```
-
-**Benefits:**
-- โ
Overrides WooCommerce CSS
-- โ
Consistent aspect ratios
-- โ
No layout shift
-- โ
Proper image display
-
----
-
-## ๐ Before vs After Comparison
-
-### Layout Structure:
-
-**BEFORE (WooCommerce Clone):**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Image Gallery โ
-โ Product Info โ
-โ โ
-โ [Description] [Additional] [Reviews]โ โ Horizontal Tabs (27% overlook)
-โ โโโโโโโโโโโโโ โ
-โ Content here... โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**AFTER (Research-Backed):**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Image Gallery (larger thumbnails) โ
-โ Product Info (prominent price) โ
-โ Trust Badges (shipping, returns) โ
-โ โ
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โ โ โผ Product Description โ โ โ Vertical Sections (8% overlook)
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โ โ โผ Specifications (scannable) โ โ
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โ โ โผ Customer Reviews โ โ
-โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
----
-
-## ๐ฏ Research Compliance Checklist
-
-### From PRODUCT_PAGE_SOP.md:
-
-- [x] **Avoid Horizontal Tabs** - Now using vertical sections
-- [x] **Scannable Table** - Specifications have clear visual hierarchy
-- [x] **Mobile-First** - Fixed width overflow issues
-- [x] **Prominent Price** - 4xl-5xl font size in highlighted box
-- [x] **Trust Badges** - Free shipping, returns, secure checkout
-- [x] **Stock Status** - Large badge with icon
-- [x] **Larger Thumbnails** - 96-112px (was 80px)
-- [x] **Sale Badge** - Floating on image
-- [x] **Image Override** - !h-full on all images
-
----
-
-## ๐ฑ Mobile Optimizations Applied
-
-1. **Responsive Text:**
- - Trust badges: `text-xs` on mobile
- - Price: `text-4xl md:text-5xl`
- - Title: `text-2xl md:text-3xl`
-
-2. **Overflow Prevention:**
- - Thumbnail slider: `w-full overflow-hidden`
- - Trust badges: `min-w-0 flex-1 truncate`
- - Tables: Proper padding and spacing
-
-3. **Touch Targets:**
- - Quantity buttons: `p-3` (larger)
- - Collapsible sections: `p-5` (full width)
- - Add to Cart: `h-14` (prominent)
-
----
-
-## ๐ Performance Impact
-
-### User Experience:
-- **27% โ 8%** content overlook rate (tabs โ vertical)
-- **Faster scanning** with visual hierarchy
-- **Better mobile UX** with no overflow
-- **Higher conversion** with prominent CTAs
-
-### Technical:
-- โ
No layout shift
-- โ
Smooth animations
-- โ
Proper responsive breakpoints
-- โ
Accessible collapsible sections
-
----
-
-## ๐ Key Takeaways
-
-### What We Learned:
-1. **Research > Assumptions** - Following Baymard Institute data beats copying WooCommerce
-2. **Vertical > Horizontal** - 3x better visibility for vertical sections
-3. **Mobile Constraints** - Always test for overflow on small screens
-4. **Visual Hierarchy** - Scannable tables beat plain tables
-
-### What Makes This Different:
-- โ Not a WooCommerce clone
-- โ
Research-backed design decisions
-- โ
Industry best practices
-- โ
Conversion-optimized layout
-- โ
Mobile-first approach
-
----
-
-## ๐ Result
-
-A product page that:
-- Follows Baymard Institute 2025 UX research
-- Reduces content overlook from 27% to 8%
-- Works perfectly on mobile (no overflow)
-- Has clear visual hierarchy
-- Prioritizes conversion elements
-- Overrides WooCommerce styles properly
-
-**Status:** โ
Research-Compliant | โ
Mobile-Optimized | โ
Conversion-Focused
diff --git a/PRODUCT_PAGE_SOP.md b/PRODUCT_PAGE_SOP.md
deleted file mode 100644
index 6c35f40..0000000
--- a/PRODUCT_PAGE_SOP.md
+++ /dev/null
@@ -1,436 +0,0 @@
-# Product Page Design SOP - Industry Best Practices
-
-**Document Version:** 1.0
-**Last Updated:** November 26, 2025
-**Purpose:** Guide for building industry-standard product pages in Customer SPA
-
----
-
-## ๐ Executive Summary
-
-This SOP consolidates research-backed best practices for e-commerce product pages based on Baymard Institute's 2025 UX research and industry standards. Since Customer SPA is not fully customizable by end-users, we must implement the best practices as defaults.
-
----
-
-## ๐ฏ Core Principles
-
-1. **Avoid Horizontal Tabs** - 27% of users overlook horizontal tabs entirely
-2. **Vertical Collapsed Sections** - Only 8% overlook content (vs 27% for tabs)
-3. **Images Are Critical** - After images, reviews are the most important content
-4. **Trust & Social Proof** - Essential for conversion
-5. **Mobile-First** - But optimize desktop experience separately
-
----
-
-## ๐ Layout Structure (Priority Order)
-
-### 1. **Hero Section** (Above the Fold)
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Breadcrumb โ
-โโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ โ Product Title โ
-โ Product โ Price (with sale) โ
-โ Images โ Rating & Reviews Count โ
-โ Gallery โ Stock Status โ
-โ โ Short Description โ
-โ โ Variations Selector โ
-โ โ Quantity โ
-โ โ Add to Cart Button โ
-โ โ Wishlist/Save โ
-โ โ Trust Badges โ
-โโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-### 2. **Product Information** (Below the Fold - Vertical Sections)
-- โ
Full Description (expandable)
-- โ
Specifications/Attributes (scannable table)
-- โ
Shipping & Returns Info
-- โ
Size Guide (if applicable)
-- โ
Reviews Section
-- โ
Related Products
-- โ
Recently Viewed
-
----
-
-## ๐ผ๏ธ Image Gallery Requirements
-
-### Must-Have Features:
-1. **Main Image Display**
- - Large, zoomable image
- - High resolution (min 1200px width)
- - Aspect ratio: 1:1 or 4:3
-
-2. **Thumbnail Slider**
- - Horizontal scrollable
- - 4-6 visible thumbnails
- - Active thumbnail highlighted
- - Arrow navigation for >4 images
- - Touch/swipe enabled on mobile
-
-3. **Image Types Required:**
- - โ
Product on white background (default)
- - โ
"In Scale" images (with reference object/person)
- - โ
"Human Model" images (for wearables)
- - โ
Lifestyle/context images
- - โ
Detail shots (close-ups)
- - โ
360ยฐ view (optional but recommended)
-
-4. **Variation Images:**
- - Each variation should have its own image
- - Auto-switch main image when variation selected
- - Variation image highlighted in thumbnail slider
-
-### Image Gallery Interaction:
-```javascript
-// User Flow:
-1. Click thumbnail โ Change main image
-2. Select variation โ Auto-switch to variation image
-3. Click main image โ Open lightbox/zoom
-4. Swipe thumbnails โ Scroll horizontally
-5. Hover thumbnail โ Preview in main (desktop)
-```
-
----
-
-## ๐ Buy Section Elements
-
-### Required Elements (in order):
-1. **Product Title** - H1, clear, descriptive
-2. **Price Display:**
- - Regular price (strikethrough if on sale)
- - Sale price (highlighted in red/primary)
- - Savings amount/percentage
- - Unit price (for bulk items)
-
-3. **Rating & Reviews:**
- - Star rating (visual)
- - Number of reviews (clickable โ scroll to reviews)
- - "Write a Review" link
-
-4. **Stock Status:**
- - โ
In Stock (green)
- - โ ๏ธ Low Stock (orange, show quantity)
- - โ Out of Stock (red, "Notify Me" option)
-
-5. **Variation Selector:**
- - Dropdown for each attribute
- - Visual swatches for colors
- - Size chart link (for apparel)
- - Clear labels
- - Disabled options grayed out
-
-6. **Quantity Selector:**
- - Plus/minus buttons
- - Number input
- - Min/max validation
- - Bulk pricing info (if applicable)
-
-7. **Action Buttons:**
- - **Primary:** Add to Cart (large, prominent)
- - **Secondary:** Buy Now (optional)
- - **Tertiary:** Add to Wishlist/Save for Later
-
-8. **Trust Elements:**
- - Security badges (SSL, payment methods)
- - Free shipping threshold
- - Return policy summary
- - Warranty info
-
----
-
-## ๐ Product Information Sections
-
-### 1. Description Section
-```
-Format: Vertical collapsed/expandable
-- Short description (2-3 sentences) always visible
-- Full description expandable
-- Rich text formatting
-- Bullet points for features
-- Video embed support
-```
-
-### 2. Specifications/Attributes
-```
-Format: Scannable table
-- Two-column layout (Label | Value)
-- Grouped by category
-- Tooltips for technical terms
-- Expandable for long lists
-- Copy-to-clipboard for specs
-```
-
-### 3. Shipping & Returns
-```
-Always visible near buy section:
-- Estimated delivery date
-- Shipping cost calculator
-- Return policy link
-- Free shipping threshold
-- International shipping info
-```
-
-### 4. Size Guide (Apparel/Footwear)
-```
-- Modal/drawer popup
-- Size chart table
-- Measurement instructions
-- Fit guide (slim, regular, loose)
-- Model measurements
-```
-
----
-
-## โญ Reviews Section
-
-### Must-Have Features:
-1. **Review Summary:**
- - Overall rating (large)
- - Rating distribution (5-star breakdown)
- - Total review count
- - Verified purchase badge
-
-2. **Review Filters:**
- - Sort by: Most Recent, Highest Rating, Lowest Rating, Most Helpful
- - Filter by: Rating (1-5 stars), Verified Purchase, With Photos
-
-3. **Individual Review Display:**
- - Reviewer name (or anonymous)
- - Rating (stars)
- - Date
- - Verified purchase badge
- - Review text
- - Helpful votes (thumbs up/down)
- - Seller response (if any)
- - Review images (clickable gallery)
-
-4. **Review Submission:**
- - Star rating (required)
- - Title (optional)
- - Review text (required, min 50 chars)
- - Photo upload (optional)
- - Recommend product (yes/no)
- - Fit guide (for apparel)
-
-5. **Review Images Gallery:**
- - Navigate all customer photos
- - Filter reviews by "with photos"
- - Lightbox view
-
----
-
-## ๐ Promotions & Offers
-
-### Display Locations:
-1. **Product Badge** (on image)
- - "Sale" / "New" / "Limited"
- - Percentage off
- - Free shipping
-
-2. **Price Section:**
- - Coupon code field
- - Auto-apply available coupons
- - Bulk discount tiers
- - Member pricing
-
-3. **Sticky Banner** (optional):
- - Site-wide promotions
- - Flash sales countdown
- - Free shipping threshold
-
-### Coupon Integration:
-```
-- Auto-detect applicable coupons
-- One-click apply
-- Show savings in cart preview
-- Stackable coupons indicator
-```
-
----
-
-## ๐ Trust & Social Proof Elements
-
-### 1. Trust Badges (Near Add to Cart):
-- Payment security (SSL, PCI)
-- Payment methods accepted
-- Money-back guarantee
-- Secure checkout badge
-
-### 2. Social Proof:
-- "X people viewing this now"
-- "X sold in last 24 hours"
-- "X people added to cart today"
-- Customer photos/UGC
-- Influencer endorsements
-
-### 3. Credibility Indicators:
-- Brand certifications
-- Awards & recognition
-- Press mentions
-- Expert reviews
-
----
-
-## ๐ฑ Mobile Optimization
-
-### Mobile-Specific Considerations:
-1. **Image Gallery:**
- - Swipeable main image
- - Thumbnail strip below (horizontal scroll)
- - Pinch to zoom
-
-2. **Sticky Add to Cart:**
- - Fixed bottom bar
- - Price + Add to Cart always visible
- - Collapse on scroll down, expand on scroll up
-
-3. **Collapsed Sections:**
- - All info sections collapsed by default
- - Tap to expand
- - Smooth animations
-
-4. **Touch Targets:**
- - Min 44x44px for buttons
- - Adequate spacing between elements
- - Large, thumb-friendly controls
-
----
-
-## ๐จ Visual Design Guidelines
-
-### Typography:
-- **Product Title:** 28-32px, bold
-- **Price:** 24-28px, bold
-- **Body Text:** 14-16px
-- **Labels:** 12-14px, medium weight
-
-### Colors:
-- **Primary CTA:** High contrast, brand color
-- **Sale Price:** Red (#DC2626) or brand accent
-- **Success:** Green (#10B981)
-- **Warning:** Orange (#F59E0B)
-- **Error:** Red (#EF4444)
-
-### Spacing:
-- Section padding: 24-32px
-- Element spacing: 12-16px
-- Button padding: 12px 24px
-
----
-
-## ๐ Interaction Patterns
-
-### 1. Variation Selection:
-```javascript
-// When user selects variation:
-1. Update price
-2. Update stock status
-3. Switch main image
-4. Update SKU
-5. Highlight variation image in gallery
-6. Enable/disable Add to Cart
-```
-
-### 2. Add to Cart:
-```javascript
-// On Add to Cart click:
-1. Validate selection (all variations selected)
-2. Show loading state
-3. Add to cart (API call)
-4. Show success toast with cart preview
-5. Update cart count in header
-6. Offer "View Cart" or "Continue Shopping"
-```
-
-### 3. Image Gallery:
-```javascript
-// Image interactions:
-1. Click thumbnail โ Change main image
-2. Click main image โ Open lightbox
-3. Swipe main image โ Next/prev image
-4. Hover thumbnail โ Preview (desktop)
-```
-
----
-
-## ๐ Performance Metrics
-
-### Key Metrics to Track:
-- Time to First Contentful Paint (< 1.5s)
-- Largest Contentful Paint (< 2.5s)
-- Image load time (< 1s)
-- Add to Cart conversion rate
-- Bounce rate
-- Time on page
-- Scroll depth
-
----
-
-## โ
Implementation Checklist
-
-### Phase 1: Core Features (MVP)
-- [ ] Responsive image gallery with thumbnails
-- [ ] Horizontal scrollable thumbnail slider
-- [ ] Variation selector with image switching
-- [ ] Price display with sale pricing
-- [ ] Stock status indicator
-- [ ] Quantity selector
-- [ ] Add to Cart button
-- [ ] Product description (expandable)
-- [ ] Specifications table
-- [ ] Breadcrumb navigation
-
-### Phase 2: Enhanced Features
-- [ ] Reviews section with filtering
-- [ ] Review submission form
-- [ ] Related products carousel
-- [ ] Wishlist/Save for later
-- [ ] Share buttons
-- [ ] Shipping calculator
-- [ ] Size guide modal
-- [ ] Image zoom/lightbox
-
-### Phase 3: Advanced Features
-- [ ] 360ยฐ product view
-- [ ] Video integration
-- [ ] Live chat integration
-- [ ] Recently viewed products
-- [ ] Personalized recommendations
-- [ ] Social proof notifications
-- [ ] Coupon auto-apply
-- [ ] Bulk pricing display
-
----
-
-## ๐ซ What to Avoid
-
-1. โ Horizontal tabs for content
-2. โ Hiding critical info below the fold
-3. โ Auto-playing videos
-4. โ Intrusive popups
-5. โ Tiny product images
-6. โ Unclear variation selectors
-7. โ Hidden shipping costs
-8. โ Complicated checkout process
-9. โ Fake urgency/scarcity
-10. โ Too many CTAs (decision paralysis)
-
----
-
-## ๐ References
-
-- Baymard Institute - Product Page UX 2025
-- Nielsen Norman Group - E-commerce UX
-- Shopify - Product Page Best Practices
-- ConvertCart - Social Proof Guidelines
-- Google - Mobile Page Speed Guidelines
-
----
-
-## ๐ Version History
-
-| Version | Date | Changes |
-|---------|------|---------|
-| 1.0 | 2025-11-26 | Initial SOP creation based on industry research |
-
diff --git a/RAJAONGKIR_INTEGRATION.md b/RAJAONGKIR_INTEGRATION.md
deleted file mode 100644
index d48c274..0000000
--- a/RAJAONGKIR_INTEGRATION.md
+++ /dev/null
@@ -1,313 +0,0 @@
-# Rajaongkir Integration with WooNooW SPA
-
-This guide explains how to integrate Rajaongkir's destination selector with WooNooW's customer checkout SPA.
-
----
-
-## Prerequisites
-
-Before using this integration:
-
-1. **Rajaongkir Plugin Installed & Active**
-2. **WooCommerce Shipping Zone Configured**
- - Go to: WC โ Settings โ Shipping โ Zones
- - Add Rajaongkir method to your Indonesia zone
-3. **Valid API Key** (Check in Rajaongkir settings)
-4. **Couriers Selected** (In Rajaongkir settings)
-
----
-
-## Code Snippet
-
-Add this to **Code Snippets** or **WPCodebox**:
-
-```php
- 'GET',
- 'callback' => 'woonoow_rajaongkir_search_destinations',
- 'permission_callback' => '__return_true',
- 'args' => [
- 'search' => [
- 'required' => false,
- 'type' => 'string',
- ],
- ],
- ]);
-});
-
-function woonoow_rajaongkir_search_destinations($request) {
- $search = sanitize_text_field($request->get_param('search') ?? '');
-
- if (strlen($search) < 3) {
- return [];
- }
-
- // Check if Rajaongkir plugin is active
- if (!class_exists('Cekongkir_API')) {
- return new WP_Error('rajaongkir_missing', 'Rajaongkir plugin not active', ['status' => 400]);
- }
-
- // Use Rajaongkir's API class for the search
- // NOTE: Method is search_destination_api() not search_destination()
- $api = Cekongkir_API::get_instance();
- $results = $api->search_destination_api($search);
-
- if (is_wp_error($results)) {
- error_log('Rajaongkir search error: ' . $results->get_error_message());
- return [];
- }
-
- if (!is_array($results)) {
- error_log('Rajaongkir search returned non-array: ' . print_r($results, true));
- return [];
- }
-
- // Format for WooNooW's SearchableSelect component
- $formatted = [];
- foreach ($results as $r) {
- $formatted[] = [
- 'value' => (string) ($r['id'] ?? ''),
- 'label' => $r['label'] ?? $r['text'] ?? '',
- ];
- }
-
- // Limit results
- return array_slice($formatted, 0, 50);
-}
-
-// ============================================================
-// 2. Add destination field and hide redundant fields for Indonesia
-// The destination_id from Rajaongkir contains province/city/subdistrict
-// ============================================================
-add_filter('woocommerce_checkout_fields', function($fields) {
- // Check if Rajaongkir is active
- if (!class_exists('Cekongkir_API')) {
- return $fields;
- }
-
- // Check if store sells to Indonesia (check allowed countries)
- $allowed = WC()->countries->get_allowed_countries();
- if (!isset($allowed['ID'])) {
- return $fields;
- }
-
- // Check if Indonesia is the ONLY allowed country
- $indonesia_only = count($allowed) === 1 && isset($allowed['ID']);
-
- // If Indonesia only, hide country/state/city fields (Rajaongkir destination has all this)
- if ($indonesia_only) {
- // Hide billing fields
- if (isset($fields['billing']['billing_country'])) {
- $fields['billing']['billing_country']['type'] = 'hidden';
- $fields['billing']['billing_country']['default'] = 'ID';
- $fields['billing']['billing_country']['required'] = false;
- }
- if (isset($fields['billing']['billing_state'])) {
- $fields['billing']['billing_state']['type'] = 'hidden';
- $fields['billing']['billing_state']['required'] = false;
- }
- if (isset($fields['billing']['billing_city'])) {
- $fields['billing']['billing_city']['type'] = 'hidden';
- $fields['billing']['billing_city']['required'] = false;
- }
- if (isset($fields['billing']['billing_postcode'])) {
- $fields['billing']['billing_postcode']['type'] = 'hidden';
- $fields['billing']['billing_postcode']['required'] = false;
- }
-
- // Hide shipping fields
- if (isset($fields['shipping']['shipping_country'])) {
- $fields['shipping']['shipping_country']['type'] = 'hidden';
- $fields['shipping']['shipping_country']['default'] = 'ID';
- $fields['shipping']['shipping_country']['required'] = false;
- }
- if (isset($fields['shipping']['shipping_state'])) {
- $fields['shipping']['shipping_state']['type'] = 'hidden';
- $fields['shipping']['shipping_state']['required'] = false;
- }
- if (isset($fields['shipping']['shipping_city'])) {
- $fields['shipping']['shipping_city']['type'] = 'hidden';
- $fields['shipping']['shipping_city']['required'] = false;
- }
- if (isset($fields['shipping']['shipping_postcode'])) {
- $fields['shipping']['shipping_postcode']['type'] = 'hidden';
- $fields['shipping']['shipping_postcode']['required'] = false;
- }
- }
-
- // Destination field definition (reused for billing and shipping)
- $destination_field = [
- 'type' => 'searchable_select',
- 'label' => __('Destination (Province, City, Subdistrict)', 'woonoow'),
- 'required' => $indonesia_only, // Required if Indonesia only
- 'priority' => 85,
- 'class' => ['form-row-wide'],
- 'placeholder' => __('Search destination...', 'woonoow'),
- // WooNooW-specific: API endpoint configuration
- // NOTE: Path is relative to /wp-json/woonoow/v1
- 'search_endpoint' => '/rajaongkir/destinations',
- 'search_param' => 'search',
- 'min_chars' => 3,
- // Custom attribute to indicate this is for Indonesia only
- 'custom_attributes' => [
- 'data-show-for-country' => 'ID',
- ],
- ];
-
- // Add to billing (used when "Ship to different address" is NOT checked)
- $fields['billing']['billing_destination_id'] = $destination_field;
-
- // Add to shipping (used when "Ship to different address" IS checked)
- $fields['shipping']['shipping_destination_id'] = $destination_field;
-
- return $fields;
-}, 20); // Priority 20 to run after Rajaongkir's own filter
-
-// ============================================================
-// 3. Bridge WooNooW shipping data to Rajaongkir session
-// Sets destination_id in WC session for Rajaongkir to use
-// ============================================================
-add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
- // Check if Rajaongkir is active
- if (!class_exists('Cekongkir_API')) {
- return;
- }
-
- // For Indonesia-only stores, always set country to ID
- $allowed = WC()->countries->get_allowed_countries();
- $indonesia_only = count($allowed) === 1 && isset($allowed['ID']);
-
- if ($indonesia_only) {
- WC()->customer->set_shipping_country('ID');
- WC()->customer->set_billing_country('ID');
- } elseif (!empty($shipping['country'])) {
- WC()->customer->set_shipping_country($shipping['country']);
- WC()->customer->set_billing_country($shipping['country']);
- }
-
- // Only process Rajaongkir for Indonesia
- $country = $shipping['country'] ?? WC()->customer->get_shipping_country();
- if ($country !== 'ID') {
- // Clear destination for non-Indonesia
- WC()->session->__unset('selected_destination_id');
- WC()->session->__unset('selected_destination_label');
- return;
- }
-
- // Get destination_id from shipping data (various possible keys)
- $destination_id = $shipping['destination_id']
- ?? $shipping['shipping_destination_id']
- ?? $shipping['billing_destination_id']
- ?? null;
-
- if (empty($destination_id)) {
- return;
- }
-
- // Set session for Rajaongkir
- WC()->session->set('selected_destination_id', intval($destination_id));
-
- // Also set label if provided
- $label = $shipping['destination_label']
- ?? $shipping['shipping_destination_id_label']
- ?? $shipping['billing_destination_id_label']
- ?? '';
- if ($label) {
- WC()->session->set('selected_destination_label', sanitize_text_field($label));
- }
-
- // Clear shipping cache to force recalculation
- WC()->session->set('shipping_for_package_0', false);
-
-}, 10, 2);
-```
-
----
-
-## Testing
-
-### 1. Test the API Endpoint
-
-After adding the snippet:
-```
-GET /wp-json/woonoow/v1/rajaongkir/destinations?search=bandung
-```
-
-Should return:
-```json
-[
- {"value": "1234", "label": "Jawa Barat, Bandung, Kota"},
- ...
-]
-```
-
-### 2. Test Checkout Flow
-
-1. Add product to cart
-2. Go to SPA checkout: `/store/checkout`
-3. Set country to Indonesia
-4. "Destination" field should appear
-5. Type 2+ characters to search
-6. Select a destination
-7. Rajaongkir rates should appear
-
----
-
-## Troubleshooting
-
-### API returns empty?
-
-Check `debug.log` for errors:
-```php
-// Added logging in the search function
-error_log('Rajaongkir search error: ...');
-```
-
-Common issues:
-- Invalid Rajaongkir API key
-- Rajaongkir plugin not active
-- API quota exceeded
-
-### Field not appearing?
-
-1. Ensure snippet is active
-2. Check if store sells to Indonesia
-3. Check browser console for JS errors
-
-### Rajaongkir rates not showing?
-
-1. Check session is set:
-```php
-add_action('woonoow/shipping/before_calculate', function($shipping) {
- error_log('Shipping data: ' . print_r($shipping, true));
-}, 5);
-```
-
-2. Check Rajaongkir is enabled in shipping zone
-
----
-
-## Known Limitations
-
-1. **Field visibility**: Currently field always shows for checkout. Future improvement: hide in React when country โ ID.
-
-2. **Session timing**: Must select destination before calculating shipping.
-
----
-
-## Related Documentation
-
-- [SHIPPING_INTEGRATION.md](SHIPPING_INTEGRATION.md) - General shipping patterns
-- [HOOKS_REGISTRY.md](HOOKS_REGISTRY.md) - WooNooW hooks reference
diff --git a/REDIRECT_DEBUG.md b/REDIRECT_DEBUG.md
deleted file mode 100644
index 4555950..0000000
--- a/REDIRECT_DEBUG.md
+++ /dev/null
@@ -1,119 +0,0 @@
-# Product Page Redirect Debugging
-
-## Issue
-Direct access to product URLs like `/product/edukasi-anak` redirects to `/shop`.
-
-## Debugging Steps
-
-### 1. Check Console Logs
-Open browser console and navigate to: `https://woonoow.local/product/edukasi-anak`
-
-Look for these logs:
-```
-Product Component - Slug: edukasi-anak
-Product Component - Current URL: https://woonoow.local/product/edukasi-anak
-Product Query - Starting fetch for slug: edukasi-anak
-Product API Response: {...}
-```
-
-### 2. Possible Causes
-
-#### A. WordPress Canonical Redirect
-WordPress might be redirecting the URL because it doesn't recognize `/product/` as a valid route.
-
-**Solution:** Disable canonical redirects for SPA pages.
-
-#### B. React Router Not Matching
-The route might not be matching correctly.
-
-**Check:** Does the slug parameter get extracted?
-
-#### C. WooCommerce Redirect
-WooCommerce might be redirecting to shop page.
-
-**Check:** Is `is_product()` returning true?
-
-#### D. 404 Handling
-WordPress might be treating it as 404 and redirecting.
-
-**Check:** Is the page returning 404 status?
-
-### 3. Quick Tests
-
-#### Test 1: Check if Template Loads
-Add this to `spa-full-page.php` at the top:
-```php
-
-```
-
-#### Test 2: Check React Router
-Add this to `App.tsx`:
-```tsx
-useEffect(() => {
- console.log('Current Path:', window.location.pathname);
- console.log('Is Product Route:', window.location.pathname.includes('/product/'));
-}, []);
-```
-
-#### Test 3: Check if Assets Load
-Open Network tab and check if `customer-spa.js` loads on product page.
-
-### 4. Likely Solution
-
-The issue is probably WordPress canonical redirect. Add this to `TemplateOverride.php`:
-
-```php
-public static function init() {
- // ... existing code ...
-
- // Disable canonical redirects for SPA pages
- add_filter('redirect_canonical', [__CLASS__, 'disable_canonical_redirect'], 10, 2);
-}
-
-public static function disable_canonical_redirect($redirect_url, $requested_url) {
- $settings = get_option('woonoow_customer_spa_settings', []);
- $mode = isset($settings['mode']) ? $settings['mode'] : 'disabled';
-
- if ($mode === 'full') {
- // Check if this is a SPA route
- $spa_routes = ['/product/', '/cart', '/checkout', '/my-account'];
-
- foreach ($spa_routes as $route) {
- if (strpos($requested_url, $route) !== false) {
- return false; // Disable redirect
- }
- }
- }
-
- return $redirect_url;
-}
-```
-
-### 5. Alternative: Use Hash Router
-
-If canonical redirects can't be disabled, use HashRouter instead:
-
-```tsx
-// In App.tsx
-import { HashRouter } from 'react-router-dom';
-
-// Change BrowserRouter to HashRouter
-
- {/* routes */}
-
-```
-
-URLs will be: `https://woonoow.local/#/product/edukasi-anak`
-
-This works because everything after `#` is client-side only.
-
-## Next Steps
-
-1. Add console logs (already done)
-2. Test and check console
-3. If slug is undefined โ React Router issue
-4. If slug is defined but redirects โ WordPress redirect issue
-5. Apply appropriate fix
diff --git a/SHIPPING_BRIDGE_PATTERN.md b/SHIPPING_BRIDGE_PATTERN.md
deleted file mode 100644
index b8d6e5f..0000000
--- a/SHIPPING_BRIDGE_PATTERN.md
+++ /dev/null
@@ -1,219 +0,0 @@
-# WooNooW Shipping Bridge Pattern
-
-This document describes a generic pattern for integrating any external shipping API with WooNooW's SPA checkout.
-
----
-
-## Overview
-
-WooNooW provides hooks and endpoints that allow any shipping plugin to:
-1. **Register custom checkout fields** (searchable selects, dropdowns, etc.)
-2. **Bridge data to the plugin's session/API** before shipping calculation
-3. **Display live rates** from external APIs
-
-This pattern is NOT specific to Rajaongkir - it can be used for any shipping provider.
-
----
-
-## Architecture
-
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ WooNooW Customer SPA โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ 1. Checkout loads โ calls /checkout/fields โ
-โ 2. Renders custom fields (e.g., searchable destination) โ
-โ 3. User fills form โ calls /checkout/shipping-rates โ
-โ 4. Hook triggers โ shipping plugin calculates rates โ
-โ 5. Rates displayed โ user selects โ order submitted โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ
- โผ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Your Bridge Snippet โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ โข woocommerce_checkout_fields โ Add custom fields โ
-โ โข register_rest_route โ API endpoint for field data โ
-โ โข woonoow/shipping/before_calculate โ Set session/data โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- โ
- โผ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Shipping Plugin (Any) โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ โข Reads from WC session or customer data โ
-โ โข Calls external API (Rajaongkir, Sicepat, JNE, etc.) โ
-โ โข Returns rates via get_rates_for_package() โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
----
-
-## Generic Bridge Template
-
-```php
- 'GET',
- 'callback' => 'woonoow_[provider]_search',
- 'permission_callback' => '__return_true', // Public for customer use
- 'args' => [
- 'search' => ['type' => 'string', 'required' => false],
- ],
- ]);
-});
-
-function woonoow_[provider]_search($request) {
- $search = sanitize_text_field($request->get_param('search') ?? '');
-
- if (strlen($search) < 3) {
- return [];
- }
-
- // Check if plugin is active
- if (!class_exists('[PROVIDER_CLASS]')) {
- return new WP_Error('[provider]_missing', 'Plugin not active', ['status' => 400]);
- }
-
- // Call provider's API
- // $results = [PROVIDER_CLASS]::search($search);
-
- // Format for WooNooW's SearchableSelect
- $formatted = [];
- foreach ($results as $r) {
- $formatted[] = [
- 'value' => (string) $r['id'],
- 'label' => $r['name'],
- ];
- }
-
- return array_slice($formatted, 0, 50);
-}
-
-// ============================================================
-// 2. Add custom field(s) to checkout
-// ============================================================
-add_filter('woocommerce_checkout_fields', function($fields) {
- if (!class_exists('[PROVIDER_CLASS]')) {
- return $fields;
- }
-
- $custom_field = [
- 'type' => 'searchable_select', // or 'select', 'text'
- 'label' => __('[Field Label]', 'woonoow'),
- 'required' => true,
- 'priority' => 85,
- 'class' => ['form-row-wide'],
- 'placeholder' => __('Search...', 'woonoow'),
- 'search_endpoint' => '/[provider]/search', // Relative to /wp-json/woonoow/v1
- 'search_param' => 'search',
- 'min_chars' => 3,
- ];
-
- $fields['billing']['billing_[provider]_field'] = $custom_field;
- $fields['shipping']['shipping_[provider]_field'] = $custom_field;
-
- return $fields;
-}, 20);
-
-// ============================================================
-// 3. Bridge data to provider before shipping calculation
-// ============================================================
-add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
- if (!class_exists('[PROVIDER_CLASS]')) {
- return;
- }
-
- // Get custom field value from shipping data
- $field_value = $shipping['[provider]_field']
- ?? $shipping['shipping_[provider]_field']
- ?? $shipping['billing_[provider]_field']
- ?? null;
-
- if (empty($field_value)) {
- return;
- }
-
- // Set in WC session for the shipping plugin to use
- WC()->session->set('[PROVIDER_SESSION_KEY]', $field_value);
-
- // Clear shipping cache to force recalculation
- WC()->session->set('shipping_for_package_0', false);
-
-}, 10, 2);
-```
-
----
-
-## Supported Field Types
-
-| Type | Description | Use Case |
-|------|-------------|----------|
-| `searchable_select` | Dropdown with API search | Destinations, locations, service points |
-| `select` | Static dropdown | Service types, delivery options |
-| `text` | Free text input | Reference numbers, notes |
-| `hidden` | Hidden field | Default values, auto-set data |
-
----
-
-## WooNooW Hooks Reference
-
-| Hook | Type | Description |
-|------|------|-------------|
-| `woonoow/shipping/before_calculate` | Action | Called before shipping rates are calculated |
-| `woocommerce_checkout_fields` | Filter | Standard WC filter for checkout fields |
-
----
-
-## Examples
-
-### Example 1: Sicepat Integration
-```php
-// Endpoint
-register_rest_route('woonoow/v1', '/sicepat/destinations', ...);
-
-// Session key
-WC()->session->set('sicepat_destination_code', $code);
-```
-
-### Example 2: JNE Direct API
-```php
-// Endpoint for origin selection
-register_rest_route('woonoow/v1', '/jne/origins', ...);
-register_rest_route('woonoow/v1', '/jne/destinations', ...);
-
-// Multiple session keys
-WC()->session->set('jne_origin', $origin);
-WC()->session->set('jne_destination', $destination);
-```
-
----
-
-## Checklist for New Integration
-
-- [ ] Identify the shipping plugin's class name
-- [ ] Find what session/data it reads for API calls
-- [ ] Create REST endpoint for searchable data
-- [ ] Add checkout field(s) via filter
-- [ ] Bridge data via `woonoow/shipping/before_calculate`
-- [ ] Test shipping rate calculation
-- [ ] Document in dedicated `[PROVIDER]_INTEGRATION.md`
-
----
-
-## Related Documentation
-
-- [RAJAONGKIR_INTEGRATION.md](RAJAONGKIR_INTEGRATION.md) - Rajaongkir-specific implementation
-- [SHIPPING_INTEGRATION.md](SHIPPING_INTEGRATION.md) - General shipping patterns
-- [HOOKS_REGISTRY.md](HOOKS_REGISTRY.md) - All WooNooW hooks
diff --git a/SHIPPING_INTEGRATION.md b/SHIPPING_INTEGRATION.md
deleted file mode 100644
index 18386ea..0000000
--- a/SHIPPING_INTEGRATION.md
+++ /dev/null
@@ -1,322 +0,0 @@
-# Shipping Integration Guide
-
-This document consolidates shipping integration patterns and addon specifications for WooNooW.
-
----
-
-## Overview
-
-WooNooW supports flexible shipping integration through:
-1. **Standard WooCommerce Shipping Methods** - Works with any WC shipping plugin
-2. **Custom Shipping Addons** - Build shipping addons using WooNooW addon bridge
-3. **Indonesian Shipping** - Special handling for Indonesian address systems
-
----
-
-## Indonesian Shipping Challenges
-
-### RajaOngkir Integration Issue
-
-**Problem**: RajaOngkir plugin doesn't use standard WooCommerce address fields.
-
-#### How RajaOngkir Works:
-
-1. **Removes Standard Fields:**
-```php
-// class-cekongkir.php
-public function customize_checkout_fields($fields) {
- unset($fields['billing']['billing_state']);
- unset($fields['billing']['billing_city']);
- unset($fields['shipping']['shipping_state']);
- unset($fields['shipping']['shipping_city']);
- return $fields;
-}
-```
-
-2. **Adds Custom Destination Dropdown:**
-```php
-
-```
-
-3. **Stores in Session:**
-```php
-WC()->session->set('selected_destination_id', $destination_id);
-WC()->session->set('selected_destination_label', $destination_label);
-```
-
-4. **Triggers Shipping Calculation:**
-```php
-WC()->cart->calculate_shipping();
-WC()->cart->calculate_totals();
-```
-
-#### Why Standard Implementation Fails:
-
-- WooNooW OrderForm uses standard fields: `city`, `state`, `postcode`
-- RajaOngkir ignores these fields
-- RajaOngkir only reads from session: `selected_destination_id`
-
-#### Solution:
-
-Use **Biteship** instead (see below) or create custom RajaOngkir addon that:
-- Hooks into WooNooW OrderForm
-- Adds Indonesian address selector
-- Syncs with RajaOngkir session
-
----
-
-## Biteship Integration Addon
-
-### Plugin Specification
-
-**Plugin Name:** WooNooW Indonesia Shipping
-**Description:** Indonesian shipping integration using Biteship Rate API
-**Version:** 1.0.0
-**Requires:** WooNooW 1.0.0+, WooCommerce 8.0+
-
-### Features
-
-- โ
Indonesian address fields (Province, City, District, Subdistrict)
-- โ
Real-time shipping rate calculation
-- โ
Multiple courier support (JNE, SiCepat, J&T, AnterAja, etc.)
-- โ
Works in frontend checkout AND admin order form
-- โ
No subscription required (uses free Biteship Rate API)
-
-### Implementation Phases
-
-#### Phase 1: Core Functionality
-- WooCommerce Shipping Method integration
-- Biteship Rate API integration
-- Indonesian address database (Province โ Subdistrict)
-- Frontend checkout integration
-- Admin settings page
-
-#### Phase 2: SPA Integration
-- REST API endpoints for address data
-- REST API for rate calculation
-- React components (SubdistrictSelector, CourierSelector)
-- Hook integration with WooNooW OrderForm
-- Admin order form support
-
-#### Phase 3: Advanced Features
-- Rate caching (reduce API calls)
-- Custom rate markup
-- Free shipping threshold
-- Multi-origin support
-- Shipping label generation (optional, requires paid Biteship plan)
-
-### Plugin Structure
-
-```
-woonoow-indonesia-shipping/
-โโโ woonoow-indonesia-shipping.php
-โโโ includes/
-โ โโโ class-shipping-method.php
-โ โโโ class-biteship-api.php
-โ โโโ class-address-database.php
-โ โโโ class-rest-controller.php
-โโโ admin/
-โ โโโ class-settings.php
-โ โโโ views/
-โโโ assets/
-โ โโโ js/
-โ โ โโโ checkout.js
-โ โ โโโ admin-order.js
-โ โโโ css/
-โโโ data/
- โโโ indonesia-addresses.json
-```
-
-### API Integration
-
-#### Biteship Rate API Endpoint
-```
-POST https://api.biteship.com/v1/rates/couriers
-```
-
-**Request:**
-```json
-{
- "origin_area_id": "IDNP6IDNC148IDND1820IDZ16094",
- "destination_area_id": "IDNP9IDNC235IDND3256IDZ41551",
- "couriers": "jne,sicepat,jnt",
- "items": [
- {
- "name": "Product Name",
- "value": 100000,
- "weight": 1000,
- "quantity": 1
- }
- ]
-}
-```
-
-**Response:**
-```json
-{
- "success": true,
- "object": "courier_pricing",
- "pricing": [
- {
- "courier_name": "JNE",
- "courier_service_name": "REG",
- "price": 15000,
- "duration": "2-3 days"
- }
- ]
-}
-```
-
-### React Components
-
-#### SubdistrictSelector Component
-```tsx
-interface SubdistrictSelectorProps {
- value: {
- province_id: string;
- city_id: string;
- district_id: string;
- subdistrict_id: string;
- };
- onChange: (value: any) => void;
-}
-
-export function SubdistrictSelector({ value, onChange }: SubdistrictSelectorProps) {
- // Cascading dropdowns: Province โ City โ District โ Subdistrict
- // Uses WooNooW API: /woonoow/v1/shipping/indonesia/provinces
-}
-```
-
-#### CourierSelector Component
-```tsx
-interface CourierSelectorProps {
- origin: string;
- destination: string;
- items: CartItem[];
- onSelect: (courier: ShippingRate) => void;
-}
-
-export function CourierSelector({ origin, destination, items, onSelect }: CourierSelectorProps) {
- // Fetches rates from Biteship
- // Displays courier options with prices
- // Uses WooNooW API: /woonoow/v1/shipping/indonesia/rates
-}
-```
-
-### Hook Integration
-
-```php
-// Register shipping addon
-add_filter('woonoow/shipping/address_fields', function($fields) {
- if (get_option('woonoow_indonesia_shipping_enabled')) {
- return [
- 'province' => [
- 'type' => 'select',
- 'label' => 'Province',
- 'required' => true,
- ],
- 'city' => [
- 'type' => 'select',
- 'label' => 'City',
- 'required' => true,
- ],
- 'district' => [
- 'type' => 'select',
- 'label' => 'District',
- 'required' => true,
- ],
- 'subdistrict' => [
- 'type' => 'select',
- 'label' => 'Subdistrict',
- 'required' => true,
- ],
- ];
- }
- return $fields;
-});
-
-// Register React component
-add_filter('woonoow/checkout/shipping_selector', function($component) {
- if (get_option('woonoow_indonesia_shipping_enabled')) {
- return 'IndonesiaShippingSelector';
- }
- return $component;
-});
-```
-
----
-
-## General Shipping Integration
-
-### Standard WooCommerce Shipping
-
-WooNooW automatically supports any WooCommerce shipping plugin that uses standard shipping methods:
-
-- WooCommerce Flat Rate
-- WooCommerce Free Shipping
-- WooCommerce Local Pickup
-- Table Rate Shipping
-- Distance Rate Shipping
-- Any third-party shipping plugin
-
-### Custom Shipping Addons
-
-To create a custom shipping addon:
-
-1. **Create WooCommerce Shipping Method**
-```php
-class Custom_Shipping_Method extends WC_Shipping_Method {
- public function calculate_shipping($package = []) {
- // Your shipping calculation logic
- $this->add_rate([
- 'id' => $this->id,
- 'label' => $this->title,
- 'cost' => $cost,
- ]);
- }
-}
-```
-
-2. **Register with WooCommerce**
-```php
-add_filter('woocommerce_shipping_methods', function($methods) {
- $methods['custom_shipping'] = 'Custom_Shipping_Method';
- return $methods;
-});
-```
-
-3. **Add SPA Integration (Optional)**
-```php
-// REST API for frontend
-register_rest_route('woonoow/v1', '/shipping/custom/rates', [
- 'methods' => 'POST',
- 'callback' => 'get_custom_shipping_rates',
-]);
-
-// React component hook
-add_filter('woonoow/checkout/shipping_fields', function($fields) {
- // Add custom fields if needed
- return $fields;
-});
-```
-
----
-
-## Best Practices
-
-1. **Use Standard WC Fields** - Whenever possible, use standard WooCommerce address fields
-2. **Cache Rates** - Cache shipping rates to reduce API calls
-3. **Error Handling** - Always provide fallback rates if API fails
-4. **Mobile Friendly** - Ensure shipping selectors work well on mobile
-5. **Admin Support** - Make sure shipping works in admin order form too
-
----
-
-## Resources
-
-- [WooCommerce Shipping Method Tutorial](https://woocommerce.com/document/shipping-method-api/)
-- [Biteship API Documentation](https://biteship.com/docs)
-- [WooNooW Addon Development Guide](ADDON_DEVELOPMENT_GUIDE.md)
-- [WooNooW Hooks Registry](HOOKS_REGISTRY.md)
diff --git a/SHIPPING_METHOD_TYPES.md b/SHIPPING_METHOD_TYPES.md
deleted file mode 100644
index 6da6d28..0000000
--- a/SHIPPING_METHOD_TYPES.md
+++ /dev/null
@@ -1,327 +0,0 @@
-# Shipping Method Types - WooCommerce Core Structure
-
-## The Two Types of Shipping Methods
-
-WooCommerce has TWO fundamentally different shipping method types:
-
----
-
-## Type 1: Static Methods (WooCommerce Core)
-
-**Characteristics:**
-- No API calls
-- Fixed rates or free
-- Configured once in settings
-- Available immediately
-
-**Examples:**
-- Free Shipping
-- Flat Rate
-- Local Pickup
-
-**Structure:**
-```
-Method: Free Shipping
-โโโ Conditions: Order total > $50
-โโโ Cost: $0
-```
-
-**In Create Order:**
-```
-User fills address
-โ Static methods appear immediately
-โ User selects one
-โ Done!
-```
-
----
-
-## Type 2: Live Rate Methods (API-based)
-
-**Characteristics:**
-- Requires API call
-- Dynamic rates based on address + weight
-- Returns multiple service options
-- Needs "Calculate" button
-
-**Examples:**
-- UPS (International)
-- FedEx, DHL
-- Indonesian Shipping Addons (J&T, JNE, SiCepat)
-
-**Structure:**
-```
-Method: UPS Live Rates
-โโโ API Credentials configured
-โโโ On calculate:
- โโโ Service: UPS Ground - $15.00
- โโโ Service: UPS 2nd Day - $25.00
- โโโ Service: UPS Next Day - $45.00
-```
-
-**In Create Order:**
-```
-User fills address
-โ Click "Calculate Shipping"
-โ API returns service options
-โ User selects one
-โ Done!
-```
-
----
-
-## The Real Hierarchy
-
-### Static Method (Simple):
-```
-Method
-โโโ (No sub-levels)
-```
-
-### Live Rate Method (Complex):
-```
-Method
-โโโ Courier (if applicable)
-โ โโโ Service Option 1
-โ โโโ Service Option 2
-โ โโโ Service Option 3
-โโโ Or directly:
- โโโ Service Option 1
- โโโ Service Option 2
-```
-
----
-
-## Indonesian Shipping Example
-
-**Method:** Indonesian Shipping (API-based)
-**API:** Biteship / RajaOngkir / Custom
-
-**After Calculate:**
-```
-J&T Express
-โโโ Regular Service: Rp15,000 (2-3 days)
-โโโ Express Service: Rp25,000 (1 day)
-
-JNE
-โโโ REG: Rp18,000 (2-4 days)
-โโโ YES: Rp28,000 (1-2 days)
-โโโ OKE: Rp12,000 (3-5 days)
-
-SiCepat
-โโโ Regular: Rp16,000 (2-3 days)
-โโโ BEST: Rp20,000 (1-2 days)
-```
-
-**User sees:** Courier name + Service name + Price + Estimate
-
----
-
-## UPS Example (International)
-
-**Method:** UPS Live Rates
-**API:** UPS API
-
-**After Calculate:**
-```
-UPS Ground: $15.00 (5-7 business days)
-UPS 2nd Day Air: $25.00 (2 business days)
-UPS Next Day Air: $45.00 (1 business day)
-```
-
-**User sees:** Service name + Price + Estimate
-
----
-
-## Address Field Requirements
-
-### Static Methods:
-- Country
-- State/Province
-- City
-- Postal Code
-- Address Line 1
-- Address Line 2 (optional)
-
-### Live Rate Methods:
-
-**International (UPS, FedEx, DHL):**
-- Country
-- State/Province
-- City
-- **Postal Code** (REQUIRED - used for rate calculation)
-- Address Line 1
-- Address Line 2 (optional)
-
-**Indonesian (J&T, JNE, SiCepat):**
-- Country: Indonesia
-- Province
-- City/Regency
-- **Subdistrict** (REQUIRED - used for rate calculation)
-- Postal Code
-- Address Line 1
-- Address Line 2 (optional)
-
----
-
-## The Pattern
-
-| Method Type | Address Requirement | Rate Calculation |
-|-------------|---------------------|------------------|
-| Static | Basic address | Fixed/Free |
-| Live Rate (International) | **Postal Code** required | API call with postal code |
-| Live Rate (Indonesian) | **Subdistrict** required | API call with subdistrict ID |
-
----
-
-## Implementation in Create Order
-
-### Current Problem:
-- We probably require subdistrict for ALL methods
-- This breaks international live rate methods
-
-### Solution:
-
-**Step 1: Detect Available Methods**
-```javascript
-const availableMethods = getShippingMethods(address.country);
-
-const needsSubdistrict = availableMethods.some(method =>
- method.type === 'live_rate' && method.country === 'ID'
-);
-
-const needsPostalCode = availableMethods.some(method =>
- method.type === 'live_rate' && method.country !== 'ID'
-);
-```
-
-**Step 2: Show Conditional Fields**
-```javascript
-// Always show
-- Country
-- State/Province
-- City
-- Address Line 1
-
-// Conditional
-if (needsSubdistrict) {
- - Subdistrict (required)
-}
-
-if (needsPostalCode || needsSubdistrict) {
- - Postal Code (required)
-}
-
-// Always optional
-- Address Line 2
-```
-
-**Step 3: Calculate Shipping**
-```javascript
-// Static methods
-if (method.type === 'static') {
- return method.cost; // Immediate
-}
-
-// Live rate methods
-if (method.type === 'live_rate') {
- const rates = await fetchLiveRates({
- method: method.id,
- address: {
- country: address.country,
- state: address.state,
- city: address.city,
- subdistrict: address.subdistrict, // If Indonesian
- postal_code: address.postal_code, // If international
- // ... other fields
- }
- });
-
- return rates; // Array of service options
-}
-```
-
----
-
-## UI Flow
-
-### Scenario 1: Static Method Only
-```
-1. User fills basic address
-2. Shipping options appear immediately:
- - Free Shipping: $0
- - Flat Rate: $10
-3. User selects one
-4. Done!
-```
-
-### Scenario 2: Indonesian Live Rate
-```
-1. User fills address including subdistrict
-2. Click "Calculate Shipping"
-3. API returns:
- - J&T Regular: Rp15,000
- - JNE REG: Rp18,000
- - SiCepat BEST: Rp20,000
-4. User selects one
-5. Done!
-```
-
-### Scenario 3: International Live Rate
-```
-1. User fills address including postal code
-2. Click "Calculate Shipping"
-3. API returns:
- - UPS Ground: $15.00
- - UPS 2nd Day: $25.00
-4. User selects one
-5. Done!
-```
-
-### Scenario 4: Mixed (Static + Live Rate)
-```
-1. User fills address
-2. Static methods appear immediately:
- - Free Shipping: $0
-3. Click "Calculate Shipping" for live rates
-4. Live rates appear:
- - UPS Ground: $15.00
-5. User selects from all options
-6. Done!
-```
-
----
-
-## WooCommerce Core Behavior
-
-**Yes, this is all in WooCommerce core!**
-
-- Static methods: `WC_Shipping_Method` class
-- Live rate methods: Extend `WC_Shipping_Method` with API logic
-- Service options: Stored as shipping rates with method_id + instance_id
-
-**WooCommerce handles:**
-- Method registration
-- Rate calculation
-- Service option display
-- Selection and storage
-
-**We need to handle:**
-- Conditional address fields
-- "Calculate" button for live rates
-- Service option display in Create Order
-- Proper address validation
-
----
-
-## Next Steps
-
-1. Investigate Create Order address field logic
-2. Add conditional field display based on available methods
-3. Add "Calculate Shipping" button for live rates
-4. Display service options properly
-5. Test with:
- - Static methods only
- - Indonesian live rates
- - International live rates
- - Mixed scenarios
diff --git a/SPRINT_1-2_COMPLETION_REPORT.md b/SPRINT_1-2_COMPLETION_REPORT.md
deleted file mode 100644
index 7da8337..0000000
--- a/SPRINT_1-2_COMPLETION_REPORT.md
+++ /dev/null
@@ -1,415 +0,0 @@
-# Sprint 1-2 Completion Report โ
COMPLETE
-
-**Status:** โ
All objectives achieved and tested
-**Date Completed:** November 22, 2025
-## Customer SPA Foundation
-
-**Date:** November 22, 2025
-**Status:** โ
Foundation Complete - Ready for Build & Testing
-
----
-
-## Executive Summary
-
-Sprint 1-2 objectives have been **successfully completed**. The customer-spa foundation is now in place with:
-- โ
Backend API controllers (Shop, Cart, Account)
-- โ
Frontend base layout components (Header, Footer, Container)
-- โ
WordPress integration (Shortcodes, Asset loading)
-- โ
Authentication flow (using WordPress user session)
-- โ
Routing structure
-- โ
State management (Zustand for cart)
-- โ
API client with endpoints
-
----
-
-## What Was Built
-
-### 1. Backend API Controllers โ
-
-Created three new customer-facing API controllers in `includes/Frontend/`:
-
-#### **ShopController.php**
-```
-GET /woonoow/v1/shop/products # List products with filters
-GET /woonoow/v1/shop/products/{id} # Get single product (with variations)
-GET /woonoow/v1/shop/categories # List categories
-GET /woonoow/v1/shop/search # Search products
-```
-
-**Features:**
-- Product listing with pagination, category filter, search
-- Single product with detailed info (variations, gallery, related products)
-- Category listing with images
-- Product search
-
-#### **CartController.php**
-```
-GET /woonoow/v1/cart # Get cart contents
-POST /woonoow/v1/cart/add # Add item to cart
-POST /woonoow/v1/cart/update # Update cart item quantity
-POST /woonoow/v1/cart/remove # Remove item from cart
-POST /woonoow/v1/cart/apply-coupon # Apply coupon
-POST /woonoow/v1/cart/remove-coupon # Remove coupon
-```
-
-**Features:**
-- Full cart CRUD operations
-- Coupon management
-- Cart totals calculation (subtotal, tax, shipping, discount)
-- WooCommerce session integration
-
-#### **AccountController.php**
-```
-GET /woonoow/v1/account/orders # Get customer orders
-GET /woonoow/v1/account/orders/{id} # Get single order
-GET /woonoow/v1/account/profile # Get customer profile
-POST /woonoow/v1/account/profile # Update profile
-POST /woonoow/v1/account/password # Update password
-GET /woonoow/v1/account/addresses # Get addresses
-POST /woonoow/v1/account/addresses # Update addresses
-GET /woonoow/v1/account/downloads # Get digital downloads
-```
-
-**Features:**
-- Order history with pagination
-- Order details with items, addresses, totals
-- Profile management
-- Password update
-- Billing/shipping address management
-- Digital downloads support
-- Permission checks (logged-in users only)
-
-**Files Created:**
-- `includes/Frontend/ShopController.php`
-- `includes/Frontend/CartController.php`
-- `includes/Frontend/AccountController.php`
-
-**Integration:**
-- Updated `includes/Api/Routes.php` to register frontend controllers
-- All routes registered under `woonoow/v1` namespace
-
----
-
-### 2. WordPress Integration โ
-
-#### **Assets Manager** (`includes/Frontend/Assets.php`)
-- Enqueues customer-spa JS/CSS on pages with shortcodes
-- Adds inline config with API URL, nonce, user info
-- Supports both production build and dev mode
-- Smart loading (only loads when needed)
-
-#### **Shortcodes Manager** (`includes/Frontend/Shortcodes.php`)
-Created four shortcodes:
-- `[woonoow_shop]` - Product listing page
-- `[woonoow_cart]` - Shopping cart page
-- `[woonoow_checkout]` - Checkout page (requires login)
-- `[woonoow_account]` - My account page (requires login)
-
-**Features:**
-- Renders mount point for React app
-- Passes data attributes for page-specific config
-- Login requirement for protected pages
-- Loading state placeholder
-
-**Integration:**
-- Updated `includes/Core/Bootstrap.php` to initialize frontend classes
-- Assets and shortcodes auto-load on `plugins_loaded` hook
-
----
-
-### 3. Frontend Components โ
-
-#### **Base Layout Components**
-Created in `customer-spa/src/components/Layout/`:
-
-**Header.tsx**
-- Logo and navigation
-- Cart icon with item count badge
-- User account link (if logged in)
-- Search button
-- Mobile menu button
-- Sticky header with backdrop blur
-
-**Footer.tsx**
-- Multi-column footer (About, Shop, Account, Support)
-- Links to main pages
-- Copyright notice
-- Responsive grid layout
-
-**Container.tsx**
-- Responsive container wrapper
-- Uses `container-safe` utility class
-- Consistent padding and max-width
-
-**Layout.tsx**
-- Main layout wrapper
-- Header + Content + Footer structure
-- Flex layout with sticky footer
-
-#### **UI Components**
-- `components/ui/button.tsx` - Button component with variants (shadcn/ui pattern)
-
-#### **Utilities**
-- `lib/utils.ts` - Helper functions:
- - `cn()` - Tailwind class merging
- - `formatPrice()` - Currency formatting
- - `formatDate()` - Date formatting
- - `debounce()` - Debounce function
-
-**Integration:**
-- Updated `App.tsx` to use Layout wrapper
-- All pages now render inside consistent layout
-
----
-
-### 4. Authentication Flow โ
-
-**Implementation:**
-- Uses WordPress session (no separate auth needed)
-- User info passed via `window.woonoowCustomer.user`
-- Nonce-based API authentication
-- Login requirement enforced at shortcode level
-
-**User Data Available:**
-```typescript
-window.woonoowCustomer = {
- apiUrl: '/wp-json/woonoow/v1',
- nonce: 'wp_rest_nonce',
- siteUrl: 'https://site.local',
- user: {
- isLoggedIn: true,
- id: 123
- }
-}
-```
-
-**Protected Routes:**
-- Checkout page requires login
-- Account pages require login
-- API endpoints check `is_user_logged_in()`
-
----
-
-## File Structure
-
-```
-woonoow/
-โโโ includes/
-โ โโโ Frontend/ # NEW - Customer-facing backend
-โ โ โโโ ShopController.php # Product catalog API
-โ โ โโโ CartController.php # Cart operations API
-โ โ โโโ AccountController.php # Customer account API
-โ โ โโโ Assets.php # Asset loading
-โ โ โโโ Shortcodes.php # Shortcode handlers
-โ โโโ Api/
-โ โ โโโ Routes.php # UPDATED - Register frontend routes
-โ โโโ Core/
-โ โโโ Bootstrap.php # UPDATED - Initialize frontend
-โ
-โโโ customer-spa/
- โโโ src/
- โ โโโ components/
- โ โ โโโ Layout/ # NEW - Layout components
- โ โ โ โโโ Header.tsx
- โ โ โ โโโ Footer.tsx
- โ โ โ โโโ Container.tsx
- โ โ โ โโโ Layout.tsx
- โ โ โโโ ui/ # NEW - UI components
- โ โ โโโ button.tsx
- โ โโโ lib/
- โ โ โโโ api/
- โ โ โ โโโ client.ts # EXISTING - API client
- โ โ โโโ cart/
- โ โ โ โโโ store.ts # EXISTING - Cart state
- โ โ โโโ utils.ts # NEW - Utility functions
- โ โโโ pages/ # EXISTING - Page placeholders
- โ โโโ App.tsx # UPDATED - Add Layout wrapper
- โ โโโ index.css # EXISTING - Global styles
- โโโ package.json # EXISTING - Dependencies
-```
-
----
-
-## Sprint 1-2 Checklist
-
-According to `CUSTOMER_SPA_MASTER_PLAN.md`, Sprint 1-2 tasks:
-
-- [x] **Setup customer-spa build system** - โ
Vite + React + TypeScript configured
-- [x] **Create base layout components** - โ
Header, Footer, Container, Layout
-- [x] **Implement routing** - โ
React Router with routes for all pages
-- [x] **Setup API client** - โ
Client exists with all endpoints defined
-- [x] **Cart state management** - โ
Zustand store with persistence
-- [x] **Authentication flow** - โ
WordPress session integration
-
-**All Sprint 1-2 objectives completed!** โ
-
----
-
-## Next Steps (Sprint 3-4)
-
-### Immediate: Build & Test
-1. **Build customer-spa:**
- ```bash
- cd customer-spa
- npm install
- npm run build
- ```
-
-2. **Create test pages in WordPress:**
- - Create page "Shop" with `[woonoow_shop]`
- - Create page "Cart" with `[woonoow_cart]`
- - Create page "Checkout" with `[woonoow_checkout]`
- - Create page "My Account" with `[woonoow_account]`
-
-3. **Test API endpoints:**
- ```bash
- # Test shop API
- curl "https://woonoow.local/wp-json/woonoow/v1/shop/products"
-
- # Test cart API
- curl "https://woonoow.local/wp-json/woonoow/v1/cart"
- ```
-
-### Sprint 3-4: Product Catalog
-According to the master plan:
-- [ ] Product listing page (with real data)
-- [ ] Product filters (category, price, search)
-- [ ] Product search functionality
-- [ ] Product detail page (with variations)
-- [ ] Product variations selector
-- [ ] Image gallery with zoom
-- [ ] Related products section
-
----
-
-## Technical Notes
-
-### API Design
-- All customer-facing routes use `/woonoow/v1` namespace
-- Public routes (shop) use `'permission_callback' => '__return_true'`
-- Protected routes (account) check `is_user_logged_in()`
-- Consistent response format with proper HTTP status codes
-
-### Frontend Architecture
-- **Hybrid approach:** Works with any theme via shortcodes
-- **Progressive enhancement:** Theme provides layout, WooNooW provides interactivity
-- **Mobile-first:** Responsive design with Tailwind utilities
-- **Performance:** Code splitting, lazy loading, optimized builds
-
-### WordPress Integration
-- **Safe activation:** No database changes, reversible
-- **Theme compatibility:** Works with any theme
-- **SEO-friendly:** Server-rendered product pages (future)
-- **Tracking-ready:** WooCommerce event triggers for pixels (future)
-
----
-
-## Known Limitations
-
-### Current Sprint (1-2)
-1. **Pages are placeholders** - Need real implementations in Sprint 3-4
-2. **No product data rendering** - API works, but UI needs to consume it
-3. **No checkout flow** - CheckoutController not created yet (Sprint 5-6)
-4. **No cart drawer** - Cart page exists, but no slide-out drawer yet
-
-### Future Sprints
-- Sprint 3-4: Product catalog implementation
-- Sprint 5-6: Cart drawer + Checkout flow
-- Sprint 7-8: My Account pages implementation
-- Sprint 9-10: Polish, testing, performance optimization
-
----
-
-## Testing Checklist
-
-### Backend API Testing
-- [ ] Test `/shop/products` - Returns product list
-- [ ] Test `/shop/products/{id}` - Returns single product
-- [ ] Test `/shop/categories` - Returns categories
-- [ ] Test `/cart` - Returns empty cart
-- [ ] Test `/cart/add` - Adds product to cart
-- [ ] Test `/account/orders` - Requires login, returns orders
-
-### Frontend Testing
-- [ ] Build customer-spa successfully
-- [ ] Create test pages with shortcodes
-- [ ] Verify assets load on shortcode pages
-- [ ] Check `window.woonoowCustomer` config exists
-- [ ] Verify Header renders with cart count
-- [ ] Verify Footer renders with links
-- [ ] Test navigation between pages
-
-### Integration Testing
-- [ ] Shortcodes render mount point
-- [ ] React app mounts on shortcode pages
-- [ ] API calls work from frontend
-- [ ] Cart state persists in localStorage
-- [ ] User login state detected correctly
-
----
-
-## Success Criteria
-
-โ
**Sprint 1-2 is complete when:**
-- [x] Backend API controllers created and registered
-- [x] Frontend layout components created
-- [x] WordPress integration (shortcodes, assets) working
-- [x] Authentication flow implemented
-- [x] Build system configured
-- [ ] **Build succeeds** (pending: run `npm run build`)
-- [ ] **Test pages work** (pending: create WordPress pages)
-
-**Status:** 5/7 complete - Ready for build & testing phase
-
----
-
-## Commands Reference
-
-### Build Customer SPA
-```bash
-cd /Users/dwindown/Local\ Sites/woonoow/app/public/wp-content/plugins/woonoow/customer-spa
-npm install
-npm run build
-```
-
-### Dev Mode (Hot Reload)
-```bash
-cd customer-spa
-npm run dev
-# Runs at https://woonoow.local:5174
-```
-
-### Test API Endpoints
-```bash
-# Shop API
-curl "https://woonoow.local/wp-json/woonoow/v1/shop/products"
-
-# Cart API
-curl "https://woonoow.local/wp-json/woonoow/v1/cart" \
- -H "X-WP-Nonce: YOUR_NONCE"
-
-# Account API (requires auth)
-curl "https://woonoow.local/wp-json/woonoow/v1/account/orders" \
- -H "X-WP-Nonce: YOUR_NONCE" \
- -H "Cookie: wordpress_logged_in_..."
-```
-
----
-
-## Conclusion
-
-**Sprint 1-2 foundation is complete!** ๐
-
-The customer-spa now has:
-- โ
Solid backend API foundation
-- โ
Clean frontend architecture
-- โ
WordPress integration layer
-- โ
Authentication flow
-- โ
Base layout components
-
-**Ready for:**
-- Building the customer-spa
-- Creating test pages
-- Moving to Sprint 3-4 (Product Catalog implementation)
-
-**Next session:** Build, test, and start implementing real product listing page.
diff --git a/SPRINT_3-4_PLAN.md b/SPRINT_3-4_PLAN.md
deleted file mode 100644
index 716c0f0..0000000
--- a/SPRINT_3-4_PLAN.md
+++ /dev/null
@@ -1,288 +0,0 @@
-# Sprint 3-4: Product Catalog & Cart
-
-**Duration:** Sprint 3-4 (2 weeks)
-**Status:** ๐ Ready to Start
-**Prerequisites:** โ
Sprint 1-2 Complete
-
----
-
-## Objectives
-
-Build out the complete product catalog experience and shopping cart functionality.
-
-### Sprint 3: Product Catalog Enhancement
-1. **Product Detail Page** - Full product view with variations
-2. **Product Filters** - Category, price, attributes
-3. **Product Search** - Real-time search with debouncing
-4. **Product Sorting** - Price, popularity, rating, date
-
-### Sprint 4: Shopping Cart
-1. **Cart Page** - View and manage cart items
-2. **Cart Sidebar** - Quick cart preview
-3. **Cart API Integration** - Sync with WooCommerce cart
-4. **Coupon Application** - Apply and remove coupons
-
----
-
-## Sprint 3: Product Catalog Enhancement
-
-### 1. Product Detail Page (`/product/:id`)
-
-**File:** `customer-spa/src/pages/Product/index.tsx`
-
-**Features:**
-- Product images gallery with zoom
-- Product title, price, description
-- Variation selector (size, color, etc.)
-- Quantity selector
-- Add to cart button
-- Related products
-- Product reviews (if enabled)
-
-**API Endpoints:**
-- `GET /shop/products/:id` - Get product details
-- `GET /shop/products/:id/related` - Get related products (optional)
-
-**Components to Create:**
-- `ProductGallery.tsx` - Image gallery with thumbnails
-- `VariationSelector.tsx` - Select product variations
-- `QuantityInput.tsx` - Quantity selector
-- `ProductMeta.tsx` - SKU, categories, tags
-- `RelatedProducts.tsx` - Related products carousel
-
----
-
-### 2. Product Filters
-
-**File:** `customer-spa/src/components/Shop/Filters.tsx`
-
-**Features:**
-- Category filter (tree structure)
-- Price range slider
-- Attribute filters (color, size, brand, etc.)
-- Stock status filter
-- On sale filter
-- Clear all filters button
-
-**State Management:**
-- Use URL query parameters for filters
-- Persist filters in URL for sharing
-
-**Components:**
-- `CategoryFilter.tsx` - Hierarchical category tree
-- `PriceRangeFilter.tsx` - Price slider
-- `AttributeFilter.tsx` - Checkbox list for attributes
-- `ActiveFilters.tsx` - Show active filters with remove buttons
-
----
-
-### 3. Product Search Enhancement
-
-**Current:** Basic search input
-**Enhancement:** Real-time search with suggestions
-
-**Features:**
-- Search as you type
-- Search suggestions dropdown
-- Recent searches
-- Popular searches
-- Product thumbnails in results
-- Keyboard navigation (arrow keys, enter, escape)
-
-**File:** `customer-spa/src/components/Shop/SearchBar.tsx`
-
----
-
-### 4. Product Sorting
-
-**Features:**
-- Sort by: Default, Popularity, Rating, Price (low to high), Price (high to low), Latest
-- Dropdown selector
-- Persist in URL
-
-**File:** `customer-spa/src/components/Shop/SortDropdown.tsx`
-
----
-
-## Sprint 4: Shopping Cart
-
-### 1. Cart Page (`/cart`)
-
-**File:** `customer-spa/src/pages/Cart/index.tsx`
-
-**Features:**
-- Cart items list with thumbnails
-- Quantity adjustment (+ / -)
-- Remove item button
-- Update cart button
-- Cart totals (subtotal, tax, shipping, total)
-- Coupon code input
-- Proceed to checkout button
-- Continue shopping link
-- Empty cart state
-
-**Components:**
-- `CartItem.tsx` - Single cart item row
-- `CartTotals.tsx` - Cart totals summary
-- `CouponForm.tsx` - Apply coupon code
-- `EmptyCart.tsx` - Empty cart message
-
----
-
-### 2. Cart Sidebar/Drawer
-
-**File:** `customer-spa/src/components/Cart/CartDrawer.tsx`
-
-**Features:**
-- Slide-in from right
-- Mini cart items (max 5, then scroll)
-- Cart totals
-- View cart button
-- Checkout button
-- Close button
-- Backdrop overlay
-
-**Trigger:**
-- Click cart icon in header
-- Auto-open when item added (optional)
-
----
-
-### 3. Cart API Integration
-
-**Endpoints:**
-- `GET /cart` - Get current cart
-- `POST /cart/add` - Add item to cart
-- `PUT /cart/update` - Update item quantity
-- `DELETE /cart/remove` - Remove item
-- `POST /cart/apply-coupon` - Apply coupon
-- `DELETE /cart/remove-coupon` - Remove coupon
-
-**State Management:**
-- Zustand store already created (`customer-spa/src/lib/cart/store.ts`)
-- Sync with WooCommerce session
-- Persist cart in localStorage
-- Handle cart conflicts (server vs local)
-
----
-
-### 4. Coupon System
-
-**Features:**
-- Apply coupon code
-- Show discount amount
-- Show coupon description
-- Remove coupon button
-- Error handling (invalid, expired, usage limit)
-
-**Backend:**
-- Already implemented in `CartController.php`
-- `POST /cart/apply-coupon`
-- `DELETE /cart/remove-coupon`
-
----
-
-## Technical Considerations
-
-### Performance
-- Lazy load product images
-- Implement infinite scroll for product grid (optional)
-- Cache product data with TanStack Query
-- Debounce search and filter inputs
-
-### UX Enhancements
-- Loading skeletons for all states
-- Optimistic updates for cart actions
-- Toast notifications for user feedback
-- Smooth transitions and animations
-- Mobile-first responsive design
-
-### Error Handling
-- Network errors
-- Out of stock products
-- Invalid variations
-- Cart conflicts
-- API timeouts
-
-### Accessibility
-- Keyboard navigation
-- Screen reader support
-- Focus management
-- ARIA labels
-- Color contrast
-
----
-
-## Implementation Order
-
-### Week 1 (Sprint 3)
-1. **Day 1-2:** Product Detail Page
- - Basic layout and product info
- - Image gallery
- - Add to cart functionality
-
-2. **Day 3:** Variation Selector
- - Handle simple and variable products
- - Update price based on variation
- - Validation
-
-3. **Day 4-5:** Filters & Search
- - Category filter
- - Price range filter
- - Search enhancement
- - Sort dropdown
-
-### Week 2 (Sprint 4)
-1. **Day 1-2:** Cart Page
- - Cart items list
- - Quantity adjustment
- - Cart totals
- - Coupon application
-
-2. **Day 3:** Cart Drawer
- - Slide-in sidebar
- - Mini cart items
- - Quick actions
-
-3. **Day 4:** Cart API Integration
- - Sync with backend
- - Handle conflicts
- - Error handling
-
-4. **Day 5:** Polish & Testing
- - Responsive design
- - Loading states
- - Error states
- - Cross-browser testing
-
----
-
-## Success Criteria
-
-### Sprint 3
-- โ
Product detail page displays all product info
-- โ
Variations can be selected and price updates
-- โ
Filters work and update product list
-- โ
Search returns relevant results
-- โ
Sorting works correctly
-
-### Sprint 4
-- โ
Cart page displays all cart items
-- โ
Quantity can be adjusted
-- โ
Items can be removed
-- โ
Coupons can be applied and removed
-- โ
Cart drawer opens and closes smoothly
-- โ
Cart syncs with WooCommerce backend
-- โ
Cart persists across page reloads
-
----
-
-## Next Steps
-
-1. Review this plan
-2. Confirm priorities
-3. Start with Product Detail Page
-4. Implement features incrementally
-5. Test each feature before moving to next
-
-**Ready to start Sprint 3?** ๐
diff --git a/STORE_UI_UX_GUIDE.md b/STORE_UI_UX_GUIDE.md
deleted file mode 100644
index 98cab01..0000000
--- a/STORE_UI_UX_GUIDE.md
+++ /dev/null
@@ -1,634 +0,0 @@
-# WooNooW Store UI/UX Guide
-## Official Design System & Standards
-
-**Version:** 1.0
-**Last Updated:** November 26, 2025
-**Status:** Living Document (Updated by conversation)
-
----
-
-## ๐ Purpose
-
-This document serves as the single source of truth for all UI/UX decisions in WooNooW Customer SPA. All design and implementation decisions should reference this guide.
-
-**Philosophy:** Pragmatic, not dogmatic. Follow convention when strong, follow research when clear, use hybrid when beneficial.
-
----
-
-## ๐ฏ Core Principles
-
-1. **Convention Over Innovation** - Users expect familiar patterns
-2. **Research-Backed Decisions** - When convention is weak or wrong
-3. **Mobile-First Approach** - Design for mobile, enhance for desktop
-4. **Performance Matters** - Fast > Feature-rich
-5. **Accessibility Always** - WCAG 2.1 AA minimum
-
----
-
-## ๐ Layout Standards
-
-### Container Widths
-
-```css
-Mobile: 100% (with padding)
-Tablet: 768px max-width
-Desktop: 1200px max-width
-Wide: 1400px max-width
-```
-
-### Spacing Scale
-
-```css
-xs: 0.25rem (4px)
-sm: 0.5rem (8px)
-md: 1rem (16px)
-lg: 1.5rem (24px)
-xl: 2rem (32px)
-2xl: 3rem (48px)
-```
-
-### Breakpoints
-
-```css
-sm: 640px
-md: 768px
-lg: 1024px
-xl: 1280px
-2xl: 1536px
-```
-
----
-
-## ๐จ Typography
-
-### Hierarchy
-
-```
-H1 (Product Title): 28-32px, bold
-H2 (Section Title): 24-28px, bold
-H3 (Subsection): 20-24px, semibold
-Price (Primary): 24-28px, bold
-Price (Sale): 24-28px, bold, red
-Price (Regular): 18-20px, line-through, gray
-Body: 16px, regular
-Small: 14px, regular
-Tiny: 12px, regular
-```
-
-### Font Stack
-
-```css
-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
- Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
-```
-
-### Rules
-
-- โ
Title > Price in hierarchy (we're not a marketplace)
-- โ
Use weight and color for emphasis, not just size
-- โ
Line height: 1.5 for body, 1.2 for headings
-- โ Don't use more than 3 font sizes per section
-
----
-
-## ๐ผ๏ธ Product Page Standards
-
-### Image Gallery
-
-#### Desktop:
-```
-Layout:
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ [Main Image] โ
-โ (Large, square) โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-[โญ] [โญ] [โญ] [โญ] [โญ] โ Thumbnails (96-112px)
-```
-
-**Rules:**
-- โ
Thumbnails: 96-112px (24-28 in Tailwind)
-- โ
Horizontal scrollable if >4 images
-- โ
Active thumbnail: Primary border + ring
-- โ
Main image: object-contain with padding
-- โ
Click thumbnail โ change main image
-- โ
Click main image โ fullscreen lightbox
-
-#### Mobile:
-```
-Layout:
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ [Main Image] โ
-โ (Full width, square) โ
-โ โ โ โ โ โ โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Rules:**
-- โ
Dots only (NO thumbnails)
-- โ
Swipe gesture for navigation
-- โ
Dots: 8-10px, centered below image
-- โ
Active dot: Primary color, larger
-- โ
Image counter optional (e.g., "1/5")
-- โ NO thumbnails (redundant with dots)
-
-**Rationale:** Convention (Amazon, Tokopedia, Shopify all use dots only on mobile)
-
----
-
-### Variation Selectors
-
-#### Pattern: Pills/Buttons (NOT Dropdowns)
-
-**Color Variations:**
-```html
-[โฌ White] [โฌ Black] [๐ด Red] [๐ต Blue]
-```
-
-**Size/Text Variations:**
-```html
-[36] [37] [38] [39] [40] [41]
-```
-
-**Rules:**
-- โ
All options visible at once
-- โ
Pills: min 44x44px (touch target)
-- โ
Active state: Primary background + white text
-- โ
Hover state: Border color change
-- โ
Disabled state: Gray + opacity 50%
-- โ NO dropdowns (hides options, poor UX)
-
-**Rationale:** Convention + Research align (Nielsen Norman Group)
-
----
-
-### Product Information Sections
-
-#### Pattern: Vertical Accordions
-
-**Desktop & Mobile:**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ โผ Product Description โ โ Auto-expanded
-โ Full description text... โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ โถ Specifications โ โ Collapsed
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ โถ Customer Reviews โ โ Collapsed
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Rules:**
-- โ
Description: Auto-expanded on load
-- โ
Other sections: Collapsed by default
-- โ
Arrow icon: Rotates on expand/collapse
-- โ
Smooth animation: 200-300ms
-- โ
Full-width clickable header
-- โ NO horizontal tabs (27% overlook rate)
-
-**Rationale:** Research (Baymard: vertical > horizontal)
-
----
-
-### Specifications Table
-
-**Pattern: Scannable Two-Column Table**
-
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Material โ 100% Cotton โ
-โ Weight โ 250g โ
-โ Color โ Black, White, Gray โ
-โ Size โ S, M, L, XL โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Rules:**
-- โ
Label column: 33% width, bold, gray background
-- โ
Value column: 67% width, regular weight
-- โ
Padding: py-4 px-6
-- โ
Border: Bottom border on each row
-- โ
Last row: No border
-- โ NO plain table (hard to scan)
-
-**Rationale:** Research (scannable > plain)
-
----
-
-### Buy Section
-
-#### Desktop & Mobile:
-
-**Structure:**
-```
-1. Product Title (H1)
-2. Price (prominent, but not overwhelming)
-3. Stock Status (badge with icon)
-4. Short Description (if exists)
-5. Variation Selectors (pills)
-6. Quantity Selector (large buttons)
-7. Add to Cart (prominent CTA)
-8. Wishlist Button (secondary)
-9. Trust Badges (shipping, returns, secure)
-10. Product Meta (SKU, categories)
-```
-
-**Price Display:**
-```html
-
-
- $79.00
- $99.00
- SAVE 20%
-
-
-
-
$99.00
-```
-
-**Stock Status:**
-```html
-
-
-
- In Stock - Ships Today
-
-
-
-
-
- Out of Stock
-
-```
-
-**Add to Cart Button:**
-```html
-
-
-```
-
-**Trust Badges:**
-```html
-
-
-
-
-
-
Free Shipping
-
On orders over $50
-
-
-
-
-
-
-
-
30-Day Returns
-
Money-back guarantee
-
-
-
-
-
-
-
-
Secure Checkout
-
SSL encrypted payment
-
-
-
-```
-
----
-
-### Mobile-Specific Patterns
-
-#### Sticky Bottom Bar (Optional - Future Enhancement)
-
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ $79.00 [Add to Cart] โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Rules:**
-- โ
Fixed at bottom on scroll
-- โ
Shows price + CTA
-- โ
Appears after scrolling past buy section
-- โ
z-index: 50 (above content)
-- โ
Shadow for depth
-
-**Rationale:** Convention (Tokopedia does this)
-
----
-
-## ๐จ Color System
-
-### Primary Colors
-
-```css
-Primary: #222222 (dark gray/black)
-Primary Hover: #000000
-Primary Light: #F5F5F5
-```
-
-### Semantic Colors
-
-```css
-Success: #10B981 (green)
-Error: #EF4444 (red)
-Warning: #F59E0B (orange)
-Info: #3B82F6 (blue)
-```
-
-### Sale/Discount
-
-```css
-Sale Price: #DC2626 (red-600)
-Sale Badge: #DC2626 bg, white text
-Savings: #DC2626 text
-```
-
-### Stock Status
-
-```css
-In Stock: #10B981 (green-600)
-Low Stock: #F59E0B (orange-500)
-Out of Stock: #EF4444 (red-500)
-```
-
-### Neutral Scale
-
-```css
-Gray 50: #F9FAFB
-Gray 100: #F3F4F6
-Gray 200: #E5E7EB
-Gray 300: #D1D5DB
-Gray 400: #9CA3AF
-Gray 500: #6B7280
-Gray 600: #4B5563
-Gray 700: #374151
-Gray 800: #1F2937
-Gray 900: #111827
-```
-
----
-
-## ๐ Interactive Elements
-
-### Buttons
-
-**Primary CTA:**
-```css
-Height: h-14 (56px)
-Padding: px-6
-Font: text-lg font-bold
-Border Radius: rounded-lg
-Shadow: shadow-lg hover:shadow-xl
-```
-
-**Secondary:**
-```css
-Height: h-12 (48px)
-Padding: px-4
-Font: text-base font-semibold
-Border: border-2
-```
-
-**Quantity Buttons:**
-```css
-Size: 44x44px minimum (touch target)
-Border: border-2
-Icon: Plus/Minus (20px)
-```
-
-### Touch Targets
-
-**Minimum Sizes:**
-```css
-Mobile: 44x44px (WCAG AAA)
-Desktop: 40x40px (acceptable)
-```
-
-**Rules:**
-- โ
All interactive elements: min 44x44px on mobile
-- โ
Adequate spacing between targets (8px min)
-- โ
Visual feedback on tap/click
-- โ
Disabled state clearly indicated
-
----
-
-## ๐ผ๏ธ Images
-
-### Product Images
-
-**Main Image:**
-```css
-Aspect Ratio: 1:1 (square)
-Object Fit: object-contain (shows full product)
-Padding: p-4 (breathing room)
-Background: white or light gray
-Border: border-2 border-gray-200
-Shadow: shadow-lg
-```
-
-**Thumbnails:**
-```css
-Desktop: 96-112px (w-24 md:w-28)
-Mobile: N/A (use dots)
-Aspect Ratio: 1:1
-Object Fit: object-cover
-Border: border-2
-Active: border-primary ring-4 ring-primary
-```
-
-**Rules:**
-- โ
Always use `!h-full` to override WooCommerce styles
-- โ
Lazy loading for performance
-- โ
Alt text for accessibility
-- โ
WebP format when possible
-- โ Never use object-cover for main image (crops product)
-
----
-
-## ๐ฑ Responsive Behavior
-
-### Grid Layout
-
-**Product Page:**
-```css
-Mobile: grid-cols-1 (single column)
-Desktop: grid-cols-2 (image | info)
-Gap: gap-8 lg:gap-12
-```
-
-### Image Gallery
-
-**Desktop:**
-- Thumbnails: Horizontal scroll if >4 images
-- Arrows: Show when >4 images
-- Layout: Main image + thumbnail strip below
-
-**Mobile:**
-- Dots: Always visible
-- Swipe: Primary interaction
-- Counter: Optional (e.g., "1/5")
-
-### Typography
-
-**Responsive Sizes:**
-```css
-Title: text-2xl md:text-3xl
-Price: text-2xl md:text-2xl (same)
-Body: text-base (16px, no change)
-Small: text-sm md:text-sm (same)
-```
-
----
-
-## โฟ Accessibility
-
-### WCAG 2.1 AA Requirements
-
-**Color Contrast:**
-- Text: 4.5:1 minimum
-- Large text (18px+): 3:1 minimum
-- Interactive elements: 3:1 minimum
-
-**Keyboard Navigation:**
-- โ
All interactive elements focusable
-- โ
Visible focus indicators
-- โ
Logical tab order
-- โ
Skip links for main content
-
-**Screen Readers:**
-- โ
Semantic HTML (h1, h2, nav, main, etc.)
-- โ
Alt text for images
-- โ
ARIA labels for icons
-- โ
Live regions for dynamic content
-
-**Touch Targets:**
-- โ
Minimum 44x44px on mobile
-- โ
Adequate spacing (8px min)
-
----
-
-## ๐ Performance
-
-### Loading Strategy
-
-**Critical:**
-- Hero image (main product image)
-- Product title, price, CTA
-- Variation selectors
-
-**Deferred:**
-- Thumbnails (lazy load)
-- Description content
-- Reviews section
-- Related products
-
-**Rules:**
-- โ
Lazy load images below fold
-- โ
Skeleton loading states
-- โ
Optimize images (WebP, compression)
-- โ
Code splitting for routes
-- โ No layout shift (reserve space)
-
----
-
-## ๐ Component Checklist
-
-### Product Page Must-Haves
-
-**Above the Fold:**
-- [ ] Breadcrumb navigation
-- [ ] Product title (H1)
-- [ ] Price display (with sale if applicable)
-- [ ] Stock status badge
-- [ ] Main product image
-- [ ] Image navigation (thumbnails/dots)
-- [ ] Variation selectors (pills)
-- [ ] Quantity selector
-- [ ] Add to Cart button
-- [ ] Trust badges
-
-**Below the Fold:**
-- [ ] Product description (auto-expanded)
-- [ ] Specifications table (collapsed)
-- [ ] Reviews section (collapsed)
-- [ ] Product meta (SKU, categories)
-- [ ] Related products (future)
-
-**Mobile Specific:**
-- [ ] Dots for image navigation
-- [ ] Large touch targets (44x44px)
-- [ ] Responsive text sizes
-- [ ] Collapsible sections
-- [ ] Optional: Sticky bottom bar
-
-**Desktop Specific:**
-- [ ] Thumbnails for image navigation
-- [ ] Hover states
-- [ ] Larger layout (2-column grid)
-
----
-
-## ๐ฏ Decision Log
-
-### Image Gallery
-- **Decision:** Dots only on mobile, thumbnails on desktop
-- **Rationale:** Convention (Amazon, Tokopedia, Shopify)
-- **Date:** Nov 26, 2025
-
-### Variation Selectors
-- **Decision:** Pills/buttons, not dropdowns
-- **Rationale:** Convention + Research align (NN/g)
-- **Date:** Nov 26, 2025
-
-### Typography Hierarchy
-- **Decision:** Title > Price (28-32px > 24-28px)
-- **Rationale:** Context (we're not a marketplace)
-- **Date:** Nov 26, 2025
-
-### Description Pattern
-- **Decision:** Auto-expanded accordion
-- **Rationale:** Research (don't hide primary content)
-- **Date:** Nov 26, 2025
-
-### Tabs vs Accordions
-- **Decision:** Vertical accordions, not horizontal tabs
-- **Rationale:** Research (27% overlook tabs)
-- **Date:** Nov 26, 2025
-
----
-
-## ๐ References
-
-### Research Sources
-- Baymard Institute UX Research
-- Nielsen Norman Group Guidelines
-- WCAG 2.1 Accessibility Standards
-
-### Convention Sources
-- Amazon (marketplace reference)
-- Tokopedia (marketplace reference)
-- Shopify (e-commerce reference)
-
----
-
-## ๐ Version History
-
-**v1.0 - Nov 26, 2025**
-- Initial guide created
-- Product page standards defined
-- Decision framework established
-
----
-
-**Status:** โ
Active
-**Maintenance:** Updated by conversation
-**Owner:** WooNooW Development Team
diff --git a/admin-spa/BUGFIXES.md b/admin-spa/BUGFIXES.md
deleted file mode 100644
index eac5cd4..0000000
--- a/admin-spa/BUGFIXES.md
+++ /dev/null
@@ -1,242 +0,0 @@
-# Bug Fixes & User Feedback Resolution
-
-## All 7 Issues Resolved โ
-
----
-
-### 1. WordPress Media Library Not Loading
-
-**Issue:**
-- Error: "WordPress media library is not loaded. Please refresh the page."
-- Blocking users from inserting images
-
-**Root Cause:**
-- WordPress Media API (`window.wp.media`) not available in some contexts
-- No fallback mechanism
-
-**Solution:**
-```typescript
-// Added fallback to URL prompt
-if (typeof window.wp === 'undefined' || typeof window.wp.media === 'undefined') {
- const url = window.prompt('WordPress Media library is not loaded. Please enter image URL:');
- if (url) {
- onSelect({ url, id: 0, title: 'External Image', filename: url.split('/').pop() || 'image' });
- }
- return;
-}
-```
-
-**Result:**
-- Users can still insert images via URL if WP Media fails
-- Better error handling
-- No blocking errors
-
----
-
-### 2. Button Variables - Too Many Options
-
-**Issue:**
-- All variables shown in button link field
-- Confusing for users (why show customer_name for a link?)
-
-**Solution:**
-```typescript
-// Filter to only show URL variables
-{variables.filter(v => v.includes('_url')).map((variable) => (
-
setButtonHref(buttonHref + `{${variable}}`)}>{`{${variable}}`}
-))}
-```
-
-**Before:**
-```
-{order_number} {order_total} {customer_name} {customer_email} ...
-```
-
-**After:**
-```
-{order_url} {store_url}
-```
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-- `components/EmailBuilder/EmailBuilder.tsx`
-
----
-
-### 3. Color Customization - Future Feature
-
-**Issue:**
-- Colors are hardcoded:
- - Hero card gradient: `#667eea` to `#764ba2`
- - Button primary: `#7f54b3`
- - Button secondary border: `#7f54b3`
-
-**Plan:**
-- Will be added to email customization form
-- Allow users to set brand colors
-- Apply to all email templates
-- Store in settings
-
-**Note:**
-Confirmed for future implementation. Not blocking current release.
-
----
-
-### 4 & 5. Headings Not Visible in Editor & Builder
-
-**Issue:**
-- Headings (H1-H4) looked like paragraphs
-- No visual distinction
-- Confusing for users
-
-**Root Cause:**
-- No CSS styles applied to heading elements
-- Default browser styles insufficient
-
-**Solution:**
-Added Tailwind utility classes for heading styles:
-
-```typescript
-// RichTextEditor
-className="prose prose-sm max-w-none [&_h1]:text-3xl [&_h1]:font-bold [&_h1]:mt-4 [&_h1]:mb-2 [&_h2]:text-2xl [&_h2]:font-bold [&_h2]:mt-3 [&_h2]:mb-2 [&_h3]:text-xl [&_h3]:font-bold [&_h3]:mt-2 [&_h3]:mb-1 [&_h4]:text-lg [&_h4]:font-bold [&_h4]:mt-2 [&_h4]:mb-1"
-
-// BlockRenderer (builder preview)
-className="prose prose-sm max-w-none [&_h1]:text-3xl [&_h1]:font-bold [&_h1]:mt-0 [&_h1]:mb-4 [&_h2]:text-2xl [&_h2]:font-bold [&_h2]:mt-0 [&_h2]:mb-3 [&_h3]:text-xl [&_h3]:font-bold [&_h3]:mt-0 [&_h3]:mb-2 [&_h4]:text-lg [&_h4]:font-bold [&_h4]:mt-0 [&_h4]:mb-2"
-```
-
-**Heading Sizes:**
-- **H1**: 3xl (1.875rem / 30px), bold
-- **H2**: 2xl (1.5rem / 24px), bold
-- **H3**: xl (1.25rem / 20px), bold
-- **H4**: lg (1.125rem / 18px), bold
-
-**Result:**
-- Headings now visually distinct
-- Clear hierarchy
-- Matches email preview
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-- `components/EmailBuilder/BlockRenderer.tsx`
-
----
-
-### 6. Missing Order Items Variable
-
-**Issue:**
-- No variable for product list/table
-- Users can't show ordered products in emails
-
-**Solution:**
-Added `order_items` variable to order variables:
-
-```php
-'order_items' => __('Order Items (formatted table)', 'woonoow'),
-```
-
-**Usage:**
-```html
-[card]
-
Order Summary
-{order_items}
-[/card]
-```
-
-**Will Render:**
-```html
-
-
- | Product Name |
- Quantity |
- Price |
-
-
-
-```
-
-**File Modified:**
-- `includes/Core/Notifications/TemplateProvider.php`
-
----
-
-### 7. Edit Icon on Spacer & Divider
-
-**Issue:**
-- Edit button (โ) shown for spacer and divider
-- No options to edit (they have no configurable properties)
-- Clicking does nothing
-
-**Solution:**
-Conditional rendering of edit button:
-
-```typescript
-{/* Only show edit button for card and button blocks */}
-{(block.type === 'card' || block.type === 'button') && (
-
-)}
-```
-
-**Controls Now:**
-- **Card**: โ โ โ ร (all controls)
-- **Button**: โ โ โ ร (all controls)
-- **Spacer**: โ โ ร (no edit)
-- **Divider**: โ โ ร (no edit)
-
-**File Modified:**
-- `components/EmailBuilder/BlockRenderer.tsx`
-
----
-
-## Testing Checklist
-
-### Issue 1: WP Media Fallback
-- [ ] Try inserting image when WP Media is loaded
-- [ ] Try inserting image when WP Media is not loaded
-- [ ] Verify fallback prompt appears
-- [ ] Verify image inserts correctly
-
-### Issue 2: Button Variables
-- [ ] Open button dialog in RichTextEditor
-- [ ] Verify only URL variables shown
-- [ ] Open button dialog in EmailBuilder
-- [ ] Verify only URL variables shown
-
-### Issue 3: Color Customization
-- [ ] Note documented for future implementation
-- [ ] Colors currently hardcoded (expected)
-
-### Issue 4 & 5: Heading Display
-- [ ] Create card with H1 heading
-- [ ] Verify H1 is large and bold in editor
-- [ ] Verify H1 is large and bold in builder
-- [ ] Test H2, H3, H4 similarly
-- [ ] Verify preview matches
-
-### Issue 6: Order Items Variable
-- [ ] Check variable list includes `order_items`
-- [ ] Insert `{order_items}` in template
-- [ ] Verify description shows "formatted table"
-
-### Issue 7: Edit Icon Removal
-- [ ] Hover over spacer block
-- [ ] Verify no edit button (only โ โ ร)
-- [ ] Hover over divider block
-- [ ] Verify no edit button (only โ โ ร)
-- [ ] Hover over card block
-- [ ] Verify edit button present (โ โ โ ร)
-
----
-
-## Summary
-
-All 7 user-reported issues have been resolved:
-
-1. โ
**WP Media Fallback** - No more blocking errors
-2. โ
**Button Variables Filtered** - Only relevant variables shown
-3. โ
**Color Customization Noted** - Future feature documented
-4. โ
**Headings Visible in Editor** - Proper styling applied
-5. โ
**Headings Visible in Builder** - Consistent with editor
-6. โ
**Order Items Variable** - Product list support added
-7. โ
**Edit Icon Removed** - Only on editable blocks
-
-**Status: Ready for Testing** ๐
diff --git a/admin-spa/EMAIL_BUILDER_COMPLETE.md b/admin-spa/EMAIL_BUILDER_COMPLETE.md
deleted file mode 100644
index 195ee28..0000000
--- a/admin-spa/EMAIL_BUILDER_COMPLETE.md
+++ /dev/null
@@ -1,329 +0,0 @@
-# Email Template & Builder System - Complete โ
-
-## Overview
-The WooNooW email template and builder system is now production-ready with improved templates, enhanced markdown support, and a fully functional visual builder.
-
----
-
-## ๐ What's Complete
-
-### 1. **Default Email Templates** โ
-**File:** `includes/Email/DefaultTemplates.php`
-
-**Features:**
-- โ
16 production-ready email templates (9 customer + 7 staff)
-- โ
Modern, clean markdown format (easy to read and edit)
-- โ
Professional, friendly tone
-- โ
Complete variable support
-- โ
Ready to use without any customization
-
-**Templates Included:**
-
-**Customer Templates:**
-1. Order Placed - Initial order confirmation
-2. Order Confirmed - Payment confirmed, ready to ship
-3. Order Shipped - Tracking information
-4. Order Completed - Delivery confirmation with review request
-5. Order Cancelled - Cancellation notice with refund info
-6. Payment Received - Payment confirmation
-7. Payment Failed - Payment issue with resolution steps
-8. Customer Registered - Welcome email with account benefits
-9. Customer VIP Upgraded - VIP status announcement
-
-**Staff Templates:**
-1. Order Placed - New order notification
-2. Order Confirmed - Order ready to process
-3. Order Shipped - Shipment confirmation
-4. Order Completed - Order lifecycle complete
-5. Order Cancelled - Cancellation with action items
-6. Payment Received - Payment notification
-7. Payment Failed - Payment failure alert
-
-**Template Syntax:**
-```
-[card type="hero"]
-Welcome message here
-[/card]
-
-[card]
-**Order Number:** #{order_number}
-**Order Total:** {order_total}
-[/card]
-
-[button url="{order_url}"]View Order Details[/button]
-
----
-
-ยฉ {current_year} {site_name}
-```
-
----
-
-### 2. **Enhanced Markdown Parser** โ
-**File:** `admin-spa/src/lib/markdown-parser.ts`
-
-**New Features:**
-- โ
Button shortcode: `[button url="..."]Text[/button]`
-- โ
Horizontal rules: `---`
-- โ
Checkmarks and bullet points: `โ` `โข` `-` `*`
-- โ
Card blocks with types: `[card type="success"]...[/card]`
-- โ
Bold, italic, headings, lists, links
-- โ
Variable support: `{variable_name}`
-
-**Supported Markdown:**
-```markdown
-# Heading 1
-## Heading 2
-### Heading 3
-
-**Bold text**
-*Italic text*
-
-- List item
-โข Bullet point
-โ Checkmark item
-
-[Link text](url)
-
----
-
-[card type="hero"]
-Card content
-[/card]
-
-[button url="#"]Button Text[/button]
-```
-
----
-
-### 3. **Visual Email Builder** โ
-**File:** `admin-spa/src/components/EmailBuilder/EmailBuilder.tsx`
-
-**Features:**
-- โ
Drag-and-drop block editor
-- โ
Card blocks (default, success, info, warning, hero)
-- โ
Button blocks (solid/outline, width/alignment controls)
-- โ
Image blocks with WordPress media library integration
-- โ
Divider and spacer blocks
-- โ
Rich text editor with variable insertion
-- โ
Mobile fallback UI (desktop-only message)
-- โ
WordPress media modal integration (z-index and pointer-events fixed)
-- โ
Dialog outside-click prevention with WP media exception
-
-**Block Types:**
-1. **Card** - Content container with type variants
-2. **Button** - CTA button with style and layout options
-3. **Image** - Image with alignment and width controls
-4. **Divider** - Horizontal line separator
-5. **Spacer** - Vertical spacing control
-
----
-
-### 4. **Preview System** โ
-**File:** `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`
-
-**Features:**
-- โ
Live preview with actual branding colors
-- โ
Sample data for all variables
-- โ
Mobile-responsive preview (reduced padding on small screens)
-- โ
Button shortcode parsing
-- โ
Card parsing with type support
-- โ
Variable replacement with sample data
-
-**Mobile Responsive:**
-```css
-@media only screen and (max-width: 600px) {
- body { padding: 8px; }
- .card-gutter { padding: 0 8px; }
- .card { padding: 20px 16px; }
-}
-```
-
----
-
-### 5. **Variable System** โ
-
-**Complete Variable Support:**
-
-**Order Variables:**
-- `{order_number}` - Order number/ID
-- `{order_date}` - Order creation date
-- `{order_total}` - Total order amount
-- `{order_url}` - Link to view order
-- `{order_item_table}` - Formatted order items table
-- `{completion_date}` - Order completion date
-
-**Customer Variables:**
-- `{customer_name}` - Customer's full name
-- `{customer_email}` - Customer's email
-- `{customer_phone}` - Customer's phone
-
-**Payment Variables:**
-- `{payment_method}` - Payment method used
-- `{payment_status}` - Payment status
-- `{payment_date}` - Payment date
-- `{transaction_id}` - Transaction ID
-- `{payment_retry_url}` - URL to retry payment
-
-**Shipping Variables:**
-- `{tracking_number}` - Tracking number
-- `{tracking_url}` - Tracking URL
-- `{shipping_carrier}` - Carrier name
-- `{shipping_address}` - Full shipping address
-- `{billing_address}` - Full billing address
-
-**URL Variables:**
-- `{order_url}` - Order details page
-- `{review_url}` - Leave review page
-- `{shop_url}` - Shop homepage
-- `{my_account_url}` - Customer account page
-- `{vip_dashboard_url}` - VIP dashboard
-
-**Store Variables:**
-- `{site_name}` - Store name
-- `{store_url}` - Store URL
-- `{support_email}` - Support email
-- `{current_year}` - Current year
-
-**VIP Variables:**
-- `{vip_free_shipping_threshold}` - Free shipping threshold
-
----
-
-### 6. **Bug Fixes** โ
-
-**WordPress Media Modal Integration:**
-- โ
Fixed z-index conflict (WP media now appears above Radix components)
-- โ
Fixed pointer-events blocking (WP media is now fully clickable)
-- โ
Fixed dialog closing when selecting image (dialog stays open)
-- โ
Added exception for WP media in outside-click prevention
-
-**CSS Fixes:**
-```css
-/* WordPress Media Modal z-index fix */
-.media-modal {
- z-index: 999999 !important;
- pointer-events: auto !important;
-}
-
-.media-modal-content {
- z-index: 1000000 !important;
- pointer-events: auto !important;
-}
-```
-
-**Dialog Fix:**
-```typescript
-onInteractOutside={(e) => {
- const wpMediaOpen = document.querySelector('.media-modal');
- if (wpMediaOpen) {
- e.preventDefault(); // Keep dialog open when WP media is active
- return;
- }
- e.preventDefault(); // Prevent closing for other outside clicks
-}}
-```
-
----
-
-## ๐ฑ Mobile Strategy
-
-**Current Implementation (Optimal):**
-- โ
**Preview Tab** - Works on mobile (read-only viewing)
-- โ
**Code Tab** - Works on mobile (advanced users can edit)
-- โ **Builder Tab** - Desktop-only with clear message
-
-**Why This Works:**
-- Users can view email previews on any device
-- Power users can make quick code edits on mobile
-- Visual builder requires desktop for optimal UX
-
----
-
-## ๐จ Email Customization Features
-
-**Available in Settings:**
-1. **Brand Colors**
- - Primary color
- - Secondary color
- - Hero gradient (start/end)
- - Hero text color
- - Button text color
-
-2. **Layout**
- - Body background color
- - Logo upload
- - Header text
- - Footer text
-
-3. **Social Links**
- - Facebook, Twitter, Instagram, LinkedIn, YouTube, Website
- - Custom icon color (white/color)
-
----
-
-## ๐ Ready for Production
-
-**What Store Owners Get:**
-1. โ
Professional email templates out-of-the-box
-2. โ
Easy customization with visual builder
-3. โ
Code mode for advanced users
-4. โ
Live preview with branding
-5. โ
Mobile-friendly emails
-6. โ
Complete variable system
-7. โ
WordPress media library integration
-
-**No Setup Required:**
-- Templates are ready to use immediately
-- Store owners can start selling without editing emails
-- Customization is optional but easy
-- However, backend integration is still required for full functionality
-
----
-
-## Next Steps (REQUIRED)
-
-**IMPORTANT: Backend Integration Still Needed**
-
-The new `DefaultTemplates.php` is ready but NOT YET WIRED to the backend!
-
-**Current State:**
-- New templates created: `includes/Email/DefaultTemplates.php`
-- Backend still using old: `includes/Core/Notifications/DefaultEmailTemplates.php`
-
-**To Complete Integration:**
-1. Update `includes/Core/Notifications/DefaultEmailTemplates.php` to use new `DefaultTemplates` class
-2. Or replace old class entirely with new one
-3. Update API controller to return correct event counts per recipient
-4. Wire up to database on plugin activation
-5. Hook into WooCommerce order status changes
-6. Test email sending
-
-**Example:**
-```php
-use WooNooW\Email\DefaultTemplates;
-
-// On plugin activation
-$templates = DefaultTemplates::get_all_templates();
-foreach ($templates['customer'] as $event => $body) {
- $subject = DefaultTemplates::get_default_subject('customer', $event);
- // Save to database
-}
-```
-
----
-
-## โ
Phase Complete
-
-The email template and builder system is now **production-ready** and can be shipped to users!
-
-**Key Achievements:**
-- โ
16 professional email templates
-- โ
Visual builder with drag-and-drop
-- โ
WordPress media library integration
-- โ
Mobile-responsive preview
-- โ
Complete variable system
-- โ
All bugs fixed
-- โ
Ready for general store owners
-
-**Time to move on to the next phase!** ๐
diff --git a/admin-spa/EMAIL_BUILDER_IMPROVEMENTS.md b/admin-spa/EMAIL_BUILDER_IMPROVEMENTS.md
deleted file mode 100644
index d93e081..0000000
--- a/admin-spa/EMAIL_BUILDER_IMPROVEMENTS.md
+++ /dev/null
@@ -1,388 +0,0 @@
-# Email Builder - All Improvements Complete! ๐
-
-## Overview
-
-All 5 user-requested improvements have been successfully implemented, creating a professional, user-friendly email template builder that respects WordPress conventions.
-
----
-
-## โ
1. Heading Selector in RichTextEditor
-
-### Problem
-Users couldn't control heading levels without typing HTML manually.
-
-### Solution
-Added a dropdown selector in the RichTextEditor toolbar.
-
-**Features:**
-- Dropdown with options: Paragraph, H1, H2, H3, H4
-- Visual feedback (shows active heading level)
-- One-click heading changes
-- User controls document structure
-
-**UI Location:**
-```
-[Paragraph โผ] [B] [I] [List] [Link] ...
- โ
- First item in toolbar
-```
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-
----
-
-## โ
2. Styled Buttons in Cards
-
-### Problem
-- Buttons in TipTap cards looked raw (unstyled)
-- Different appearance from standalone buttons
-- Not editable (couldn't change text/URL by clicking)
-
-### Solution
-Created a custom TipTap extension for buttons with proper styling.
-
-**Features:**
-- Same inline styles as standalone buttons
-- Solid & Outline styles available
-- Fully editable via dialog
-- Non-editable in editor (atomic node)
-- Click button icon โ dialog opens
-
-**Button Styles:**
-```css
-Solid (Primary):
- background: #7f54b3
- color: white
- padding: 14px 28px
-
-Outline (Secondary):
- background: transparent
- color: #7f54b3
- border: 2px solid #7f54b3
-```
-
-**Files Created:**
-- `components/ui/tiptap-button-extension.ts`
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-
----
-
-## โ
3. Variable Pills for Button Links
-
-### Problem
-- Users had to type `{variable_name}` manually
-- Easy to make typos
-- No suggestions or discovery
-
-### Solution
-Added clickable variable pills under Button Link inputs.
-
-**Features:**
-- Visual display of available variables
-- One-click insertion
-- No typing errors
-- Works in both:
- - RichTextEditor button dialog
- - EmailBuilder button dialog
-
-**UI:**
-```
-Button Link
-โโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ {order_url} โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโ
-
-{order_number} {order_total} {customer_name} ...
- โ Click any pill to insert
-```
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-- `components/EmailBuilder/EmailBuilder.tsx`
-
----
-
-## โ
4. WordPress Media Modal for TipTap Images
-
-### Problem
-- Prompt dialog for image URL
-- Manual URL entry required
-- No access to media library
-
-### Solution
-Integrated WordPress native Media Modal for image selection.
-
-**Features:**
-- Native WordPress Media Modal
-- Browse existing uploads
-- Upload new images
-- Full media library features
-- Auto-sets: src, alt, title
-
-**User Flow:**
-1. Click image icon in RichTextEditor toolbar
-2. WordPress Media Modal opens
-3. Select from library OR upload new
-4. Image inserted with proper attributes
-
-**Files Created:**
-- `lib/wp-media.ts` (WordPress Media helper)
-
-**Files Modified:**
-- `components/ui/rich-text-editor.tsx`
-
----
-
-## โ
5. WordPress Media Modal for Store Logos/Favicon
-
-### Problem
-- Only drag-and-drop or file picker available
-- No access to existing media library
-- Couldn't reuse uploaded assets
-
-### Solution
-Added "Choose from Media Library" button to ImageUpload component.
-
-**Features:**
-- WordPress Media Modal integration
-- Filtered by media type:
- - **Logo**: PNG, JPEG, SVG, WebP
- - **Favicon**: PNG, ICO
-- Browse and reuse existing assets
-- Drag-and-drop still works
-
-**UI:**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ [Upload Icon] โ
-โ โ
-โ Drop image here or click โ
-โ Max size: 2MB โ
-โ โ
-โ [Choose from Media Library] โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Files Modified:**
-- `components/ui/image-upload.tsx`
-- `routes/Settings/Store.tsx`
-
----
-
-## ๐ฆ New Files Created
-
-### 1. `lib/wp-media.ts`
-WordPress Media Modal integration helper.
-
-**Functions:**
-- `openWPMedia()` - Core function with options
-- `openWPMediaImage()` - For general images
-- `openWPMediaLogo()` - For logos (filtered)
-- `openWPMediaFavicon()` - For favicons (filtered)
-
-**Interface:**
-```typescript
-interface WPMediaFile {
- url: string;
- id: number;
- title: string;
- filename: string;
- alt?: string;
- width?: number;
- height?: number;
-}
-```
-
-### 2. `components/ui/tiptap-button-extension.ts`
-Custom TipTap node for styled buttons.
-
-**Features:**
-- Renders with inline styles
-- Atomic node (non-editable)
-- Data attributes for editing
-- Matches email rendering exactly
-
----
-
-## ๐จ User Experience Improvements
-
-### For Non-Technical Users
-- **Heading Control**: No HTML knowledge needed
-- **Visual Buttons**: Professional styling automatically
-- **Variable Discovery**: See all available variables
-- **Media Library**: Familiar WordPress interface
-
-### For Tech-Savvy Users
-- **Code Mode**: Still available with CodeMirror
-- **Full Control**: Can edit raw HTML
-- **Professional Tools**: Syntax highlighting, auto-completion
-
-### For Everyone
-- **Consistent UX**: Matches WordPress conventions
-- **No Learning Curve**: Familiar interfaces
-- **Professional Results**: Beautiful emails every time
-
----
-
-## ๐ Respecting WordPress
-
-### Why This Matters
-
-**1. Familiar Interface**
-Users already know WordPress Media Modal from Posts/Pages.
-
-**2. Existing Assets**
-Access to all uploaded media, no re-uploading.
-
-**3. Better UX**
-No manual URL entry, visual selection.
-
-**4. Professional**
-Native WordPress integration, not a custom solution.
-
-**5. Consistent**
-Same experience across WordPress admin.
-
-### WordPress Integration Details
-
-**Uses:**
-- `window.wp.media` API
-- WordPress REST API for uploads
-- Proper nonce handling
-- User permissions respected
-
-**Compatible with:**
-- WordPress Media Library
-- Custom upload handlers
-- Media organization plugins
-- CDN integrations
-
----
-
-## ๐ Complete Feature List
-
-### Email Builder Features
-โ
Visual block-based editor
-โ
Drag-and-drop reordering
-โ
Card blocks with rich content
-โ
Standalone buttons (outside cards)
-โ
Dividers and spacers
-โ
Code mode with CodeMirror
-โ
Variable insertion
-โ
Preview mode
-โ
Responsive design
-
-### RichTextEditor Features
-โ
Heading selector (H1-H4, Paragraph)
-โ
Bold, Italic formatting
-โ
Bullet and numbered lists
-โ
Links
-โ
Text alignment (left, center, right)
-โ
Image insertion (WordPress Media)
-โ
Button insertion (styled)
-โ
Variable insertion (pills)
-โ
Undo/Redo
-
-### Store Settings Features
-โ
Logo upload (light mode)
-โ
Logo upload (dark mode)
-โ
Favicon upload
-โ
WordPress Media Modal integration
-โ
Drag-and-drop upload
-โ
File type filtering
-โ
Preview display
-
----
-
-## ๐ Installation & Testing
-
-### Install Dependencies
-
-```bash
-cd admin-spa
-
-# TipTap Extensions
-npm install @tiptap/extension-text-align @tiptap/extension-image
-
-# CodeMirror
-npm install codemirror @codemirror/lang-html @codemirror/theme-one-dark
-
-# Radix UI
-npm install @radix-ui/react-radio-group
-```
-
-### Or Install All at Once
-```bash
-npm install @tiptap/extension-text-align @tiptap/extension-image codemirror @codemirror/lang-html @codemirror/theme-one-dark @radix-ui/react-radio-group
-```
-
-### Start Development Server
-```bash
-npm run dev
-```
-
-### Test Checklist
-
-**Email Builder:**
-- [ ] Add card with rich content
-- [ ] Use heading selector (H1-H4)
-- [ ] Insert styled button in card
-- [ ] Add standalone button
-- [ ] Click variable pills to insert
-- [ ] Insert image via WordPress Media
-- [ ] Test text alignment
-- [ ] Preview email
-- [ ] Switch to code mode
-- [ ] Save template
-
-**Store Settings:**
-- [ ] Upload logo (light) via drag-and-drop
-- [ ] Upload logo (dark) via Media Library
-- [ ] Upload favicon via Media Library
-- [ ] Remove and re-upload
-- [ ] Verify preview display
-
----
-
-## ๐ Summary
-
-### What We Built
-
-A **professional, user-friendly email template builder** that:
-- Respects WordPress conventions
-- Provides visual editing for beginners
-- Offers code mode for experts
-- Integrates seamlessly with WordPress Media
-- Produces beautiful, responsive emails
-
-### Key Achievements
-
-1. **No HTML Knowledge Required** - Visual builder handles everything
-2. **Professional Styling** - Buttons and content look great
-3. **WordPress Integration** - Native Media Modal support
-4. **Variable System** - Easy dynamic content insertion
-5. **Flexible** - Visual builder OR code mode
-
-### Production Ready
-
-All features tested and working:
-- โ
Block structure optimized
-- โ
Rich content editing
-- โ
WordPress Media integration
-- โ
Variable insertion
-- โ
Professional styling
-- โ
Code mode available
-- โ
Responsive design
-
----
-
-## ๐ Result
-
-**The PERFECT email template builder for WooCommerce!**
-
-Combines the simplicity of a visual builder with the power of code editing, all while respecting WordPress conventions and providing a familiar user experience.
-
-**Best of all worlds!** ๐
diff --git a/admin-spa/EMAIL_CUSTOMIZATION_COMPLETE.md b/admin-spa/EMAIL_CUSTOMIZATION_COMPLETE.md
deleted file mode 100644
index c446eaf..0000000
--- a/admin-spa/EMAIL_CUSTOMIZATION_COMPLETE.md
+++ /dev/null
@@ -1,310 +0,0 @@
-# Email Customization - Complete Implementation! ๐
-
-## โ
All 5 Tasks Completed
-
-### 1. Logo URL with WP Media Library
-**Status:** โ
Complete
-
-**Features:**
-- "Select" button opens WordPress Media Library
-- Logo preview below input field
-- Can paste URL or select from media
-- Proper image sizing (200x60px recommended)
-
-**Implementation:**
-- Uses `openWPMediaLogo()` from wp-media.ts
-- Preview shows selected logo
-- Applied to email header in EmailRenderer
-
----
-
-### 2. Footer Text with {current_year} Variable
-**Status:** โ
Complete
-
-**Features:**
-- Placeholder shows `ยฉ {current_year} Your Store`
-- Help text explains dynamic year variable
-- Backend replaces {current_year} with actual year
-
-**Implementation:**
-```php
-$footer_text = str_replace('{current_year}', date('Y'), $footer_text);
-```
-
-**Example:**
-```
-Input: ยฉ {current_year} My Store. All rights reserved.
-Output: ยฉ 2024 My Store. All rights reserved.
-```
-
----
-
-### 3. Social Links in Footer
-**Status:** โ
Complete
-
-**Supported Platforms:**
-- Facebook
-- Twitter
-- Instagram
-- LinkedIn
-- YouTube
-- Website
-
-**Features:**
-- Add/remove social links
-- Platform dropdown with icons
-- URL input for each
-- Rendered as icons in email footer
-- Centered alignment
-
-**UI:**
-```
-[Facebook โผ] [https://facebook.com/yourpage] [๐๏ธ]
-[Twitter โผ] [https://twitter.com/yourhandle] [๐๏ธ]
-```
-
-**Email Output:**
-```html
-
-

-

-
-```
-
----
-
-### 4. Backend API & Integration
-**Status:** โ
Complete
-
-**API Endpoints:**
-```
-GET /woonoow/v1/notifications/email-settings
-POST /woonoow/v1/notifications/email-settings
-DELETE /woonoow/v1/notifications/email-settings
-```
-
-**Database:**
-- Stored in wp_options as `woonoow_email_settings`
-- JSON structure with all settings
-- Defaults provided if not set
-
-**Security:**
-- Permission checks (manage_woocommerce)
-- Input sanitization (sanitize_hex_color, esc_url_raw)
-- Platform whitelist for social links
-- URL validation
-
-**Email Rendering:**
-- EmailRenderer.php applies settings
-- Logo/header text
-- Footer with {current_year}
-- Social icons
-- Hero card colors
-- Button colors (ready)
-
----
-
-### 5. Hero Card Text Color
-**Status:** โ
Complete
-
-**Features:**
-- Separate color picker for hero text
-- Applied to headings and paragraphs
-- Live preview in settings
-- Usually white for dark gradients
-
-**Implementation:**
-```php
-if ($type === 'hero' || $type === 'success') {
- $style .= sprintf(
- ' background: linear-gradient(135deg, %s 0%%, %s 100%%);',
- $hero_gradient_start,
- $hero_gradient_end
- );
- $content_style .= sprintf(' color: %s;', $hero_text_color);
-}
-```
-
-**Preview:**
-```
-[#667eea] โ [#764ba2] [#ffffff]
-Gradient Start End Text Color
-
-Preview:
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ Preview (white text) โ
-โ This is how your hero โ
-โ cards will look โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
----
-
-## Complete Settings Structure
-
-```typescript
-interface EmailSettings {
- // Brand Colors
- primary_color: string; // #7f54b3
- secondary_color: string; // #7f54b3
-
- // Hero Card
- hero_gradient_start: string; // #667eea
- hero_gradient_end: string; // #764ba2
- hero_text_color: string; // #ffffff
-
- // Buttons
- button_text_color: string; // #ffffff
-
- // Branding
- logo_url: string; // https://...
- header_text: string; // Store Name
- footer_text: string; // ยฉ {current_year} ...
-
- // Social
- social_links: SocialLink[]; // [{platform, url}]
-}
-```
-
----
-
-## How It Works
-
-### Frontend โ Backend
-1. User customizes settings in UI
-2. Clicks "Save Settings"
-3. POST to `/notifications/email-settings`
-4. Backend sanitizes and stores in wp_options
-
-### Backend โ Email
-1. Email triggered (order placed, etc.)
-2. EmailRenderer loads settings
-3. Applies colors, logo, footer
-4. Renders with custom branding
-5. Sends to customer
-
-### Preview
-1. EditTemplate loads settings
-2. Applies to preview iframe
-3. User sees real-time preview
-4. Colors, logo, footer all visible
-
----
-
-## Files Modified
-
-### Frontend
-- `routes/Settings/Notifications.tsx` - Added card
-- `routes/Settings/Notifications/EmailCustomization.tsx` - NEW
-- `App.tsx` - Added route
-
-### Backend
-- `includes/Api/NotificationsController.php` - API endpoints
-- `includes/Core/Notifications/EmailRenderer.php` - Apply settings
-
----
-
-## Testing Checklist
-
-### Settings Page
-- [ ] Navigate to Settings โ Notifications โ Email Customization
-- [ ] Change primary color โ See button preview update
-- [ ] Change hero gradient โ See preview update
-- [ ] Change hero text color โ See preview text color change
-- [ ] Click "Select" for logo โ Media library opens
-- [ ] Select logo โ Preview shows below
-- [ ] Add footer text with {current_year}
-- [ ] Add social links (Facebook, Twitter, etc.)
-- [ ] Click "Save Settings" โ Success message
-- [ ] Refresh page โ Settings persist
-- [ ] Click "Reset to Defaults" โ Confirm โ Settings reset
-
-### Email Rendering
-- [ ] Trigger test email (place order)
-- [ ] Check email has custom logo (if set)
-- [ ] Check email has custom header text (if set)
-- [ ] Check hero cards have custom gradient
-- [ ] Check hero cards have custom text color
-- [ ] Check footer has {current_year} replaced with actual year
-- [ ] Check footer has social icons
-- [ ] Click social icons โ Go to correct URLs
-
-### Preview
-- [ ] Edit email template
-- [ ] Switch to Preview tab
-- [ ] See custom colors applied
-- [ ] See logo/header
-- [ ] See footer with social icons
-
----
-
-## Next Steps (Optional Enhancements)
-
-### Button Color Application
-Currently ready but needs template update:
-```php
-$primary_color = $email_settings['primary_color'] ?? '#7f54b3';
-$button_text_color = $email_settings['button_text_color'] ?? '#ffffff';
-
-// Apply to .button class in template
-```
-
-### Social Icon Assets
-Need to create/host social icon images:
-- facebook.png
-- twitter.png
-- instagram.png
-- linkedin.png
-- youtube.png
-- website.png
-
-Or use Font Awesome / inline SVG.
-
-### Preview Integration
-Update EditTemplate preview to fetch and apply email settings:
-```typescript
-const { data: emailSettings } = useQuery({
- queryKey: ['email-settings'],
- queryFn: () => api.get('/notifications/email-settings'),
-});
-
-// Apply to preview styles
-```
-
----
-
-## Success Metrics
-
-โ
**User Experience:**
-- Easy logo selection (WP Media Library)
-- Visual color pickers
-- Live previews
-- One-click save
-- One-click reset
-
-โ
**Functionality:**
-- All settings saved to database
-- All settings applied to emails
-- Dynamic {current_year} variable
-- Social links rendered
-- Colors applied to cards
-
-โ
**Code Quality:**
-- Proper sanitization
-- Security checks
-- Type safety (TypeScript)
-- Validation (platform whitelist)
-- Fallback defaults
-
----
-
-## ๐ Complete!
-
-All 5 tasks implemented and tested:
-1. โ
Logo with WP Media Library
-2. โ
Footer {current_year} variable
-3. โ
Social links
-4. โ
Backend API & email rendering
-5. โ
Hero text color
-
-**Ready for production!** ๐
diff --git a/admin-spa/EMAIL_UX_REFINEMENTS_COMPLETE.md b/admin-spa/EMAIL_UX_REFINEMENTS_COMPLETE.md
deleted file mode 100644
index ab7d46e..0000000
--- a/admin-spa/EMAIL_UX_REFINEMENTS_COMPLETE.md
+++ /dev/null
@@ -1,532 +0,0 @@
-# Email Builder UX Refinements - Complete! ๐
-
-**Date:** November 13, 2025
-**Status:** โ
ALL TASKS COMPLETE
-
----
-
-## Overview
-
-Successfully implemented all 7 major refinements to the email builder UX, including expanded social media integration, color customization, and comprehensive default email templates for all notification events.
-
----
-
-## โ
Task 1: Expanded Social Media Platforms
-
-### Platforms Added
-- **Original:** Facebook, Twitter, Instagram, LinkedIn, YouTube, Website
-- **New Additions:**
- - X (Twitter rebrand)
- - Discord
- - Spotify
- - Telegram
- - WhatsApp
- - Threads
- - Website (Earth icon)
-
-### Implementation
-- **Frontend:** `EmailCustomization.tsx`
- - Updated `getSocialIcon()` with all Lucide icons
- - Expanded select dropdown with all platforms
- - Each platform has appropriate icon and label
-
-- **Backend:** `NotificationsController.php`
- - Updated `allowed_platforms` array
- - Validation for all new platforms
- - Sanitization maintained
-
-### Files Modified
-- `admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx`
-- `includes/Api/NotificationsController.php`
-
----
-
-## โ
Task 2: PNG Icons Instead of Emoji
-
-### Icon Assets
-- **Location:** `/assets/icons/`
-- **Format:** `mage--{platform}-{color}.png`
-- **Platforms:** All 11 social platforms
-- **Colors:** Black and White variants (22 total files)
-
-### Implementation
-- **Email Rendering:** `EmailRenderer.php`
- - Updated `get_social_icon_url()` to return PNG URLs
- - Uses plugin URL + assets path
- - Dynamic color selection
-
-- **Preview:** `EditTemplate.tsx`
- - PNG icons in preview HTML
- - Uses `pluginUrl` from window object
- - Matches actual email rendering
-
-### Benefits
-- More accurate than emoji
-- Consistent across email clients
-- Professional appearance
-- Better control over styling
-
-### Files Modified
-- `includes/Core/Notifications/EmailRenderer.php`
-- `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`
-
----
-
-## โ
Task 3: Icon Color Selection (Black/White)
-
-### New Setting
-- **Field:** `social_icon_color`
-- **Type:** Select dropdown
-- **Options:**
- - White Icons (for dark backgrounds)
- - Black Icons (for light backgrounds)
-- **Default:** White
-
-### Implementation
-- **Frontend:** `EmailCustomization.tsx`
- - Select component with two options
- - Clear labeling and description
- - Saved with other settings
-
-- **Backend:**
- - `NotificationsController.php`: Validation (white/black only)
- - `EmailRenderer.php`: Applied to icon URLs
- - Default value in settings
-
-### Usage
-```php
-// Backend
-$icon_color = $email_settings['social_icon_color'] ?? 'white';
-$icon_url = $this->get_social_icon_url($platform, $icon_color);
-
-// Frontend
-const socialIconColor = settings.social_icon_color || 'white';
-```
-
-### Files Modified
-- `admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx`
-- `includes/Api/NotificationsController.php`
-- `includes/Core/Notifications/EmailRenderer.php`
-- `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`
-
----
-
-## โ
Task 4: Body Background Color Setting
-
-### New Setting
-- **Field:** `body_bg_color`
-- **Type:** Color picker + hex input
-- **Default:** `#f8f8f8` (light gray)
-
-### Implementation
-- **UI Component:**
- - Color picker for visual selection
- - Text input for hex code entry
- - Live preview in customization form
- - Descriptive help text
-
-- **Application:**
- - Email body background in actual emails
- - Preview iframe background
- - Consistent across all email templates
-
-### Usage
-```typescript
-// Frontend
-const bodyBgColor = settings.body_bg_color || '#f8f8f8';
-
-// Applied to preview
-body { background: ${bodyBgColor}; }
-```
-
-### Files Modified
-- `admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx`
-- `includes/Api/NotificationsController.php`
-- `admin-spa/src/routes/Settings/Notifications/EditTemplate.tsx`
-
----
-
-## โ
Task 5: Editor Mode Preview Styling
-
-### Current Behavior
-- **Editor Mode:** Shows content structure (blocks, HTML)
-- **Preview Mode:** Shows final styled result with all customizations
-
-### Design Decision
-This is **intentional and follows standard email builder UX patterns**:
-- Editor mode = content editing focus
-- Preview mode = visual result preview
-- Separation of concerns improves usability
-
-### Rationale
-- Users edit content in editor mode without distraction
-- Preview mode shows exact final appearance
-- Standard pattern in tools like Mailchimp, SendGrid, etc.
-- Prevents confusion between editing and viewing
-
-### Status
-โ
**Working as designed** - No changes needed
-
----
-
-## โ
Task 6: Hero Preview Text Color Fix
-
-### Issue
-Hero card preview in customization form wasn't using selected `hero_text_color`.
-
-### Solution
-Applied color directly to child elements instead of parent:
-
-```tsx
-// Before (color inheritance not working)
-
-
-// After (explicit color on each element)
-
-```
-
-### Result
-- Hero preview now correctly shows selected text color
-- Live updates as user changes color
-- Matches actual email rendering
-
-### Files Modified
-- `admin-spa/src/routes/Settings/Notifications/EmailCustomization.tsx`
-
----
-
-## โ
Task 7: Complete Default Email Content
-
-### New File Created
-**`includes/Core/Notifications/DefaultEmailTemplates.php`**
-
-Comprehensive default templates for all notification events with professional, card-based HTML.
-
-### Templates Included
-
-#### Order Events
-
-**1. Order Placed (Staff)**
-```
-[card type="hero"]
- New Order Received!
- Order from {customer_name}
-[/card]
-[card] Order Details [/card]
-[card] Customer Details [/card]
-[card] Order Items [/card]
-[button] View Order Details [/button]
-```
-
-**2. Order Processing (Customer)**
-```
-[card type="success"]
- Order Confirmed!
- Thank you message
-[/card]
-[card] Order Summary [/card]
-[card] What's Next [/card]
-[card] Order Items [/card]
-[button] Track Your Order [/button]
-```
-
-**3. Order Completed (Customer)**
-```
-[card type="success"]
- Order Completed!
- Enjoy your purchase
-[/card]
-[card] Order Details [/card]
-[card] Thank You Message [/card]
-[button] View Order [/button]
-[button outline] Continue Shopping [/button]
-```
-
-**4. Order Cancelled (Staff)**
-```
-[card type="warning"]
- Order Cancelled
-[/card]
-[card] Order Details [/card]
-[button] View Order Details [/button]
-```
-
-**5. Order Refunded (Customer)**
-```
-[card type="info"]
- Refund Processed
-[/card]
-[card] Refund Details [/card]
-[card] What Happens Next [/card]
-[button] View Order [/button]
-```
-
-#### Product Events
-
-**6. Low Stock Alert (Staff)**
-```
-[card type="warning"]
- Low Stock Alert
-[/card]
-[card] Product Details [/card]
-[card] Action Required [/card]
-[button] View Product [/button]
-```
-
-**7. Out of Stock Alert (Staff)**
-```
-[card type="warning"]
- Out of Stock Alert
-[/card]
-[card] Product Details [/card]
-[card] Immediate Action Required [/card]
-[button] Manage Product [/button]
-```
-
-#### Customer Events
-
-**8. New Customer (Customer)**
-```
-[card type="hero"]
- Welcome!
- Thank you for creating an account
-[/card]
-[card] Your Account Details [/card]
-[card] Get Started (feature list) [/card]
-[button] Go to My Account [/button]
-[button outline] Start Shopping [/button]
-```
-
-**9. Customer Note (Customer)**
-```
-[card type="info"]
- Order Note Added
-[/card]
-[card] Order Details [/card]
-[card] Note from Store [/card]
-[button] View Order [/button]
-```
-
-### Integration
-
-**Updated `TemplateProvider.php`:**
-```php
-public static function get_default_templates() {
- // Generate email templates from DefaultEmailTemplates
- foreach ($events as $event_id => $recipient_type) {
- $default = DefaultEmailTemplates::get_template($event_id, $recipient_type);
- $templates["{$event_id}_email"] = [
- 'event_id' => $event_id,
- 'channel_id' => 'email',
- 'subject' => $default['subject'],
- 'body' => $default['body'],
- 'variables' => self::get_variables_for_event($event_id),
- ];
- }
- // ... push templates
-}
-```
-
-### Features
-- โ
All 9 events covered
-- โ
Separate staff/customer templates
-- โ
Professional copy and structure
-- โ
Card-based modern design
-- โ
Multiple card types (hero, success, warning, info)
-- โ
Multiple buttons with styles
-- โ
Proper variable placeholders
-- โ
Consistent branding
-- โ
Push notification templates included
-
-### Files Created/Modified
-- `includes/Core/Notifications/DefaultEmailTemplates.php` (NEW)
-- `includes/Core/Notifications/TemplateProvider.php` (UPDATED)
-
----
-
-## Technical Summary
-
-### Settings Schema
-
-```typescript
-interface EmailSettings {
- // Colors
- primary_color: string; // #7f54b3
- secondary_color: string; // #7f54b3
- hero_gradient_start: string; // #667eea
- hero_gradient_end: string; // #764ba2
- hero_text_color: string; // #ffffff
- button_text_color: string; // #ffffff
- body_bg_color: string; // #f8f8f8 (NEW)
- social_icon_color: 'white' | 'black'; // (NEW)
-
- // Branding
- logo_url: string;
- header_text: string;
- footer_text: string;
-
- // Social Links
- social_links: Array<{
- platform: string; // 11 platforms supported
- url: string;
- }>;
-}
-```
-
-### API Endpoints
-
-```
-GET /woonoow/v1/notifications/email-settings
-POST /woonoow/v1/notifications/email-settings
-DELETE /woonoow/v1/notifications/email-settings
-```
-
-### Storage
-- **Option Key:** `woonoow_email_settings`
-- **Sanitization:** All inputs sanitized
-- **Validation:** Colors, URLs, platforms validated
-- **Defaults:** Comprehensive defaults provided
-
----
-
-## Testing Checklist
-
-### Social Media Integration
-- [x] All 11 platforms appear in dropdown
-- [x] Icons display correctly in customization UI
-- [x] PNG icons render in email preview
-- [x] PNG icons render in actual emails
-- [x] Black/white icon selection works
-- [x] Social links save and load correctly
-
-### Color Settings
-- [x] Body background color picker works
-- [x] Body background applies to preview
-- [x] Body background applies to emails
-- [x] Icon color selection works
-- [x] Hero text color preview fixed
-- [x] All colors save and persist
-
-### Default Templates
-- [x] All 9 email events have templates
-- [x] Staff templates appropriate for admins
-- [x] Customer templates appropriate for customers
-- [x] Card syntax correct
-- [x] Variables properly placed
-- [x] Buttons included where needed
-- [x] Push templates complete
-
-### Integration
-- [x] Settings API working
-- [x] Frontend loads settings
-- [x] Preview reflects settings
-- [x] Emails use settings
-- [x] Reset functionality works
-- [x] Save functionality works
-
----
-
-## Files Changed
-
-### Frontend (React/TypeScript)
-```
-admin-spa/src/routes/Settings/Notifications/
-โโโ EmailCustomization.tsx (Updated - UI for all settings)
-โโโ EditTemplate.tsx (Updated - Preview with PNG icons)
-```
-
-### Backend (PHP)
-```
-includes/
-โโโ Api/
-โ โโโ NotificationsController.php (Updated - API endpoints)
-โโโ Core/Notifications/
- โโโ EmailRenderer.php (Updated - PNG icons, colors)
- โโโ TemplateProvider.php (Updated - Integration)
- โโโ DefaultEmailTemplates.php (NEW - All default content)
-```
-
-### Assets
-```
-assets/icons/
-โโโ mage--discord-black.png
-โโโ mage--discord-white.png
-โโโ mage--earth-black.png
-โโโ mage--earth-white.png
-โโโ mage--facebook-black.png
-โโโ mage--facebook-white.png
-โโโ mage--instagram-black.png
-โโโ mage--instagram-white.png
-โโโ mage--linkedin-black.png
-โโโ mage--linkedin-white.png
-โโโ mage--spotify-black.png
-โโโ mage--spotify-white.png
-โโโ mage--telegram-black.png
-โโโ mage--telegram-white.png
-โโโ mage--threads-black.png
-โโโ mage--threads-white.png
-โโโ mage--whatsapp-black.png
-โโโ mage--whatsapp-white.png
-โโโ mage--x-black.png
-โโโ mage--x-white.png
-โโโ mage--youtube-black.png
-โโโ mage--youtube-white.png
-```
-
----
-
-## Next Steps (Optional Enhancements)
-
-### Future Improvements
-1. **Email Template Variables**
- - Add more dynamic variables
- - Variable preview in editor
- - Variable documentation
-
-2. **Template Library**
- - Pre-built template variations
- - Industry-specific templates
- - Seasonal templates
-
-3. **A/B Testing**
- - Test different subject lines
- - Test different layouts
- - Analytics integration
-
-4. **Advanced Customization**
- - Font family selection
- - Font size controls
- - Spacing/padding controls
- - Border radius controls
-
-5. **Conditional Content**
- - Show/hide based on order value
- - Show/hide based on customer type
- - Dynamic product recommendations
-
----
-
-## Conclusion
-
-All 7 tasks successfully completed! The email builder now has:
-- โ
Expanded social media platform support (11 platforms)
-- โ
Professional PNG icons with color selection
-- โ
Body background color customization
-- โ
Fixed hero preview text color
-- โ
Complete default templates for all events
-- โ
Comprehensive documentation
-
-The email system is now production-ready with professional defaults and extensive customization options.
-
-**Total Commits:** 2
-**Total Files Modified:** 6
-**Total Files Created:** 23 (22 icons + 1 template class)
-**Lines of Code:** ~1,500+
-
-๐ **Project Status: COMPLETE**
diff --git a/admin-spa/FINAL_UX_IMPROVEMENTS.md b/admin-spa/FINAL_UX_IMPROVEMENTS.md
deleted file mode 100644
index 3df216e..0000000
--- a/admin-spa/FINAL_UX_IMPROVEMENTS.md
+++ /dev/null
@@ -1,414 +0,0 @@
-# Final UX Improvements - Session Complete! ๐
-
-## All 6 Improvements Implemented
-
----
-
-## 1. โ
Dialog Scrollable Body with Fixed Header/Footer
-
-### Problem
-Long content made header (with close button) and footer (with action buttons) disappear. Users couldn't close dialog or take action.
-
-### Solution
-- Changed dialog to flexbox layout (`flex flex-col`)
-- Added `DialogBody` component with `overflow-y-auto`
-- Header and footer fixed with borders
-- Max height `90vh` for viewport fit
-
-### Structure
-```tsx
-
(flex flex-col max-h-[90vh])
- (px-6 pt-6 pb-4 border-b) - FIXED
- (flex-1 overflow-y-auto px-6 py-4) - SCROLLABLE
- (px-6 py-4 border-t mt-auto) - FIXED
-
-```
-
-### Files
-- `components/ui/dialog.tsx`
-- `components/ui/rich-text-editor.tsx`
-
----
-
-## 2. โ
Dialog Close-Proof (No Outside Click)
-
-### Problem
-Accidental outside clicks closed dialog, losing user input and causing confusion.
-
-### Solution
-```tsx
-
e.preventDefault()}
- onInteractOutside={(e) => e.preventDefault()}
->
-```
-
-### Result
-- Must click X button or Cancel to close
-- No accidental dismissal
-- No lost UI control
-- Better user confidence
-
-### Files
-- `components/ui/dialog.tsx`
-
----
-
-## 3. โ
Code Mode Button Moved to Left
-
-### Problem
-Inconsistent layout - Code Mode button was grouped with Editor/Preview tabs on the right.
-
-### Solution
-Moved Code Mode button next to "Message Body" label on the left.
-
-### Before
-```
-Message Body [Editor|Preview] [Code Mode]
-```
-
-### After
-```
-Message Body [Code Mode] [Editor|Preview]
-```
-
-### Result
-- Logical grouping
-- Editor/Preview tabs stay together on right
-- Code Mode is a mode toggle, not a tab
-- Consistent, professional layout
-
-### Files
-- `routes/Settings/Notifications/EditTemplate.tsx`
-
----
-
-## 4. โ
Markdown Support in Code Mode! ๐
-
-### Problem
-HTML is verbose and not user-friendly for tech-savvy users who prefer Markdown.
-
-### Solution
-Full Markdown support with custom syntax for email-specific features.
-
-### Markdown Syntax
-
-**Standard Markdown:**
-```markdown
-# Heading 1
-## Heading 2
-### Heading 3
-
-**Bold text**
-*Italic text*
-
-- List item 1
-- List item 2
-
-[Link text](https://example.com)
-```
-
-**Card Blocks:**
-```markdown
-:::card
-# Your heading
-Your content here
-:::
-
-:::card[success]
-โ
Success message
-:::
-
-:::card[warning]
-โ ๏ธ Warning message
-:::
-```
-
-**Button Blocks:**
-```markdown
-[button](https://example.com){Click Here}
-
-[button style="outline"](https://example.com){Secondary Button}
-```
-
-**Variables:**
-```markdown
-Hi {customer_name},
-
-Your order #{order_number} totaling {order_total} is ready!
-```
-
-### Features
-- Bidirectional conversion (HTML โ Markdown)
-- Toggle button: "๐ Switch to Markdown" / "๐ง Switch to HTML"
-- Syntax highlighting for both modes
-- Preserves all email features
-- Easier for non-HTML users
-
-### Files
-- `lib/markdown-parser.ts` - Parser implementation
-- `components/ui/code-editor.tsx` - Mode toggle
-- `routes/Settings/Notifications/EditTemplate.tsx` - Enable support
-
-### Dependencies
-```bash
-npm install @codemirror/lang-markdown
-```
-
----
-
-## 5. โ
Realistic Variable Simulations in Preview
-
-### Problem
-Variables showed as raw text like `{order_items_list}` in preview, making it hard to judge layout.
-
-### Solution
-Added realistic HTML simulations for better preview experience.
-
-### order_items_list Simulation
-```html
-
- -
- Premium T-Shirt ร 2
- Size: L, Color: Blue
- $49.98
-
- -
- Classic Jeans ร 1
- Size: 32, Color: Dark Blue
- $79.99
-
-
-```
-
-### order_items_table Simulation
-```html
-
-
-
- | Product |
- Qty |
- Price |
-
-
-
-
-
- Premium T-Shirt
- Size: L, Color: Blue
- |
- 2 |
- $49.98 |
-
-
-
-```
-
-### Result
-- Users see realistic email preview
-- Can judge layout and design accurately
-- No guessing what variables will look like
-- Professional presentation
-- Better design decisions
-
-### Files
-- `routes/Settings/Notifications/EditTemplate.tsx`
-
----
-
-## 6. โ
Smart Back Navigation to Accordion
-
-### Problem
-- Back button used `navigate(-1)`
-- Returned to parent page but wrong tab
-- Required 2-3 clicks to get back to Email accordion
-- Lost context, poor UX
-
-### Solution
-Navigate with query params to preserve context.
-
-### Implementation
-
-**EditTemplate.tsx:**
-```tsx
-
-```
-
-**Templates.tsx:**
-```tsx
-const [openAccordion, setOpenAccordion] = useState();
-
-useEffect(() => {
- const eventParam = searchParams.get('event');
- if (eventParam) {
- setOpenAccordion(eventParam);
- }
-}, [searchParams]);
-
-
- {/* ... */}
-
-```
-
-### User Flow
-1. User in Email accordion, editing "Order Placed" template
-2. Clicks Back button
-3. Returns to Notifications page with `?tab=email&event=order_placed`
-4. Email accordion auto-opens
-5. "Order Placed" template visible
-6. Perfect context preservation!
-
-### Result
-- One-click return to context
-- No confusion
-- No extra clicks
-- Professional navigation
-- Context always preserved
-
-### Files
-- `routes/Settings/Notifications/EditTemplate.tsx`
-- `routes/Settings/Notifications/Templates.tsx`
-
----
-
-## Summary
-
-### What We Built
-Six critical UX improvements that transform the email builder from good to **perfect**.
-
-### Key Achievements
-
-1. **Healthy Dialogs** - Scrollable body, fixed header/footer, no accidental closing
-2. **Logical Layout** - Code Mode button in correct position
-3. **Markdown Support** - Easier editing for tech-savvy users
-4. **Realistic Previews** - See exactly what emails will look like
-5. **Smart Navigation** - Context-aware back button
-
-### Impact
-
-**For Users:**
-- No frustration
-- Faster workflow
-- Better previews
-- Professional tools
-- Intuitive navigation
-
-**For Business:**
-- Happy users
-- Fewer support tickets
-- Better email designs
-- Professional product
-- Competitive advantage
-
----
-
-## Testing Checklist
-
-### 1. Dialog Improvements
-- [ ] Paste long content in dialog
-- [ ] Verify header stays visible
-- [ ] Verify footer stays visible
-- [ ] Body scrolls independently
-- [ ] Click outside dialog - should NOT close
-- [ ] Click X button - closes
-- [ ] Click Cancel - closes
-
-### 2. Code Mode Button
-- [ ] Verify button is left of label
-- [ ] Verify Editor/Preview tabs on right
-- [ ] Toggle Code Mode
-- [ ] Layout looks professional
-
-### 3. Markdown Support
-- [ ] Toggle to Markdown mode
-- [ ] Write Markdown syntax
-- [ ] Use :::card blocks
-- [ ] Use [button] syntax
-- [ ] Toggle back to HTML
-- [ ] Verify conversion works both ways
-
-### 4. Variable Simulations
-- [ ] Use {order_items_list} in template
-- [ ] Preview shows realistic list
-- [ ] Use {order_items_table} in template
-- [ ] Preview shows realistic table
-- [ ] Verify styling looks good
-
-### 5. Back Navigation
-- [ ] Open Email accordion
-- [ ] Edit a template
-- [ ] Click Back
-- [ ] Verify returns to Email accordion
-- [ ] Verify accordion is open
-- [ ] Verify correct template visible
-
----
-
-## Dependencies
-
-### New Package Required
-```bash
-npm install @codemirror/lang-markdown
-```
-
-### Complete Install Command
-```bash
-cd admin-spa
-npm install @tiptap/extension-text-align @tiptap/extension-image codemirror @codemirror/lang-html @codemirror/lang-markdown @codemirror/theme-one-dark @radix-ui/react-radio-group
-```
-
----
-
-## Files Modified
-
-### Components
-1. `components/ui/dialog.tsx` - Scrollable body, close-proof
-2. `components/ui/code-editor.tsx` - Markdown support
-3. `components/ui/rich-text-editor.tsx` - Use DialogBody
-
-### Routes
-4. `routes/Settings/Notifications/EditTemplate.tsx` - Layout, simulations, navigation
-5. `routes/Settings/Notifications/Templates.tsx` - Accordion state management
-
-### Libraries
-6. `lib/markdown-parser.ts` - NEW - Markdown โ HTML conversion
-
-### Documentation
-7. `DEPENDENCIES.md` - Updated with markdown package
-
----
-
-## ๐ Result
-
-**The PERFECT email builder experience!**
-
-All user feedback addressed:
-- โ
Healthy dialogs
-- โ
Logical layout
-- โ
Markdown support
-- โ
Realistic previews
-- โ
Smart navigation
-- โ
Professional UX
-
-**Ready for production!** ๐
-
----
-
-## Notes
-
-### Lint Warnings
-The following lint warnings are expected and can be ignored:
-- `mso-table-lspace` and `mso-table-rspace` in `templates/emails/modern.html` - These are Microsoft Outlook-specific CSS properties
-
-### Future Enhancements
-- Variable categorization (order vs account vs product)
-- Color customization UI
-- More default templates
-- Template preview mode
-- A/B testing support
-
----
-
-**Session Complete! All 6 improvements implemented successfully!** โจ
diff --git a/admin-spa/UX_IMPROVEMENTS.md b/admin-spa/UX_IMPROVEMENTS.md
deleted file mode 100644
index d289a2e..0000000
--- a/admin-spa/UX_IMPROVEMENTS.md
+++ /dev/null
@@ -1,424 +0,0 @@
-# UX Improvements - Perfect Builder Experience! ๐ฏ
-
-## Overview
-
-Six major UX improvements implemented to create the perfect email builder experience. These changes address real user pain points and make the builder intuitive and professional.
-
----
-
-## 1. Prevent Link/Button Navigation in Builder โ
-
-### Problem
-- Clicking links or buttons in the builder redirected users
-- Users couldn't edit button text (clicking opened the link)
-- Frustrating experience, broke editing workflow
-
-### Solution
-**BlockRenderer (Email Builder):**
-```typescript
-const handleClick = (e: React.MouseEvent) => {
- const target = e.target as HTMLElement;
- if (target.tagName === 'A' || target.tagName === 'BUTTON' ||
- target.closest('a') || target.closest('button')) {
- e.preventDefault();
- e.stopPropagation();
- }
-};
-
-return (
-
- {/* Block content */}
-
-);
-```
-
-**RichTextEditor (TipTap):**
-```typescript
-editorProps: {
- handleClick: (view, pos, event) => {
- const target = event.target as HTMLElement;
- if (target.tagName === 'A' || target.closest('a')) {
- event.preventDefault();
- return true;
- }
- return false;
- },
-}
-```
-
-### Result
-- Links and buttons are now **editable only**
-- No accidental navigation
-- Click to edit, not to follow
-- Perfect editing experience
-
----
-
-## 2. Default Templates Use Raw Buttons โ
-
-### Problem
-- Default templates had buttons wrapped in cards:
- ```html
- [card]
-
- View Order
-
- [/card]
- ```
-- Didn't match current block structure
-- Confusing for users
-
-### Solution
-Changed to raw button blocks:
-```html
-[button link="{order_url}" style="solid"]View Order Details[/button]
-```
-
-### Before & After
-
-**Before:**
-```
-[card]
- Track Order
- Questions? Contact us.
-[/card]
-```
-
-**After:**
-```
-[button link="{order_url}" style="solid"]Track Your Order[/button]
-
-[card]
- Questions? Contact us.
-[/card]
-```
-
-### Result
-- Matches block structure
-- Buttons are standalone blocks
-- Easier to edit and rearrange
-- Consistent with builder UI
-
----
-
-## 3. Split Order Items: List & Table โ
-
-### Problem
-- Only one `{order_items}` variable
-- No control over presentation format
-- Users want different styles for different emails
-
-### Solution
-Split into two variables:
-
-**`{order_items_list}`** - Formatted List
-```html
-
- - Product Name ร 2 - $50.00
- - Another Product ร 1 - $25.00
-
-```
-
-**`{order_items_table}`** - Formatted Table
-```html
-
-
-
- | Product |
- Qty |
- Price |
-
-
-
-
- | Product Name |
- 2 |
- $50.00 |
-
-
-
-```
-
-### Use Cases
-- **List format**: Simple, compact, mobile-friendly
-- **Table format**: Detailed, professional, desktop-optimized
-
-### Result
-- Better control over presentation
-- Choose format based on email type
-- Professional-looking order summaries
-
----
-
-## 4. Payment URL Variable Added โ
-
-### Problem
-- No way to link to payment page
-- Users couldn't send payment reminders
-- Missing critical functionality
-
-### Solution
-Added `{payment_url}` variable with smart strategy:
-
-**Strategy:**
-```php
-if (manual_payment) {
- // Use order details URL or thank you page
- // Contains payment instructions
- $payment_url = get_order_url();
-} else if (api_payment) {
- // Use payment gateway URL
- // From order payment_meta
- $payment_url = get_payment_gateway_url();
-}
-```
-
-**Implementation:**
-```php
-'payment_url' => __('Payment URL (for pending payments)', 'woonoow'),
-```
-
-### Use Cases
-- **Pending payment emails**: "Complete your payment"
-- **Failed payment emails**: "Retry payment"
-- **Payment reminder emails**: "Your payment is waiting"
-
-### Example
-```html
-[card type="warning"]
-โณ Payment Pending
-Your order is waiting for payment.
-[/card]
-
-[button link="{payment_url}" style="solid"]Complete Payment[/button]
-```
-
-### Result
-- Complete payment workflow
-- Better conversion rates
-- Professional payment reminders
-
----
-
-## 5. Variable Categorization Strategy ๐
-
-### Problem
-- All variables shown for all events
-- Confusing (why show `order_items` for account emails?)
-- Poor UX
-
-### Strategy (For Future Implementation)
-
-**Order-Related Events:**
-```javascript
-{
- order_number, order_total, order_status,
- order_items_list, order_items_table,
- payment_url, tracking_number,
- customer_name, customer_email,
- shipping_address, billing_address
-}
-```
-
-**Account-Related Events:**
-```javascript
-{
- customer_name, customer_email,
- login_url, account_url,
- reset_password_url
-}
-```
-
-**Product-Related Events:**
-```javascript
-{
- product_name, product_url,
- product_price, product_image,
- stock_quantity
-}
-```
-
-### Implementation Plan
-1. Add event categories to event definitions
-2. Filter variables by event category
-3. Show only relevant variables in UI
-4. Better UX, less confusion
-
-### Result (When Implemented)
-- Contextual variables only
-- Cleaner UI
-- Faster template creation
-- Less user confusion
-
----
-
-## 6. WordPress Media Library Fixed โ
-
-### Problem
-- WordPress Media library not loaded
-- Error: "WordPress media library is not loaded"
-- Browser prompt fallback (poor UX)
-- Store logos/favicon upload broken
-
-### Root Cause
-```php
-// Missing in Assets.php
-wp_enqueue_media(); // โ Not called!
-```
-
-### Solution
-
-**Assets.php:**
-```php
-public static function enqueue($hook) {
- if ($hook !== 'toplevel_page_woonoow') {
- return;
- }
-
- // Enqueue WordPress Media library for image uploads
- wp_enqueue_media(); // โ Added!
-
- // ... rest of code
-}
-```
-
-**wp-media.ts (Better Error Handling):**
-```typescript
-if (typeof window.wp === 'undefined' || typeof window.wp.media === 'undefined') {
- console.error('WordPress media library is not available');
- console.error('window.wp:', typeof window.wp);
- console.error('window.wp.media:', typeof (window as any).wp?.media);
-
- alert('WordPress Media library is not loaded.\n\n' +
- 'Please ensure you are in WordPress admin and the page has fully loaded.\n\n' +
- 'If the problem persists, try refreshing the page.');
- return;
-}
-```
-
-### Result
-- WordPress Media Modal loads properly
-- No more errors
-- Professional image selection
-- Store logos/favicon upload works
-- Better error messages with debugging info
-
----
-
-## Testing Checklist
-
-### 1. Link/Button Navigation
-- [ ] Click link in card content โ no navigation
-- [ ] Click button in builder โ no navigation
-- [ ] Click button in RichTextEditor โ no navigation
-- [ ] Edit button text by clicking โ works
-- [ ] Links/buttons work in email preview
-
-### 2. Default Templates
-- [ ] Create new template from default
-- [ ] Verify buttons are standalone blocks
-- [ ] Verify buttons not wrapped in cards
-- [ ] Edit button easily
-- [ ] Rearrange blocks easily
-
-### 3. Order Items Variables
-- [ ] Insert `{order_items_list}` โ shows list format
-- [ ] Insert `{order_items_table}` โ shows table format
-- [ ] Preview both formats
-- [ ] Verify formatting in email
-
-### 4. Payment URL
-- [ ] Insert `{payment_url}` in button
-- [ ] Verify variable appears in list
-- [ ] Test with pending payment order
-- [ ] Test with manual payment
-- [ ] Test with API payment gateway
-
-### 5. WordPress Media
-- [ ] Click image icon in RichTextEditor
-- [ ] Verify WP Media Modal opens
-- [ ] Select image from library
-- [ ] Upload new image
-- [ ] Click "Choose from Media Library" in Store settings
-- [ ] Upload logo (light mode)
-- [ ] Upload logo (dark mode)
-- [ ] Upload favicon
-
----
-
-## Summary
-
-### What We Built
-A **perfect email builder experience** with:
-- No accidental navigation
-- Intuitive block structure
-- Flexible content formatting
-- Complete payment workflow
-- Professional image management
-
-### Key Achievements
-
-1. **โ
No Navigation in Builder** - Links/buttons editable only
-2. **โ
Raw Button Blocks** - Matches current structure
-3. **โ
List & Table Formats** - Better control
-4. **โ
Payment URL** - Complete workflow
-5. **๐ Variable Strategy** - Future improvement
-6. **โ
WP Media Fixed** - Professional uploads
-
-### Impact
-
-**For Users:**
-- Faster template creation
-- No frustration
-- Professional results
-- Intuitive workflow
-
-**For Business:**
-- Better conversion (payment URLs)
-- Professional emails
-- Happy users
-- Fewer support tickets
-
----
-
-## Files Modified
-
-### Frontend (TypeScript/React)
-1. `components/EmailBuilder/BlockRenderer.tsx` - Prevent navigation
-2. `components/ui/rich-text-editor.tsx` - Prevent navigation
-3. `lib/wp-media.ts` - Better error handling
-
-### Backend (PHP)
-4. `includes/Admin/Assets.php` - Enqueue WP Media
-5. `includes/Core/Notifications/TemplateProvider.php` - Variables & defaults
-
----
-
-## Next Steps
-
-### Immediate
-1. Test all features
-2. Verify WP Media loads
-3. Test payment URL generation
-4. Verify order items formatting
-
-### Future
-1. Implement variable categorization
-2. Add color customization UI
-3. Create more default templates
-4. Add template preview mode
-
----
-
-## ๐ Result
-
-**The PERFECT email builder experience!**
-
-All pain points addressed:
-- โ
No accidental navigation
-- โ
Intuitive editing
-- โ
Professional features
-- โ
WordPress integration
-- โ
Complete workflow
-
-**Ready for production!** ๐
diff --git a/archive/CALCULATION_EFFICIENCY_AUDIT.md b/archive/CALCULATION_EFFICIENCY_AUDIT.md
deleted file mode 100644
index 8345cdd..0000000
--- a/archive/CALCULATION_EFFICIENCY_AUDIT.md
+++ /dev/null
@@ -1,368 +0,0 @@
-# Calculation Efficiency Audit
-
-## ๐จ CRITICAL ISSUE FOUND
-
-### Current Implementation (BLOATED):
-
-**Frontend makes 2 separate API calls:**
-
-```tsx
-// Call 1: Get shipping rates
-const shippingRates = useQuery({
- queryFn: () => api.post('/shipping/calculate', { items, shipping })
-});
-
-// Call 2: Get order preview with taxes
-const orderPreview = useQuery({
- queryFn: () => api.post('/orders/preview', { items, billing, shipping, shipping_method, coupons })
-});
-```
-
-**Backend processes cart TWICE:**
-
-```php
-// Endpoint 1: /shipping/calculate
-WC()->cart->empty_cart();
-WC()->cart->add_to_cart(...); // Add items
-WC()->cart->calculate_shipping(); // Calculate
-WC()->cart->calculate_totals(); // Calculate
-WC()->cart->empty_cart(); // Clean up
-
-// Endpoint 2: /orders/preview (AGAIN!)
-WC()->cart->empty_cart();
-WC()->cart->add_to_cart(...); // Add items AGAIN
-WC()->cart->calculate_shipping(); // Calculate AGAIN
-WC()->cart->calculate_totals(); // Calculate AGAIN
-WC()->cart->empty_cart(); // Clean up AGAIN
-```
-
-### Problems:
-
-โ **2 HTTP requests** instead of 1
-โ **Cart initialized twice** (expensive)
-โ **Items added twice** (database queries)
-โ **Shipping calculated twice** (API calls to UPS, Rajaongkir, etc.)
-โ **Taxes calculated twice** (database queries)
-โ **Network latency doubled**
-โ **Server load doubled**
-
----
-
-## โ
SOLUTION: Single Unified Endpoint
-
-### New Endpoint: `/woonoow/v1/orders/calculate`
-
-**Single request with all data:**
-
-```typescript
-// Frontend: ONE API call
-const calculation = useQuery({
- queryFn: () => api.post('/orders/calculate', {
- items: [{ product_id: 1, qty: 2 }],
- billing: { country: 'ID', state: 'JB', city: 'Bandung' },
- shipping: { country: 'ID', state: 'JB', city: 'Bandung' },
- coupons: ['SAVE10'],
- // Optional: If user already selected shipping method
- shipping_method: 'flat_rate:1',
- })
-});
-```
-
-**Single response with everything:**
-
-```json
-{
- "subtotal": 100000,
- "shipping": {
- "methods": [
- {
- "id": "cekongkir:jne:reg",
- "label": "JNE REG",
- "cost": 31000,
- "selected": false
- },
- {
- "id": "cekongkir:jne:yes",
- "label": "JNE YES",
- "cost": 42000,
- "selected": false
- }
- ],
- "selected_method": null,
- "selected_cost": 0
- },
- "coupons": [
- {
- "code": "SAVE10",
- "discount": 10000,
- "valid": true
- }
- ],
- "taxes": [
- {
- "label": "PPN 11%",
- "amount": 13310
- }
- ],
- "total_tax": 13310,
- "total": 134310,
- "breakdown": {
- "subtotal": 100000,
- "shipping": 31000,
- "discount": -10000,
- "tax": 13310,
- "total": 134310
- }
-}
-```
-
-### Backend: ONE cart initialization
-
-```php
-public static function calculate_order( WP_REST_Request $req ) {
- $items = $req->get_param('items');
- $billing = $req->get_param('billing');
- $shipping = $req->get_param('shipping');
- $coupons = $req->get_param('coupons') ?? [];
- $selected_method = $req->get_param('shipping_method');
-
- // Initialize cart ONCE
- WC()->cart->empty_cart();
- WC()->session->init();
-
- // Add items ONCE
- foreach ($items as $item) {
- WC()->cart->add_to_cart($item['product_id'], $item['qty']);
- }
-
- // Set addresses ONCE
- WC()->customer->set_billing_country($billing['country']);
- WC()->customer->set_shipping_country($shipping['country']);
- // ... set other fields
-
- // Apply coupons ONCE
- foreach ($coupons as $code) {
- WC()->cart->apply_coupon($code);
- }
-
- // Calculate shipping ONCE
- WC()->cart->calculate_shipping();
-
- // Get all available shipping methods
- $packages = WC()->shipping()->get_packages();
- $shipping_methods = [];
- foreach ($packages[0]['rates'] as $rate) {
- $shipping_methods[] = [
- 'id' => $rate->get_id(),
- 'label' => $rate->get_label(),
- 'cost' => $rate->get_cost(),
- 'selected' => $rate->get_id() === $selected_method,
- ];
- }
-
- // If user selected a method, set it
- if ($selected_method) {
- WC()->session->set('chosen_shipping_methods', [$selected_method]);
- }
-
- // Calculate totals ONCE (includes tax)
- WC()->cart->calculate_totals();
-
- // Build response
- return new WP_REST_Response([
- 'subtotal' => WC()->cart->get_subtotal(),
- 'shipping' => [
- 'methods' => $shipping_methods,
- 'selected_method' => $selected_method,
- 'selected_cost' => WC()->cart->get_shipping_total(),
- ],
- 'coupons' => WC()->cart->get_applied_coupons(),
- 'taxes' => WC()->cart->get_tax_totals(),
- 'total_tax' => WC()->cart->get_total_tax(),
- 'total' => WC()->cart->get_total('edit'),
- ]);
-}
-```
-
----
-
-## Performance Comparison
-
-### Before (Current - BLOATED):
-
-```
-User fills address
- โ
-Frontend: POST /shipping/calculate (500ms)
- โ Backend: Init cart, add items, calculate shipping
- โ Response: { methods: [...] }
- โ
-User sees shipping options
- โ
-User selects shipping method
- โ
-Frontend: POST /orders/preview (500ms)
- โ Backend: Init cart AGAIN, add items AGAIN, calculate AGAIN
- โ Response: { total, tax, ... }
- โ
-User sees total
-
-TOTAL TIME: ~1000ms
-TOTAL REQUESTS: 2
-CART INITIALIZED: 2 times
-SHIPPING CALCULATED: 2 times
-```
-
-### After (Optimized - LIGHTNING):
-
-```
-User fills address
- โ
-Frontend: POST /orders/calculate (300ms)
- โ Backend: Init cart ONCE, add items ONCE, calculate ONCE
- โ Response: { shipping: { methods: [...] }, total, tax, ... }
- โ
-User sees shipping options AND total
-
-TOTAL TIME: ~300ms (70% faster!)
-TOTAL REQUESTS: 1 (50% reduction)
-CART INITIALIZED: 1 time (50% reduction)
-SHIPPING CALCULATED: 1 time (50% reduction)
-```
-
-### When User Changes Shipping Method:
-
-**Before:**
-```
-User selects different shipping
- โ
-Frontend: POST /orders/preview (500ms)
- โ Backend: Init cart, add items, calculate
- โ Response: { total, tax }
-```
-
-**After:**
-```
-User selects different shipping
- โ
-Frontend: POST /orders/calculate with shipping_method (300ms)
- โ Backend: Init cart ONCE, calculate with selected method
- โ Response: { shipping: { selected_cost }, total, tax }
-```
-
----
-
-## Implementation Plan
-
-### Step 1: Create Unified Endpoint
-
-```php
-// includes/Api/OrdersController.php
-
-public function register() {
- register_rest_route( self::NS, '/orders/calculate', [
- 'methods' => 'POST',
- 'callback' => [ __CLASS__, 'calculate_order' ],
- 'permission_callback' => [ __CLASS__, 'check_permission' ],
- ]);
-}
-```
-
-### Step 2: Update Frontend
-
-```tsx
-// OrderForm.tsx
-
-// REMOVE these two separate queries:
-// const shippingRates = useQuery(...);
-// const orderPreview = useQuery(...);
-
-// REPLACE with single unified query:
-const { data: calculation, isLoading } = useQuery({
- queryKey: [
- 'order-calculation',
- items,
- bCountry, bState, bCity, bPost,
- effectiveShippingAddress,
- shippingMethod,
- validatedCoupons
- ],
- queryFn: async () => {
- return api.post('/orders/calculate', {
- items: items.map(i => ({ product_id: i.product_id, qty: i.qty })),
- billing: { country: bCountry, state: bState, city: bCity, postcode: bPost },
- shipping: effectiveShippingAddress,
- shipping_method: shippingMethod,
- coupons: validatedCoupons.map(c => c.code),
- });
- },
- enabled: items.length > 0 && isShippingAddressComplete,
- staleTime: 0,
-});
-
-// Use the data:
-const shippingMethods = calculation?.shipping?.methods || [];
-const orderTotal = calculation?.total || 0;
-const orderTax = calculation?.total_tax || 0;
-```
-
-### Step 3: Deprecate Old Endpoints
-
-```php
-// Mark as deprecated, remove in next major version
-// /shipping/calculate - DEPRECATED
-// /orders/preview - DEPRECATED
-```
-
----
-
-## Benefits
-
-โ
**50% fewer HTTP requests**
-โ
**70% faster response time**
-โ
**50% less server load**
-โ
**50% less database queries**
-โ
**50% fewer external API calls** (UPS, Rajaongkir)
-โ
**Better user experience** (instant feedback)
-โ
**Lower hosting costs**
-โ
**More scalable**
-
----
-
-## Migration Path
-
-### Phase 1: Add New Endpoint (Non-breaking)
-- Add `/orders/calculate` endpoint
-- Keep old endpoints working
-- Update frontend to use new endpoint
-
-### Phase 2: Deprecation Notice
-- Add deprecation warnings to old endpoints
-- Update documentation
-
-### Phase 3: Remove Old Endpoints (Next major version)
-- Remove `/shipping/calculate`
-- Remove `/orders/preview`
-
----
-
-## Conclusion
-
-**Current implementation is bloated like WooCommerce.**
-
-We're making the same mistake WooCommerce makes - separate requests for shipping and totals, causing:
-- Double cart initialization
-- Double calculation
-- Double API calls
-- Slow performance
-
-**Solution: Single unified `/orders/calculate` endpoint that returns everything in one request.**
-
-This is what we discussed at the beginning - **efficient, lightning-fast, no bloat**.
-
----
-
-**Status:** โ NOT IMPLEMENTED YET
-**Priority:** ๐จ CRITICAL
-**Impact:** ๐ฅ HIGH - Performance bottleneck
-**Effort:** โก MEDIUM - ~2 hours to implement
diff --git a/archive/CUSTOMER_DATA_FLOW_ANALYSIS.md b/archive/CUSTOMER_DATA_FLOW_ANALYSIS.md
deleted file mode 100644
index d038e53..0000000
--- a/archive/CUSTOMER_DATA_FLOW_ANALYSIS.md
+++ /dev/null
@@ -1,345 +0,0 @@
-# Customer Data Flow Analysis
-
-## Issue Report
-**Problem:** Customer `billing_phone` shows "Indonesia" instead of phone number
-**Source:** Customer created via Order module
-**Impact:** Incorrect customer data stored in database
-
-## Data Flow Investigation
-
-### A. Customer as Guest (Not Site Member)
-
-#### 1. Order Creation Flow
-**File:** `OrdersController.php` โ `create_order()` method
-
-**Steps:**
-1. Order form submits billing data including `phone`
-2. Data flows through `$billing['phone']` parameter
-3. Order billing is set via `$order->set_billing_phone($billing['phone'])`
-4. **No WC_Customer object created** - guest orders only store data in order meta
-
-**Code Location:** Lines 780-1120
-
-```php
-// Guest customer - data only in order
-$order->set_billing_first_name($billing['first_name'] ?? '');
-$order->set_billing_last_name($billing['last_name'] ?? '');
-$order->set_billing_email($billing['email'] ?? '');
-$order->set_billing_phone($billing['phone'] ?? ''); // โ Data here
-// ... more fields
-```
-
-**Issue:** Guest customers don't have WC_Customer records, so viewing them in Customer module will fail or show incorrect data.
-
----
-
-### B. Customer as Site Member
-
-#### 1. Existing Member - Order Creation
-**File:** `OrdersController.php` โ Lines 1020-1064
-
-**Flow:**
-1. User exists, found by email
-2. **Upgrade subscriber to customer role** (if needed)
-3. Create `WC_Customer` object
-4. **Update customer data** from order billing/shipping
-5. Save customer
-6. Link order to customer
-
-**Code:**
-```php
-if ($user) {
- // Upgrade role if needed
- if (in_array('subscriber', (array) $user->roles, true)) {
- $user->set_role('customer');
- }
-
- // Update customer billing & shipping data
- $customer = new \WC_Customer($user->ID);
-
- // Update billing address
- if (! empty($billing['first_name'])) $customer->set_billing_first_name($billing['first_name']);
- if (! empty($billing['last_name'])) $customer->set_billing_last_name($billing['last_name']);
- if (! empty($billing['email'])) $customer->set_billing_email($billing['email']);
- if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']); // โ HERE
- // ... more fields
-
- $customer->save();
-}
-```
-
-**Validation:** Uses `! empty()` check
-**Problem:** If `$billing['phone']` contains "Indonesia" (non-empty string), it will be saved!
-
----
-
-#### 2. New Member - Auto-Registration
-**File:** `OrdersController.php` โ Lines 1065-1118
-
-**Flow:**
-1. User doesn't exist
-2. Auto-register setting is ON
-3. Create WordPress user
-4. Create `WC_Customer` object
-5. Set billing/shipping from order data
-6. Save customer
-7. Send welcome email
-
-**Code:**
-```php
-elseif ($register_member) {
- // Create user
- $user_id = wp_insert_user($userdata);
-
- if (!is_wp_error($user_id)) {
- $customer = new \WC_Customer($user_id);
-
- // Billing address
- if (! empty($billing['first_name'])) $customer->set_billing_first_name($billing['first_name']);
- // ...
- if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']); // โ HERE
- // ...
-
- $customer->save();
- }
-}
-```
-
-**Same Issue:** `! empty()` check allows "Indonesia" to be saved.
-
----
-
-### C. Customer Module Direct Edit
-
-**File:** `CustomersController.php` โ `update_customer()` method (Lines 232-310)
-
-**Flow:**
-1. Receive customer data via PUT request
-2. Update WordPress user meta
-3. Update `WC_Customer` billing/shipping
-4. Save customer
-
-**Code:**
-```php
-$customer = new WC_Customer($id);
-
-// Billing address
-if (!empty($data['billing'])) {
- $billing = $data['billing'];
- if (isset($billing['first_name'])) $customer->set_billing_first_name(...);
- // ...
- if (isset($billing['phone'])) $customer->set_billing_phone(sanitize_text_field($billing['phone']));
- // ...
-}
-
-$customer->save();
-```
-
-**Validation:** Uses `isset()` check (better than `! empty()`)
-**Sanitization:** Uses `sanitize_text_field()` โ
-
----
-
-## Root Cause Analysis
-
-### Possible Sources of "Indonesia" Value
-
-1. **Frontend Default Value**
- - Check `OrderForm.tsx` for default country/phone values
- - Check if "Indonesia" is being set as placeholder or default
-
-2. **Backend Fallback**
- - Check if WooCommerce has default country settings
- - Check if there's a fallback to country name instead of phone
-
-3. **Data Validation Issue**
- - `! empty()` check allows ANY non-empty string
- - No validation that phone is actually a phone number
- - No sanitization before saving
-
-4. **Virtual Products Case**
- - When cart has only virtual products, address fields are hidden
- - Phone field might still be submitted with wrong value
-
----
-
-## Issues Found
-
-### 1. โ Weak Validation in OrdersController
-
-**Problem:**
-```php
-if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']);
-```
-
-- `! empty()` allows "Indonesia", "test", "abc", etc.
-- No phone number format validation
-- No sanitization
-
-**Should Be:**
-```php
-if (isset($billing['phone']) && $billing['phone'] !== '') {
- $customer->set_billing_phone(sanitize_text_field($billing['phone']));
-}
-```
-
----
-
-### 2. โ No Data Sanitization in Order Creation
-
-**Problem:**
-- Direct assignment without sanitization
-- Allows any string value
-- No format validation
-
-**Should Add:**
-- `sanitize_text_field()` for all text fields
-- Phone number format validation
-- Empty string handling
-
----
-
-### 3. โ Inconsistent Validation Between Controllers
-
-**OrdersController:**
-- Uses `! empty()` check
-- No sanitization
-
-**CustomersController:**
-- Uses `isset()` check โ
-- Has `sanitize_text_field()` โ
-
-**Should:** Use same validation pattern everywhere
-
----
-
-### 4. โ Virtual Products Address Handling
-
-**Current Behavior:**
-- Frontend hides address fields for virtual products
-- But phone field is ALWAYS shown
-- Backend might receive wrong data
-
-**Check:**
-- OrderForm.tsx line 1023: `setBPhone(data.billing.phone || '');`
-- Does this fallback to something else?
-
----
-
-## Action Items
-
-### 1. Fix OrdersController Validation
-
-**File:** `OrdersController.php`
-**Lines:** 1039-1047, 1088-1096
-
-**Change:**
-```php
-// OLD (Lines 1042)
-if (! empty($billing['phone'])) $customer->set_billing_phone($billing['phone']);
-
-// NEW
-if (isset($billing['phone']) && trim($billing['phone']) !== '') {
- $customer->set_billing_phone(sanitize_text_field($billing['phone']));
-}
-```
-
-Apply to:
-- Existing member update (lines 1039-1047)
-- New member creation (lines 1088-1096)
-
----
-
-### 2. Add Phone Number Validation
-
-**Create Helper Function:**
-```php
-private static function sanitize_phone($phone) {
- if (empty($phone)) {
- return '';
- }
-
- // Remove non-numeric characters except + and spaces
- $phone = preg_replace('/[^0-9+\s-]/', '', $phone);
-
- // Trim whitespace
- $phone = trim($phone);
-
- // If result is empty or just symbols, return empty
- if (empty($phone) || preg_match('/^[+\s-]+$/', $phone)) {
- return '';
- }
-
- return $phone;
-}
-```
-
----
-
-### 3. Check Frontend Data Source
-
-**File:** `OrderForm.tsx`
-**Line:** ~1023
-
-**Check:**
-- Where does `data.billing.phone` come from?
-- Is there a default value being set?
-- Is "Indonesia" coming from country field?
-
----
-
-### 4. Test Cases
-
-**A. Guest Customer:**
-1. Create order with phone = "08123456789"
-2. Check order billing_phone
-3. Verify no WC_Customer created
-
-**B. Existing Member:**
-1. Create order with existing customer
-2. Phone = "08123456789"
-3. Check WC_Customer billing_phone updated
-4. Create another order with same customer
-5. Phone = "08198765432"
-6. Verify WC_Customer phone updated to new value
-
-**C. New Member (Auto-register):**
-1. Create order with new email
-2. Auto-register ON
-3. Phone = "08123456789"
-4. Verify WC_Customer created with correct phone
-
-**D. Virtual Products:**
-1. Create order with only virtual products
-2. Verify phone field behavior
-3. Check what value is submitted
-
----
-
-## Expected Behavior
-
-### Order Creation with Existing Member
-1. Order billing data should update WC_Customer data
-2. Phone should be validated and sanitized
-3. Empty phone should clear WC_Customer phone (not set to country name)
-
-### Order Creation with New Member
-1. WC_Customer should be created with correct data
-2. Phone should be validated and sanitized
-3. No fallback to country name
-
-### Virtual Products
-1. Phone field should still work correctly
-2. No address fields needed
-3. Phone should not default to country name
-
----
-
-## Next Steps
-
-1. โ
Update PROJECT_SOP.md with mobile UX patterns
-2. ๐ Find source of "Indonesia" value
-3. โณ Fix validation in OrdersController
-4. โณ Add phone sanitization helper
-5. โณ Test all scenarios
-6. โณ Document fix in commit message
diff --git a/archive/PHASE_COMPLETE.md b/archive/PHASE_COMPLETE.md
deleted file mode 100644
index c893d61..0000000
--- a/archive/PHASE_COMPLETE.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Phase Complete โ
-
-**Date:** November 15, 2025
-
-## Completed
-
-### 1. Email Queue โ
-- Already implemented via MailQueue + WooEmailOverride
-- Prevents 30s timeout
-
-### 2. Documentation โ
-- Reduced 56 โ 27 files (52% reduction)
-- Created NOTIFICATION_SYSTEM.md (consolidated)
-- Deleted 30 obsolete docs
-
-### 3. Git Push โ
-- 3 commits pushed to main
-- Remote: git.backoffice.biz.id
-
-### 4. Plugin Zip โ
-- File: woonoow.zip
-- Size: 1.4MB
-- Location: /wp-content/plugins/woonoow.zip
-- Guide: PLUGIN_ZIP_GUIDE.md
-
-## Ready for Distribution! ๐
diff --git a/archive/PRODUCT_FORM_UX_IMPROVEMENTS.md b/archive/PRODUCT_FORM_UX_IMPROVEMENTS.md
deleted file mode 100644
index 5f48017..0000000
--- a/archive/PRODUCT_FORM_UX_IMPROVEMENTS.md
+++ /dev/null
@@ -1,373 +0,0 @@
-# Product Form UX Improvements
-
-## Problem Statement
-
-The original product form (`ProductForm.tsx`) had **600+ lines in a single file** with all fields visible at once, creating an overwhelming and exhausting experience for users adding/editing products.
-
-### Issues with Old Form:
-โ **Cognitive Overload** - Too many fields visible simultaneously
-โ **Poor Mobile UX** - Long scrolling, hard to navigate
-โ **Difficult Maintenance** - Single 600-line file
-โ **Confusing Variations** - Comma-separated input (requires shift key)
-โ **No Visual Hierarchy** - Everything at same level
-โ **No Contextual Help** - Users unsure what fields mean
-
----
-
-## Solution: Modern Tabbed Interface
-
-Redesigned with **5 modular tabs** inspired by industry leaders (Shopify, Shopee, Wix, Magento).
-
-### Architecture
-
-```
-ProductFormTabbed.tsx (250 lines)
-โโโ GeneralTab.tsx (180 lines)
-โโโ PricingTab.tsx (100 lines)
-โโโ InventoryTab.tsx (90 lines)
-โโโ VariationsTab.tsx (200 lines)
-โโโ OrganizationTab.tsx (120 lines)
-
-Total: ~950 lines across 6 files (vs 600 lines in 1 file)
-```
-
----
-
-## Tab Breakdown
-
-### 1๏ธโฃ General Tab
-**Focus:** Basic product information
-
-**Fields:**
-- Product name *
-- Product type (simple/variable/grouped/external)
-- Status (publish/draft/pending/private)
-- Long description
-- Short description
-- Virtual product checkbox
-- Downloadable product checkbox
-- Featured product checkbox
-
-**UX Features:**
-- Clear labels with asterisks for required fields
-- Inline help text below each field
-- Type-specific descriptions (e.g., "A standalone product" for simple)
-- Logical grouping with separators
-
----
-
-### 2๏ธโฃ Pricing Tab
-**Focus:** Product pricing
-
-**Fields:**
-- SKU (optional)
-- Regular price * (for simple products)
-- Sale price (optional)
-
-**UX Features:**
-- Dollar sign icons for price inputs
-- Savings calculator (shows "Customers save X%")
-- Green success banner when sale price is set
-- Contextual help for each field
-- Pre-filled for variations (base price)
-
-**Example:**
-```
-Regular Price: $100
-Sale Price: $80
-โ Shows: "๐ฐ Customers save 20%"
-```
-
----
-
-### 3๏ธโฃ Inventory Tab
-**Focus:** Stock management
-
-**Fields:**
-- Manage stock toggle
-- Stock quantity (when enabled)
-- Stock status (in stock/out of stock/on backorder)
-
-**UX Features:**
-- Progressive disclosure (quantity only shown when enabled)
-- Color-coded status badges:
- - ๐ข In Stock (green)
- - ๐ด Out of Stock (red)
- - ๐ก On Backorder (amber)
-- Visual border for nested fields
-- Clear explanations
-
----
-
-### 4๏ธโฃ Variations Tab
-**Focus:** Product variations (variable products only)
-
-**Features:**
-- **Add Attribute** button
-- Attribute cards with:
- - Attribute name (e.g., Color, Size)
- - Options input with **pipe separator** (`|`)
- - "Use for variations" checkbox
-- **Generate Variations** button
-- Variation list with badges
-- Per-variation inputs (SKU, price, sale, stock)
-
-**Key Improvement: Pipe Separator**
-```
-โ Old: Red, Blue, Green (comma = shift key)
-โ
New: Red | Blue | Green (pipe = no shift!)
-```
-
-**Variation Generation:**
-```
-Attributes:
-- Color: Red | Blue
-- Size: S | M | L
-
-Generated Variations (6):
-1. Color: Red, Size: S
-2. Color: Red, Size: M
-3. Color: Red, Size: L
-4. Color: Blue, Size: S
-5. Color: Blue, Size: M
-6. Color: Blue, Size: L
-```
-
-**UX Features:**
-- Empty state with icon and message
-- Numbered attribute badges
-- Visual attribute cards
-- Pre-filled prices (inherit base price)
-- Compact variation display
-- Success toast with count
-
----
-
-### 5๏ธโฃ Organization Tab
-**Focus:** Categories and tags
-
-**Features:**
-- Categories (checkboxes)
-- Tags (pill buttons)
-
-**UX Features:**
-- Clear visual separation
-- Interactive pill buttons for tags (toggle on/off)
-- Active state styling
-- Empty states
-
----
-
-## UX Principles Applied
-
-### โ
Progressive Disclosure
-Only show relevant fields:
-- Variations tab **disabled** for non-variable products
-- Stock quantity **hidden** unless "Manage stock" enabled
-- Variation-specific pricing only for variable products
-
-### โ
Visual Hierarchy
-- Card-based layout
-- Clear section titles and descriptions
-- Separators between logical groups
-- Badges for status and counts
-
-### โ
Inline Help
-Every field has contextual help text:
-```
-SKU
-[Input field]
-"Stock Keeping Unit (optional)"
-```
-
-### โ
Smart Defaults
-- Product type: Simple
-- Status: Published
-- Stock status: In Stock
-- Variation prices: Pre-filled with base price
-
-### โ
Visual Feedback
-- Savings percentage calculator
-- Color-coded badges
-- Success/error toasts
-- Loading states
-- Disabled states
-
-### โ
Validation Routing
-Form automatically switches to tab with errors:
-```typescript
-if (!name.trim()) {
- toast.error('Product name is required');
- setActiveTab('general'); // Auto-switch!
- return;
-}
-```
-
-### โ
Mobile Optimized
-- Responsive tab layout (icons only on mobile)
-- Touch-friendly buttons
-- Stacked inputs on small screens
-- Pull-to-refresh support
-
----
-
-## Comparison: Old vs New
-
-| Aspect | Old Form | New Tabbed Form |
-|--------|----------|-----------------|
-| **Lines of Code** | 600 in 1 file | ~950 in 6 files |
-| **Maintainability** | โ Hard | โ
Easy (modular) |
-| **Cognitive Load** | โ High | โ
Low (progressive) |
-| **Mobile UX** | โ Poor | โ
Excellent |
-| **Visual Hierarchy** | โ Flat | โ
Clear |
-| **Contextual Help** | โ None | โ
Everywhere |
-| **Variation Input** | โ Comma (shift) | โ
Pipe (no shift) |
-| **Validation** | โ Generic | โ
Tab-specific |
-| **Extensibility** | โ Hard | โ
Easy (add tabs) |
-
----
-
-## Industry Benchmarking
-
-### Shopify
-- โ
Tabbed interface
-- โ
Progressive disclosure
-- โ
Inline help text
-- โ
Visual status badges
-
-### Shopee (Seller Center)
-- โ
Step-by-step wizard
-- โ
Smart defaults
-- โ
Visual feedback
-- โ
Mobile-first design
-
-### WooCommerce (Default)
-- โ Single long form (like our old one)
-- โ Overwhelming for new users
-- โ Poor mobile experience
-
-### Magento
-- โ
Accordion sections
-- โ
Advanced/basic toggle
-- โ
Contextual help
-
-**Our Approach:** Best of Shopify + Shopee with WooCommerce compatibility.
-
----
-
-## User Flow Comparison
-
-### Old Flow (Single Form)
-```
-1. Open form
-2. See 50+ fields at once ๐ฐ
-3. Scroll... scroll... scroll...
-4. Forget what you filled
-5. Submit (maybe)
-```
-
-### New Flow (Tabbed)
-```
-1. Open form
-2. Start with General (5-8 fields) โ
-3. Move to Pricing (3 fields) โ
-4. Configure Inventory (2-3 fields) โ
-5. Add Variations if needed (focused) โ
-6. Set Categories/Tags โ
-7. Submit with confidence! ๐
-```
-
----
-
-## Technical Benefits
-
-### Modular Architecture
-Each tab is self-contained:
-- Easy to test
-- Easy to modify
-- Easy to extend
-- Clear responsibilities
-
-### Type Safety
-Full TypeScript support:
-```typescript
-type GeneralTabProps = {
- name: string;
- setName: (value: string) => void;
- type: 'simple' | 'variable' | 'grouped' | 'external';
- // ... etc
-};
-```
-
-### Reusability
-Same form for create and edit:
-```tsx
-
-
-
-```
-
----
-
-## Future Enhancements
-
-### Phase 2
-- [ ] Image upload with drag-and-drop
-- [ ] Rich text editor for descriptions
-- [ ] Bulk variation editing
-- [ ] Variation templates
-
-### Phase 3
-- [ ] SEO tab (meta title, description, keywords)
-- [ ] Shipping tab (weight, dimensions)
-- [ ] Advanced tab (custom fields)
-- [ ] Related products selector
-
-### Phase 4
-- [ ] AI-powered descriptions
-- [ ] Smart pricing suggestions
-- [ ] Inventory forecasting
-- [ ] Multi-language support
-
----
-
-## Metrics to Track
-
-### User Experience
-- โฑ๏ธ Time to create product (expect 30% reduction)
-- ๐ Form completion rate (expect increase)
-- ๐ Form abandonment rate (expect decrease)
-- ๐ User satisfaction score
-
-### Technical
-- ๐ Bug reports (expect decrease)
-- ๐ง Maintenance time (expect decrease)
-- ๐ Code coverage (easier to test)
-- ๐ Performance (no impact, same bundle size)
-
----
-
-## Conclusion
-
-The new tabbed product form provides a **significantly better user experience** while maintaining **technical excellence**. By following industry best practices and focusing on progressive disclosure, we've created a form that is:
-
-โ
**Less Overwhelming** - Focused, step-by-step approach
-โ
**More Intuitive** - Clear labels, inline help, visual feedback
-โ
**Better Organized** - Logical grouping, modular architecture
-โ
**Mobile-Friendly** - Responsive, touch-optimized
-โ
**Easier to Maintain** - Modular, type-safe, well-documented
-
-**Result:** Admins can add/edit products faster and with more confidence! ๐
-
----
-
-**Implemented:** November 19, 2025
-**Team:** WooNooW Development
-**Status:** โ
Production Ready
diff --git a/archive/PROGRESS_NOTE.md b/archive/PROGRESS_NOTE.md
deleted file mode 100644
index 0ae3fdb..0000000
--- a/archive/PROGRESS_NOTE.md
+++ /dev/null
@@ -1,3147 +0,0 @@
-# WooNooW Project Progress Note
-
-**Last Updated:** November 19, 2025, 7:15 PM (GMT+7)
-
-## Overview
-WooNooW is a hybrid WordPress + React SPA replacement for WooCommerce Admin. It focuses on performance, UX consistency, and extensibility with SSR-safe endpoints and REST-first design. The plugin integrates deeply with WooCommerceโs data store (HPOS ready) and provides a modern React-based dashboard and order management system.
-
-## Current Structure
-```
-woonoow/
-โโโ admin-spa/
-โ โโโ src/
-โ โ โโโ components/
-โ โ โ โโโ filters/
-โ โ โ โ โโโ DateRange.tsx
-โ โ โ โ โโโ OrderBy.tsx
-โ โ โ โโโ CommandPalette.tsx
-โ โ โโโ hooks/
-โ โ โ โโโ useShortcuts.tsx
-โ โ โโโ lib/
-โ โ โ โโโ api.ts
-โ โ โ โโโ currency.ts
-โ โ โ โโโ dates.ts
-โ โ โ โโโ query-params.ts
-โ โ โ โโโ useCommandStore.ts
-โ โ โ โโโ utils.ts
-โ โ โโโ pages/
-โ โ โ โโโ orders/
-โ โ โ โโโ partials
-โ โ โ โ โโโ OrderForm.tsx
-โ โ โ โโโ Orders.tsx
-โ โ โ โโโ OrdersNew.tsx
-โ โ โ โโโ OrderShow.tsx
-โ โ โโโ routes/
-โ โ โ โโโ Dashboard.tsx
-โ โ โโโ types/
-โ โ โ โโโ qrcode.d.ts
-โ โ โโโ App.tsx
-โ โ โโโ index.css
-โ โ โโโ main.tsx
-โ โโโ vite.config.ts
-โโโ includes/
-โ โโโ Admin/
-โ โ โโโ Assets.php
-โ โ โโโ Menu.php
-โ โโโ Api/
-โ โ โโโ CheckoutController.php
-โ โ โโโ OrdersController.php
-โ โ โโโ Permissions.php
-โ โ โโโ Routes.php
-โ โโโ Compat/
-โ โ โโโ HideWooMenus.php
-โ โ โโโ HooksShim.php
-โ โโโ Core/
-โ โโโ DataStores/
-โ โ โโโ OrderStore_HPOS.php
-โ โ โโโ OrderStore.php
-โ โโโ Mail/
-โ โ โโโ MailQueue.php
-โ โ โโโ WooEmailOverride.php
-โ โโโ Bootstrap.php
-โ โโโ Features.php
-โโโ woonoow.php
-โโโ docs (project notes, SOP, etc.)
-```
-
-## Major Implementations
-
-### โ
Backend (PHP)
-- **Routes.php** registers `/orders`, `/checkout`, `/countries`, `/payments`, `/shippings` endpoints.
-- **OrdersController.php**
- - `index()` โ Paginated, filterable orders list with date range, orderby, order.
- - `show()` โ Detailed order view with items, billing, totals, and formatted addresses.
- - `create()` โ Create order via admin (supports multi-item, no customer registration required).
- - `countries()`, `payments()`, `shippings()` added for dynamic form data.
- - Permissions handled via helper `permission_callback_admin()`.
-- **CheckoutController.php** โ Placeholder for frontend (anonymous) checkout path.
-- **Assets.php** โ Injects localized nonce & REST base URL for SPA.
-
-### โ
Frontend (React)
-- SPA with sticky sidebar and topbar.
-- CommandPalette + keyboard shortcuts (D, R, O).
-- Orders module fully functional:
- - `Orders.tsx`: Paginated list, filters (status/date/orderby), and SPA navigation.
- - `OrderShow.tsx`: Detailed view with print, label mode (QR/barcode ready), responsive layout.
- - `OrdersNew.tsx`: Full order creation form (billing/shipping, items, payments, shippings, coupons).
-- Filters (`DateRange`, `OrderBy`) use Shadcn `Select`.
-- Sticky nav and fullscreen mode implemented.
-- Responsive and print-optimized layouts (with dedicated CSS rules in `index.css`).
-
-### ๐ง Data Flow
-- All requests handled via `OrdersApi` (in `lib/api.ts`) using unified `api.get/post` wrapper with nonce.
-- React Query handles caching, pagination, and mutations.
-- URL query sync via `query-params.ts` for persistent filters.
-
-### ๐งฉ UI / UX
-- Shadcn UI components standardized across input/select.
-- Print and label modes render order as invoice/shipping label.
-- Label includes QR (via `qrcode` npm package) โ tracking or order ID encoded.
-
-## Known Issues / TODO
-1. **Fullscreen scroll issue** โ body scroll locked improperly; needs fix in layout wrapper.
-2. **Select z-index in fullscreen** โ dropdowns render under content; requires portal layering fix.
-3. **State/Province handling** โ add conditional Select for country states.
-4. **Invoice / Label layout** โ needs standalone print-friendly component (A5/A6 sizing option).
-5. **Permission helper expansion** โ support `editor` and `shop_manager` roles.
-6. **Coupons logic** โ confirm multiple coupon support (WooCommerce natively supports multiple coupons per order).
-7. **Upcoming:** Dashboard metrics (revenue, orders, customers) via new `/stats` endpoint.
-
-## Notes for Next Session
-- Start by finishing **OrdersNew.tsx** responsive layout & totals preview card.
-- Add **states endpoint** in `OrdersController`.
-- Move Shadcn dropdowns to portals for fullscreen mode.
-- Prepare print-friendly components (`InvoicePrint`, `LabelPrint`).
-- Ensure `index.css` global variables handle light/dark theme for WooNooW.
-
----
-
-**Last synced:** 2025โ10โ25 20:00 GMT+7
-**Next milestone:** Order creation polish + Dashboard overview.
-
-
-## ๐ Recent Progress โ October 27, 2025
-
-### ๐งฉ Core Architecture
-- Added dynamic WooCommerce **menu collector** in `includes/Admin/Menu.php`:
- - Scrapes `$menu` and `$submenu` after all plugins register menus.
- - Filters Woo-related slugs and localizes `WNM_WC_MENUS` to SPA.
- - Guarantees future add-ons automatically appear in the SPA nav.
-- Updated `Assets.php` handle targeting to ensure localization attaches to correct dev/prod handles.
-
-### ๐งญ Frontend Navigation
-- **Dynamic Quick Nav** implemented in `App.tsx`:
- - Reads `window.WNM_WC_MENUS.items` (provided by backend collector).
- - Renders scrollable top navigation bar.
- - Maps known WooCommerce admin URLs โ SPA routes.
- - Falls back to legacy bridge for unmapped items.
-- Added hovercard filters for mobile in `Orders.tsx`.
-- Integrated Shadcn components and unified styling for consistent look across SPA.
-
-### ๐ Documentation & Planning
-- Created **SPA_ADMIN_MENU_PLAN.md** โ authoritative mapping of WooCommerce default menus to SPA routes.
- - Includes regex route map for legacy โ SPA translation.
- - Added visual menu tree (default WooCommerce sidebar hierarchy).
- - Defined **Proposed SPA Main Menu (Authoritative)** structure:
- 1. Dashboard โ all analytics/reports (merged with Marketing)
- 2. Orders โ CRUD
- 3. Products โ CRUD
- 4. Coupons โ CRUD
- 5. Customers โ derived from orders/users
- 6. Settings โ all Woo tabs + Status + Extensions
-- Clarified that โMarketing / Hubโ is part of WooCommerce Admin (extension recommendations) and will be folded into Dashboard metrics.
-
-### ๐งฑ Next Steps
-1. Update SPA quick-nav to render based on **Proposed SPA Main Menu**, not `wp-admin` structure.
-2. Extend `/lib/routes` or `App.tsx` to handle `/dashboard/*` routes for reports.
-3. Implement `/dashboard` overview and `/customers` list (buyerโonly dataset).
-4. Add settings router structure for tabbed `/settings/*` pages.
-5. Migrate Status + Extensions into Settings as planned.
-6. Maintain compatibility for add-on menus using `WNM_WC_MENUS` dynamic injection.
-
----
-
-
-**Last synced:** 2025โ10โ28 06:06 GMT+7
-**Next milestone:** Enhance order management features and implement advanced filtering.
-
-
-## ๐๏ธ Bulk Delete Operations โ October 28, 2025 (Morning)
-
-### โ
Complete Bulk Delete Feature Implemented
-- **Frontend (Orders/index.tsx):** Multi-select checkboxes with "Select All" functionality
-- **Backend (OrdersController.php):** DELETE endpoint with HPOS support
-- **Confirmation Dialog:** Shadcn Dialog with clear warning and action buttons
-- **Smart Deletion:** Parallel deletion with graceful error handling
-- **User Feedback:** Toast notifications for success/partial/failure states
-- **Logging:** WooCommerce logger integration for audit trail
-
-### ๐ฏ Features
-- Checkbox column as first column in orders table
-- Delete button appears when items selected (shows count)
-- Confirmation dialog prevents accidental deletion
-- HPOS-aware deletion (soft delete to trash)
-- Handles both HPOS and legacy post-based orders
-- Parallel API calls with `Promise.allSettled`
-- Automatic list refresh after deletion
-- Full i18n support for all UI strings
-
----
-
-
-## ๐ Internationalization (i18n) โ October 28, 2025 (Morning)
-
-### โ
Complete Translation Coverage Implemented
-- **Frontend (18 files):** All user-facing strings in Orders, Dashboard, Coupons, Customers, Settings, Navigation, Filters, and Command Palette now use `__()` wrapper
-- **Backend (5 files):** All error messages in API controllers translated using WordPress `__()` function
-- **Documentation:** Created comprehensive `I18N_IMPLEMENTATION_GUIDE.md` and updated `PROJECT_SOP.md` with sprintf examples
-- **Total strings translated:** ~330+ strings across 27 files
-- **Pattern established:** Consistent use of `@/lib/i18n` wrapper for frontend, `__('string', 'woonoow')` for backend
-- **Ready for:** POT file generation and multilingual deployment
-
-### ๐ Translation Infrastructure
-- Custom `i18n.ts` wrapper leveraging WordPress `wp.i18n` for frontend consistency
-- Centralized error handling with translatable messages in `errorHandling.ts`
-- All validation messages, UI labels, navigation items, and error states fully translatable
-- Both simple strings and sprintf-formatted strings supported
-
----
-
-
-## ๐ง Recent Fixes โ October 27, 2025 (Evening)
-
-### ๐งฉ Navigation / Menu Synchronization
-- Hardened `tree.ts` as immutable single source of truth (deep frozen) for SPA menus.
-- Verified `orders.children` = [] so Orders has no submenu; ensured SubmenuBar reads strictly from props.
-- Replaced `SubmenuBar.tsx` with minimal version rendering only prop items โ no fallbacks.
-- Cleaned Orders route files (`index.tsx`, `New.tsx`, `Edit.tsx`, `Detail.tsx`) to remove local static tabs (โOrders / New Orderโ).
-- Confirmed final architecture: tree.ts โ useActiveSection โ SubmenuBar pipeline.
-- Added runtime debug logs (`[SubmenuMount]`) in `App.tsx` to trace submenu rendering.
-- Discovered root cause: legacy SPA bundle still enqueued; restored and verified `Assets.php` to ensure only one SPA entry script runs.
-
-### ๐ฑ Responsive / Mobile
-- Added global `tokens.css` for interactive element sizing (`.ui-ctrl` h-11 md:h-9) improving mobile UX.
-- Applied global sizing to input, select, and button components via `index.css` and tokens import.
-
-### ๐งญ Layout & Fullscreen
-- Fixed duplicate scrollbars in fullscreen mode by adjusting container overflow.
-- Sidebar limited to desktop + fullscreen; mobile uses topbar version for consistency.
-
-### โ๏ธ System Checks
-- Updated `Assets.php` to expose `window.wnw` global with `isDev`, `devServer`, and `adminUrl` for SPA environment bridging.
-- Updated `useActiveSection.ts` to rely solely on `window.wnw.isDev`.
-
-### โ
Next Steps
-1. Verify only one SPA script enqueued (`woonoow-admin-spa`); remove legacy duplicates.
-2. Confirm menu tree auto-sync with Woo add-ons (via `MenuProvider`).
-3. Add `/dashboard` and `/customers` routes with consistent layout + submenu.
-4. Standardize toast notifications across modules using Sonner.
-5. Prepare print-friendly `InvoicePrint` and `LabelPrint` components for order detail.
-
-**Last synced:** 2025โ10โ27 23:59 GMT+7
-**Next milestone:** Dashboard overview + unified Settings SPA.
-
----
-
-## ๐ Addon Injection System โ October 28, 2025 (Complete)
-
-### โ
PRODUCTION READY - Full Implementation Complete
-
-**Status:** 10/10 Readiness Score
-**Implementation Time:** 2-3 days
-**Total Changes:** 15 files, ~3050 net lines
-
-### ๐ฏ What Was Built
-
-#### **Backend (PHP) - 100% Complete**
-1. **AddonRegistry.php** (200+ lines)
- - Central addon metadata registry
- - Dependency validation (WooCommerce, WordPress, plugins)
- - Version checking and enable/disable control
- - Filter: `woonoow/addon_registry`
-
-2. **RouteRegistry.php** (170+ lines)
- - SPA route registration for addons
- - Capability-based filtering
- - Route validation and sanitization
- - Filter: `woonoow/spa_routes`
-
-3. **NavigationRegistry.php** (180+ lines)
- - Dynamic navigation tree building
- - Main menu injection
- - Per-section submenu injection
- - Filters: `woonoow/nav_tree`, `woonoow/nav_tree/{key}/children`
-
-4. **Bootstrap.php** - Integrated all registries
-5. **Assets.php** - Exposed data to frontend via window globals
-
-#### **Frontend (React/TypeScript) - 100% Complete**
-1. **nav/tree.ts** - Dynamic navigation tree (reads from `window.WNW_NAV_TREE`)
-2. **hooks/useActiveSection.ts** - Dynamic path matching
-3. **App.tsx** - AddonRoute component with lazy loading, error handling, loading states
-4. **Removed Bridge/iframe** - Cleaned ~150 lines of legacy code
-
-#### **Documentation - 100% Complete**
-1. **ADDON_INJECTION_GUIDE.md** (900+ lines)
- - Quick start (5-minute integration)
- - Complete API reference
- - Component development guide
- - Best practices and examples
-
-2. **HOOKS_REGISTRY.md** (500+ lines)
- - Complete hook tree structure
- - All active hooks documented
- - Priority guidelines
- - Usage examples
-
-3. **PROJECT_SOP.md** - Section 6 added (320+ lines)
- - Hook naming convention
- - Filter template pattern
- - **Non-React addon development (3 approaches)**
- - Development checklist
-
-4. **IMPLEMENTATION_SUMMARY.md** (400+ lines)
- - Complete implementation summary
- - Questions answered
- - Quick reference guide
-
-### ๐ Key Features
-
-**For Addon Developers:**
-- โ
5-minute integration with simple filters
-- โ
**Three development approaches:**
- 1. **Traditional PHP** - No React, uses WordPress admin pages
- 2. **Vanilla JS** - SPA integration without React
- 3. **React** - Full SPA with React (optional)
-- โ
Zero configuration - automatic discovery
-- โ
Dependency validation
-- โ
Error handling and loading states
-- โ
Full i18n support
-
-**For End Users:**
-- โ
Seamless integration (no iframes!)
-- โ
Fast loading with lazy loading
-- โ
Consistent UI
-- โ
Mobile responsive
-
-### ๐ Hook Structure
-
-```
-woonoow/
-โโโ addon_registry โ
ACTIVE (Priority: 20)
-โโโ spa_routes โ
ACTIVE (Priority: 25)
-โโโ nav_tree โ
ACTIVE (Priority: 30)
-โ โโโ {section_key}/children โ
ACTIVE (Priority: 30)
-โโโ dashboard/widgets ๐ PLANNED
-โโโ order/detail/panels ๐ PLANNED
-โโโ admin_is_dev โ
ACTIVE
-```
-
-### ๐ Orders Module as Reference
-
-Orders module serves as the model for all future implementations:
-- Clean route structure (`/orders`, `/orders/new`, `/orders/:id`)
-- No submenu (by design)
-- Full CRUD operations
-- Type-safe components
-- Proper error handling
-- Mobile responsive
-- i18n complete
-
-### ๐ฆ Example Addon Created
-
-**Location:** `examples/example-addon.php`
-- Complete working example
-- Addon registration
-- Route registration
-- Navigation injection
-- REST API endpoint
-- React component
-
-### โ
Success Criteria - ALL MET
-- [x] Remove Bridge/iframe system
-- [x] Implement AddonRegistry
-- [x] Implement RouteRegistry
-- [x] Implement NavigationRegistry
-- [x] Dynamic route loading
-- [x] Dynamic navigation
-- [x] Component lazy loading
-- [x] Error handling
-- [x] Comprehensive documentation
-- [x] Hook registry with tree structure
-- [x] Non-React support documented
-- [x] Production ready
-
-### ๐ฏ What This Enables
-
-Addons can now:
-- Register with metadata & dependencies
-- Add custom SPA routes
-- Inject main menu items
-- Inject submenu items
-- Load React components dynamically
-- Use vanilla JavaScript (no React)
-- Use traditional PHP/HTML/CSS
-- Access WooNooW APIs
-- Declare capabilities
-- Handle errors gracefully
-
-**Use Cases:**
-- WooCommerce Subscriptions
-- Bookings & Appointments
-- Memberships
-- Custom Reports
-- Third-party integrations
-- Custom product types
-- Marketing automation
-- **ANY custom functionality!**
-
-### ๐ Documentation Files
-
-- `ADDON_INJECTION_GUIDE.md` - Developer guide (900+ lines)
-- `HOOKS_REGISTRY.md` - Hook reference (500+ lines)
-- `PROJECT_SOP.md` - Section 6 (320+ lines)
-- `IMPLEMENTATION_SUMMARY.md` - Summary (400+ lines)
-- `ADDONS_ADMIN_UI_REQUIREMENTS.md` - Updated status
-- `ADDON_INJECTION_READINESS_REPORT.md` - Technical analysis
-- `examples/example-addon.php` - Working example
-
-**Total Documentation:** 2400+ lines
-
----
-
-**Last synced:** 2025โ10โ28 09:35 GMT+7
-**Next milestone:** Test addon system, then proceed with Dashboard module development.
-
----
-
-## ๐ณ Payment Gateway Integration โ October 28, 2025 (Afternoon)
-
-### โ
Phase 1: Core Integration - COMPLETE
-
-**Problem:** Payment gateways (Tripay, Duitku, Xendit) not receiving transactions when orders created via WooNooW Admin.
-
-**Root Cause:** WooCommerce payment gateways expect `process_payment()` to be called during checkout, but admin-created orders bypass this flow.
-
-### ๐ฏ Solution Implemented
-
-#### **Backend Changes**
-
-**File:** `includes/Api/OrdersController.php`
-
-1. **Auto-trigger payment processing** (lines 913-915)
- ```php
- if ( $payment_method && $status === 'pending' ) {
- self::process_payment_gateway( $order, $payment_method );
- }
- ```
-
-2. **New method: `process_payment_gateway()`** (lines 1509-1602)
- - Initializes WooCommerce cart (prevents `empty_cart()` errors)
- - Initializes WooCommerce session (prevents `set()` errors)
- - Gets payment gateway instance
- - Handles channel-based IDs (e.g., `tripay_bniva`, `bacs_account_0`)
- - Calls `$gateway->process_payment($order_id)`
- - Stores result metadata (`_woonoow_payment_redirect`)
- - Adds order notes
- - Logs success/failure
- - Graceful error handling (doesn't fail order creation)
-
-### ๐ง Technical Details
-
-**Session Initialization:**
-```php
-// Initialize cart
-if ( ! WC()->cart ) {
- WC()->initialize_cart();
-}
-
-// Initialize session
-if ( ! WC()->session || ! WC()->session instanceof \WC_Session ) {
- WC()->initialize_session();
-}
-```
-
-**Why needed:**
-- Payment gateways call `WC()->cart->empty_cart()` after successful payment
-- Payment gateways call `WC()->session->set()` to store payment data
-- Admin-created orders don't have active cart/session
-- Without initialization: `Call to a member function on null` errors
-
-### ๐ Features
-
-- โ
Universal solution (works with all WooCommerce payment gateways)
-- โ
Handles Tripay, Duitku, Xendit, PayPal, and custom gateways
-- โ
Stores payment metadata for display
-- โ
Adds order notes for audit trail
-- โ
Error logging for debugging
-- โ
Non-blocking (order creation succeeds even if payment fails)
-- โ
Channel support (e.g., Tripay BNI VA, Mandiri VA, etc.)
-
-### ๐ Documentation
-
-- `PAYMENT_GATEWAY_INTEGRATION.md` - Complete implementation guide
-- `PAYMENT_GATEWAY_PATTERNS.md` - Analysis of 4 major gateways
-
----
-
-## ๐ฐ Order Totals Calculation โ October 28, 2025 (Afternoon)
-
-### โ
COMPLETE - Shipping & Coupon Fixes
-
-**Problem:** Orders created via WooNooW showed incorrect totals:
-- Shipping cost always Rp0 (hardcoded)
-- Coupon discounts not calculated
-- Total = products only (missing shipping)
-
-### ๐ฏ Solutions Implemented
-
-#### **1. Shipping Cost Calculation**
-
-**File:** `includes/Api/OrdersController.php` (lines 830-858)
-
-**Before:**
-```php
-$ship_item->set_total( 0 ); // โ Always 0
-```
-
-**After:**
-```php
-// Get shipping method cost from settings
-$shipping_cost = 0;
-if ( $instance_id ) {
- $zones = \WC_Shipping_Zones::get_zones();
- foreach ( $zones as $zone ) {
- foreach ( $zone['shipping_methods'] as $method ) {
- if ( $method->id === $method_id && $method->instance_id == $instance_id ) {
- $shipping_cost = $method->get_option( 'cost', 0 ); // โ
Actual cost!
- break 2;
- }
- }
- }
-}
-$ship_item->set_total( $shipping_cost );
-```
-
-#### **2. Coupon Discount Calculation**
-
-**File:** `includes/Api/OrdersController.php` (lines 876-886)
-
-**Before:**
-```php
-$citem = new \WC_Order_Item_Coupon();
-$citem->set_code( $coupon->get_code() );
-$order->add_item( $citem ); // โ No discount calculated
-```
-
-**After:**
-```php
-$order->apply_coupon( $coupon ); // โ
Calculates discount!
-```
-
-### ๐ Results
-
-**Order Calculation Flow:**
-```
-1. Add products โ Subtotal: Rp112.000
-2. Add shipping โ Get cost from settings โ Rp25.000 โ
-3. Apply coupons โ Calculate discount โ -RpX โ
-4. Calculate totals โ Products + Shipping - Discount + Tax โ
-5. Payment gateway โ Receives correct total โ
-```
-
-**Example:**
-- Products: Rp112.000
-- Shipping: Rp25.000
-- **Total: Rp137.000** โ
(was Rp112.000 โ)
-
-### ๐ Documentation
-
-- `ORDER_TOTALS_FIX.md` - Complete fix documentation with test cases
-
----
-
-## ๐จ Order Totals Display โ October 28, 2025 (Afternoon)
-
-### โ
COMPLETE - Frontend Breakdown Display
-
-**Problem:** Order form only showed items count and subtotal. No shipping, discount, or total visible.
-
-### ๐ฏ Solution Implemented
-
-#### **Backend: Add Shipping Cost to API**
-
-**File:** `includes/Api/OrdersController.php` (lines 1149-1159)
-
-**Added `cost` field to shipping methods API:**
-```php
-$rows[] = [
- 'id' => $instance ? "{$id}:{$instance}" : $id,
- 'method' => $id,
- 'title' => (string) ( $m->title ?? $m->get_method_title() ?? $id ),
- 'cost' => (float) $cost, // โ
New!
-];
-```
-
-#### **Frontend: Complete Order Breakdown**
-
-**File:** `admin-spa/src/routes/Orders/partials/OrderForm.tsx`
-
-**Added calculations:**
-```typescript
-// Calculate shipping cost
-const shippingCost = React.useMemo(() => {
- if (!shippingMethod) return 0;
- const method = shippings.find(s => s.id === shippingMethod);
- return method ? Number(method.cost) || 0 : 0;
-}, [shippingMethod, shippings]);
-
-// Calculate order total
-const orderTotal = React.useMemo(() => {
- return itemsTotal + shippingCost;
-}, [itemsTotal, shippingCost]);
-```
-
-**Display:**
-```tsx
-
-
Items: 2
-
Subtotal: Rp112.000
-
Shipping: Rp25.000
-
Discount: (calculated on save)
-
- Total (est.): Rp137.000
-
-
-```
-
-### ๐ Features
-
-- โ
Real-time shipping cost display
-- โ
Subtotal + Shipping = Total
-- โ
Discount note (calculated server-side)
-- โ
Professional breakdown layout
-- โ
Responsive design
-
-### ๐ก Coupon Calculation - Best Practice
-
-**Decision:** Show "(calculated on save)" instead of frontend calculation
-
-**Why:**
-- โ
Accurate - Backend has all coupon rules
-- โ
Secure - Can't bypass restrictions
-- โ
Simple - No complex frontend logic
-- โ
Reliable - Always matches final total
-
-**Industry Standard:** Shopify, WooCommerce, Amazon all calculate discounts server-side.
-
-### ๐ Documentation
-
-- `ORDER_TOTALS_DISPLAY.md` - Complete display documentation
-
----
-
-## ๐ซ Phase 2: Payment Display โ October 28, 2025 (Evening)
-
-### โ
COMPLETE - Payment Instructions Card
-
-**Goal:** Display payment gateway metadata (VA numbers, QR codes, expiry, etc.) in Order Detail view.
-
-### ๐ฏ Solution Implemented
-
-#### **Backend: Payment Metadata API**
-
-**File:** `includes/Api/OrdersController.php`
-
-**New method: `get_payment_metadata()`** (lines 1604-1662)
-```php
-private static function get_payment_metadata( $order ): array {
- $meta_keys = apply_filters( 'woonoow/payment_meta_keys', [
- // Tripay
- '_tripay_payment_pay_code' => __( 'Payment Code', 'woonoow' ),
- '_tripay_payment_reference' => __( 'Reference', 'woonoow' ),
- '_tripay_payment_expired_time' => __( 'Expires At', 'woonoow' ),
- '_tripay_payment_amount' => __( 'Amount', 'woonoow' ),
-
- // Duitku
- '_duitku_va_number' => __( 'VA Number', 'woonoow' ),
- '_duitku_payment_url' => __( 'Payment URL', 'woonoow' ),
-
- // Xendit
- '_xendit_invoice_id' => __( 'Invoice ID', 'woonoow' ),
- '_xendit_invoice_url' => __( 'Invoice URL', 'woonoow' ),
-
- // WooNooW
- '_woonoow_payment_redirect' => __( 'Payment URL', 'woonoow' ),
- ], $order );
-
- // Extract, format timestamps, amounts, booleans
- // Return structured array
-}
-```
-
-**Features:**
-- โ
Auto-formats timestamps โ readable dates
-- โ
Auto-formats amounts โ currency (Rp70.000)
-- โ
Auto-formats booleans โ Yes/No
-- โ
Extensible via `woonoow/payment_meta_keys` filter
-- โ
Supports Tripay, Duitku, Xendit, custom gateways
-
-**Added to order API response** (line 442):
-```php
-'payment_meta' => self::get_payment_metadata($order),
-```
-
-#### **Frontend: Payment Instructions Card**
-
-**File:** `admin-spa/src/routes/Orders/Detail.tsx` (lines 212-242)
-
-```tsx
-{order.payment_meta && order.payment_meta.length > 0 && (
-
-
-
- {__('Payment Instructions')}
-
-
- {order.payment_meta.map((meta: any) => (
-
-
{meta.label}
-
- {meta.key.includes('url') ? (
-
- {meta.value}
-
- ) : meta.key.includes('amount') ? (
-
- ) : (
- meta.value
- )}
-
-
- ))}
-
-
-)}
-```
-
-### ๐ Example Display
-
-**Tripay BNI VA Order:**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ ๐ซ Payment Instructions โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ Payment Code 8808123456789012 โ
-โ Reference T1234567890 โ
-โ Expires At Oct 28, 2025 11:59 PM โ
-โ Amount Rp137.000 โ โ Currency formatted!
-โ Payment Type BNIVA โ
-โ Payment URL https://tripay.co/... ๐โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-### ๐ Features
-
-- โ
Only shows if payment metadata exists
-- โ
Ticket icon for visual clarity
-- โ
Grid layout: Label | Value
-- โ
Auto-detects URLs โ clickable with external icon
-- โ
Currency formatting for amounts
-- โ
Timestamp formatting
-- โ
Responsive design
-- โ
Extensible for custom gateways
-
-### ๐ Documentation
-
-- `PHASE2_PAYMENT_DISPLAY.md` - Complete Phase 2 documentation
-
----
-
-## ๐ Summary of October 28, 2025 Progress
-
-### โ
Completed Features
-
-1. **Payment Gateway Integration (Phase 1)**
- - Auto-trigger `process_payment()` for admin orders
- - Session initialization (cart + session)
- - Universal gateway support
- - Error handling and logging
-
-2. **Order Totals Calculation**
- - Shipping cost from method settings
- - Coupon discount calculation
- - Correct totals sent to payment gateway
-
-3. **Order Totals Display**
- - Complete breakdown in order form
- - Real-time shipping cost
- - Professional UI
-
-4. **Payment Display (Phase 2)**
- - Payment metadata extraction API
- - Payment Instructions card
- - Auto-formatting (timestamps, currency, URLs)
- - Multi-gateway support
-
-### ๐ Files Changed
-
-**Backend:**
-- `includes/Api/OrdersController.php` - 7 major changes
-
-**Frontend:**
-- `admin-spa/src/routes/Orders/partials/OrderForm.tsx` - Totals display
-- `admin-spa/src/routes/Orders/Detail.tsx` - Payment Instructions card
-
-**Documentation:**
-- `PAYMENT_GATEWAY_INTEGRATION.md`
-- `PAYMENT_GATEWAY_PATTERNS.md`
-- `ORDER_TOTALS_FIX.md`
-- `ORDER_TOTALS_DISPLAY.md`
-- `PHASE2_PAYMENT_DISPLAY.md`
-
-### ๐ฏ Next Phase: Actions
-
-**Phase 3 Features (Planned):**
-- [ ] "Retry Payment" button
-- [ ] "Cancel Payment" button
-- [ ] Manual payment status sync
-- [ ] Payment status webhooks
-- [ ] Real-time payment updates
-
----
-
-**Last synced:** 2025โ10โ28 22:00 GMT+7
-**Next milestone:** Phase 3 Payment Actions OR Dashboard module development.
-
----
-
-## ๐ Phase 3: Payment Actions โ October 28, 2025 (Night)
-
-### โ
Retry Payment Feature - COMPLETE
-
-**Goal:** Allow admins to manually retry payment processing for orders with payment issues.
-
-### ๐ฏ Solution Implemented
-
-#### **Backend: Retry Payment Endpoint**
-
-**File:** `includes/Api/OrdersController.php`
-
-**New endpoint** (lines 100-105):
-```php
-register_rest_route('woonoow/v1', '/orders/(?P\d+)/retry-payment', [
- 'methods' => 'POST',
- 'callback' => [__CLASS__, 'retry_payment'],
- 'permission_callback' => function () { return current_user_can('manage_woocommerce'); },
-]);
-```
-
-**New method: `retry_payment()`** (lines 1676-1726):
-```php
-public static function retry_payment( WP_REST_Request $req ): WP_REST_Response {
- // Validate permissions
- if ( ! current_user_can( 'manage_woocommerce' ) ) {
- return new WP_REST_Response( [ 'error' => 'forbidden' ], 403 );
- }
-
- // Get order
- $order = wc_get_order( $id );
- if ( ! $order ) {
- return new WP_REST_Response( [ 'error' => 'not_found' ], 404 );
- }
-
- // Validate payment method exists
- $payment_method = $order->get_payment_method();
- if ( empty( $payment_method ) ) {
- return new WP_REST_Response( [
- 'error' => 'no_payment_method',
- 'message' => __( 'Order has no payment method', 'woonoow' )
- ], 400 );
- }
-
- // Only allow retry for pending/on-hold/failed orders
- $status = $order->get_status();
- if ( ! in_array( $status, [ 'pending', 'on-hold', 'failed' ] ) ) {
- return new WP_REST_Response( [
- 'error' => 'invalid_status',
- 'message' => sprintf(
- __( 'Cannot retry payment for order with status: %s', 'woonoow' ),
- $status
- )
- ], 400 );
- }
-
- // Add order note
- $order->add_order_note( __( 'Payment retry requested via WooNooW Admin', 'woonoow' ) );
- $order->save();
-
- // Trigger payment processing
- self::process_payment_gateway( $order, $payment_method );
-
- return new WP_REST_Response( [
- 'success' => true,
- 'message' => __( 'Payment processing retried', 'woonoow' )
- ], 200 );
-}
-```
-
-**Features:**
-- โ
Permission check (manage_woocommerce)
-- โ
Order validation
-- โ
Payment method validation
-- โ
Status validation (only pending/on-hold/failed)
-- โ
Order note for audit trail
-- โ
Reuses existing `process_payment_gateway()` method
-- โ
Error handling with i18n messages
-
----
-
-#### **Frontend: Retry Payment Button**
-
-**File:** `admin-spa/src/routes/Orders/Detail.tsx`
-
-**Added mutation** (lines 113-130):
-```typescript
-// Mutation for retry payment
-const retryPaymentMutation = useMutation({
- mutationFn: () => api.post(`/orders/${id}/retry-payment`, {}),
- onSuccess: () => {
- showSuccessToast(__('Payment processing retried'));
- q.refetch();
- },
- onError: (err: any) => {
- showErrorToast(err, __('Failed to retry payment'));
- },
-});
-
-function handleRetryPayment() {
- if (!id) return;
- if (confirm(__('Retry payment processing for this order?'))) {
- retryPaymentMutation.mutate();
- }
-}
-```
-
-**Added button in Payment Instructions card** (lines 234-253):
-```tsx
-
-
-
- {__('Payment Instructions')}
-
- {['pending', 'on-hold', 'failed'].includes(order.status) && (
-
- )}
-
-```
-
-**Features:**
-- โ
Only shows for pending/on-hold/failed orders
-- โ
Confirmation dialog before retry
-- โ
Loading state with spinner
-- โ
Disabled during processing
-- โ
Success/error toast notifications
-- โ
Auto-refresh order data after retry
-- โ
Full i18n support
-
----
-
-### ๐ How It Works
-
-**Flow:**
-```
-1. Admin views order with pending payment
- โ
-2. Payment Instructions card shows "Retry Payment" button
- โ
-3. Admin clicks button โ Confirmation dialog
- โ
-4. Frontend calls POST /orders/{id}/retry-payment
- โ
-5. Backend validates order status & payment method
- โ
-6. Backend adds order note
- โ
-7. Backend calls process_payment_gateway()
- โ
-8. Gateway creates new transaction/payment
- โ
-9. Frontend shows success toast
- โ
-10. Order data refreshes with new payment metadata
-```
-
----
-
-### ๐ฏ Use Cases
-
-**When to use Retry Payment:**
-
-1. **Payment Gateway Timeout**
- - Initial payment failed due to network issue
- - Gateway API was temporarily down
- - Retry creates new transaction
-
-2. **Expired Payment**
- - VA number expired
- - QR code expired
- - Retry generates new payment code
-
-3. **Failed Transaction**
- - Customer payment failed
- - Need to generate new payment link
- - Retry creates fresh transaction
-
-4. **Admin Error**
- - Wrong payment method selected initially
- - Need to regenerate payment instructions
- - Retry with correct gateway
-
----
-
-### ๐ Example Display
-
-**Order Detail - Pending Payment:**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ ๐ซ Payment Instructions [๐ Retry Payment] โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ Payment Code 8808123456789012 (expired) โ
-โ Reference T1234567890 โ
-โ Expires At Oct 28, 2025 3:47 PM (past) โ
-โ Amount Rp137.000 โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**After clicking Retry Payment:**
-```
-โ
Payment processing retried
-
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ ๐ซ Payment Instructions [๐ Retry Payment] โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
-โ Payment Code 8808987654321098 (new!) โ
-โ Reference T9876543210 โ
-โ Expires At Oct 29, 2025 11:59 PM โ
-โ Amount Rp137.000 โ
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
----
-
-### ๐ Features Summary
-
-**Backend:**
-- โ
New `/orders/{id}/retry-payment` endpoint
-- โ
Status validation (pending/on-hold/failed only)
-- โ
Payment method validation
-- โ
Order note for audit trail
-- โ
Reuses existing payment gateway logic
-- โ
Full error handling
-
-**Frontend:**
-- โ
Retry Payment button in Payment Instructions card
-- โ
Conditional display (only for eligible statuses)
-- โ
Confirmation dialog
-- โ
Loading states
-- โ
Toast notifications
-- โ
Auto-refresh after retry
-
-**UX:**
-- โ
Clear button placement
-- โ
Icon + text label
-- โ
Hover states
-- โ
Disabled state during processing
-- โ
Responsive design
-
----
-
-### ๐ Files Changed
-
-**Backend:**
-- `includes/Api/OrdersController.php` (lines 100-105, 1676-1726)
-
-**Frontend:**
-- `admin-spa/src/routes/Orders/Detail.tsx` (lines 7, 113-130, 234-253)
-
----
-
-### ๐ฏ Next Steps
-
-**Phase 3 Remaining Features:**
-- [ ] "Cancel Payment" button
-- [ ] Manual payment status sync
-- [ ] Payment status webhooks
-- [ ] Real-time payment updates
-
----
-
-**Last synced:** 2025โ10โ28 23:20 GMT+7
-**Next milestone:** Complete Phase 3 (Cancel Payment + Status Sync) OR Dashboard module.
-
----
-
-## ๐ง Phase 3: Fixes & Polish โ October 28, 2025 (Night)
-
-### โ
Retry Payment Improvements - COMPLETE
-
-**Issues Found During Testing:**
-
-1. **โ Native confirm() dialog** - Not consistent with app design
-2. **โ 20-30 second delay** when retrying payment (Test 2 & 3)
-3. **โ Success toast on error** - Shows green even when payment fails (Test 6)
-
----
-
-### ๐ฏ Fixes Implemented
-
-#### **1. Replace confirm() with Shadcn Dialog**
-
-**File:** `admin-spa/src/routes/Orders/Detail.tsx`
-
-**Added Dialog component** (lines 9-10, 60, 124-132, 257-283):
-```tsx
-// Import Dialog components
-import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
-import { Button } from '@/components/ui/button';
-
-// State
-const [showRetryDialog, setShowRetryDialog] = useState(false);
-
-// Handlers
-function handleRetryPayment() {
- if (!id) return;
- setShowRetryDialog(true); // Show dialog instead of confirm()
-}
-
-function confirmRetryPayment() {
- setShowRetryDialog(false);
- retryPaymentMutation.mutate();
-}
-
-// Dialog UI
-
-```
-
-**Result:**
-- โ
Professional dialog matching Delete Orders design
-- โ
Warning message about creating new transaction
-- โ
Loading state in dialog button
-- โ
Full i18n support
-
----
-
-#### **2. Fix 20-30 Second Delay**
-
-**Problem:** WooCommerce analytics tracking to `pixel.wp.com` during `$order->save()`
-
-**File:** `includes/Api/OrdersController.php` (lines 1718-1728)
-
-**Solution:**
-```php
-// Block WooCommerce analytics tracking during save (prevents 30s delay)
-add_filter('pre_http_request', function($preempt, $args, $url) {
- if (strpos($url, 'pixel.wp.com') !== false || strpos($url, 'stats.wp.com') !== false) {
- return new \WP_Error('http_request_blocked', 'WooCommerce analytics blocked');
- }
- return $preempt;
-}, PHP_INT_MAX, 3);
-
-$order->save(); // Now completes in ~0.02s instead of 30s!
-
-remove_all_filters('pre_http_request');
-```
-
-**Result:**
-- โ
Retry payment now completes in <1 second
-- โ
1500x faster (30s โ 0.02s)
-- โ
Same fix used in order status updates
-
----
-
-#### **3. Fix Error Handling**
-
-**Problem:** Always shows success toast, even when payment gateway fails
-
-**File:** `includes/Api/OrdersController.php` (lines 1730-1739)
-
-**Before:**
-```php
-self::process_payment_gateway( $order, $payment_method );
-
-return new WP_REST_Response( [
- 'success' => true,
- 'message' => __( 'Payment processing retried', 'woonoow' )
-], 200 );
-```
-
-**After:**
-```php
-// Trigger payment processing and capture result
-$result = self::process_payment_gateway( $order, $payment_method );
-
-// Check if payment processing failed
-if ( is_wp_error( $result ) ) {
- return new WP_REST_Response( [
- 'error' => 'payment_failed',
- 'message' => $result->get_error_message()
- ], 400 );
-}
-
-return new WP_REST_Response( [
- 'success' => true,
- 'message' => __( 'Payment processing retried', 'woonoow' )
-], 200 );
-```
-
-**Result:**
-- โ
Returns 400 error when payment fails
-- โ
Shows red error toast with actual error message
-- โ
Frontend properly handles errors
-
----
-
-### ๐ Test Results
-
-**Before Fixes:**
-- โฑ๏ธ Retry payment: 20-30 seconds
-- โ Error shows green success toast
-- ๐ฒ Native browser confirm() dialog
-
-**After Fixes:**
-- โก Retry payment: <1 second (1500x faster!)
-- โ
Error shows red error toast with message
-- โจ Professional Shadcn dialog
-
----
-
-### ๐ Files Changed
-
-**Frontend:**
-- `admin-spa/src/routes/Orders/Detail.tsx` (lines 9-10, 60, 124-132, 257-283)
-
-**Backend:**
-- `includes/Api/OrdersController.php` (lines 1718-1739)
-
----
-
-### ๐ฏ Cancel Payment Analysis
-
-**Question:** Should we implement "Cancel Payment" feature?
-
-**Research:** Analyzed Tripay, Duitku, Xendit, PayPal gateways
-
-**Findings:**
-- โ Most Indonesian gateways **do NOT support** canceling pending payments via API
-- โ VA numbers and QR codes expire automatically
-- โ No explicit "cancel transaction" endpoint
-- โ ๏ธ Changing order status to "Cancelled" doesn't cancel gateway transaction
-- โ ๏ธ Customer can still pay after order cancelled (until expiry)
-- โ
Gateways handle expired payments automatically
-
-**Decision:** **Skip "Cancel Payment" feature**
-
-**Reasons:**
-1. Not supported by major Indonesian gateways
-2. Would require gateway-specific implementations
-3. Limited value (payments auto-expire)
-4. Order status "Cancelled" is sufficient for store management
-5. Webhooks handle late payments
-
-**Alternative:** Use order status changes + webhook handling
-
----
-
-## ๐ Dashboard Module Implementation
-**Date:** 2025-10-29 14:45 GMT+7
-
-### โ
Complete Dashboard with Dummy Data
-
-**Objective:** Create a fully functional Dashboard SPA module with dummy data for visualization before connecting to real data sources.
-
-### ๐ฏ Key Features Implemented
-
-#### 1. **Unified Date Range Control**
-- Single source of truth for period selection (7/14/30 days)
-- Positioned inline with Dashboard title (desktop) / below title (mobile)
-- Affects all date-based metrics and charts:
- - Revenue, Orders, Avg Order Value stat cards
- - Sales Overview chart
- - Top Products list
- - Top Customers list
- - Order Status Distribution
-
-#### 2. **Metric Cards with Period Comparison**
-- **Revenue** - Total for selected period with comparison
-- **Orders** - Count for selected period with comparison
-- **Avg Order Value** - Calculated from period data
-- **Conversion Rate** - Percentage with change indicator
-- Period comparison text: "vs previous 7/14/30 days"
-- Color-coded trend indicators (green โ / red โ)
-
-#### 3. **Low Stock Alert Banner**
-- Edge-to-edge amber warning banner
-- Positioned between stat cards and chart
-- Shows count of products needing attention
-- Direct link to Products page
-- Fully responsive (stacks on mobile)
-- Dark mode support
-
-#### 4. **Interactive Sales Overview Chart**
-- Toggle between Revenue / Orders / Both
-- Dual-axis chart (Revenue left, Orders right)
-- Proper currency formatting with store settings
-- Thousand separator support (e.g., Rp10.200.000)
-- Y-axis shows M/K format (millions/thousands)
-- Translatable axis labels
-- Custom tooltip with formatted values
-- Filtered by selected period
-
-#### 5. **Interactive Order Status Pie Chart**
-- Dropdown selector for order statuses
-- Thick donut chart with double-ring expansion
-- Active state shows selected status
-- Hover state with visual feedback
-- Center label displays count and status name
-- Color-coded status indicators in dropdown
-- Smooth transitions
-
-#### 6. **Top Products & Customers Tabs**
-- Single card with tab switcher
-- Products tab: Shows top 5 with revenue
-- Customers tab: Shows top 5 with total spent
-- Product icons/emojis for visual appeal
-- "View all" link to respective pages
-
-### ๐ง Technical Implementation
-
-**Files Created/Modified:**
-- `admin-spa/src/routes/Dashboard/index.tsx` - Main Dashboard component
-- `admin-spa/src/components/ui/tabs.tsx` - Tabs component for Shadcn UI
-
-**Key Technologies:**
-- **Recharts 3.3.0** - Chart library
-- **React hooks** - useState, useMemo for performance
-- **TanStack Query** - Ready for real data integration
-- **Shadcn UI** - Select, Tabs components
-- **Tailwind CSS** - Responsive styling
-
-**State Management:**
-```typescript
-const [period, setPeriod] = useState('30');
-const [chartMetric, setChartMetric] = useState('both');
-const [activeStatus, setActiveStatus] = useState('Completed');
-const [hoverIndex, setHoverIndex] = useState();
-```
-
-**Computed Metrics:**
-```typescript
-const periodMetrics = useMemo(() => {
- // Calculate revenue, orders, avgOrderValue
- // Compare with previous period
- return { revenue, orders, avgOrderValue };
-}, [chartData, period]);
-```
-
-### ๐จ UX Improvements
-
-#### Currency Formatting
-- Uses `formatMoney()` with store currency settings
-- Proper thousand separator (dot for IDR, comma for USD)
-- Decimal separator support
-- Symbol positioning (left/right/space)
-- Example: `Rp344.750.000` (Indonesian Rupiah)
-
-#### Responsive Design
-- **Desktop:** 4-column metric grid, inline controls
-- **Tablet:** 2-column metric grid
-- **Mobile:** Single column, stacked layout
-- Low Stock banner adapts to screen size
-- Chart maintains aspect ratio
-
-#### Interactive Elements
-- Pie chart responds to dropdown selection
-- Hover states on all interactive elements
-- Smooth transitions and animations
-- Keyboard navigation support
-
-### ๐ Dummy Data Structure
-
-```typescript
-DUMMY_DATA = {
- metrics: { revenue, orders, averageOrderValue, conversionRate },
- salesChart: [{ date, revenue, orders }, ...], // 30 days
- topProducts: [{ id, name, image, quantity, revenue }, ...],
- topCustomers: [{ id, name, orders, totalSpent }, ...],
- orderStatusDistribution: [{ name, value, color }, ...],
- lowStock: [{ id, name, stock, threshold, status }, ...]
-}
-```
-
-### ๐ Issues Fixed
-
-1. **TypeScript activeIndex error** - Used spread operator with `as any` to bypass type checking
-2. **Currency thousand separator** - Added `preferSymbol: true` to force store settings
-3. **Pie chart not expanding** - Removed key-based re-render, used hover state instead
-4. **Mobile responsiveness** - Fixed Low Stock banner layout for mobile
-5. **CSS class conflicts** - Removed duplicate `self-*` classes, fixed `flex-shrink-1` to `shrink`
-
-### ๐ฏ Next Steps
-
-**Ready for Real Data Integration:**
-1. Replace dummy data with API calls
-2. Connect to WooCommerce analytics
-3. Implement date range picker (custom dates)
-4. Add loading states
-5. Add error handling
-6. Add data refresh functionality
-
-**Future Enhancements:**
-- Export data functionality
-- More chart types (bar, line, scatter)
-- Comparison mode (year-over-year)
-- Custom metric cards
-- Dashboard customization
-
----
-
-## ๐ Dashboard Submenus Implementation
-**Date:** 2025-11-03 21:05 GMT+7
-
-### โ
All Dashboard Report Pages Complete
-
-**Objective:** Implement all 6 dashboard submenu pages with dummy data, shared components, and full functionality.
-
-### ๐ฏ Pages Implemented
-
-#### 1. **Revenue Report** (`/dashboard/revenue`)
-**File:** `admin-spa/src/routes/Dashboard/Revenue.tsx`
-
-**Features:**
-- 4 metric cards (Gross Revenue, Net Revenue, Tax Collected, Refunds)
-- Area chart showing revenue over time with gradient fills
-- Period selector (7/14/30 days)
-- Granularity selector (Daily/Weekly/Monthly)
-- 4 tabbed breakdown tables:
- - By Product (with refunds and net revenue)
- - By Category (with percentage of total)
- - By Payment Method (BCA VA, Mandiri VA, GoPay, OVO)
- - By Shipping Method (JNE, J&T, SiCepat, Pickup)
-- Sortable columns with custom rendering
-- Proper currency formatting with store settings
-
-#### 2. **Orders Analytics** (`/dashboard/orders`)
-**File:** `admin-spa/src/routes/Dashboard/Orders.tsx`
-
-**Features:**
-- 4 metric cards (Total Orders, Avg Order Value, Fulfillment Rate, Cancellation Rate)
-- Line chart showing orders timeline with status breakdown
-- Pie chart for order status distribution (Completed, Processing, Pending, etc.)
-- Bar chart for orders by day of week
-- Bar chart for orders by hour (24-hour heatmap showing peak times)
-- Additional metrics cards (Avg Processing Time, Performance Summary)
-- Color-coded status indicators
-
-#### 3. **Products Performance** (`/dashboard/products`)
-**File:** `admin-spa/src/routes/Dashboard/Products.tsx`
-
-**Features:**
-- 4 metric cards (Items Sold, Revenue, Low Stock Items, Out of Stock)
-- Top products table with emoji icons (๐ง, โ, ๐, etc.)
-- Product details: SKU, items sold, revenue, stock, conversion rate
-- Category performance table with percentage breakdown
-- Stock analysis with 3 tabs:
- - Low Stock (products below threshold)
- - Out of Stock (unavailable products)
- - Slow Movers (no recent sales)
-- Highlighted low stock items in amber color
-- Last sale date and days since sale tracking
-
-#### 4. **Customers Analytics** (`/dashboard/customers`)
-**File:** `admin-spa/src/routes/Dashboard/Customers.tsx`
-
-**Features:**
-- 4 metric cards (Total Customers, Avg LTV, Retention Rate, Avg Orders/Customer)
-- 4 customer segment cards with percentages:
- - New Customers (green)
- - Returning Customers (blue)
- - VIP Customers (purple)
- - At Risk (red)
-- Customer acquisition line chart (New vs Returning over time)
-- Top customers table with segment badges
-- Customer details: name, email, orders, total spent, avg order value
-- LTV distribution bar chart (5 spending ranges)
-- Angled x-axis labels for better readability
-
-#### 5. **Coupons Report** (`/dashboard/coupons`)
-**File:** `admin-spa/src/routes/Dashboard/Coupons.tsx`
-
-**Features:**
-- 4 metric cards (Total Discount, Coupons Used, Revenue with Coupons, Avg Discount/Order)
-- Line chart showing coupon usage and discount amount over time
-- Coupon performance table with:
- - Coupon code (WELCOME10, FLASH50K, etc.)
- - Type (Percentage, Fixed Cart, Fixed Product)
- - Amount (10%, Rp50.000, etc.)
- - Uses count
- - Total discount amount
- - Revenue generated
- - ROI calculation (e.g., 6.1x)
-- Sortable by any metric
-
-#### 6. **Taxes Report** (`/dashboard/taxes`)
-**File:** `admin-spa/src/routes/Dashboard/Taxes.tsx`
-
-**Features:**
-- 3 metric cards (Total Tax Collected, Avg Tax per Order, Orders with Tax)
-- Line chart showing tax collection over time
-- Tax by rate table (PPN 11%)
-- Tax by location table:
- - Indonesian provinces (DKI Jakarta, Jawa Barat, etc.)
- - Orders count per location
- - Tax amount per location
- - Percentage of total
-- Two-column layout for rate and location breakdowns
-
-### ๐ง Shared Components Created
-
-**Files:** `admin-spa/src/routes/Dashboard/components/`
-
-#### StatCard.tsx
-**Purpose:** Reusable metric card with trend indicators
-
-**Features:**
-- Supports 3 formats: money, number, percent
-- Trend indicators (โ green / โ red)
-- Period comparison text
-- Loading skeleton state
-- Icon support (lucide-react)
-- Responsive design
-
-**Usage:**
-```typescript
-
-```
-
-#### ChartCard.tsx
-**Purpose:** Consistent chart container with title and actions
-
-**Features:**
-- Title and description
-- Action buttons slot (for selectors)
-- Loading skeleton state
-- Configurable height
-- Responsive padding
-
-**Usage:**
-```typescript
-...}
->
- ...
-
-```
-
-#### DataTable.tsx
-**Purpose:** Sortable, searchable data table
-
-**Features:**
-- Sortable columns (asc/desc/none)
-- Custom cell rendering
-- Column alignment (left/center/right)
-- Loading skeleton (5 rows)
-- Empty state message
-- Responsive overflow
-- Hover states
-
-**Usage:**
-```typescript
-
-```
-
-### ๐ Dummy Data Files
-
-**Files:** `admin-spa/src/routes/Dashboard/data/`
-
-All dummy data structures match the planned REST API responses:
-
-#### dummyRevenue.ts
-- 30 days of chart data
-- 8 top products
-- 4 categories
-- 4 payment methods
-- 4 shipping methods
-- Overview metrics with comparison
-
-#### dummyOrders.ts
-- 30 days of chart data
-- 6 order statuses with colors
-- 24-hour breakdown
-- 7-day breakdown
-- Processing time metrics
-
-#### dummyProducts.ts
-- 8 top products with emojis
-- 4 categories
-- Stock analysis (4 low, 2 out, 3 slow)
-- Conversion rates
-- Last sale tracking
-
-#### dummyCustomers.ts
-- 10 top customers
-- 30 days acquisition data
-- 4 customer segments
-- 5 LTV ranges
-- Indonesian names and emails
-
-#### dummyCoupons.ts
-- 7 active coupons
-- 30 days usage data
-- ROI calculations
-- Multiple coupon types
-
-#### dummyTaxes.ts
-- 30 days tax data
-- PPN 11% rate
-- 6 Indonesian provinces
-- Location-based breakdown
-
-### ๐จ Technical Highlights
-
-**Recharts Integration:**
-- Area charts with gradient fills
-- Line charts with multiple series
-- Bar charts with rounded corners
-- Pie charts with custom labels
-- Custom tooltips with proper formatting
-- Responsive containers
-- Legend support
-
-**Currency Formatting:**
-- Uses `formatMoney()` with store settings
-- Proper thousand separator (dot for IDR)
-- Decimal separator support
-- Symbol positioning
-- M/K abbreviations for large numbers
-- Example: `Rp344.750.000`
-
-**Responsive Design:**
-- Desktop: 4-column grids, side-by-side layouts
-- Tablet: 2-column grids
-- Mobile: Single column, stacked layouts
-- Charts maintain aspect ratio
-- Tables scroll horizontally
-- Period selectors adapt to screen size
-
-**TypeScript:**
-- Full type safety for all data structures
-- Exported interfaces for each data type
-- Generic DataTable component
-- Type-safe column definitions
-- Proper Recharts type handling (with `as any` workaround)
-
-### ๐บ๏ธ Navigation Integration
-
-**File:** `admin-spa/src/nav/tree.ts`
-
-**Added dashboard submenus:**
-```typescript
-{
- key: 'dashboard',
- label: 'Dashboard',
- path: '/',
- children: [
- { label: 'Overview', mode: 'spa', path: '/', exact: true },
- { label: 'Revenue', mode: 'spa', path: '/dashboard/revenue' },
- { label: 'Orders', mode: 'spa', path: '/dashboard/orders' },
- { label: 'Products', mode: 'spa', path: '/dashboard/products' },
- { label: 'Customers', mode: 'spa', path: '/dashboard/customers' },
- { label: 'Coupons', mode: 'spa', path: '/dashboard/coupons' },
- { label: 'Taxes', mode: 'spa', path: '/dashboard/taxes' },
- ],
-}
-```
-
-**Routing:** `admin-spa/src/App.tsx`
-
-All routes already added:
-```typescript
-} />
-} />
-} />
-} />
-} />
-} />
-} />
-```
-
-### ๐ฏ Dummy Data Toggle System
-
-**Files:**
-- `admin-spa/src/lib/useDummyData.ts` - Zustand store
-- `admin-spa/src/components/DummyDataToggle.tsx` - Toggle button
-
-**Features:**
-- Global state with LocalStorage persistence
-- Toggle button on all dashboard pages
-- Visual indicator (Database vs DatabaseZap icon)
-- Works across page navigation
-- Ready for real API integration
-
-**Usage in pages:**
-```typescript
-const useDummy = useDummyData();
-const data = useDummy ? DUMMY_DATA : realApiData;
-```
-
-### ๐ Statistics
-
-**Files Created:** 19
-- 7 page components
-- 3 shared components
-- 6 dummy data files
-- 1 dummy data store
-- 1 toggle component
-- 1 tooltip component
-
-**Lines of Code:** ~4,000+
-**Chart Types:** Area, Line, Bar, Pie
-**Tables:** 15+ with sortable columns
-**Metric Cards:** 25+ across all pages
-
-### ๐ฏ Next Steps
-
-**Immediate:**
-1. โ
Add dashboard submenus to navigation tree
-2. โ
Verify all routes work
-3. โ
Test dummy data toggle
-4. โณ Update DASHBOARD_PLAN.md
-
-**Short Term:**
-1. Wire to real API endpoints
-2. Add loading states
-3. Add error handling
-4. Add data refresh functionality
-5. Add export functionality (CSV/PDF)
-
-**Long Term:**
-1. Custom date range picker
-2. Comparison mode (year-over-year)
-3. Dashboard customization
-4. Real-time updates
-5. Advanced filters
-
----
-
-**Last synced:** 2025โ11โ03 21:05 GMT+7
-**Next milestone:** Wire Dashboard to real data OR Products module.# ๐ Dashboard Analytics Implementation โ November 4, 2025
-
-## โ
COMPLETE - All 7 Analytics Pages with Real Data
-
-**Status:** Production Ready
-**Implementation:** Full HPOS integration with 5-minute caching
-**Total Lines:** ~1200 lines (AnalyticsController.php)
-
-### ๐ฏ Implemented Pages
-
-#### **1. Overview** (`/analytics/overview`)
-- โ
Sales chart (revenue + orders over time) with **filled dates**
-- โ
Top 5 products by revenue
-- โ
Top 5 customers by spending
-- โ
Order status distribution (pie chart with sorting)
-- โ
Key metrics: Revenue, Orders, Avg Order Value, **Conversion Rate**
-
-#### **2. Revenue** (`/analytics/revenue`)
-- โ
Revenue chart (gross, net, tax, refunds, shipping)
-- โ
Top 10 products by revenue
-- ๐ Revenue by category (TODO)
-- ๐ Revenue by payment method (TODO)
-- ๐ Revenue by shipping method (TODO)
-
-#### **3. Orders** (`/analytics/orders`)
-- โ
Orders over time (total + by status)
-- โ
Orders by status (sorted by importance)
-- โ
Orders by hour of day (24h breakdown)
-- โ
Orders by day of week
-- โ
Average processing time (human-readable)
-- โ
Fulfillment rate & Cancellation rate
-
-#### **4. Products** (`/analytics/products`)
-- โ
Top 20 products by revenue
-- โ
Stock analysis (low stock, out of stock counts)
-- โ
Average price calculation
-- ๐ Conversion rate placeholder (0.00)
-
-#### **5. Customers** (`/analytics/customers`)
-- โ
Top 20 customers by spending
-- โ
New vs Returning customers
-- โ
Customer segments
-- โ
Average LTV (Lifetime Value)
-- โ
Average orders per customer
-
-#### **6. Coupons** (`/analytics/coupons`)
-- โ
Coupon usage chart over time
-- โ
Top coupons by discount amount
-- โ
**ROI calculation** (Revenue Generated / Discount Given)
-- โ
Coupon performance metrics
-
-#### **7. Taxes** (`/analytics/taxes`)
-- โ
Tax chart over time
-- โ
Total tax collected
-- โ
Average tax per order
-- โ
Orders with tax count
-
----
-
-## ๐ง Key Features Implemented
-
-### **1. Conversion Rate Calculation**
-**Formula:** `(Completed Orders / Total Orders) ร 100`
-
-**Example:**
-- 10 orders total
-- 3 completed
-- Conversion Rate = 30.00%
-
-**Location:** `AnalyticsController.php` lines 383-406
-
-```php
-$total_all_orders = 0;
-$completed_orders = 0;
-
-foreach ($orderStatusDistribution as $status) {
- $total_all_orders += $count;
- if ($status->status === 'wc-completed') {
- $completed_orders = $count;
- }
-}
-
-$conversion_rate = $total_all_orders > 0
- ? round(($completed_orders / $total_all_orders) * 100, 2)
- : 0.00;
-```
-
----
-
-### **2. Fill All Dates in Charts**
-**Best Practice:** Show all dates in range, even with no data
-
-**Implementation:** `AnalyticsController.php` lines 324-358
-
-```php
-// Create a map of existing data
-$data_map = [];
-foreach ($salesChart as $row) {
- $data_map[$row->date] = [
- 'revenue' => round(floatval($row->revenue), 2),
- 'orders' => intval($row->orders),
- ];
-}
-
-// Fill in ALL dates in the range
-for ($i = $days - 1; $i >= 0; $i--) {
- $date = date('Y-m-d', strtotime("-{$i} days"));
-
- if (isset($data_map[$date])) {
- $revenue = $data_map[$date]['revenue'];
- $orders = $data_map[$date]['orders'];
- } else {
- // No data for this date, fill with zeros
- $revenue = 0.00;
- $orders = 0;
- }
-
- $formatted_sales[] = [
- 'date' => $date,
- 'revenue' => $revenue,
- 'orders' => $orders,
- ];
-}
-```
-
-**Benefits:**
-- โ
Shows complete timeline (no gaps)
-- โ
Weekends/holidays with no orders are visible
-- โ
Accurate trend visualization
-- โ
Matches Google Analytics, Shopify standards
-
----
-
-### **3. Frontend Improvements**
-
-#### **Conversion Rate Display**
-- โ
Uses real API data (no dummy fallback)
-- โ
Formatted as percentage with 2 decimals
-- โ
Shows comparison for non-"all time" periods
-
-#### **Low Stock Alert**
-- โ
Hides when count is zero
-- โ
Shows actual count from API
-- โ
No dummy data fallback
-
-**Location:** `admin-spa/src/routes/Dashboard/index.tsx`
-
-```typescript
-// Conversion rate from real data
-const currentConversionRate = data?.metrics?.conversionRate?.today ?? 0;
-
-// Low stock alert - hide if zero
-{(data?.lowStock?.length ?? 0) > 0 && (
-
- {data?.lowStock?.length ?? 0} products need attention
-
-)}
-```
-
----
-
-### **4. Chart Visualization**
-
-**Sales Overview Chart:**
-- โ
Area chart for revenue (gradient fill)
-- โ
Line chart with dots for orders
-- โ
Balanced visual hierarchy
-- โ
Professional appearance
-
-**Order Status Pie Chart:**
-- โ
Sorted by importance (completed first)
-- โ
Auto-selection of first status
-- โ
Interactive hover states
-- โ
Color-coded by status
-
----
-
-## ๐ API Endpoints
-
-All endpoints support caching (5 minutes):
-
-1. `GET /woonoow/v1/analytics/overview?period=30`
-2. `GET /woonoow/v1/analytics/revenue?period=30&granularity=day`
-3. `GET /woonoow/v1/analytics/orders?period=30`
-4. `GET /woonoow/v1/analytics/products?period=30`
-5. `GET /woonoow/v1/analytics/customers?period=30`
-6. `GET /woonoow/v1/analytics/coupons?period=30`
-7. `GET /woonoow/v1/analytics/taxes?period=30`
-
-**Period Options:** `7`, `14`, `30`, `all`
-
----
-
-## ๐จ UI/UX Features
-
-- โ
Period selector (Last 7/14/30 days, All time)
-- โ
Real Data toggle (switches between real and dummy data)
-- โ
Responsive design (mobile-first)
-- โ
Dark mode support
-- โ
Loading states
-- โ
Error handling
-- โ
Empty states
-- โ
Metric cards with comparison
-- โ
Professional charts (Recharts)
-- โ
Consistent styling (Shadcn UI)
-
----
-
-## ๐ Files Changed
-
-### Backend (PHP)
-- `includes/Api/AnalyticsController.php` - Complete implementation (~1200 lines)
-- `includes/Api/Routes.php` - 7 new endpoints
-
-### Frontend (React/TypeScript)
-- `admin-spa/src/routes/Dashboard/index.tsx` - Overview page
-- `admin-spa/src/routes/Dashboard/Revenue.tsx` - Revenue page
-- `admin-spa/src/routes/Dashboard/Orders.tsx` - Orders analytics
-- `admin-spa/src/routes/Dashboard/Products.tsx` - Products analytics
-- `admin-spa/src/routes/Dashboard/Customers.tsx` - Customers analytics
-- `admin-spa/src/routes/Dashboard/Coupons.tsx` - Coupons analytics
-- `admin-spa/src/routes/Dashboard/Taxes.tsx` - Taxes analytics
-- `admin-spa/src/hooks/useAnalytics.ts` - Shared analytics hook
-
----
-
-## ๐ Fixes Applied
-
-1. โ
**Recharts prop warning** - Changed from function to string-based `dataKey`/`nameKey`
-2. โ
**Conversion rate dummy data** - Now uses real API data
-3. โ
**Low stock alert** - Hides when zero
-4. โ
**Date gaps in charts** - All dates filled with zeros
-5. โ
**"All time" comparison** - Suppressed for all time period
-6. โ
**Percentage formatting** - Consistent 2 decimal places
-
----
-
-## ๐ฏ Next Steps (Optional Enhancements)
-
-1. **Revenue by Category** - Group products by category
-2. **Revenue by Payment Method** - Breakdown by gateway
-3. **Revenue by Shipping Method** - Breakdown by shipping
-4. **Product Conversion Rate** - Track views โ purchases
-5. **Customer Retention Rate** - Calculate repeat purchase rate
-6. **Previous Period Comparison** - Calculate "yesterday" metrics
-7. **Export to CSV** - Download analytics data
-8. **Date Range Picker** - Custom date selection
-9. **Real-time Updates** - WebSocket or polling
-10. **Dashboard Widgets** - Customizable widget system
-
----
-
-## โ
Success Criteria - ALL MET
-
-- [x] 7 analytics pages implemented
-- [x] Real HPOS data integration
-- [x] Caching (5 minutes)
-- [x] Conversion rate calculation
-- [x] Fill all dates in charts
-- [x] ROI calculation for coupons
-- [x] Responsive design
-- [x] Dark mode support
-- [x] Error handling
-- [x] Loading states
-- [x] No dummy data fallbacks in Real Data mode
-- [x] Professional UI/UX
-
----
-
-**Implementation Date:** November 4, 2025
-**Total Development Time:** ~6 hours
-**Status:** โ
Production Ready
-**Next Milestone:** Products module OR Settings module
-
----
-
-## ๐ Standalone Admin Mode โ November 5, 2025
-
-### โ
COMPLETE - Three Admin Modes Implemented
-
-**Goal:** Provide flexible admin interface access with three distinct modes: normal (wp-admin), fullscreen, and standalone.
-
-### ๐ฏ Three Admin Modes
-
-#### **1. Normal Mode (wp-admin)**
-- **URL:** `/wp-admin/admin.php?page=woonoow`
-- **Layout:** WordPress admin sidebar + WooNooW SPA
-- **Use Case:** Traditional WordPress admin workflow
-- **Features:**
- - WordPress admin bar visible
- - WordPress sidebar navigation
- - WooNooW SPA in main content area
- - Settings submenu hidden (use WooCommerce settings)
-
-#### **2. Fullscreen Mode**
-- **Toggle:** Fullscreen button in header
-- **Layout:** WooNooW SPA only (no WordPress chrome)
-- **Use Case:** Focus mode for order processing
-- **Features:**
- - Maximized workspace
- - Distraction-free interface
- - All WooNooW features accessible
- - Settings submenu hidden
-
-#### **3. Standalone Mode** โจ NEW
-- **URL:** `https://yoursite.com/admin`
-- **Layout:** Complete standalone application
-- **Use Case:** Quick daily access, mobile-friendly
-- **Features:**
- - Custom login page (`/admin#/login`)
- - WordPress authentication integration
- - Settings submenu visible (SPA settings pages)
- - "WordPress" button to access wp-admin
- - "Logout" button in header
- - Admin bar link in wp-admin to standalone
-
-### ๐ง Implementation Details
-
-#### **Backend Changes**
-
-**File:** `includes/Admin/StandaloneAdmin.php`
-- Handles `/admin` and `/admin/` requests
-- Renders standalone HTML template
-- Localizes `WNW_CONFIG` with `standaloneMode: true`
-- Provides authentication state
-- Includes store settings (currency, formatting)
-
-**File:** `includes/Admin/Menu.php`
-- Added admin bar link to standalone mode
-- Icon: `dashicons-store`
-- Only visible to users with `manage_woocommerce` capability
-
-**File:** `includes/Api/AuthController.php`
-- Login endpoint using native WordPress authentication
-- Sequence: `wp_authenticate()` โ `wp_clear_auth_cookie()` โ `wp_set_current_user()` โ `wp_set_auth_cookie()` โ `do_action('wp_login')`
-- Ensures session persistence between standalone and wp-admin
-
-#### **Frontend Changes**
-
-**File:** `admin-spa/src/App.tsx`
-- `AuthWrapper` component handles authentication
-- Login/logout flow with page reload
-- "WordPress" button in header (standalone only)
-- "Logout" button in header (standalone only)
-
-**File:** `admin-spa/src/routes/Login.tsx`
-- Custom login form
-- Username/password authentication
-- Redirects to dashboard after login
-- Page reload to pick up fresh cookies/nonces
-
-**File:** `admin-spa/src/nav/tree.ts`
-- Dynamic settings submenu using getter
-- Only shows in standalone mode: `get children() { return isStandalone ? [...] : [] }`
-- Dashboard path: `/dashboard` (with redirect from `/`)
-
-### ๐ Navigation Structure
-
-**Standalone Mode Settings:**
-```
-Settings
-โโโ WooNooW (main settings)
-โโโ General (store settings)
-โโโ Payments (gateways)
-โโโ Shipping (zones, methods)
-โโโ Products (inventory)
-โโโ Tax (rates)
-โโโ Accounts & Privacy
-โโโ Emails (templates)
-โโโ Advanced (bridge to wp-admin)
-โโโ Integration (bridge to wp-admin)
-โโโ Status (bridge to wp-admin)
-โโโ Extensions (bridge to wp-admin)
-```
-
-**Strategy:** Option A - Everyday Use Dashboard
-- Focus on most-used settings
-- Bridge to wp-admin for advanced settings
-- Extensible for 3rd party plugins
-- Coexist with WooCommerce
-
-### ๐ Authentication Flow
-
-**Standalone Login:**
-1. User visits `/admin`
-2. Not authenticated โ redirect to `/admin#/login`
-3. Submit credentials โ `POST /wp-json/woonoow/v1/auth/login`
-4. Backend sets WordPress auth cookies
-5. Page reload โ authenticated state
-6. Access all WooNooW features
-
-**Session Persistence:**
-- Login in standalone โ logged in wp-admin โ
-- Login in wp-admin โ logged in standalone โ
-- Logout in standalone โ logged out wp-admin โ
-- Logout in wp-admin โ logged out standalone โ
-
-### ๐ฑ Cross-Navigation
-
-**From Standalone to wp-admin:**
-- Click "WordPress" button in header
-- Opens `/wp-admin` in same tab
-- Session persists
-
-**From wp-admin to Standalone:**
-- Click "WooNooW" in admin bar
-- Opens `/admin` in same tab
-- Session persists
-
-### โ
Features Completed
-
-- [x] Standalone mode routing (`/admin`)
-- [x] Custom login page
-- [x] WordPress authentication integration
-- [x] Session persistence
-- [x] Settings submenu (standalone only)
-- [x] WordPress button in header
-- [x] Logout button in header
-- [x] Admin bar link to standalone
-- [x] Dashboard path consistency (`/dashboard`)
-- [x] Dynamic navigation tree
-- [x] Settings placeholder pages
-- [x] Documentation updates
-
-### ๐ Documentation
-
-- `STANDALONE_ADMIN_SETUP.md` - Setup guide
-- `PROJECT_BRIEF.md` - Updated Phase 4
-- `PROJECT_SOP.md` - Section 7 (modes explanation)
-- `PROGRESS_NOTE.md` - This section
-
----
-
-**Implementation Date:** November 5, 2025
-**Status:** โ
Production Ready
-**Next Milestone:** Implement General/Payments/Shipping settings pages
-
----
-
-## ๐ฑ Mobile Orders UI Enhancement & Contextual Headers
-
-**Date:** November 8, 2025
-**Status:** โ
Completed & Documented
-
-### Overview
-
-Enhanced the Orders module with a complete mobile-first redesign, implementing industry-standard patterns for card layouts, filtering, and contextual headers across all CRUD pages.
-
-### Features Implemented
-
-#### 1. Mobile Orders List Redesign โ
-- **Card-based layout** for mobile (replaces table)
-- **OrderCard component** with status-colored badges
-- **SearchBar component** with integrated filter button
-- **FilterBottomSheet** for mobile-friendly filtering
-- **Pull-to-refresh** functionality
-- **Infinite scroll** support
-- **Responsive design** (cards on mobile, table on desktop)
-
-**Files:**
-- `admin-spa/src/routes/Orders/index.tsx` - Complete mobile redesign
-- `admin-spa/src/routes/Orders/components/OrderCard.tsx` - Card component
-- `admin-spa/src/routes/Orders/components/SearchBar.tsx` - Search with filter button
-- `admin-spa/src/routes/Orders/components/FilterBottomSheet.tsx` - Mobile filter UI
-
-#### 2. OrderCard Design Evolution โ
-
-**Final Design:**
-```
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-โ โ [#337] Nov 04, 2025, 11:44 PMโ โ Order ID badge (status color)
-โ Dwindi Ramadhana โโ โ Customer (bold)
-โ 1 item ยท Test Digital โ โ Items
-โ Rp64.500 โ โ Total (large, primary)
-โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
-```
-
-**Features:**
-- Order ID as colored badge (replaces icon)
-- Status colors: Green (completed), Blue (processing), Amber (pending), etc.
-- Compact layout with efficient space usage
-- Touch-optimized tap targets
-- Inspired by Uber, DoorDash, Airbnb patterns
-
-#### 3. Filter Bottom Sheet โ
-
-**Features:**
-- Z-index layering: Above FAB and bottom nav
-- Instant filtering (no Apply button)
-- Clear all filters button (when filters active)
-- Proper padding for bottom navigation
-- Scrollable content area
-
-**UX Pattern:**
-- Filters apply immediately on change
-- "Clear all filters" button only when filters active
-- Follows industry standards (Gmail, Amazon, Airbnb)
-
-#### 4. DateRange Component Fixes โ
-
-**Issues Fixed:**
-- Horizontal overflow in bottom sheet
-- WP forms.css overriding styles
-- Redundant Apply button
-
-**Solution:**
-- Vertical layout (`flex-col`)
-- Full shadcn/ui styling with `!important` overrides
-- Instant filtering on date change
-
-#### 5. Mobile Contextual Header Pattern โ
-
-**Concept: Dual Header System**
-
-1. **Contextual Header** (Mobile + Desktop)
- - Format: `[Back] Page Title [Action]`
- - Common actions (Back, Edit, Save, Create)
- - Always visible (sticky)
-
-2. **Page Header** (Desktop Only)
- - Extra actions (Print, Invoice, Label)
- - Hidden on mobile (`hidden md:flex`)
-
-**Implementation:**
-
-| Page | Contextual Header | Page Header |
-|------|-------------------|-------------|
-| **Orders List** | None | Filters, Search |
-| **Order Detail** | [Back] Order #337 [Edit] | Print, Invoice, Label |
-| **New Order** | [Back] New Order [Create] | None |
-| **Edit Order** | [Back] Edit Order #337 [Save] | None |
-
-**Files:**
-- `admin-spa/src/routes/Orders/Detail.tsx` - Contextual header with Back + Edit
-- `admin-spa/src/routes/Orders/New.tsx` - Contextual header with Back + Create
-- `admin-spa/src/routes/Orders/Edit.tsx` - Contextual header with Back + Save
-- `admin-spa/src/routes/Orders/partials/OrderForm.tsx` - formRef + hideSubmitButton props
-
-**Form Submit Pattern:**
-```typescript
-// Trigger form submit from header button
-const formRef = useRef(null);
-
-const actions = (
-
-);
-
-
-```
-
-#### 6. Code Quality โ
-
-**ESLint Fixes:**
-- Fixed React hooks rule violations
-- Fixed TypeScript type mismatches
-- Fixed React Compiler memoization warnings
-- Zero errors, zero warnings in modified files
-
-**Files Fixed:**
-- `admin-spa/src/routes/Orders/components/OrderCard.tsx` - Type fixes
-- `admin-spa/src/routes/Orders/Edit.tsx` - Hooks order fix
-- `admin-spa/src/routes/Orders/index.tsx` - Memoization fix
-
-### Technical Implementation
-
-**Key Patterns:**
-
-1. **usePageHeader Hook**
- ```typescript
- const { setPageHeader, clearPageHeader } = usePageHeader();
-
- useEffect(() => {
- setPageHeader('Page Title', );
- return () => clearPageHeader();
- }, [dependencies]);
- ```
-
-2. **Form Ref Pattern**
- ```typescript
- const formRef = useRef(null);
-