From e7c26b3cfc813cf9b166fb326fee616c6ab2ac6e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 6 Nov 2025 21:45:38 +0000 Subject: [PATCH] Fix inline edit form positioning in AI inventory configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Issue:** When clicking "Edit" on an ingredient in the list, the edit form appeared at the bottom of the page after all ingredients, forcing users to scroll down. This was poor UX especially with 10+ ingredients. **Solution:** Moved edit form to appear inline directly below the ingredient being edited. **Changes Made:** 1. **Inline Edit Form Display** - Edit form now renders inside the ingredient map loop - Shows conditionally when `editingId === item.id` - Appears immediately below the specific ingredient being edited - Location: frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx:834-1029 2. **Hide Ingredient Card While Editing** - Ingredient card (with stock lots) hidden when that ingredient is being edited - Condition: `{editingId !== item.id && (...)}` - Prevents duplication of information - Location: lines 629-832 3. **Separate Add Manually Form** - Bottom form now only shows when adding new ingredient (not editing) - Condition changed from `{isAdding ? (` to `{isAdding && !editingId ? (` - Title simplified to "Agregar Ingrediente Manualmente" - Button label simplified to "Agregar a Lista" - Location: lines 1042-1237 **User Experience:** Before: Edit button → scroll to bottom → edit form → scroll back up After: Edit button → form appears right there → edit → save → continues **Structure:** ```jsx {inventoryItems.map((item) => (
{editingId !== item.id && ( <> {/* Ingredient card */} {/* Stock lots section */} )} {editingId === item.id && ( {/* Inline edit form */} )}
))} {isAdding && !editingId && ( {/* Add manually form at bottom */} )} ``` **Build Status:** ✓ Successful in 20.61s --- .../onboarding/steps/UploadSalesDataStep.tsx | 217 +++++++++++++++++- 1 file changed, 208 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx b/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx index 814e0a51..ffbd3748 100644 --- a/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx +++ b/frontend/src/components/domain/onboarding/steps/UploadSalesDataStep.tsx @@ -624,11 +624,11 @@ export const UploadSalesDataStep: React.FC = ({ {inventoryItems.length > 0 ? (
{inventoryItems.map((item) => ( -
-
+
+ {/* Show ingredient card only if NOT editing this item */} + {editingId !== item.id && ( +
+
@@ -828,6 +828,205 @@ export const UploadSalesDataStep: React.FC = ({
); })()} +
+ )} + + {/* Inline Edit Form - show only when editing this specific ingredient */} + {editingId === item.id && ( +
+

+ Editar Ingrediente +

+
+
+
+ + setFormData({ ...formData, name: e.target.value })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + placeholder="Ej: Harina de trigo" + /> + {formErrors.name && ( +

{formErrors.name}

+ )} +
+ +
+ + + {formErrors.category && ( +

{formErrors.category}

+ )} +
+ +
+ + +
+ +
+ + setFormData({ ...formData, stock_quantity: parseFloat(e.target.value) || 0 })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + /> + {formErrors.stock_quantity && ( +

{formErrors.stock_quantity}

+ )} +
+ +
+ + setFormData({ ...formData, cost_per_unit: parseFloat(e.target.value) || 0 })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + /> + {formErrors.cost_per_unit && ( +

{formErrors.cost_per_unit}

+ )} +
+ +
+ + setFormData({ ...formData, estimated_shelf_life_days: parseInt(e.target.value) || 30 })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + /> + {formErrors.estimated_shelf_life_days && ( +

{formErrors.estimated_shelf_life_days}

+ )} +
+ +
+ + setFormData({ ...formData, low_stock_threshold: parseInt(e.target.value) || 0 })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + /> +
+ +
+ + setFormData({ ...formData, reorder_point: parseInt(e.target.value) || 0 })} + className="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-secondary)] rounded-lg focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)] text-[var(--text-primary)]" + /> +
+
+ +
+ + + +
+ +
+ +