Improve receipt mapping with smart filtering and table UI

Enhanced the receipt mapping modal with intelligent transaction filtering
and a clean table-based selection interface.

Smart Filtering (per receipt):
- If receipt has a date: Show transactions within ±3 days
- If receipt has merchant: Filter by merchant name match
- Calculate amount matches (within $0.10 tolerance)
- Only show transactions without receipts
- Limit to 50 most recent matches
- Fallback to recent 50 transactions if no matches

UI Improvements:
- Replaced confusing listbox with formatted data table
- Proper column alignment with fixed widths
- Sticky header for scrollable table (max 400px height)
- Clickable rows with radio button selection
- Visual feedback:
  - Green highlight for amount matches
  - Blue highlight for selected row
  - Hover effect on rows
- Context-aware helper text explaining filter criteria
- Shows which transactions match the receipt date range

Features:
- Click anywhere on row to select
- Radio buttons for explicit selection
- Hidden input field stores selected transaction ID
- Manual ID entry still available as fallback
- Clear visual indicators for best matches

This provides a much better UX for manual mapping by showing only
relevant transactions and making it easy to identify likely matches.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
AJ
2025-10-12 13:31:14 -04:00
parent c6a01e120f
commit cd7ca679ac
3 changed files with 153 additions and 32 deletions

View File

@@ -2,15 +2,10 @@
"permissions": {
"allow": [
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(dotnet ef migrations add:*)",
"Bash(dotnet build)",
"Bash(dotnet ef database:*)",
"Bash(dotnet ef migrations:*)",
"Bash(git reset:*)",
"Bash(already contains a definition for 'MultipleMatches'\".\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude <noreply@anthropic.com>\nEOF\n)\")"
"Bash(git commit:*)"
],
"deny": [],
"ask": []
}
},
"spinnerTipsEnabled": false
}