Fixed 3 critical issues: 1. ✅ Price and Type Column Display Problem: Columns showing empty even though data exists Root Cause: price_html returns empty string for products without prices Solution: - Added fallback chain in index.tsx: 1. Try price_html (formatted HTML) 2. Fallback to regular_price (plain number) 3. Fallback to "—" (dash) - Added fallback for type: {product.type || '—'} Now displays: - Formatted price if available - Plain price if no HTML - Dash if no price at all 2. ✅ Redirect After Create Product Problem: Stays on form after creating product Expected: Return to products index Solution: - Changed New.tsx redirect from: navigate(`/products/${response.id}`) → navigate('/products') - Removed conditional logic - Always redirect to index after successful create User flow now: Create product → Success toast → Back to products list ✅ 3. ✅ Edit Form Not Loading Data Problem: Edit form shows empty fields instead of product data Root Cause: Missing fields in API response (virtual, downloadable, featured) Solution: - Added to format_product_full() in ProductsController.php: * $data['virtual'] = $product->is_virtual(); * $data['downloadable'] = $product->is_downloadable(); * $data['featured'] = $product->is_featured(); Now edit form receives complete data: - Basic info (name, type, status, descriptions) - Pricing (SKU, regular_price, sale_price) - Inventory (manage_stock, stock_quantity, stock_status) - Categories & tags - Virtual, downloadable, featured flags - Attributes & variations (for variable products) Result: ✅ Products list shows prices and types correctly ✅ Creating product redirects to index ✅ Editing product loads all data properly
73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import React, { useRef, useEffect } from 'react';
|
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { useNavigate } from 'react-router-dom';
|
|
import { api } from '@/lib/api';
|
|
import { __ } from '@/lib/i18n';
|
|
import { toast } from 'sonner';
|
|
import { useFABConfig } from '@/hooks/useFABConfig';
|
|
import { usePageHeader } from '@/contexts/PageHeaderContext';
|
|
import { ProductFormTabbed as ProductForm, ProductFormData } from './partials/ProductFormTabbed';
|
|
import { Button } from '@/components/ui/button';
|
|
|
|
export default function ProductNew() {
|
|
const navigate = useNavigate();
|
|
const queryClient = useQueryClient();
|
|
const formRef = useRef<HTMLFormElement>(null);
|
|
const { setPageHeader, clearPageHeader } = usePageHeader();
|
|
|
|
// Hide FAB on new product page
|
|
useFABConfig('none');
|
|
|
|
// Create mutation
|
|
const createMutation = useMutation({
|
|
mutationFn: async (data: ProductFormData) => {
|
|
return api.post('/products', data);
|
|
},
|
|
onSuccess: (response: any) => {
|
|
toast.success(__('Product created successfully'));
|
|
queryClient.invalidateQueries({ queryKey: ['products'] });
|
|
|
|
// Navigate back to products index
|
|
navigate('/products');
|
|
},
|
|
onError: (error: any) => {
|
|
toast.error(error.message || __('Failed to create product'));
|
|
},
|
|
});
|
|
|
|
const handleSubmit = async (data: ProductFormData) => {
|
|
await createMutation.mutateAsync(data);
|
|
};
|
|
|
|
// Set page header with back button and create button
|
|
useEffect(() => {
|
|
const actions = (
|
|
<div className="flex gap-2">
|
|
<Button size="sm" variant="ghost" onClick={() => navigate('/products')}>
|
|
{__('Back')}
|
|
</Button>
|
|
<Button
|
|
size="sm"
|
|
onClick={() => formRef.current?.requestSubmit()}
|
|
disabled={createMutation.isPending}
|
|
>
|
|
{createMutation.isPending ? __('Creating...') : __('Create')}
|
|
</Button>
|
|
</div>
|
|
);
|
|
setPageHeader(__('New Product'), actions);
|
|
return () => clearPageHeader();
|
|
}, [createMutation.isPending, setPageHeader, clearPageHeader, navigate]);
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<ProductForm
|
|
mode="create"
|
|
onSubmit={handleSubmit}
|
|
formRef={formRef}
|
|
hideSubmitButton={true}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|