Skip to content

Conversation

@AmandeepMandal1077
Copy link
Contributor

No description provided.

Copilot AI review requested due to automatic review settings October 10, 2025 19:54
@netlify
Copy link

netlify bot commented Oct 10, 2025

Deploy Preview for paisable ready!

Name Link
🔨 Latest commit 03eb368
🔍 Latest deploy log https://app.netlify.com/projects/paisable/deploys/6904b338ede5e000082a18b4
😎 Deploy Preview https://deploy-preview-117--paisable.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 95
Accessibility: 100
Best Practices: 100
SEO: 91
PWA: 80
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds editing functionality for OCR extracted receipt data, allowing users to review and modify the extracted information before saving it as a transaction. The implementation introduces a two-step process: first extracting data from the receipt, then allowing user verification/editing before final save.

Key changes:

  • Separated receipt processing from transaction creation with a confirmation step
  • Added modal-based editing interface for extracted receipt data
  • Implemented new backend endpoint for saving user-confirmed transactions

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
frontend/src/pages/ReceiptsPage.jsx Added editing modal, confirmation UI, and two-step transaction creation workflow
backend/routes/receiptRoutes.js Added new route for saving confirmed transactions
backend/controllers/receiptController.js Removed automatic transaction creation and added endpoint for user-confirmed transaction saving

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.


const savedTransaction = await newTransaction.save();

// update the receipt with the final confirmed data
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

Corrected capitalization: 'update' should be 'Update' at the beginning of the comment.

Suggested change
// update the receipt with the final confirmed data
// Update the receipt with the final confirmed data

Copilot uses AI. Check for mistakes.
Comment on lines 68 to 88
const handleEditReceiptSubmit = async (formData, transactionId) => {
try {
// Update the receiptResult with the edited data
const updatedReceiptResult = {
...receiptResult,
extractedData: {
merchant: formData.name,
amount: parseFloat(formData.cost),
category: formData.category,
date: formData.addedOn,
isIncome: formData.isIncome
}
};

setReceiptResult(updatedReceiptResult);
setOpenEditReceiptResult(false);
} catch (err) {
setError('Failed to update receipt data. Please try again.');
console.error(err);
}
};
Copy link

Copilot AI Oct 10, 2025

Choose a reason for hiding this comment

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

The function parameter transactionId is not used anywhere in the function body. Either remove it or implement the intended functionality that uses this parameter.

Copilot uses AI. Check for mistakes.
@AmandeepMandal1077
Copy link
Contributor Author

what i have done is like,
when user upload a receipt, user have to explicitly click on 'Save Transaction to continue.

@AmandeepMandal1077
Copy link
Contributor Author

@archa8 could you please review this PR when you get a chance.

