Skip to content

Conversation

@shawnSpy
Copy link

What I Did

This PR fixes the transaction display bug by adding a filter dropdown for transaction types (All/Credit/Debit) and implements client-side pagination for the transaction list. The filtering and pagination are handled entirely in the frontend React component.

How to Test

  1. Checkout this branch.
  2. Run docker compose up --build.
  3. Navigate to the frontend at http://localhost:3000.
  4. Use the "Filter by type" dropdown to filter transactions by type (All, Credit, or Debit).
  5. Verify that the transaction list updates to show only transactions matching the selected filter.
  6. Verify that pagination controls appear when there are more than 10 transactions.
  7. Test the Previous/Next buttons to navigate between pages.

Architectural Decision Record (ADR)

To address the display bug, I decided to handle filtering directly in the frontend component. This approach simplifies the backend and leverages the client's processing power for immediate filtering without additional API calls. For pagination, I implemented client-side pagination by slicing the filtered transaction array, which provides a responsive user experience without requiring backend changes. The frontend fetches up to 1000 transactions at once to support this client-side approach.

AI Usage Summary

I used AI tools for minor code refactoring and to generate some boilerplate for the frontend pagination component.

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.
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');
Copy link
Author

Choose a reason for hiding this comment

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

  • Hardcoded localhost:8000 can break in different environments. We should use an environment variable or config.
  • I think limit=1000 fetches too many records upfront. As it is a client-side pagination, this will be slow and can waste bandwidth. I think we should consider server-side pagination or a more reasonable limit.

setTransactions(data);
} catch (e: unknown) {
setError(e instanceof Error ? e.message : 'An error occurred');
} catch (e: any) {
Copy link
Author

Choose a reason for hiding this comment

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

We should avoid any. We can use unknown and narrow the error as original.

const [error, setError] = useState<string | null>(null);
const [filterType, setFilterType] = useState<string>('all');
const [currentPage, setCurrentPage] = useState<number>(1);
const pageSize = 10;
Copy link
Author

Choose a reason for hiding this comment

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

What about making this configurable?

Comment on lines +44 to +47
const filteredTransactions = transactions.filter(transaction => {
if (filterType === 'all') return true;
return transaction.type === filterType;
});
Copy link
Author

Choose a reason for hiding this comment

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

This runs every render. We can use useMemo here.

Comment on lines +49 to +52
const totalPages = Math.ceil(filteredTransactions.length / pageSize);
const startIndex = (currentPage - 1) * pageSize;
const endIndex = startIndex + pageSize;
const paginatedTransactions = filteredTransactions.slice(startIndex, endIndex);
Copy link
Author

Choose a reason for hiding this comment

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

We can use useMemo here as well.

Comment on lines +87 to +92
<select
id="type-filter"
value={filterType}
onChange={handleFilterChange}
className="border border-gray-300 rounded-md px-3 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
>
Copy link
Author

Choose a reason for hiding this comment

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

We can add aria-label for screen readers.

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.

2 participants