From 2016a930adf8ce474be3a237f0e0cecfbc072015 Mon Sep 17 00:00:00 2001 From: SAI2101 Date: Mon, 27 Oct 2025 16:48:15 +0530 Subject: [PATCH 1/2] negative currency bug fixed Refactor TransactionModal component for improved readability and functionality. Added validation for cost input and adjusted form handling for better user experience.also fix negative currency issue --- frontend/src/components/TransactionModal.jsx | 160 +++++++++++++++---- 1 file changed, 129 insertions(+), 31 deletions(-) diff --git a/frontend/src/components/TransactionModal.jsx b/frontend/src/components/TransactionModal.jsx index 903ad69..8d32928 100644 --- a/frontend/src/components/TransactionModal.jsx +++ b/frontend/src/components/TransactionModal.jsx @@ -14,7 +14,16 @@ const getInitialFormData = (categories) => ({ note: '' }); -const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCategories = [], incomeCategories = [], onNewCategory, currentBalance = 0 }) => { +const TransactionModal = ({ + isOpen, + onClose, + onSubmit, + transaction, + expenseCategories = [], + incomeCategories = [], + onNewCategory, + currentBalance = 0 +}) => { const [modalView, setModalView] = useState(VIEW_MODE.EXPENSE_FORM); const [submittedAnyway, setSubmittedAnyway] = useState(false); const [formData, setFormData] = useState({ @@ -23,7 +32,7 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg cost: '', addedOn: new Date().toISOString().split('T')[0], isIncome: false, - note: ' ' + note: '' }); useEffect(() => { @@ -34,21 +43,23 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg cost: transaction.cost, addedOn: new Date(transaction.addedOn).toISOString().split('T')[0], isIncome: transaction.isIncome, - notes: transaction.note || '' + note: transaction.note || '' }); setModalView(transaction.isIncome ? VIEW_MODE.INCOME_FORM : VIEW_MODE.EXPENSE_FORM); } else { setFormData({ name: '', - category: expenseCategories[0] || '', // Default to the first category or empty + category: expenseCategories[0] || '', cost: '', addedOn: new Date().toISOString().split('T')[0], isIncome: false, + note: '' }); + if (modalView === VIEW_MODE.EXPENSE_FORM) { - setFormData(prev => ({ ...prev, category: expenseCategories[0] || '' })); + setFormData((prev) => ({ ...prev, category: expenseCategories[0] || '' })); } else { - setFormData(prev => ({ ...prev, category: incomeCategories[0] || '' })); + setFormData((prev) => ({ ...prev, category: incomeCategories[0] || '' })); } } }, [transaction, isOpen, expenseCategories, incomeCategories]); @@ -56,18 +67,16 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg const handleChange = (e) => { const { name, value } = e.target; - // Handle the "Add New" option for category if (name === 'category' && value === '__add_new__') { const newCategory = window.prompt("Enter new category name:"); - if (newCategory) { const isIncome = modalView === VIEW_MODE.INCOME_FORM; onNewCategory(newCategory, isIncome); - - setFormData(prev => ({ ...prev, category: newCategory })); + setFormData((prev) => ({ ...prev, category: newCategory })); } return; } + setFormData((prev) => ({ ...prev, [name]: value, @@ -79,6 +88,13 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg const isIncomeTransaction = modalView === VIEW_MODE.INCOME_FORM; const costValue = parseFloat(formData.cost); + + // ✅ Prevent negative or invalid amounts + if (isNaN(costValue) || costValue < 0) { + alert("Amount cannot be negative. Please enter a valid positive value."); + return; + } + if (!isIncomeTransaction && !transaction && costValue > currentBalance && !submittedAnyway) { const confirmation = window.confirm( `Warning: This expense (${costValue}) exceeds your current balance (${currentBalance}). Proceeding will result in a negative balance. Do you wish to submit anyway?` @@ -92,16 +108,20 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg } return; } + setSubmittedAnyway(false); + let transactionName = formData.name.trim(); if (isIncomeTransaction && transactionName === '') { transactionName = (formData.category ? formData.category : 'General') + ' Income'; } + const finalFormData = { ...formData, name: transactionName, isIncome: modalView === VIEW_MODE.INCOME_FORM }; + onSubmit(finalFormData, transaction?._id); }; @@ -109,45 +129,81 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg e.preventDefault(); setFormData(getInitialFormData(incomeCategories)); setModalView(VIEW_MODE.INCOME_FORM); - } + }; const handleSwitchToExpense = (e) => { e.preventDefault(); setFormData(getInitialFormData(expenseCategories)); setModalView(VIEW_MODE.EXPENSE_FORM); - } + }; if (!isOpen) return null; return (
-

{transaction ? 'Edit' : 'Add'}{modalView === VIEW_MODE.EXPENSE_FORM ? ' Expense' : ' Income'}

+

+ {transaction ? 'Edit' : 'Add'} {modalView === VIEW_MODE.EXPENSE_FORM ? 'Expense' : 'Income'} +

+
- {/* ... other form fields (name, cost, etc.) remain the same ... */} + {/* EXPENSE FORM */} {modalView === VIEW_MODE.EXPENSE_FORM && ( <>
- +
+
- - {expenseCategories.map(cat => )} - + {expenseCategories.map((cat) => ( + + ))} +
- +
- +
@@ -158,13 +214,17 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg onChange={handleChange} className="w-full px-3 py-2 border rounded resize-y" rows="3" - placeholder="E.g., Dinner at favorite restaurant, January salary" + placeholder="E.g., Dinner at favorite restaurant" />
@@ -172,25 +232,51 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg )} + {/* INCOME FORM */} {modalView === VIEW_MODE.INCOME_FORM && ( <>
- - {incomeCategories.map(cat => )} - + {incomeCategories.map((cat) => ( + + ))} +
- +
- +
@@ -201,21 +287,33 @@ const TransactionModal = ({ isOpen, onClose, onSubmit, transaction, expenseCateg onChange={handleChange} className="w-full px-3 py-2 border rounded resize-y" rows="3" - placeholder="E.g., Dinner at favorite restaurant, January salary" + placeholder="E.g., January salary" />
)} +
- + + @@ -77,11 +74,45 @@ const Layout = () => {
-
-
+ {/* ======= MAIN CONTENT ======= */} +
+
+ + {/* ======= FOOTER ======= */} +
); };