fix: CRITICAL - call onComplete synchronously with adjusted values
Root cause found: setState is async, so hookConfirmSingleItem was called before extractedItems updated, causing it to use OLD image_processing values. Fixed by: 1. Building the final newItem directly in handleImageAdjustmentConfirm 2. Using the UPDATED image_processing values (with user adjustments) 3. Calling onComplete synchronously with correct values 4. Not relying on async setState ordering This ensures backend receives the user-adjusted crop_bounds and rotation_degrees, not the original AI-detected values. Backend logs will now show user adjustments, not original AI values. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,6 +74,8 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento
|
|||||||
console.log('[Current] extractedImageBlob before:', extractedImageBlob?.size || 'null', 'bytes');
|
console.log('[Current] extractedImageBlob before:', extractedImageBlob?.size || 'null', 'bytes');
|
||||||
|
|
||||||
if (adjustments && extractedItems[index]) {
|
if (adjustments && extractedItems[index]) {
|
||||||
|
// UPDATE IMMEDIATELY - don't use setState, update the array directly
|
||||||
|
// because hookConfirmSingleItem needs to see the updated values synchronously
|
||||||
const updatedItems = [...extractedItems];
|
const updatedItems = [...extractedItems];
|
||||||
updatedItems[index] = {
|
updatedItems[index] = {
|
||||||
...updatedItems[index],
|
...updatedItems[index],
|
||||||
@@ -90,21 +92,59 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
console.log('[Update] Updated item_processing:', updatedItems[index].image_processing);
|
console.log('[Update] Updated item_processing:', updatedItems[index].image_processing);
|
||||||
|
|
||||||
|
// CRITICAL: Update state AND processed blob BEFORE calling hook
|
||||||
setExtractedItems(updatedItems);
|
setExtractedItems(updatedItems);
|
||||||
|
|
||||||
// If modal processed and returned image blob, update the hook's state
|
|
||||||
// so confirmSingleItem uses the processed blob instead of original
|
|
||||||
if (adjustments.imageBlob) {
|
if (adjustments.imageBlob) {
|
||||||
console.log('[Update] Setting extractedImageBlob to processed blob:', adjustments.imageBlob.size, 'bytes');
|
console.log('[Update] Setting extractedImageBlob to processed blob:', adjustments.imageBlob.size, 'bytes');
|
||||||
setExtractedImageBlob(adjustments.imageBlob);
|
setExtractedImageBlob(adjustments.imageBlob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CRITICAL: Call hook with UPDATED item, not old one
|
||||||
|
console.log('[Action] Calling hookConfirmSingleItem with UPDATED item');
|
||||||
|
console.log('[Action] Updated item:', updatedItems[index]);
|
||||||
|
|
||||||
|
// We need to manually call the hook logic here since we can't wait for state
|
||||||
|
// Build the item exactly as the hook does, but with updated values
|
||||||
|
const data = updatedItems[index];
|
||||||
|
const skipPhoto = data._skipPhoto === true;
|
||||||
|
|
||||||
|
const newItem = {
|
||||||
|
name: String(data.Item || data.name || "New AI Item"),
|
||||||
|
category: String(data.Category || data.category || "Uncategorized"),
|
||||||
|
type: data.Type || data.type ? String(data.Type || data.type) : null,
|
||||||
|
part_number: data.PartNr || data.part_number ? String(data.PartNr || data.part_number) : null,
|
||||||
|
color: data.Color || data.color ? String(data.Color || data.color) : null,
|
||||||
|
description: String(data.Description || data.description || ""),
|
||||||
|
connector: data.Connector || data.connector ? String(data.Connector || data.connector) : null,
|
||||||
|
size: data.Size || data.size ? String(data.Size || data.size) : null,
|
||||||
|
ocr_text: data.OCR || data.ocr_text ? String(data.OCR || data.ocr_text) : null,
|
||||||
|
specs: String(data.specs || ""),
|
||||||
|
barcode: String(data.barcode || data.PartNr || data.part_number || `AI-${Date.now()}-${index}`),
|
||||||
|
quantity: parseFloat(String(data.quantity || 1)),
|
||||||
|
min_quantity: 1.0,
|
||||||
|
box_label: data.box_label ? String(data.box_label) : null,
|
||||||
|
labels_data: JSON.stringify(data),
|
||||||
|
...(skipPhoto ? {} : {
|
||||||
|
extractedImageBlob: adjustments.imageBlob || extractedImageBlob,
|
||||||
|
imageProcessing: data.image_processing
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('[Final] newItem with ADJUSTED values:', newItem);
|
||||||
|
console.log('[Final] imageProcessing in final item:', newItem.imageProcessing);
|
||||||
|
onComplete(newItem);
|
||||||
|
|
||||||
|
// Clean up extracted items
|
||||||
|
const remaining = [...updatedItems];
|
||||||
|
remaining.splice(index, 1);
|
||||||
|
setExtractedItems(remaining.length > 0 ? remaining : []);
|
||||||
|
} else {
|
||||||
|
hookConfirmSingleItem(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always call confirm, even without adjustments
|
|
||||||
console.log('[Action] Calling hookConfirmSingleItem with index:', index);
|
|
||||||
hookConfirmSingleItem(index);
|
|
||||||
console.log('=== END CONFIRM DEBUG ===');
|
console.log('=== END CONFIRM DEBUG ===');
|
||||||
|
|
||||||
setShowImageAdjustment(false);
|
setShowImageAdjustment(false);
|
||||||
setAdjustingItemIndex(null);
|
setAdjustingItemIndex(null);
|
||||||
setPendingItemData(null);
|
setPendingItemData(null);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user