- 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
241 lines
6.0 KiB
Markdown
241 lines
6.0 KiB
Markdown
# 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
|