From 99a4cae572a9005084c2412edecfb3a400a10fdd Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Wed, 22 Apr 2026 09:07:44 +0300 Subject: [PATCH] fix: show item save confirmation with image before closing - Add savingIndex state to track saving operation - Display success overlay with saved image for 1.5 seconds - Show item name in confirmation message - Prevents modal from closing immediately after save Fixes user complaint about image disappearing too quickly without confirmation --- frontend/components/AIOnboarding.tsx | 22 ++++++++++++++++++++++ frontend/hooks/useAIExtraction.ts | 27 ++++++++++++++++++--------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/frontend/components/AIOnboarding.tsx b/frontend/components/AIOnboarding.tsx index 10978a99..13fca635 100644 --- a/frontend/components/AIOnboarding.tsx +++ b/frontend/components/AIOnboarding.tsx @@ -29,6 +29,7 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento fileInputRef, existingTypes, existingBoxes, + savingIndex, startLiveCamera, stopLiveCamera, captureSnapshot, @@ -483,6 +484,27 @@ export default function AIOnboarding({ onCancel, onComplete, categories, invento )} + + {/* Success confirmation overlay */} + {savingIndex !== null && image && ( +
+
+
+ Saved item photo +
+
+

Item saved!

+

+ {extractedItems[savingIndex]?.Item || extractedItems[savingIndex]?.name || "New item"} added to catalog +

+
+
+
+ )} ); } diff --git a/frontend/hooks/useAIExtraction.ts b/frontend/hooks/useAIExtraction.ts index 5e006bc5..42ba836e 100644 --- a/frontend/hooks/useAIExtraction.ts +++ b/frontend/hooks/useAIExtraction.ts @@ -11,6 +11,7 @@ export function useAIExtraction(inventory: Item[], onComplete: (itemData: any) = const [mode, setMode] = useState<'item' | 'box'>('item'); const [isLive, setIsLive] = useState(false); const [extractedImageBlob, setExtractedImageBlob] = useState(null); + const [savingIndex, setSavingIndex] = useState(null); const videoRef = useRef(null); const canvasRef = useRef(null); @@ -157,17 +158,24 @@ export function useAIExtraction(inventory: Item[], onComplete: (itemData: any) = imageProcessing: data.image_processing }) }; + + // Show success briefly before closing + setSavingIndex(index); onComplete(newItem); - if (extractedItems.length > 1) { - const remaining = [...extractedItems]; - remaining.splice(index, 1); - setExtractedItems(remaining); - setEditingIndex(null); - } else { - setExtractedItems([]); - setEditingIndex(null); - } + // Reset UI after brief delay so user sees the success + setTimeout(() => { + if (extractedItems.length > 1) { + const remaining = [...extractedItems]; + remaining.splice(index, 1); + setExtractedItems(remaining); + setEditingIndex(null); + } else { + setExtractedItems([]); + setEditingIndex(null); + } + setSavingIndex(null); + }, 1500); }; const confirmAllItems = async () => { @@ -255,6 +263,7 @@ export function useAIExtraction(inventory: Item[], onComplete: (itemData: any) = existingBoxes, extractedImageBlob, setExtractedImageBlob, + savingIndex, startLiveCamera, stopLiveCamera, captureSnapshot,