Back to DevLog

Receipt Scanner Gets a UX Makeover: Bottom Sheets, Multi-Select Filters & Tap-to-Zoom

3 min read

Just wrapped up a solid 11-commit session overhauling the Receipt Scanner UX. What started as a simple filter improvement turned into a full design audit – you know how it goes!

The Big Changes

Filter System Overhaul Replaced those cramped category filter pills with a proper bottom sheet. Now you get a clean slider icon in the header (with a little dot badge when filters are active) that opens up a slide-up panel. Much better use of screen real estate, especially on mobile.

The multi-select logic was fun to implement – used a Set<string> with a pending/applied state pattern. So you can check multiple categories, hit Apply, or Clear to reset. There's this nice interaction where selecting "All" deselects everything else, but pick any specific category and "All" gets unchecked automatically.

Image Viewing Finally Works Fixed the receipt image display that was broken due to some null guard issues and Supabase storage URL resolution. But the real win was adding tap-to-zoom – now you can actually read those tiny receipt details in a proper full-screen lightbox with pinch-to-zoom support.

UI Polish Across the Board Went through every page and tightened up the design:

  • Added proper icons to summary cards (TrendingDown, TrendingUp, ReceiptText) with tinted backgrounds
  • Receipt cards now have category-colored left accent bars and proper chevron arrows
  • Implemented collapsible category sections on export and settings pages
  • Consistent empty states everywhere with the icon + title + subtitle pattern
  • Wrapped filter pills instead of that annoying horizontal scroll

Technical Decisions

Hit an interesting CSS variable issue – bg-primary wasn't rendering visibly on the Apply button even though it's defined in globals.css as #14b8a6. Switched to bg-teal-500 as a workaround. Might be a Tailwind v4 @theme inline specificity thing worth investigating later.

Also had to fix the export page filter logic. It was being too strict and excluding uncategorized receipts, which caused those mysterious $0.00 totals. Changed it from requiring category_id to being more permissive.

The min-h-0 flex-1 pattern for scrollable flex children was clutch for keeping the Apply button properly pinned at the bottom.

What's Next

Everything's committed and pushed to master with a passing build. The multi-select filter behavior probably needs some testing on mobile devices with lots of categories to make sure scrolling and button visibility work smoothly.

Feels good to have the core UX feeling much more polished. These kinds of UI overhauls are never as quick as you think they'll be, but the app feels way more professional now.

Share this post