fix edit on products

This commit is contained in:
Jake Kasper
2025-08-21 21:00:52 -04:00
parent d3092b4c7b
commit 33894dec6c
2 changed files with 199 additions and 3 deletions

View File

@@ -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 }) => (
<div className="card">
<div className="flex justify-between items-start mb-3">
@@ -105,9 +125,13 @@ const Products = () => {
<span className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium mt-1 ${
product.productType === 'liquid'
? 'bg-blue-100 text-blue-800'
: 'bg-green-100 text-green-800'
: product.productType === 'granular'
? 'bg-green-100 text-green-800'
: 'bg-gray-100 text-gray-800'
}`}>
{product.productType || 'Unknown'}
{product.productType ?
product.productType.charAt(0).toUpperCase() + product.productType.slice(1)
: 'Type not set'}
</span>
</div>
</div>
@@ -115,7 +139,7 @@ const Products = () => {
{isUserProduct && (
<div className="flex gap-1">
<button
onClick={() => {/* Handle edit */}}
onClick={() => handleEditProduct(product)}
className="p-1 text-gray-400 hover:text-blue-600"
>
<PencilIcon className="h-4 w-4" />
@@ -341,6 +365,20 @@ const Products = () => {
categories={categories}
/>
)}
{/* Edit Product Form Modal */}
{showEditForm && editingProduct && (
<EditProductModal
product={editingProduct}
onSubmit={handleUpdateProduct}
onCancel={() => {
setShowEditForm(false);
setEditingProduct(null);
}}
sharedProducts={sharedProducts}
categories={categories}
/>
)}
</div>
);
};
@@ -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 (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg p-6 w-full max-w-lg max-h-[90vh] overflow-y-auto">
<h3 className="text-lg font-semibold mb-4">Edit Product</h3>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="label">Base Product (Optional)</label>
<select
className="input"
value={formData.productId}
onChange={(e) => setFormData({ ...formData, productId: e.target.value })}
>
<option value="">Select a base product...</option>
{sharedProducts.map((sharedProduct) => (
<option key={sharedProduct.id} value={sharedProduct.id}>
{sharedProduct.name} {sharedProduct.brand && `- ${sharedProduct.brand}`}
</option>
))}
</select>
</div>
<div>
<label className="label">Custom Name</label>
<input
type="text"
className="input"
value={formData.customName}
onChange={(e) => setFormData({ ...formData, customName: e.target.value })}
placeholder="e.g., My 24-0-11 Blend, Custom Herbicide Mix"
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="label">Application Rate</label>
<input
type="number"
step="0.01"
className="input"
value={formData.customRateAmount}
onChange={(e) => setFormData({ ...formData, customRateAmount: e.target.value })}
placeholder="2.5"
/>
</div>
<div>
<label className="label">Rate Unit</label>
<select
className="input"
value={formData.customRateUnit}
onChange={(e) => setFormData({ ...formData, customRateUnit: e.target.value })}
>
<option value="lbs/1000 sq ft">lbs/1000 sq ft</option>
<option value="oz/1000 sq ft">oz/1000 sq ft</option>
<option value="gal/acre">gal/acre</option>
<option value="fl oz/1000 sq ft">fl oz/1000 sq ft</option>
<option value="ml/1000 sq ft">ml/1000 sq ft</option>
<option value="tbsp/1000 sq ft">tbsp/1000 sq ft</option>
</select>
</div>
</div>
<div>
<label className="label">Notes</label>
<textarea
className="input"
rows="3"
value={formData.notes}
onChange={(e) => setFormData({ ...formData, notes: e.target.value })}
placeholder="Special mixing instructions, storage notes, etc."
/>
</div>
<div className="flex gap-3 pt-4">
<button type="submit" className="btn-primary flex-1">
Update Product
</button>
<button
type="button"
onClick={onCancel}
className="btn-secondary flex-1"
>
Cancel
</button>
</div>
</form>
</div>
</div>
);
};
export default Products;