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:
240
FIXES_APPLIED.md
Normal file
240
FIXES_APPLIED.md
Normal file
@@ -0,0 +1,240 @@
|
||||
# Customer SPA - Fixes Applied
|
||||
|
||||
## Issues Fixed
|
||||
|
||||
### 1. ✅ Image Not Fully Covering Box
|
||||
|
||||
**Problem:** Product images were not filling their containers properly, leaving gaps or distortion.
|
||||
|
||||
**Solution:** Added proper CSS to all ProductCard layouts:
|
||||
```css
|
||||
object-fit: cover
|
||||
object-center
|
||||
style={{ objectFit: 'cover' }}
|
||||
```
|
||||
|
||||
**Files Modified:**
|
||||
- `customer-spa/src/components/ProductCard.tsx`
|
||||
- Classic layout (line 48-49)
|
||||
- Modern layout (line 122-123)
|
||||
- Boutique layout (line 190-191)
|
||||
- Launch layout (line 255-256)
|
||||
|
||||
**Result:** Images now properly fill their containers while maintaining aspect ratio.
|
||||
|
||||
---
|
||||
|
||||
### 2. ✅ Product Page Created
|
||||
|
||||
**Problem:** Product detail page was not implemented, showing "Product Not Found" error.
|
||||
|
||||
**Solution:** Created complete Product detail page with:
|
||||
- Slug-based routing (`/product/:slug` instead of `/product/:id`)
|
||||
- Product fetching by slug
|
||||
- Full product display with image, price, description
|
||||
- Quantity selector
|
||||
- Add to cart button
|
||||
- Product meta (SKU, categories)
|
||||
- Breadcrumb navigation
|
||||
- Loading and error states
|
||||
|
||||
**Files Modified:**
|
||||
- `customer-spa/src/pages/Product/index.tsx` - Complete rewrite
|
||||
- `customer-spa/src/App.tsx` - Changed route from `:id` to `:slug`
|
||||
|
||||
**Key Changes:**
|
||||
```typescript
|
||||
// Old
|
||||
const { id } = useParams();
|
||||
queryFn: () => apiClient.get(apiClient.endpoints.shop.product(Number(id)))
|
||||
|
||||
// New
|
||||
const { slug } = useParams();
|
||||
queryFn: async () => {
|
||||
const response = await apiClient.get(apiClient.endpoints.shop.products, {
|
||||
slug: slug,
|
||||
per_page: 1,
|
||||
});
|
||||
return response?.products?.[0] || null;
|
||||
}
|
||||
```
|
||||
|
||||
**Result:** Product pages now load correctly with proper slug-based URLs.
|
||||
|
||||
---
|
||||
|
||||
### 3. ✅ Direct URL Access Not Working
|
||||
|
||||
**Problem:** Accessing `/product/edukasi-anak` directly redirected to `/shop`.
|
||||
|
||||
**Root Cause:** React Router was configured with a basename that interfered with direct URL access.
|
||||
|
||||
**Solution:** Removed basename from BrowserRouter:
|
||||
```typescript
|
||||
// Old
|
||||
<BrowserRouter basename="/shop">
|
||||
|
||||
// New
|
||||
<BrowserRouter>
|
||||
```
|
||||
|
||||
**Files Modified:**
|
||||
- `customer-spa/src/App.tsx` (line 53)
|
||||
|
||||
**Result:** Direct URLs now work correctly. You can access any product directly via `/product/slug-name`.
|
||||
|
||||
---
|
||||
|
||||
### 4. ⚠️ Add to Cart Failing
|
||||
|
||||
**Problem:** Clicking "Add to Cart" shows error: "Failed to add to cart"
|
||||
|
||||
**Current Status:** Frontend code is correct and ready. The issue is likely:
|
||||
|
||||
**Possible Causes:**
|
||||
1. **Missing REST API Endpoint** - `/wp-json/woonoow/v1/cart/add` may not exist yet
|
||||
2. **Authentication Issue** - Nonce validation failing
|
||||
3. **WooCommerce Cart Not Initialized** - Cart session not started
|
||||
|
||||
**Frontend Code (Ready):**
|
||||
```typescript
|
||||
// In ProductCard.tsx and Product/index.tsx
|
||||
const handleAddToCart = async (product) => {
|
||||
try {
|
||||
await apiClient.post(apiClient.endpoints.cart.add, {
|
||||
product_id: product.id,
|
||||
quantity: 1,
|
||||
});
|
||||
|
||||
addItem({
|
||||
key: `${product.id}`,
|
||||
product_id: product.id,
|
||||
name: product.name,
|
||||
price: parseFloat(product.price),
|
||||
quantity: 1,
|
||||
image: product.image,
|
||||
});
|
||||
|
||||
toast.success(`${product.name} added to cart!`);
|
||||
} catch (error) {
|
||||
toast.error('Failed to add to cart');
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
**What Needs to Be Done:**
|
||||
|
||||
1. **Check if Cart API exists:**
|
||||
```
|
||||
Check: includes/Api/Controllers/CartController.php
|
||||
Endpoint: POST /wp-json/woonoow/v1/cart/add
|
||||
```
|
||||
|
||||
2. **If missing, create CartController:**
|
||||
```php
|
||||
public function add_to_cart($request) {
|
||||
$product_id = $request->get_param('product_id');
|
||||
$quantity = $request->get_param('quantity') ?: 1;
|
||||
|
||||
$cart_item_key = WC()->cart->add_to_cart($product_id, $quantity);
|
||||
|
||||
if ($cart_item_key) {
|
||||
return new WP_REST_Response([
|
||||
'success' => true,
|
||||
'cart_item_key' => $cart_item_key,
|
||||
'cart' => WC()->cart->get_cart(),
|
||||
], 200);
|
||||
}
|
||||
|
||||
return new WP_Error('add_to_cart_failed', 'Failed to add product to cart', ['status' => 400]);
|
||||
}
|
||||
```
|
||||
|
||||
3. **Register the endpoint:**
|
||||
```php
|
||||
register_rest_route('woonoow/v1', '/cart/add', [
|
||||
'methods' => 'POST',
|
||||
'callback' => [$this, 'add_to_cart'],
|
||||
'permission_callback' => '__return_true',
|
||||
]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
### ✅ Fixed (3/4)
|
||||
1. Image object-fit - **DONE**
|
||||
2. Product page - **DONE**
|
||||
3. Direct URL access - **DONE**
|
||||
|
||||
### ⏳ Needs Backend Work (1/4)
|
||||
4. Add to cart - **Frontend ready, needs Cart API endpoint**
|
||||
|
||||
---
|
||||
|
||||
## Testing Guide
|
||||
|
||||
### Test Image Fix:
|
||||
1. Go to `/shop`
|
||||
2. Check product images fill their containers
|
||||
3. No gaps or distortion
|
||||
|
||||
### Test Product Page:
|
||||
1. Click any product
|
||||
2. Should navigate to `/product/slug-name`
|
||||
3. See full product details
|
||||
4. Image, price, description visible
|
||||
|
||||
### Test Direct URL:
|
||||
1. Copy product URL: `https://woonoow.local/product/edukasi-anak`
|
||||
2. Open in new tab
|
||||
3. Should load product directly (not redirect to shop)
|
||||
|
||||
### Test Add to Cart:
|
||||
1. Click "Add to Cart" on any product
|
||||
2. Currently shows error (needs backend API)
|
||||
3. Check browser console for error details
|
||||
4. Once API is created, should show success toast
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Create Cart API Controller**
|
||||
- File: `includes/Api/Controllers/CartController.php`
|
||||
- Endpoints: add, update, remove, get
|
||||
- Use WooCommerce cart functions
|
||||
|
||||
2. **Register Cart Routes**
|
||||
- File: `includes/Api/Routes.php` or similar
|
||||
- Register all cart endpoints
|
||||
|
||||
3. **Test Add to Cart**
|
||||
- Should work once API is ready
|
||||
- Frontend code is already complete
|
||||
|
||||
4. **Continue with remaining pages:**
|
||||
- Cart page
|
||||
- Checkout page
|
||||
- Thank you page
|
||||
- My Account pages
|
||||
|
||||
---
|
||||
|
||||
## Files Changed
|
||||
|
||||
```
|
||||
customer-spa/src/
|
||||
├── App.tsx # Removed basename, changed :id to :slug
|
||||
├── components/
|
||||
│ └── ProductCard.tsx # Fixed image object-fit in all layouts
|
||||
└── pages/
|
||||
└── Product/index.tsx # Complete rewrite with slug routing
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Status:** 3/4 issues fixed, 1 needs backend API implementation
|
||||
**Ready for:** Testing and Cart API creation
|
||||
Reference in New Issue
Block a user