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

@@ -163,3 +163,52 @@ export function openWPMediaFavicon(onSelect: (file: WPMediaFile) => void): void
onSelect
);
}
/**
* Open WordPress Media Modal for Multiple Images (Product Gallery)
*/
export function openWPMediaGallery(onSelect: (files: WPMediaFile[]) => void): void {
// Check if WordPress media is available
if (typeof window.wp === 'undefined' || typeof window.wp.media === 'undefined') {
console.error('WordPress media library is not available');
alert('WordPress Media library is not loaded.');
return;
}
// Create media frame with multiple selection
const frame = window.wp.media({
title: 'Select or Upload Product Images',
button: {
text: 'Add to Gallery',
},
multiple: true,
library: {
type: 'image',
},
});
// Handle selection
frame.on('select', () => {
const selection = frame.state().get('selection') as any;
const files: WPMediaFile[] = [];
selection.map((attachment: any) => {
const data = attachment.toJSON();
files.push({
url: data.url,
id: data.id,
title: data.title || data.filename,
filename: data.filename,
alt: data.alt || '',
width: data.width,
height: data.height,
});
return attachment;
});
onSelect(files);
});
// Open modal
frame.open();
}