diff --git a/backend/package-lock.json b/backend/package-lock.json index 7cce1e7..5a37991 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -2710,67 +2710,6 @@ "url": "https://opencollective.com/node-fetch" } }, - "node_modules/gcp-metadata": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.3.0.tgz", - "integrity": "sha512-FNTkdNEnBdlqF2oatizolQqNANMrcqJt6AAYt99B3y1aLLC8Hc5IOBb+ZnnzllodEEf6xMBp6wRcBbc16fa65w==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "gaxios": "^5.0.0", - "json-bigint": "^1.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/gcp-metadata/node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/gcp-metadata/node_modules/gaxios": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-5.1.3.tgz", - "integrity": "sha512-95hVgBRgEIRQQQHIbnxBXeHbW4TqFk4ZDJW7wmVtvYar72FdhRIo1UGOLS2eRAKCPEdPBWu+M7+A33D9CdX9rA==", - "license": "Apache-2.0", - "optional": true, - "peer": true, - "dependencies": { - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.6.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/gcp-metadata/node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -4720,56 +4659,6 @@ "node": ">=10.5.0" } }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT", - "optional": true, - "peer": true - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause", - "optional": true, - "peer": true - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "optional": true, - "peer": true, - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", diff --git a/frontend/src/pages/TransactionsPage.jsx b/frontend/src/pages/TransactionsPage.jsx index cc7f900..0c26772 100644 --- a/frontend/src/pages/TransactionsPage.jsx +++ b/frontend/src/pages/TransactionsPage.jsx @@ -42,7 +42,7 @@ const TransactionsPage = () => { const [isCategoryModalOpen, setIsCategoryModalOpen] = useState(false); const { currency } = useCurrency(); const isInitialMount = useRef(true); - const allCategories = [...new Set([...expenseCategories, ...incomeCategories])]; + const allCategories = [...new Set([...expenseCategories, ...incomeCategories])]; const fetchData = useCallback(async (currentSearchTerm = searchTerm) => { if (isInitialMount.current) { @@ -101,7 +101,7 @@ const TransactionsPage = () => { if (isInitialMount.current) { fetchData(); // Fetch on initial mount } else { - // Debounced search is handled separately in handleSearchChange + // Debounced search is handled separately in handleSearchChange if (!debounceTimer.current) { fetchData(); } @@ -138,7 +138,7 @@ const TransactionsPage = () => { setDateTo(''); setPage(1); }; - + const hasActiveFilters = searchTerm || typeFilter !== 'all' || categoryFilter !== 'all' || dateFrom || dateTo; const handleOpenTransactionModal = (transaction = null) => { @@ -193,19 +193,19 @@ const TransactionsPage = () => { }; const toggleSelect = (id) => { - setSelectedTransactionIds(prev => + setSelectedTransactionIds(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id] ); }; - + const handleBulkDelete = async () => { if (!selectedTransactionIds.length) return; - + const confirmMessage = `Are you sure you want to permanently delete these ${selectedTransactionIds.length} transactions? This action cannot be undone.`; if (window.confirm(confirmMessage)) { try { - await api.delete('/transactions/bulk', { - data: { transactionIds: selectedTransactionIds } + await api.delete('/transactions/bulk', { + data: { transactionIds: selectedTransactionIds } }); setSelectedTransactionIds([]); fetchData(); // Refetch data @@ -240,7 +240,7 @@ const TransactionsPage = () => {

Transactions

- {selectedTransactionIds.length > 0 && + {selectedTransactionIds.length > 0 && @@ -252,9 +252,14 @@ const TransactionsPage = () => { + Add Transaction @@ -336,11 +341,11 @@ const TransactionsPage = () => { ) : (
- {transactions.length > 0 ? ( - - - - + ))} + +
+ {transactions.length > 0 ? ( + + + + - - - - - - - - - - {transactions.map((tx) => ( - - + + + + + + + + + {transactions.map((tx) => ( + + - - - - - - + + + + + - - ))} - -
{ onChange={() => setSelectedTransactionIds(selectedTransactionIds.length ? [] : transactions.map(t => t._id))} /> NameCategoryAmountDateNoteActions
+ NameCategoryAmountDateNoteActions
{ onChange={() => toggleSelect(tx._id)} /> {tx.name}{tx.category} - {tx.isIncome ? '+' : '-'}{new Intl.NumberFormat('en-US', { - style: 'currency', - currency: currency.code, - }).format(tx.cost)} - {new Date(tx.addedOn).toLocaleDateString()} - - + {tx.name}{tx.category} + {tx.isIncome ? '+' : '-'}{new Intl.NumberFormat('en-US', { + style: 'currency', + currency: currency.code, + }).format(tx.cost)} + {new Date(tx.addedOn).toLocaleDateString()} + +
+
) : ( -
- -
- )} +
+ +
+ )}
)} {!loading && totalPages > 1 && (
- - +
Page {page} of {totalPages}
- -