From 65116818a78efb1690fee6e286bf60682163e034 Mon Sep 17 00:00:00 2001 From: Eduardo Garcia Julia Date: Thu, 11 Dec 2025 12:35:23 -0500 Subject: [PATCH] Fix BUG-666: Add transaction type filter with pagination Implemented filtering by transaction type (credit/debit) on the frontend. Added pagination controls to navigate through filtered results. Fetching all transactions to enable client-side filtering for better UX. --- frontend/src/components/TransactionList.tsx | 92 +++++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/TransactionList.tsx b/frontend/src/components/TransactionList.tsx index adbfd1d..78309e3 100644 --- a/frontend/src/components/TransactionList.tsx +++ b/frontend/src/components/TransactionList.tsx @@ -17,20 +17,22 @@ const TransactionList: React.FC = () => { const [transactions, setTransactions] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [filterType, setFilterType] = useState('all'); + const [currentPage, setCurrentPage] = useState(1); + const pageSize = 10; useEffect(() => { const fetchTransactions = async () => { try { setLoading(true); - const backendUrl = import.meta.env.VITE_BACKEND_URL; - const response = await fetch(`${backendUrl}/api/v1/transactions/`); + const response = await fetch('http://localhost:8000/api/v1/transactions/?limit=1000'); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data: Transaction[] = await response.json(); setTransactions(data); - } catch (e: unknown) { - setError(e instanceof Error ? e.message : 'An error occurred'); + } catch (e: any) { + setError(e.message); } finally { setLoading(false); } @@ -39,6 +41,33 @@ const TransactionList: React.FC = () => { fetchTransactions(); }, []); + const filteredTransactions = transactions.filter(transaction => { + if (filterType === 'all') return true; + return transaction.type === filterType; + }); + + const totalPages = Math.ceil(filteredTransactions.length / pageSize); + const startIndex = (currentPage - 1) * pageSize; + const endIndex = startIndex + pageSize; + const paginatedTransactions = filteredTransactions.slice(startIndex, endIndex); + + const handleFilterChange = (e: React.ChangeEvent) => { + setFilterType(e.target.value); + setCurrentPage(1); // Reset to first page when filter changes + }; + + const handleNextPage = () => { + if (currentPage < totalPages) { + setCurrentPage(currentPage + 1); + } + }; + + const handlePreviousPage = () => { + if (currentPage > 1) { + setCurrentPage(currentPage - 1); + } + }; + if (loading) { return
Loading transactions...
; } @@ -49,8 +78,23 @@ const TransactionList: React.FC = () => { return (
-
+

Recent Transactions

+
+ + +
@@ -64,7 +108,7 @@ const TransactionList: React.FC = () => { - {transactions.map((transaction, index) => ( + {paginatedTransactions.map((transaction, index) => ( ))} - {transactions.length === 0 && ( + {paginatedTransactions.length === 0 && ( @@ -95,8 +139,40 @@ const TransactionList: React.FC = () => {
{new Date(transaction.date).toLocaleDateString()} @@ -87,7 +131,7 @@ const TransactionList: React.FC = () => {
No transactions found.
+ + {totalPages > 1 && ( +
+
+ Page {currentPage} of {totalPages} ({filteredTransactions.length} transactions) +
+
+ + +
+
+ )}
); }; -export default TransactionList; \ No newline at end of file +export default TransactionList;