diff --git a/backend/scripts/fix-categories.sql b/backend/scripts/fix-categories.sql new file mode 100644 index 0000000..b812d40 --- /dev/null +++ b/backend/scripts/fix-categories.sql @@ -0,0 +1,38 @@ +-- Fix duplicate categories and clean up product categories +-- This will consolidate similar categories and fix naming + +-- Update products that reference categories we're about to merge +-- Update any references to 'Fertilizers' to point to 'Fertilizer' (if it exists) +UPDATE products SET category_id = ( + SELECT id FROM product_categories WHERE name = 'Fertilizer' LIMIT 1 +) WHERE category_id = ( + SELECT id FROM product_categories WHERE name = 'Fertilizers' LIMIT 1 +) AND EXISTS (SELECT 1 FROM product_categories WHERE name = 'Fertilizer'); + +-- Delete duplicate categories +DELETE FROM product_categories WHERE name IN ('Fertilizers') +AND EXISTS (SELECT 1 FROM product_categories WHERE name = 'Fertilizer'); + +-- Update category names to be consistent (singular form) +UPDATE product_categories SET name = 'Herbicide' WHERE name = 'Herbicides'; +UPDATE product_categories SET name = 'Fertilizer' WHERE name = 'Fertilizers'; +UPDATE product_categories SET name = 'Fungicide' WHERE name = 'Fungicides'; +UPDATE product_categories SET name = 'Insecticide' WHERE name = 'Insecticides'; +UPDATE product_categories SET name = 'Surfactant' WHERE name = 'Surfactants'; +UPDATE product_categories SET name = 'Adjuvant' WHERE name = 'Adjuvants'; +UPDATE product_categories SET name = 'Growth Regulator' WHERE name = 'Growth Regulators'; + +-- Add any missing core categories +INSERT INTO product_categories (name, description) VALUES +('Herbicide', 'Products for weed control and prevention'), +('Fertilizer', 'Nutrients for lawn growth and health'), +('Fungicide', 'Products for disease prevention and treatment'), +('Insecticide', 'Products for insect control'), +('Pre-emergent', 'Products that prevent weeds from germinating'), +('Post-emergent', 'Products that kill existing weeds'), +('Growth Regulator', 'Products that modify plant growth'), +('Surfactant', 'Products that improve spray coverage and penetration'), +('Adjuvant', 'Products that enhance pesticide performance'), +('Seed', 'Grass seeds and seed treatments'), +('Soil Amendment', 'Products that improve soil conditions') +ON CONFLICT (name) DO NOTHING; \ No newline at end of file diff --git a/frontend/src/pages/Products/Products.js b/frontend/src/pages/Products/Products.js index 3b1e8ba..1a66a8e 100644 --- a/frontend/src/pages/Products/Products.js +++ b/frontend/src/pages/Products/Products.js @@ -21,6 +21,8 @@ const Products = () => { const [selectedCategory, setSelectedCategory] = useState(''); const [selectedType, setSelectedType] = useState(''); const [activeTab, setActiveTab] = useState('shared'); // 'shared' or 'custom' + const [editingProduct, setEditingProduct] = useState(null); + const [showEditForm, setShowEditForm] = useState(false); useEffect(() => { fetchData(); @@ -88,6 +90,24 @@ const Products = () => { } }; + const handleEditProduct = (product) => { + setEditingProduct(product); + setShowEditForm(true); + }; + + const handleUpdateProduct = async (productData) => { + try { + await productsAPI.updateUserProduct(editingProduct.id, productData); + toast.success('Product updated successfully!'); + setShowEditForm(false); + setEditingProduct(null); + fetchData(); + } catch (error) { + console.error('Failed to update product:', error); + toast.error('Failed to update product'); + } + }; + const ProductCard = ({ product, isUserProduct = false }) => (
@@ -105,9 +125,13 @@ const Products = () => { - {product.productType || 'Unknown'} + {product.productType ? + product.productType.charAt(0).toUpperCase() + product.productType.slice(1) + : 'Type not set'}
@@ -115,7 +139,7 @@ const Products = () => { {isUserProduct && (
); }; @@ -538,4 +576,124 @@ const CreateProductModal = ({ onSubmit, onCancel, sharedProducts, categories }) ); }; +// Edit Product Modal Component +const EditProductModal = ({ product, onSubmit, onCancel, sharedProducts, categories }) => { + const [formData, setFormData] = useState({ + productId: product.baseProductId || '', + customName: product.customName || '', + customRateAmount: product.customRateAmount || '', + customRateUnit: product.customRateUnit || 'lbs/1000 sq ft', + notes: product.notes || '' + }); + + const handleSubmit = (e) => { + e.preventDefault(); + + if (!formData.productId && !formData.customName) { + toast.error('Please select a base product or enter a custom name'); + return; + } + + const submitData = { + productId: formData.productId ? parseInt(formData.productId) : null, + customName: formData.customName || null, + customRateAmount: formData.customRateAmount ? parseFloat(formData.customRateAmount) : null, + customRateUnit: formData.customRateUnit || null, + notes: formData.notes || null + }; + + onSubmit(submitData); + }; + + return ( +
+
+

Edit Product

+ +
+
+ + +
+ +
+ + setFormData({ ...formData, customName: e.target.value })} + placeholder="e.g., My 24-0-11 Blend, Custom Herbicide Mix" + /> +
+ +
+
+ + setFormData({ ...formData, customRateAmount: e.target.value })} + placeholder="2.5" + /> +
+
+ + +
+
+ +
+ +