- Add WP Media Library integration for product and variation images - Support images array (URLs) conversion to attachment IDs - Add images array to API responses (Admin & Customer SPA) - Implement drag-and-drop sortable images in Admin product form - Add image gallery thumbnails in Customer SPA product page - Initialize WooCommerce session for guest cart operations - Fix product variations and attributes display in Customer SPA - Add variation image field in Admin SPA Changes: - includes/Api/ProductsController.php: Handle images array, add to responses - includes/Frontend/ShopController.php: Add images array for customer SPA - includes/Frontend/CartController.php: Initialize WC session for guests - admin-spa/src/lib/wp-media.ts: Add openWPMediaGallery function - admin-spa/src/routes/Products/partials/tabs/GeneralTab.tsx: WP Media + sortable images - admin-spa/src/routes/Products/partials/tabs/VariationsTab.tsx: Add variation image field - customer-spa/src/pages/Product/index.tsx: Add gallery thumbnails display
548 lines
11 KiB
Markdown
548 lines
11 KiB
Markdown
# WooNooW Customer SPA Settings
|
|
|
|
## 📍 Settings Location
|
|
|
|
**Admin SPA > Settings > Customer SPA**
|
|
|
|
(NOT in wp-admin, but in our React admin interface)
|
|
|
|
---
|
|
|
|
## 📊 Settings Schema
|
|
|
|
### TypeScript Interface
|
|
|
|
```typescript
|
|
interface CustomerSPASettings {
|
|
// Mode
|
|
mode: 'disabled' | 'full' | 'checkout_only';
|
|
|
|
// Checkout-Only mode settings
|
|
checkoutPages?: {
|
|
checkout: boolean;
|
|
thankyou: boolean;
|
|
account: boolean;
|
|
cart: boolean;
|
|
};
|
|
|
|
// Layout (for full mode)
|
|
layout: 'classic' | 'modern' | 'boutique' | 'launch';
|
|
|
|
// Branding
|
|
branding: {
|
|
logo: string; // URL
|
|
favicon: string; // URL
|
|
siteName: string;
|
|
};
|
|
|
|
// Colors (Design Tokens)
|
|
colors: {
|
|
primary: string; // #3B82F6
|
|
secondary: string; // #8B5CF6
|
|
accent: string; // #10B981
|
|
background: string; // #FFFFFF
|
|
text: string; // #1F2937
|
|
};
|
|
|
|
// Typography
|
|
typography: {
|
|
preset: 'professional' | 'modern' | 'elegant' | 'tech' | 'custom';
|
|
customFonts?: {
|
|
heading: string;
|
|
body: string;
|
|
};
|
|
};
|
|
|
|
// Navigation
|
|
menus: {
|
|
primary: number; // WP menu ID
|
|
footer: number; // WP menu ID
|
|
};
|
|
|
|
// Homepage
|
|
homepage: {
|
|
sections: Array<{
|
|
id: string;
|
|
type: 'hero' | 'featured' | 'categories' | 'testimonials' | 'newsletter' | 'custom';
|
|
enabled: boolean;
|
|
order: number;
|
|
config: Record<string, any>;
|
|
}>;
|
|
};
|
|
|
|
// Product Page
|
|
product: {
|
|
layout: 'standard' | 'gallery' | 'minimal';
|
|
showRelatedProducts: boolean;
|
|
showReviews: boolean;
|
|
};
|
|
|
|
// Checkout
|
|
checkout: {
|
|
style: 'onepage' | 'multistep';
|
|
enableGuestCheckout: boolean;
|
|
showTrustBadges: boolean;
|
|
showOrderSummary: 'sidebar' | 'inline';
|
|
};
|
|
}
|
|
```
|
|
|
|
### Default Settings
|
|
|
|
```typescript
|
|
const DEFAULT_SETTINGS: CustomerSPASettings = {
|
|
mode: 'disabled',
|
|
checkoutPages: {
|
|
checkout: true,
|
|
thankyou: true,
|
|
account: true,
|
|
cart: false,
|
|
},
|
|
layout: 'modern',
|
|
branding: {
|
|
logo: '',
|
|
favicon: '',
|
|
siteName: get_bloginfo('name'),
|
|
},
|
|
colors: {
|
|
primary: '#3B82F6',
|
|
secondary: '#8B5CF6',
|
|
accent: '#10B981',
|
|
background: '#FFFFFF',
|
|
text: '#1F2937',
|
|
},
|
|
typography: {
|
|
preset: 'professional',
|
|
},
|
|
menus: {
|
|
primary: 0,
|
|
footer: 0,
|
|
},
|
|
homepage: {
|
|
sections: [
|
|
{ id: 'hero-1', type: 'hero', enabled: true, order: 0, config: {} },
|
|
{ id: 'featured-1', type: 'featured', enabled: true, order: 1, config: {} },
|
|
{ id: 'categories-1', type: 'categories', enabled: true, order: 2, config: {} },
|
|
],
|
|
},
|
|
product: {
|
|
layout: 'standard',
|
|
showRelatedProducts: true,
|
|
showReviews: true,
|
|
},
|
|
checkout: {
|
|
style: 'onepage',
|
|
enableGuestCheckout: true,
|
|
showTrustBadges: true,
|
|
showOrderSummary: 'sidebar',
|
|
},
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 🔌 REST API Endpoints
|
|
|
|
### Get Settings
|
|
|
|
```http
|
|
GET /wp-json/woonoow/v1/settings/customer-spa
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"enabled": true,
|
|
"layout": "modern",
|
|
"colors": {
|
|
"primary": "#3B82F6",
|
|
"secondary": "#8B5CF6",
|
|
"accent": "#10B981"
|
|
},
|
|
...
|
|
}
|
|
```
|
|
|
|
### Update Settings
|
|
|
|
```http
|
|
POST /wp-json/woonoow/v1/settings/customer-spa
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"enabled": true,
|
|
"layout": "modern",
|
|
"colors": {
|
|
"primary": "#FF6B6B"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"enabled": true,
|
|
"layout": "modern",
|
|
"colors": {
|
|
"primary": "#FF6B6B",
|
|
"secondary": "#8B5CF6",
|
|
"accent": "#10B981"
|
|
},
|
|
...
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎨 Customization Options
|
|
|
|
### 1. Layout Options (4 Presets)
|
|
|
|
#### Classic Layout
|
|
- Traditional ecommerce design
|
|
- Header with logo + horizontal menu
|
|
- Sidebar filters on shop page
|
|
- Grid product listing
|
|
- Footer with widgets
|
|
- **Best for:** B2B, traditional retail
|
|
|
|
#### Modern Layout (Default)
|
|
- Minimalist, clean design
|
|
- Centered logo
|
|
- Top filters (no sidebar)
|
|
- Large product cards with hover effects
|
|
- Simplified footer
|
|
- **Best for:** Fashion, lifestyle brands
|
|
|
|
#### Boutique Layout
|
|
- Fashion/luxury focused
|
|
- Full-width hero sections
|
|
- Masonry grid layout
|
|
- Elegant typography
|
|
- Minimal UI elements
|
|
- **Best for:** High-end fashion, luxury goods
|
|
|
|
#### Launch Layout 🆕 (Single Product Funnel)
|
|
- **Landing page:** User's custom design (Elementor/Divi) - NOT controlled by WooNooW
|
|
- **WooNooW takes over:** From checkout onwards (after CTA click)
|
|
- **No traditional header/footer** on checkout/thank you/account pages
|
|
- **Streamlined checkout** (one-page, minimal fields, no cart)
|
|
- **Upsell/downsell** on thank you page
|
|
- **Direct product access** in My Account
|
|
- **Best for:**
|
|
- Digital products (courses, ebooks, software)
|
|
- SaaS trials → paid conversion
|
|
- Webinar funnels
|
|
- High-ticket consulting
|
|
- Limited-time offers
|
|
- Product launches
|
|
|
|
**Flow:** Landing Page (Custom) → [CTA to /checkout] → Checkout (SPA) → Thank You (SPA) → My Account (SPA)
|
|
|
|
**Note:** This is essentially Checkout-Only mode with funnel-optimized design.
|
|
|
|
### 2. Color Customization
|
|
|
|
**Primary Color:**
|
|
- Used for: Buttons, links, active states
|
|
- Default: `#3B82F6` (Blue)
|
|
|
|
**Secondary Color:**
|
|
- Used for: Badges, accents, secondary buttons
|
|
- Default: `#8B5CF6` (Purple)
|
|
|
|
**Accent Color:**
|
|
- Used for: Success states, CTAs, highlights
|
|
- Default: `#10B981` (Green)
|
|
|
|
**Background & Text:**
|
|
- Auto-calculated for proper contrast
|
|
- Supports light/dark mode
|
|
|
|
### 3. Typography Presets
|
|
|
|
#### Professional
|
|
- Heading: Inter
|
|
- Body: Lora
|
|
- Use case: Corporate, B2B
|
|
|
|
#### Modern
|
|
- Heading: Poppins
|
|
- Body: Roboto
|
|
- Use case: Tech, SaaS
|
|
|
|
#### Elegant
|
|
- Heading: Playfair Display
|
|
- Body: Source Sans Pro
|
|
- Use case: Fashion, Luxury
|
|
|
|
#### Tech
|
|
- Heading: Space Grotesk
|
|
- Body: IBM Plex Mono
|
|
- Use case: Electronics, Gadgets
|
|
|
|
#### Custom
|
|
- Upload custom fonts
|
|
- Specify font families
|
|
|
|
### 4. Homepage Sections
|
|
|
|
Available section types:
|
|
|
|
#### Hero Banner
|
|
```typescript
|
|
{
|
|
type: 'hero',
|
|
config: {
|
|
image: string; // Background image URL
|
|
heading: string; // Main heading
|
|
subheading: string; // Subheading
|
|
ctaText: string; // Button text
|
|
ctaLink: string; // Button URL
|
|
alignment: 'left' | 'center' | 'right';
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Featured Products
|
|
```typescript
|
|
{
|
|
type: 'featured',
|
|
config: {
|
|
title: string;
|
|
productIds: number[]; // Manual selection
|
|
autoSelect: boolean; // Auto-select featured products
|
|
limit: number; // Number of products to show
|
|
columns: 2 | 3 | 4;
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Category Grid
|
|
```typescript
|
|
{
|
|
type: 'categories',
|
|
config: {
|
|
title: string;
|
|
categoryIds: number[];
|
|
columns: 2 | 3 | 4;
|
|
showProductCount: boolean;
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Testimonials
|
|
```typescript
|
|
{
|
|
type: 'testimonials',
|
|
config: {
|
|
title: string;
|
|
testimonials: Array<{
|
|
name: string;
|
|
avatar: string;
|
|
rating: number;
|
|
text: string;
|
|
}>;
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Newsletter
|
|
```typescript
|
|
{
|
|
type: 'newsletter',
|
|
config: {
|
|
title: string;
|
|
description: string;
|
|
placeholder: string;
|
|
buttonText: string;
|
|
mailchimpListId?: string;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 💾 Storage
|
|
|
|
### WordPress Options Table
|
|
|
|
Settings are stored in `wp_options`:
|
|
|
|
```php
|
|
// Option name: woonoow_customer_spa_enabled
|
|
// Value: boolean (true/false)
|
|
|
|
// Option name: woonoow_customer_spa_settings
|
|
// Value: JSON-encoded settings object
|
|
```
|
|
|
|
### PHP Implementation
|
|
|
|
```php
|
|
// Get settings
|
|
$settings = get_option('woonoow_customer_spa_settings', []);
|
|
|
|
// Update settings
|
|
update_option('woonoow_customer_spa_settings', $settings);
|
|
|
|
// Check if enabled
|
|
$enabled = get_option('woonoow_customer_spa_enabled', false);
|
|
```
|
|
|
|
---
|
|
|
|
## 🔒 Permissions
|
|
|
|
### Who Can Modify Settings?
|
|
|
|
- **Capability required:** `manage_woocommerce`
|
|
- **Roles:** Administrator, Shop Manager
|
|
|
|
### REST API Permission Check
|
|
|
|
```php
|
|
public function update_settings_permission_check() {
|
|
return current_user_can('manage_woocommerce');
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Settings UI Components
|
|
|
|
### Admin SPA Components
|
|
|
|
1. **Enable/Disable Toggle**
|
|
- Component: `Switch`
|
|
- Shows warning when enabling
|
|
|
|
2. **Layout Selector**
|
|
- Component: `LayoutPreview`
|
|
- Visual preview of each layout
|
|
- Radio button selection
|
|
|
|
3. **Color Picker**
|
|
- Component: `ColorPicker`
|
|
- Supports hex, rgb, hsl
|
|
- Live preview
|
|
|
|
4. **Typography Selector**
|
|
- Component: `TypographyPreview`
|
|
- Shows font samples
|
|
- Dropdown selection
|
|
|
|
5. **Homepage Section Builder**
|
|
- Component: `SectionBuilder`
|
|
- Drag-and-drop reordering
|
|
- Add/remove/configure sections
|
|
|
|
6. **Menu Selector**
|
|
- Component: `MenuDropdown`
|
|
- Fetches WP menus via API
|
|
- Dropdown selection
|
|
|
|
---
|
|
|
|
## 📤 Data Flow
|
|
|
|
### Settings Update Flow
|
|
|
|
```
|
|
1. User changes setting in Admin SPA
|
|
↓
|
|
2. React state updates (optimistic UI)
|
|
↓
|
|
3. POST to /wp-json/woonoow/v1/settings/customer-spa
|
|
↓
|
|
4. PHP validates & saves to wp_options
|
|
↓
|
|
5. Response confirms save
|
|
↓
|
|
6. React Query invalidates cache
|
|
↓
|
|
7. Customer SPA receives new settings on next load
|
|
```
|
|
|
|
### Settings Load Flow (Customer SPA)
|
|
|
|
```
|
|
1. PHP renders spa-full-page.php
|
|
↓
|
|
2. wp_head() outputs inline script:
|
|
window.woonoowCustomer = {
|
|
theme: <?php echo json_encode($settings); ?>
|
|
}
|
|
↓
|
|
3. React app reads window.woonoowCustomer
|
|
↓
|
|
4. ThemeProvider applies settings
|
|
↓
|
|
5. CSS variables injected
|
|
↓
|
|
6. Components render with theme
|
|
```
|
|
|
|
---
|
|
|
|
## 🧪 Testing
|
|
|
|
### Unit Tests
|
|
|
|
```typescript
|
|
describe('CustomerSPASettings', () => {
|
|
it('should load default settings', () => {
|
|
const settings = getDefaultSettings();
|
|
expect(settings.enabled).toBe(false);
|
|
expect(settings.layout).toBe('modern');
|
|
});
|
|
|
|
it('should validate color format', () => {
|
|
expect(isValidColor('#FF6B6B')).toBe(true);
|
|
expect(isValidColor('invalid')).toBe(false);
|
|
});
|
|
|
|
it('should merge partial updates', () => {
|
|
const current = getDefaultSettings();
|
|
const update = { colors: { primary: '#FF0000' } };
|
|
const merged = mergeSettings(current, update);
|
|
expect(merged.colors.primary).toBe('#FF0000');
|
|
expect(merged.colors.secondary).toBe('#8B5CF6'); // Unchanged
|
|
});
|
|
});
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
```php
|
|
class CustomerSPASettingsTest extends WP_UnitTestCase {
|
|
public function test_save_settings() {
|
|
$settings = ['enabled' => true, 'layout' => 'modern'];
|
|
update_option('woonoow_customer_spa_settings', $settings);
|
|
|
|
$saved = get_option('woonoow_customer_spa_settings');
|
|
$this->assertEquals('modern', $saved['layout']);
|
|
}
|
|
|
|
public function test_rest_api_requires_permission() {
|
|
wp_set_current_user(0); // Not logged in
|
|
|
|
$request = new WP_REST_Request('POST', '/woonoow/v1/settings/customer-spa');
|
|
$response = rest_do_request($request);
|
|
|
|
$this->assertEquals(401, $response->get_status());
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📚 Related Documentation
|
|
|
|
- [Customer SPA Architecture](./CUSTOMER_SPA_ARCHITECTURE.md)
|
|
- [Customer SPA Theme System](./CUSTOMER_SPA_THEME_SYSTEM.md)
|
|
- [API Routes](./API_ROUTES.md)
|