Copilot AI review requested due to automatic review settings October 22, 2025 16:05
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines 68 to 87
const handleEditReceiptSubmit = async (formData) => {
try {
// Update the receiptResult with the edited data
const updatedReceiptResult = {
...receiptResult,
extractedData: {
merchant: formData.name,
amount: parseFloat(formData.cost),
category: formData.category,
date: formData.addedOn,
isIncome: formData.isIncome
}
};

setReceiptResult(updatedReceiptResult);
setOpenEditReceiptResult(false);
} catch (err) {
setError('Failed to update receipt data. Please try again.');
console.error(err);
}
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The function is marked as async but does not contain any await operations. Since it only performs synchronous state updates, the try-catch block will not catch errors from asynchronous operations that don't exist. Remove the async keyword and consider removing the try-catch block as synchronous state updates are unlikely to throw errors.

Suggested change
const handleEditReceiptSubmit = async (formData) => {
try {
// Update the receiptResult with the edited data
const updatedReceiptResult = {
...receiptResult,
extractedData: {
merchant: formData.name,
amount: parseFloat(formData.cost),
category: formData.category,
date: formData.addedOn,
isIncome: formData.isIncome
}
};
setReceiptResult(updatedReceiptResult);
setOpenEditReceiptResult(false);
} catch (err) {
setError('Failed to update receipt data. Please try again.');
console.error(err);
}
const handleEditReceiptSubmit = (formData) => {
// Update the receiptResult with the edited data
const updatedReceiptResult = {
...receiptResult,
extractedData: {
merchant: formData.name,
amount: parseFloat(formData.cost),
category: formData.category,
date: formData.addedOn,
isIncome: formData.isIncome
}
};
setReceiptResult(updatedReceiptResult);
setOpenEditReceiptResult(false);

Copilot uses AI. Check for mistakes.
<p className="text-gray-700 dark:text-gray-300"><strong>Date:</strong> {new Date(receiptResult.extractedData.date).toLocaleDateString()}</p>
<div className="mb-4">
<p className="text-gray-700 dark:text-gray-300"><strong>Merchant:</strong> {receiptResult.extractedData.merchant}</p>
<p className="text-gray-700 dark:text-gray-300"><strong>Amount:</strong> {receiptResult.extractedData.amount.toFixed(2)}</p>
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

Potential runtime error if receiptResult.extractedData.amount is null or undefined. Since the amount comes from user-edited data and parseFloat can return NaN, consider adding a fallback: {(receiptResult.extractedData.amount || 0).toFixed(2)}

Suggested change
<p className="text-gray-700 dark:text-gray-300"><strong>Amount:</strong> {receiptResult.extractedData.amount.toFixed(2)}</p>
<p className="text-gray-700 dark:text-gray-300"><strong>Amount:</strong> {(parseFloat(receiptResult.extractedData.amount) || 0).toFixed(2)}</p>

Copilot uses AI. Check for mistakes.
name: transactionData.name,
category: transactionData.category,
cost: transactionData.cost,
addedOn: new Date(transactionData.addedOn),
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

If transactionData.addedOn is an invalid date string, new Date() will create an Invalid Date object, which could cause issues downstream. Add validation to ensure the date is valid before creating the transaction.

Copilot uses AI. Check for mistakes.
@AmandeepMandal1077
Copy link
Contributor Author

@archa8 could you please review this pr again, for any issues.

@AmandeepMandal1077
Copy link
Contributor Author

AmandeepMandal1077 commented Oct 27, 2025

@archa8 Do I have to make any further changes?

@AmandeepMandal1077 AmandeepMandal1077 changed the title added editing for ocr extracted receipt added editing for ocr extracted receipt Closes #11 Oct 27, 2025
@AmandeepMandal1077
Copy link
Contributor Author

This PR implements the feature mention in Issue: #11

Copilot AI review requested due to automatic review settings October 31, 2025 12:45
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

Comments suppressed due to low confidence (1)

frontend/src/pages/ReceiptsPage.jsx:17

  • Unused variable isEditingResult.
	const [isEditingResult, setIsEditingResult] = useState(false);

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

// Handle mobile responsive resize
useEffect(() => {
const handleResize = () => {
return setIsMobile(window.innerWidth <= 767);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The handleResize function unnecessarily returns the result of setIsMobile. Since setIsMobile returns undefined, this return statement serves no purpose. Remove the return keyword to make the function's intent clearer.

Suggested change
return setIsMobile(window.innerWidth <= 767);
setIsMobile(window.innerWidth <= 767);

Copilot uses AI. Check for mistakes.
new Date().toISOString().split("T")[0],
isIncome: receiptResult.extractedData.isIncome || false,
}}
categories={categories}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The TransactionModal component expects separate expenseCategories and incomeCategories props (see line 17 of TransactionModal.jsx), but this code passes a single categories prop. This will cause the modal to not display any categories in its dropdown. Update the prop name to match the expected API, or fetch and pass separate category arrays for expenses and income.

Suggested change
categories={categories}
expenseCategories={categories ? categories.filter(cat => !cat.isIncome) : []}
incomeCategories={categories ? categories.filter(cat => cat.isIncome) : []}

Copilot uses AI. Check for mistakes.
Comment on lines 146 to 147
const handleNewCategory = (newCategory) => {
setCategories((prev) => [...prev, newCategory].sort());
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The onNewCategory callback in TransactionModal passes two parameters: newCategory and isIncome (line 65 of TransactionModal.jsx), but handleNewCategory only accepts one parameter. This mismatch means the isIncome flag is ignored, preventing proper categorization of income vs. expense categories. Update the function signature to (newCategory, isIncome) and handle the categories accordingly.

Copilot uses AI. Check for mistakes.

const [openEditReceiptResult, setOpenEditReceiptResult] = useState(false);
const [categories, setCategories] = useState([]);
const [isEditingResult, setIsEditingResult] = useState(false);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The isEditingResult state variable is set in handleEditResult (line 142) and cleared in the modal's onClose callback (line 262), but it is never used elsewhere in the component. This unused state should be removed to reduce complexity.

Suggested change
const [isEditingResult, setIsEditingResult] = useState(false);

Copilot uses AI. Check for mistakes.
</div>

<img
src={`http://localhost:5001${receiptResult.fileUrl}`}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The hardcoded http://localhost:5001 URL creates a production deployment issue and won't work outside of local development. Use an environment variable (e.g., process.env.REACT_APP_API_BASE_URL) or construct the URL dynamically based on the current environment to ensure the application works correctly in all deployment scenarios.

Copilot uses AI. Check for mistakes.
isIncome: receiptResult.extractedData.isIncome || false,
};

const response = await api.post("/receipts/save-transaction", {
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

Unused variable response.

Suggested change
const response = await api.post("/receipts/save-transaction", {
await api.post("/receipts/save-transaction", {

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings October 31, 2025 13:01
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +212 to +216
{receiptResult.extractedData.isIncome && (
<p className="text-gray-700 dark:text-gray-300">
<strong>Income:</strong> Yes
</p>
)}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The code attempts to access receiptResult.extractedData.isIncome, but the backend's uploadReceipt endpoint (lines 68-73 in receiptController.js) doesn't set this field when creating the receipt. This will always be undefined until after the user saves the transaction. Consider setting a default value for isIncome in the extractedData when the receipt is first created, or handle the undefined case appropriately.

Suggested change
{receiptResult.extractedData.isIncome && (
<p className="text-gray-700 dark:text-gray-300">
<strong>Income:</strong> Yes
</p>
)}
{receiptResult.extractedData.isIncome === true && (
<p className="text-gray-700 dark:text-gray-300">
<strong>Income:</strong> Yes
</p>
)}
{receiptResult.extractedData.isIncome === false && (
<p className="text-gray-700 dark:text-gray-300">
<strong>Income:</strong> No
</p>
)}

Copilot uses AI. Check for mistakes.
Comment on lines +237 to +240
src={`${import.meta.env.VITE_API_URL?.replace(
"/api",
""
)}${receiptResult.fileUrl}`}
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

The image URL construction uses string replacement to remove '/api' from the VITE_API_URL. This is fragile and could break if the API URL doesn't contain '/api' or has it in a different position. Consider using a separate environment variable for the base URL without '/api', or construct the URL more reliably (e.g., using URL parsing).

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +130
});

setTimeout(() => navigate("/dashboard"), 1000);
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

Using a hardcoded setTimeout delay before navigation can lead to the user missing the success toast if they navigate away. The 1-second delay is arbitrary and may not be sufficient on slower devices. Consider navigating immediately or using the toast's onClose callback to navigate after the toast is dismissed.

Suggested change
});
setTimeout(() => navigate("/dashboard"), 1000);
onClose: () => navigate("/dashboard"),
});

Copilot uses AI. Check for mistakes.
res.status(201).json({
message: 'Transaction saved successfully',
transaction: savedTransaction,
receipt: receipt
Copy link

Copilot AI Oct 31, 2025

Choose a reason for hiding this comment

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

[nitpick] Using shorthand property syntax would be more concise. Change receipt: receipt to just receipt.

Suggested change
receipt: receipt
receipt

Copilot uses AI. Check for mistakes.
@archa8 archa8 linked an issue Oct 31, 2025 that may be closed by this pull request
Copy link
Member

@archa8 archa8 left a comment

Choose a reason for hiding this comment

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

LGTM!

@archa8 archa8 merged commit d14d04e into Code-A2Z:master Oct 31, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Add review and confirm for OCR

2 participants