docs: consolidate markdown documentation into master guides and remove obsolete files

This commit is contained in:
Dwindi Ramadhana
2026-03-12 04:19:25 +07:00
parent ab10c25c28
commit 3f2019bc7c
47 changed files with 603 additions and 18841 deletions

185
docs/ADDONS_GUIDE.md Normal file
View File

@@ -0,0 +1,185 @@
# WooNooW Addon & Module Development Guide
**Version:** 2.0.0
**Status:** Production Ready
This document is the single source of truth for extending WooNooW. It covers everything from basic code snippets (Bridge Patterns) to full-featured React SPAs (Addon Modules).
---
## 📋 Table of Contents
1. [Philosophy & Architecture](#philosophy--architecture)
2. [Addon Types & Integration Levels](#addon-types--integration-levels)
- Level 1: Vanilla JS / Bridge Patterns
- Level 2: React Runtime Expansion (Recommended)
- Level 3: Slot-Based Components
3. [Developing a Full Addon](#developing-a-full-addon)
- Registration
- Settings & Options
- The Hook System
4. [Addon & Built-in Module Unification](#addon--built-in-module-unification)
5. [Examples](#examples)
---
## 1. Philosophy & Architecture
**WooNooW Core = Zero Addon Dependencies**
We don't integrate specific addons (like shipping or payment plugins) directly into WooNooW core. Instead, we provide:
1. **Hook system** for external addons to extend functionality.
2. **Exposed React Runtime** so addons don't have to bundle heavy libraries.
3. **Unified Module Registry** where built-in features (like Affiliates, Newsletters) and external addons share the same UI and enablement toggles.
---
## 2. Addon Types & Integration Levels
### Level 1: Vanilla JS / Bridge Patterns (Basic)
Use this for simple snippets to make existing WooCommerce plugins (e.g. Rajaongkir) work with WooNooW.
```javascript
// Wait for WooNooW to load
window.addEventListener('woonoow:loaded', function() {
window.WooNooW.hooks.addFilter('woonoow_order_form_after_shipping', function(container, formData) {
const div = document.createElement('div');
div.innerHTML = `<select id="custom-dest"><option>Select...</option></select>`;
container.appendChild(div);
return container;
});
});
```
### Level 2: Exposed React Runtime (Recommended)
WooNooW exposes `React`, `ReactDOM`, its `hooks`, and its `components` on `window.WooNooW`. This allows addons to build rich UIs without bundling React.
**Webpack/Vite Setup (Externals):**
```javascript
// vite.config.js
export default {
build: {
rollupOptions: {
external: ['react', 'react-dom'],
output: {
globals: {
react: 'window.WooNooW.React',
'react-dom': 'window.WooNooW.ReactDOM'
}
}
}
}
};
```
**Usage:**
```typescript
const { React, hooks, components } = window.WooNooW;
const { addFilter } = hooks;
const { Select } = components;
function CustomField({ formData, setFormData }) {
return <Select label="Custom" onChange={(val) => setFormData({...})} />;
}
addFilter('woonoow_order_form_after_shipping', (container, props) => {
const root = window.WooNooW.ReactDOM.createRoot(container);
root.render(<CustomField {...props} />);
return container;
});
```
### Level 3: SPA Route Injection (Admin Pages)
You can inject entire new pages into the WooNooW admin SPA.
```php
add_filter('woonoow/spa_routes', function($routes) {
$routes[] = [
'path' => '/my-addon',
'component_url' => plugin_dir_url(__FILE__) . 'dist/MyPage.js',
'title' => 'My Addon',
];
return $routes;
});
```
---
## 3. Developing a Full Addon
### Step 1: Registration
Register the addon via PHP filters so WooNooW knows it exists.
```php
add_filter('woonoow/addon_registry', function($addons) {
$addons['my-addon'] = [
'id' => 'my-addon',
'name' => 'My Custom Addon',
'description' => 'Does something awesome.',
'version' => '1.0.0',
'category' => 'shipping', // Auto-groups in the UI
'icon' => 'truck',
'spa_bundle' => plugin_dir_url(__FILE__) . 'dist/addon.js',
'has_settings' => true, // Enables the ⚙️ icon
];
return $addons;
});
```
### Step 2: Settings & Options
By declaring `'has_settings' => true`, WooNooW expects your settings to live at `/settings/modules/{addon_id}`.
**Option A: Schema-based (No React needed)**
```php
add_filter('woonoow/module_settings_schema', function($schemas) {
$schemas['my-addon'] = [
'api_key' => ['type' => 'text', 'label' => 'API Key'],
];
return $schemas;
});
```
**Option B: Custom React Settings Component**
```php
// In addon_registry registration array:
'settings_component' => plugin_dir_url(__FILE__) . 'dist/Settings.js',
```
Access data in React:
```typescript
const { useModuleSettings } = window.WooNooW.hooks;
const { settings, updateSettings } = useModuleSettings('my-addon');
```
---
## 4. Addon & Built-in Module Unification
**Concept:** External addons and built-in features (e.g. Affiliates, Newsletters) look and act exactly the same in the Admin UI.
- Both use `ModuleRegistry`.
- Both generate dynamic categories (e.g. "Marketing", "Shipping").
- Both persist settings to `woonoow_module_{id}_settings`.
---
## 5. Hook System Reference
### Frontend Extension Hooks
```typescript
// Add fields
'woonoow_order_form_after_billing'
'woonoow_order_form_after_shipping'
'woonoow_order_form_custom_sections'
// Validation & Data Modification
'woonoow_order_form_validation'
'woonoow_order_form_data'
```
### Backend Action Hooks
```php
apply_filters('woonoow_before_shipping_calculate', $shipping_data);
apply_filters('woonoow_after_shipping_calculate', $rates, $shipping_data);
apply_filters('woonoow_shipping_data', $data);
```
---
*For specific implementation examples, consult the `examples/` directory in the repository.*

View File

@@ -0,0 +1,141 @@
# WooNooW Customer SPA Architecture & Master Plan
**Version:** 2.0.0
**Status:** Production Ready
This document consolidates the architectural decisions, deployment modes, UI/UX standards, and routing strategies for the WooNooW Customer SPA. It is the single source of truth for frontend development on the customer-facing side.
---
## 📋 Table of Contents
1. [Architecture Decision: Hybrid Approach](#architecture-decision-hybrid-approach)
2. [Deployment Modes](#deployment-modes)
3. [Routing Strategy: HashRouter](#routing-strategy-hashrouter)
4. [SEO & Tracking Strategy](#seo--tracking-strategy)
5. [UI/UX Design Standards](#uiux-design-standards)
6. [Implementation Roadmap](#implementation-roadmap)
---
## 1. Architecture Decision: Hybrid Approach
We previously debated whether the `customer-spa` should be built into the core plugin or sold as a separate standalone theme.
**The Decision: Option C (Hybrid Approach)**
We build the Customer SPA into the WooNooW core plugin alongside the Admin SPA.
```text
woonoow/
├── admin-spa/ (Admin interface ONLY)
├── customer-spa/ (Customer Storefront + My Account)
└── includes/
├── Admin/ (Backend logic for admin-spa)
└── Frontend/ (Backend logic for customer-spa)
```
**Benefits:**
- Better user experience (one product to install).
- Highest revenue potential (core plugin covers 60% of users, premium themes can be sold separately for agencies).
- Maximum flexibility.
---
## 2. Deployment Modes
To accommodate all store owners (from small businesses using traditional themes to enterprises wanting App-like experiences), the Customer SPA supports flexible deployment:
### Mode 1: Shortcode Mode (Default / Recommended)
**Use Case:** Works with ANY WordPress theme (Divi, Elementor, Flatsome).
**How it works:** Basic components are injected via shortcodes (`[woonoow_cart]`, `[woonoow_checkout]`).
**Benefit:** Zero theme conflicts, progressive enhancement.
### Mode 2: Full SPA Mode
**Use Case:** Maximum performance, standalone app-like experience.
**How it works:** WooNooW takes over the entire frontend routing via a dedicated settings toggle.
**Benefit:** Offline PWA support, fastest page transitions.
### Mode 3: Hybrid Rendering
**Use Case:** Best of both worlds for SEO and speed.
**How it works:** Product/Category pages use traditional WordPress PHP templates (SSR) for robust SEO, while Cart/Checkout/MyAccount use full SPA rendering for interactivity.
---
## 3. Routing Strategy: HashRouter
Direct SPA URLs (like `https://woonoow.local/product/foo`) conflict heavily with WordPress's native rewrite rules. We cannot reliably override WordPress routing without breaking standard themes or SEO canonicals.
**The Solution: HashRouter for SPA interactions**
```text
https://woonoow.local/shop#/product/edukasi-anak
```
### Why HashRouter?
- **Zero WordPress Conflicts:** WordPress loads the base `/shop` page template. React Router takes over everything after the `#`.
- **Direct Access Works:** Users can bookmark or share the URL, and it will load flawlessly.
- **Consistent with Admin SPA:** Both Admin and Customer SPAs utilize memory/hash routing to prevent 404s and permalink crashes.
*(Note: For strict SEO product pages in Hybrid mode, the actual WooCommerce Product URL is indexed, while internal SPA browsing uses the HashRouter).*
---
## 4. SEO & Tracking Strategy
### Hybrid SEO Compatibility
Because pure SPAs hurt SEO (empty HTML sent to crawler), we utilize Hybrid Rendering:
1. **Product Pages = SSR:** WordPress outputs full HTML with schema markup using standard hooks so Yoast / RankMath work perfectly.
2. **Checkout/Cart = CSR:** These pages don't need SEO indexing, so they are pure React.
### Analytics Tracking
To ensure compatibility with Google Analytics, PixelMySite, Facebook Pixel, etc., the React components **trigger standard WooCommerce jQuery events**.
```javascript
// Example: Triggering a native woo event inside React
jQuery(document.body).trigger('added_to_cart', [product.id, quantity, product.price]);
```
This guarantees that 3rd-party tracking plugins installed on the site continue to function out-of-the-box without requiring custom API webhooks for the storefront.
---
## 5. UI/UX Design Standards
Our frontend philosophy: **Pragmatic, not dogmatic.** Follow e-commerce conventions for learned behaviors (e.g. swiping), rely on UX research when conventions are broken, and prioritize mobile-first performance.
### Core Layout Rules
- **Typography:** Hierarchy is `Title > Price`. We optimize for Brand Stores, not chaotic Marketplaces.
- **Variation Selectors:** Use Pills/Buttons. **Never** use Dropdowns for variation selection (high friction).
- **Product Information:** Use Vertical Accordions instead of Horizontal Tabs (27% of users overlook horizontal tabs).
- **Images:**
- Mobile: Use dots (learned behavior from Amazon/Tokopedia).
- Desktop: Use small horizontal thumbnails below the main image.
### Buy Section Hierarchy
1. Product Title (H1)
2. Price & Sale formatting
3. Stock Status Badge
4. Variation Selectors (Pills)
5. Quantity Spinner
6. **Add to Cart (Primary CTA)**
7. Trust Badges (Shipping, Returns)
---
## 6. Implementation Roadmap
### Phase 1: Core Commerce (MVP)
- Basic Product listing / catalog with filters.
- Shopping Cart sidebar/drawer (state managed by Zustand).
- Single-page checkout (HashRouter).
- My Account dashboard (React Router).
### Phase 2: Trust & Conversion
- Wishlist / Save for later functionality.
- Product reviews integration with WooCommerce comments.
- Related Products and Cross-Sells carousels.
### Phase 3: Advanced
- Subscriptions & Memberships UI.
- Digital Downloads manager in My Account.
- Progressive Web App (PWA) manifest generation and offline Service Worker.

View File

@@ -0,0 +1,91 @@
# WooNooW Product Page Architecture & UX Guide
**Version:** 2.0.0
**Status:** Production Ready
This document serves as the master guide for the WooNooW Customer SPA Product Page. It consolidates our design decision framework, standard operating procedures (SOP), and implementation phases.
---
## 📋 Table of Contents
1. [Design Decision Framework](#design-decision-framework)
2. [Layout & Structure SOP](#layout--structure-sop)
3. [Implementation Phases](#implementation-phases)
---
## 1. Design Decision Framework
When building the WooNooW SPA, we constantly face the dilemma: **Should we follow E-commerce Convention (e.g. Tokopedia, Shopify) or UX Research (e.g. Baymard Institute)?**
**Our Approach: Context-Driven Hybrid Decisions**
| Pattern | Convention | Research | Our Decision | Rationale |
|---|---|---|---|---|
| **Image Thumbnails** | Dots (Mobile) | Visible Thumbs | **Hybrid** | Small thumbnails + dots underneath. Retains swipeability but adds information scent. |
| **Variation Selector** | Pills | Pills | **Pills** | Clear winner. Dropdowns add unnecessary friction. |
| **Typography** | Varies | Title > Price | **Title > Price** | We optimize for Brand Stores (product focus) rather than Marketplaces (price focus). |
| **Description** | Varies | Visible | **Auto-Expand** | Primary content must be visible. Secondary tabs (Reviews/Specs) can be categorized. |
| **Sticky Bottom Bar** | Common | Good | **Yes** | Essential for long-scrolling mobile experiences. |
**The Meta-Lesson:**
- Follow Convention for strongly learned behaviors (e.g., swiping).
- Follow Research when convention is weak or when research points to a clear, frictionless improvement.
- Always optimize for OUR context: We are building a high-conversion, brand-focused store SPA, not a massive chaotic marketplace.
---
## 2. Layout & Structure SOP
### 2.1 Hero Section (Above the Fold)
The visual hierarchy must prioritize the core purchasing loop:
1. **Product Images** (Left on Desktop, Top on Mobile)
2. **Title & Price** (Right on Desktop, Below Image on Mobile)
3. **Rating & Review Count**
4. **Variation Selectors** (Pills)
5. **Quantity & Add to Cart CTA**
6. **Trust Badges**
### 2.2 Image Gallery Requirements
- **Main Image:** High-res, zoomable/lightbox enabled.
- **Thumbnail Slider:** Horizontal scrolling, 4-6 visible thumbnails. Active thumbnail highlighted.
- **Variation Auto-Switch:** Selecting a color pill MUST instantly switch the main gallery image to the corresponding photo.
### 2.3 Product Information (Below the Fold)
**AVOID HORIZONTAL TABS.** Research indicates 27% of users overlook them.
Instead, use **Vertical Collapsed Sections (Accordions)**:
- Description (Auto-expanded)
- Specifications Table
- Shipping / Returns Policy
- Reviews
- Related Products
### 2.4 Mobile Optimization
- Image gallery must be native-feel swipeable.
- Sticky Add-to-Cart bottom bar on scroll.
- Touch targets minimum 44x44px.
---
## 3. Implementation Phases
If extending or modifying the product page, follow this feature prioritization:
### Phase 1: Core E-Commerce Loop (MVP)
- Horizontal thumbnail slider with arrow navigation on desktop.
- Variation selector with automatic image switching and price updating.
- Add to Cart functionality with stock validation (disable button if no variation chosen).
- Vertical accordion layout for Description and Info.
### Phase 2: Trust & Conversion Optimization
- Inject WooCommerce native Reviews.
- Inject Trust elements (Secure checkout, Payment methods).
- Auto-calculate and display Free Shipping thresholds.
- Related products carousel.
### Phase 3: Advanced Media & Personalization (Future)
- Wishlist / Save for later.
- Social Proof badges ("20 people viewing this").
- 360° product views and Video embeds.
- Auto-apply coupons and bulk tier discounts.

186
docs/SHIPPING_GUIDE.md Normal file
View File

@@ -0,0 +1,186 @@
# WooNooW Shipping & Integrations Guide
**Version:** 2.0.0
**Status:** Production Ready
This document outlines how shipping methods work within WooNooW, and how to bridge complex external/API shipping plugins (such as RajaOngkir or Sicepat) fully into the Customer SPA Order Form.
---
## 📋 Table of Contents
1. [How WooNooW Handles Shipping](#how-woonoow-handles-shipping)
2. [The Shipping Bridge Pattern](#the-shipping-bridge-pattern)
3. [RajaOngkir Integration Example](#rajaongkir-integration-example)
4. [Custom Shipping Addons](#custom-shipping-addons)
---
## 1. How WooNooW Handles Shipping
### Two Types of Shipping Methods
WooCommerce Core inherently provides two types of shipping:
**1. Static Methods (e.g. Free Shipping, Flat Rate)**
- Immediate calculation (no API).
- Configured via basic Address fields (Country, State, City, ZIP).
**2. Live Rate Methods (API Based)**
- Need an API Call (e.g., UPS, FedEx, or local Indonesian couriers like JNE/J&T).
- May require extremely specific address fragments to calculate rates accurately.
- *International APIs (UPS/FedEx):* Usually rely on **Postal Code**.
- *Indonesian APIs (RajaOngkir/Biteship):* Usually rely on **Subdistrict IDs**.
### The Problem
If a customer uses an Indonesian shipping plugin, the plugin may remove default WooCommerce fields (like `city`/`state`) and inject a custom dropdown that searches an API for a destination. The plugin then writes that Destination ID to the WooCommerce Session and forces shipping recalculation.
Because WooNooW's SPA bypasses normal PHP frontend rendering, native injected dropdowns from external plugins will not appear automatically.
---
## 2. The Shipping Bridge Pattern
To make external shipping plugins work natively within WooNooW's SPA checkout, use our Bridge Hook System.
You need 3 components:
1. **REST API Endpoint:** To let the SPA search the provider's valid locations.
2. **Checkout Field Injection:** To inject a `searchable_select` field into the SPA order form natively.
3. **Bridge Action Hook:** To take the selected value from the order form and write it to the WooCommerce Session before shipping calculates.
### Generic Bridge Skeleton
```php
// 1. Endpoint for SPA to search locations
add_action('rest_api_init', function() {
register_rest_route('woonoow/v1', '/provider/search', [
'methods' => 'GET',
'callback' => 'my_provider_search_func',
'permission_callback' => '__return_true',
]);
});
// 2. Inject field into WooNooW SPA (native JSON structure, not HTML)
add_filter('woocommerce_checkout_fields', function($fields) {
if (!class_exists('My_Shipping_Class')) return $fields;
$fields['shipping']['shipping_provider_field'] = [
'type' => 'searchable_select',
'label' => 'Select Location',
'required' => true,
'priority' => 85,
'search_endpoint' => '/provider/search', // Relative to wp-json/woonoow/v1
'search_param' => 'search',
'min_chars' => 3,
];
return $fields;
}, 20);
// 3. Bridge Data to Provider Session
add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
if (!class_exists('My_Shipping_Class')) return;
$val = $shipping['shipping_provider_field'] ?? null;
if ($val) {
WC()->session->set('my_provider_session_key', $val);
// Force recalc
WC()->session->set('shipping_for_package_0', false);
}
}, 10, 2);
```
---
## 3. RajaOngkir Integration Example
If your user wants RajaOngkir running natively inside the WooNooW SPA checkout, this snippet represents the "Best Practice Bridge".
*Note: Drop this into a Code Snippets plugin or functions.php*
```php
<?php
// 1. Search Endpoint
add_action('rest_api_init', function() {
register_rest_route('woonoow/v1', '/rajaongkir/destinations', [
'methods' => 'GET',
'callback' => function($req) {
$search = sanitize_text_field($req->get_param('search') ?? '');
if (strlen($search) < 3 || !class_exists('Cekongkir_API')) return [];
$api = Cekongkir_API::get_instance();
$results = $api->search_destination_api($search);
$formatted = [];
if (is_array($results)) {
foreach ($results as $r) {
$formatted[] = [
'value' => (string) ($r['id'] ?? ''),
'label' => $r['label'] ?? $r['text'] ?? '',
];
}
}
return array_slice($formatted, 0, 50);
},
'permission_callback' => '__return_true'
]);
});
// 2. Register Native SPA Field & cleanup unnecessary native fields
add_filter('woocommerce_checkout_fields', function($fields) {
if (!class_exists('Cekongkir_API')) return $fields;
// Check if store only ships to Indonesia to safely hide fallback fields
$allowed = WC()->countries->get_allowed_countries();
$indonesia_only = (count($allowed) === 1 && isset($allowed['ID']));
if ($indonesia_only) {
$fields['shipping']['shipping_country']['type'] = 'hidden';
$fields['shipping']['shipping_state']['type'] = 'hidden';
$fields['shipping']['shipping_city']['type'] = 'hidden';
$fields['shipping']['shipping_postcode']['type'] = 'hidden';
}
$dest_field = [
'type' => 'searchable_select',
'label' => __('Destination (Province, City, Subdistrict)', 'woonoow'),
'required' => $indonesia_only,
'priority' => 85,
'search_endpoint' => '/rajaongkir/destinations',
'search_param' => 'search',
'min_chars' => 3,
'custom_attributes' => ['data-show-for-country' => 'ID'],
];
$fields['billing']['billing_destination_id'] = $dest_field;
$fields['shipping']['shipping_destination_id'] = $dest_field;
return $fields;
}, 20);
// 3. Bridge Selection back into WooCommerce specific session key
add_action('woonoow/shipping/before_calculate', function($shipping, $items) {
if (!class_exists('Cekongkir_API')) return;
$country = $shipping['country'] ?? WC()->customer->get_shipping_country();
if ($country !== 'ID') return;
$dest_id = $shipping['destination_id']
?? $shipping['shipping_destination_id']
?? $shipping['billing_destination_id'] ?? null;
if ($dest_id) {
WC()->session->set('selected_destination_id', intval($dest_id));
WC()->session->set('shipping_for_package_0', false);
}
}, 10, 2);
```
---
## 4. Custom Shipping Addons
If you do not want to use an external plugin and instead wish to build an official WooNooW extension (like `WooNooW Indonesia Shipping` with Biteship capabilities), treat it as a standard WooNooW Addon Module.
1. Develop a native React UI component using `ADDONS_GUIDE.md`.
2. Intercept `woonoow_order_form_after_shipping` via Hook.
3. Validate and handle the custom data payload via the standard WooCommerce REST endpoints.