Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 22 additions & 19 deletions views/UploadView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const UploadView: React.FC = () => {
const [recordId, setRecordId] = useState<string | null>(null);
const [createdAt, setCreatedAt] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const [saveError, setSaveError] = useState<string | null>(null);
const [isSaved, setIsSaved] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);

Expand Down Expand Up @@ -45,7 +46,7 @@ const UploadView: React.FC = () => {
lineItems: []
};
// We need the image even if analysis failed to initialize the record
if (image) initializeRecord(emptyData, image);
if (resizedImage) initializeRecord(emptyData, resizedImage);
Comment on lines 46 to +49

@chatgpt-codex-connector chatgpt-codex-connector Bot Nov 26, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot
P1 Badge Handle analysis failures without crashing

When the receipt analysis or resize fails, the catch block tries to call initializeRecord with resizedImage, but that identifier is only declared inside the preceding try block and is out of scope here. As soon as the catch executes, React will throw a ReferenceError instead of showing the manual entry fallback, leaving users stuck whenever extraction fails. Declare the resized image in a shared scope or use the already stored image state when handling errors.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot

![P1 Badge (https://camo.githubusercontent.com/c595229c0ecb6ee85b9c7804144d495f131a495ec87091fea2b262d954c9a92d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f50312d6f72616e67653f7374796c653d666c6174) Handle analysis failures without crashing

When the receipt analysis or resize fails, the catch block tries to call initializeRecord with resizedImage, but that identifier is only declared inside the preceding try block and is out of scope here. As soon as the catch executes, React will throw a ReferenceError instead of showing the manual entry fallback, leaving users stuck whenever extraction fails. Declare the resized image in a shared scope or use the already stored image state when handling errors.

Useful? React with 👍 / 👎.

} finally {
setIsAnalyzing(false);
}
Expand All @@ -59,24 +60,29 @@ const UploadView: React.FC = () => {
setData(initialData);
setRecordId(newId);
setCreatedAt(created);
};

const handleSave = async () => {
if (!data || !recordId || !image || !createdAt) return;

// Autosave immediately
setSaveError(null);
try {
await saveBill({
...initialData,
id: newId,
imageData: imgData,
createdAt: created,
...data,
id: recordId,
imageData: image,
createdAt: createdAt,
});
setIsSaved(true);
setTimeout(() => setIsSaved(false), 2000);
} catch (e) {
console.error("Failed to save bill", e);
setSaveError("Failed to save. Please try again.");
}
};

const updateField = (field: keyof BillData, value: any) => {
if (!data || !recordId || !image || !createdAt) return;
if (!data) return;

let newData = { ...data, [field]: value };

Expand All @@ -89,14 +95,6 @@ const UploadView: React.FC = () => {
}

setData(newData);

// Autosave on change
saveBill({
...newData,
id: recordId,
imageData: image,
createdAt: createdAt,
}).catch(err => console.error("Autosave failed", err));
};

const handleBack = () => navigate('/');
Expand Down Expand Up @@ -163,8 +161,8 @@ const UploadView: React.FC = () => {
onBack={handleBack}
action={
<div className="text-sm text-gray-500">
<Button onClick={handleBack} variant="primary">
{isSaved ? <span className="flex items-center"><Check className="w-4 h-4 mr-1"/> Saved</span> : "Done"}
<Button onClick={handleSave} variant="primary">
{isSaved ? <span className="flex items-center"><Check className="w-4 h-4 mr-1"/> Saved</span> : "Save"}
</Button>
<Button onClick={handleUploadAnother} variant="secondary" className="ml-3">
Upload Next Receipt
Expand All @@ -188,12 +186,18 @@ const UploadView: React.FC = () => {
</button>
</div>
</div>
{error && (
{error && (
<div className="mt-4 bg-amber-50 border border-amber-200 rounded-lg p-4 flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5" />
<p className="text-sm text-amber-800">{error}</p>
</div>
)}
{saveError && (
<div className="mt-4 bg-red-50 border border-red-200 rounded-lg p-4 flex items-start gap-3">
<AlertCircle className="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" />
<p className="text-sm text-red-800">{saveError}</p>
</div>
)}
</div>

{/* Form - Right Side on Desktop */}
Expand All @@ -203,7 +207,6 @@ const UploadView: React.FC = () => {
<Card className="p-6 space-y-5 shadow-md">
<div className="flex items-center justify-between">
<h3 className="text-lg font-bold text-gray-900">Receipt Details</h3>
<span className="text-xs font-medium text-indigo-600 bg-indigo-50 px-2 py-1 rounded">Autosave On</span>
</div>

<div>
Expand Down