feat: Add product images support with WP Media Library integration

- 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
This commit is contained in:
Dwindi Ramadhana
2025-11-26 16:18:43 +07:00
parent 909bddb23d
commit f397ef850f
69 changed files with 12481 additions and 156 deletions

View File

@@ -67,12 +67,107 @@ WooNooW modernizes WooCommerce **without migration**, delivering a Hybrid + SPA
| Backend | PHP 8.2+, WordPress, WooCommerce (HPOS), Action Scheduler |
| Frontend | React 18 + TypeScript, Vite, React Query, Tailwind CSS + Shadcn UI, Recharts |
| Architecture | Modular PSR4 autoload, RESTdriven logic, SPA hydration islands |
| Routing | Admin SPA: HashRouter, Customer SPA: HashRouter |
| Build | Composer + NPM + ESM scripts |
| Packaging | `scripts/package-zip.mjs` |
| Deployment | LocalWP for dev, Coolify for staging |
---
## 3.1 🔀 Customer SPA Routing Pattern
### HashRouter Implementation
**Why HashRouter?**
The Customer SPA uses **HashRouter** instead of BrowserRouter to avoid conflicts with WordPress routing:
```typescript
// customer-spa/src/App.tsx
import { HashRouter } from 'react-router-dom';
<HashRouter>
<Routes>
<Route path="/product/:slug" element={<Product />} />
<Route path="/cart" element={<Cart />} />
{/* ... */}
</Routes>
</HashRouter>
```
**URL Format:**
```
Shop: https://example.com/shop#/
Product: https://example.com/shop#/product/product-slug
Cart: https://example.com/shop#/cart
Checkout: https://example.com/shop#/checkout
Account: https://example.com/shop#/my-account
```
**How It Works:**
1. **WordPress loads:** `/shop` (valid WordPress page)
2. **React takes over:** `#/product/product-slug` (client-side only)
3. **No conflicts:** Everything after `#` is invisible to WordPress
**Benefits:**
| Benefit | Description |
|---------|-------------|
| **Zero WordPress conflicts** | WordPress never sees routes after `#` |
| **Direct URL access** | Works from any source (email, social, QR codes) |
| **Shareable links** | Perfect for marketing campaigns |
| **No server config** | No .htaccess or rewrite rules needed |
| **Reliable** | No canonical redirects or 404 issues |
| **Consistent with Admin SPA** | Same routing approach |
**Use Cases:**
**Email campaigns:** `https://example.com/shop#/product/special-offer`
**Social media:** Share product links directly
**QR codes:** Generate codes for products
**Bookmarks:** Users can bookmark product pages
**Direct access:** Type URL in browser
**Implementation Rules:**
1.**Always use HashRouter** for Customer SPA
2.**Use React Router Link** components (automatically use hash URLs)
3.**Test direct URL access** for all routes
4.**Document URL format** in user guides
5.**Never use BrowserRouter** (causes WordPress conflicts)
6.**Never try to override WordPress routes** (unreliable)
**Comparison: BrowserRouter vs HashRouter**
| Feature | BrowserRouter | HashRouter |
|---------|---------------|------------|
| **URL Format** | `/product/slug` | `#/product/slug` |
| **Clean URLs** | ✅ Yes | ❌ Has `#` |
| **SEO** | ✅ Better | ⚠️ Acceptable |
| **Direct Access** | ❌ Conflicts | ✅ Works |
| **WordPress Conflicts** | ❌ Many | ✅ None |
| **Sharing** | ❌ Unreliable | ✅ Reliable |
| **Email Links** | ❌ Breaks | ✅ Works |
| **Setup Complexity** | ❌ Complex | ✅ Simple |
| **Reliability** | ❌ Fragile | ✅ Solid |
**Winner:** HashRouter for Customer SPA ✅
**SEO Considerations:**
- WooCommerce product pages still exist for SEO
- Search engines index actual product URLs
- SPA provides better UX for users
- Canonical tags point to real products
- Best of both worlds approach
**Files:**
- `customer-spa/src/App.tsx` - HashRouter configuration
- `customer-spa/src/pages/*` - All page components use React Router
---
## 4. 🧩 Folder Structure
```