Add duplicate button to ProductList
This commit is contained in:
@@ -8,6 +8,7 @@ interface AddProductModalProps {
|
|||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
onProductAdded: () => void;
|
onProductAdded: () => void;
|
||||||
editProduct?: Product | null;
|
editProduct?: Product | null;
|
||||||
|
duplicateProduct?: Product | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProductFormData {
|
interface ProductFormData {
|
||||||
@@ -19,7 +20,7 @@ interface ProductFormData {
|
|||||||
weight_unit: string;
|
weight_unit: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onProductAdded, editProduct }) => {
|
const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onProductAdded, editProduct, duplicateProduct }) => {
|
||||||
const [formData, setFormData] = useState<ProductFormData>({
|
const [formData, setFormData] = useState<ProductFormData>({
|
||||||
name: '',
|
name: '',
|
||||||
category_id: undefined,
|
category_id: undefined,
|
||||||
@@ -64,7 +65,7 @@ const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onPr
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Populate form when editing
|
// Populate form when editing or duplicating
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editProduct) {
|
if (editProduct) {
|
||||||
setFormData({
|
setFormData({
|
||||||
@@ -75,6 +76,15 @@ const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onPr
|
|||||||
weight: editProduct.weight,
|
weight: editProduct.weight,
|
||||||
weight_unit: editProduct.weight_unit
|
weight_unit: editProduct.weight_unit
|
||||||
});
|
});
|
||||||
|
} else if (duplicateProduct) {
|
||||||
|
setFormData({
|
||||||
|
name: duplicateProduct.name,
|
||||||
|
category_id: duplicateProduct.category_id,
|
||||||
|
brand_id: duplicateProduct.brand_id,
|
||||||
|
organic: duplicateProduct.organic,
|
||||||
|
weight: duplicateProduct.weight,
|
||||||
|
weight_unit: duplicateProduct.weight_unit
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Reset form for adding new product
|
// Reset form for adding new product
|
||||||
setFormData({
|
setFormData({
|
||||||
@@ -87,7 +97,7 @@ const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onPr
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setError('');
|
setError('');
|
||||||
}, [editProduct, isOpen]);
|
}, [editProduct, duplicateProduct, isOpen]);
|
||||||
|
|
||||||
const handleSubmit = useCallback(async (e: React.FormEvent) => {
|
const handleSubmit = useCallback(async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -187,7 +197,7 @@ const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onPr
|
|||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
<div className="flex justify-between items-center mb-4">
|
<div className="flex justify-between items-center mb-4">
|
||||||
<h3 className="text-lg font-medium text-gray-900">
|
<h3 className="text-lg font-medium text-gray-900">
|
||||||
{editProduct ? 'Edit Product' : 'Add New Product'}
|
{editProduct ? 'Edit Product' : duplicateProduct ? 'Duplicate Product' : 'Add New Product'}
|
||||||
</h3>
|
</h3>
|
||||||
<button
|
<button
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
@@ -324,8 +334,8 @@ const AddProductModal: React.FC<AddProductModalProps> = ({ isOpen, onClose, onPr
|
|||||||
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
>
|
>
|
||||||
{loading
|
{loading
|
||||||
? (editProduct ? 'Updating...' : 'Adding...')
|
? (editProduct ? 'Updating...' : duplicateProduct ? 'Duplicating...' : 'Adding...')
|
||||||
: (editProduct ? 'Update Product' : 'Add Product')
|
: (editProduct ? 'Update Product' : duplicateProduct ? 'Duplicate Product' : 'Add Product')
|
||||||
}
|
}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ const ProductList: React.FC = () => {
|
|||||||
const [editingProduct, setEditingProduct] = useState<Product | null>(null);
|
const [editingProduct, setEditingProduct] = useState<Product | null>(null);
|
||||||
const [deletingProduct, setDeletingProduct] = useState<Product | null>(null);
|
const [deletingProduct, setDeletingProduct] = useState<Product | null>(null);
|
||||||
const [deleteLoading, setDeleteLoading] = useState(false);
|
const [deleteLoading, setDeleteLoading] = useState(false);
|
||||||
|
const [duplicatingProduct, setDuplicatingProduct] = useState<Product | null>(null);
|
||||||
const [sortField, setSortField] = useState<string>('name');
|
const [sortField, setSortField] = useState<string>('name');
|
||||||
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
|
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc');
|
||||||
|
|
||||||
@@ -46,6 +47,11 @@ const ProductList: React.FC = () => {
|
|||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleDuplicate = (product: Product) => {
|
||||||
|
setDuplicatingProduct(product);
|
||||||
|
setIsModalOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
const handleDelete = (product: Product) => {
|
const handleDelete = (product: Product) => {
|
||||||
setDeletingProduct(product);
|
setDeletingProduct(product);
|
||||||
};
|
};
|
||||||
@@ -73,6 +79,7 @@ const ProductList: React.FC = () => {
|
|||||||
const handleCloseModal = () => {
|
const handleCloseModal = () => {
|
||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
setEditingProduct(null);
|
setEditingProduct(null);
|
||||||
|
setDuplicatingProduct(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseDeleteModal = () => {
|
const handleCloseDeleteModal = () => {
|
||||||
@@ -176,6 +183,7 @@ const ProductList: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setEditingProduct(null);
|
setEditingProduct(null);
|
||||||
|
setDuplicatingProduct(null);
|
||||||
setIsModalOpen(true);
|
setIsModalOpen(true);
|
||||||
}}
|
}}
|
||||||
className="w-full sm:w-auto bg-blue-500 hover:bg-blue-700 text-white font-bold py-3 sm:py-2 px-4 rounded text-base sm:text-sm"
|
className="w-full sm:w-auto bg-blue-500 hover:bg-blue-700 text-white font-bold py-3 sm:py-2 px-4 rounded text-base sm:text-sm"
|
||||||
@@ -271,6 +279,12 @@ const ProductList: React.FC = () => {
|
|||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDuplicate(product)}
|
||||||
|
className="text-green-600 hover:text-green-900 mr-3"
|
||||||
|
>
|
||||||
|
Duplicate
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(product)}
|
onClick={() => handleDelete(product)}
|
||||||
className="text-red-600 hover:text-red-900"
|
className="text-red-600 hover:text-red-900"
|
||||||
@@ -317,6 +331,12 @@ const ProductList: React.FC = () => {
|
|||||||
>
|
>
|
||||||
Edit
|
Edit
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => handleDuplicate(product)}
|
||||||
|
className="flex-1 text-center py-2 px-4 border border-green-300 text-green-600 hover:bg-green-50 rounded-md text-sm font-medium"
|
||||||
|
>
|
||||||
|
Duplicate
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => handleDelete(product)}
|
onClick={() => handleDelete(product)}
|
||||||
className="flex-1 text-center py-2 px-4 border border-red-300 text-red-600 hover:bg-red-50 rounded-md text-sm font-medium"
|
className="flex-1 text-center py-2 px-4 border border-red-300 text-red-600 hover:bg-red-50 rounded-md text-sm font-medium"
|
||||||
@@ -336,6 +356,7 @@ const ProductList: React.FC = () => {
|
|||||||
onClose={handleCloseModal}
|
onClose={handleCloseModal}
|
||||||
onProductAdded={handleProductAdded}
|
onProductAdded={handleProductAdded}
|
||||||
editProduct={editingProduct}
|
editProduct={editingProduct}
|
||||||
|
duplicateProduct={duplicatingProduct}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ConfirmDeleteModal
|
<ConfirmDeleteModal
|
||||||
|
|||||||
Reference in New Issue
Block a user