Finally Taming the Filter UI Beast — Bottom Sheets Everywhere
Another day, another battle with mobile UI quirks. Today I spent most of my time standardizing the filter experience across ReceiptScanner and fixing some annoying bugs that were driving me nuts.
The Great Bottom Sheet Migration
I've been slowly moving away from inline filter controls to bottom sheets across the app, and today I finally tackled the export and settings pages. There's something satisfying about having a consistent pattern — tap the filter icon, get a nice slide-up panel with a drag handle, make your selections, and hit Apply.
The export page was straightforward: multi-select checkboxes with an "All" option and a badge count showing how many categories are selected. Clean and simple.
Settings was trickier since it deals with visibility toggles that persist to Supabase. I implemented a pending state pattern where changes are staged locally until you hit Apply, then I diff against the actual DB values to minimize writes. No point hammering the database with identical updates.
Bug Squashing Session
The most annoying bug was the Apply button getting hidden behind the bottom navigation bar. Classic mobile development pain point. A quick change from pb-6 to pb-24 fixed it on both the dashboard and receipts pages.
Then there was the "All" checkbox logic that was completely broken. It should check/uncheck all category rows when toggled, and auto-select itself when you manually check everything. Took a bit of state wrangling but it's working properly now.
The Consistency Win
All four pages (dashboard, receipts, export, settings) now follow the same bottom sheet pattern. Same drag handle, same max-h-[80vh] sizing, same scrollable list structure. It feels cohesive in a way that the old mismatched UI didn't.
Next up, I'm definitely extracting a shared FilterBottomSheet component. Having nearly identical code across four pages is making my refactoring senses tingle. But for now, everything works and the UX is solid.
Sometimes the best coding sessions are the ones where you just fix a bunch of small annoying things. Nothing glamorous, but the app feels so much better to use.