When user customizes an item, add selections directly under the root
item instead of creating an intermediate group node. This matches how
attachDefaultChildren works on the server and prevents duplicate
modifiers showing in KDS.
Before: Double Double → Customize Lettuce → Light, Extra
After: Double Double → Light, Extra
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix login to check for existing cart after OTP verification
- Add abandonOrder API call for Start Fresh functionality
- Fix stale service point showing for non-dine-in orders
- Add Chat button for non-dine-in orders (was only Call Server)
- Add quantity selector in item customization sheet
- Compact cart layout with quantity badge, accordion modifiers
- Add scroll indicator when cart has hidden content
- Fix restaurant list tappable before images load
- Add ForceNew parameter to setLineItem for customized items
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use cart's businessId when appState doesn't have one
(e.g., when ordering without beacon detection).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- OrderLineItem now includes itemName, itemParentName, and
isCheckedByDefault from API response
- Cart view displays modifiers as "Category: Selection" format
(e.g., "Select Drink: Coke") instead of just item IDs
- No longer requires menu item lookup for modifier names
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove 60+ debug print statements from services and screens
- Sanitize error messages to not expose internal API details
- Remove stack trace exposure in beacon_scan_screen
- Delete unused order_home_screen.dart
- Remove unused ChatScreen route from app_router
- Fix widget_test.dart to compile
- Remove unused foundation.dart import from menu_browse_screen
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add real-time chat between customers and staff via WebSocket
- Add HTTP polling fallback when WebSocket unavailable
- Chat auto-closes when worker ends conversation with dialog notification
- Add user search API for group order invites (phone/email/name)
- Store group order invites in app state
- Add login check before starting chat with sign-in prompt
- Remove table change button (not allowed currently)
- Fix About screen to show dynamic version from pubspec
- Update snackbar styling to green with black text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Restore FOREGROUND_SERVICE permission for beacon scanning
- Remove FOREGROUND_SERVICE_LOCATION (no video required)
- Update all SnackBars to Payfrit green (#90EE90) with black text
- Float SnackBars with 80px bottom margin to avoid buttons
- Add signup screen with OTP verification flow
- Fix build.gradle.kts to use Flutter version system
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add About Payfrit screen with app info, features, and contact details
- Add Order Detail screen showing line items with non-default modifiers
- Add order_detail model with parent-child line item hierarchy
- Update order history to navigate to detail screen on tap
- Add getOrderDetail API method
- Add about route to app router
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Load user profile on Account screen init
- Display FirstName LastInitial format
- Fall back to User #ID if profile fails to load
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CFBundleURLTypes with payfrit scheme for Cash App redirect
- Add returnURL to Stripe PaymentSheet config
- Update Podfile to specify iOS 13.0 platform
- Change order status notification to Payfrit light green with black text
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add delivery address list, add, edit, delete, set default functionality
- Add order history screen
- Add profile settings screen
- Add account screen with avatar upload
- Update restaurant select gradient direction
- Add states API endpoint for address forms
- Fix table names (tt_States)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove neverForLocation flag from BLUETOOTH_SCAN (was blocking beacon detection)
- Add Bluetooth state check before scanning with prompt to enable
- Add iOS Bluetooth/Location permission descriptions and UIBackgroundModes
- Fix exclusive modifier selection (deselect siblings when max=1)
- Update cart service point when existing cart found
- Add delivery fee support to cart and stripe service
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
iOS Permissions:
- Add missing Info.plist keys for location and Bluetooth usage descriptions
- Configure Podfile to enable PERMISSION_LOCATION and PERMISSION_BLUETOOTH
- Fix beacon_permissions.dart to use correct iOS permission (Permission.bluetooth)
instead of Android-only bluetoothScan/bluetoothConnect
The permission_handler plugin requires platform-specific handling:
- iOS: Uses Permission.bluetooth for Bluetooth access
- Android: Uses Permission.bluetoothScan and Permission.bluetoothConnect
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cart/Payment:
- Custom tip option (0-200%) with dialog input
- Tip buttons now include "Custom" option
- Default custom tip starts at 25%
Order Flow:
- New order type selection screen (Dine-In, Takeout, Delivery)
- Group order invite screen (placeholder)
- App router updated with new routes
Menu Display:
- Category headers now text-only (removed image loading)
- Simplified category background with gradient and styled text
Beacon Scanning:
- Improved beacon detection flow
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fixed 'simport' typo to 'import' in cart_view_screen.dart
- Changed hasActiveOrder to activeOrderId != null in menu_browse_screen.dart
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Snackbar Improvements:
- All snackbars now have colored backgrounds (green/red/orange/blue)
- Added icons to snackbar messages (check_circle, error, warning, info)
- Floating behavior with bottom margin to avoid obscuring action buttons
- Consistent styling across menu_browse, cart_view, and login screens
App State Fixes:
- Clear cartItemCount when switching businesses (setBusiness, setServicePoint, setBusinessAndServicePoint, clearAll)
- Prevents stale cart count showing after switching restaurants
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added a table icon button in the menu screen AppBar that allows users to navigate back to restaurant selection. The button includes dine-and-dash prevention - it blocks table changes if there's an active order and shows an explanatory dialog.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added /menu_browse route alias to fix navigation from restaurant selection screen. The app was trying to navigate to /menu_browse but only /menu route was registered, causing route not found errors.
Also added iOS and macOS Podfiles for dependency management.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add item image (100x100) with shadow in header
- Green price badge for base price
- Styled modifier options as cards with blue highlight when selected
- Green price badges for modifier add-on prices
- Large blue "Add to Cart" button with cart icon and price badge
- Centered drag handle at top
- Better visual hierarchy throughout
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Larger white cards with rounded corners and soft shadows
- Bigger item images (90x90) with shadow effect
- Gradient placeholder for items without images
- Material wrapper for better touch ripple effect
- Better spacing and layout for card content
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
App Branding:
- New Payfrit app icon (blue gradient with white P logo)
- Custom splash screen with animated logo and tagline
- Android adaptive icon with foreground/background layers
- iOS app icons for all required sizes
- Updated launch screen backgrounds with brand colors
Splash Screen Experience:
- Animated logo with fade-in effect
- "Order. Pay. Go." tagline with staggered animations
- Restaurant list display with search functionality
- Beacon scanning integration from splash
- Smooth transition to menu browse
Modifier Validation Fix:
- Fixed validation to check ALL modifier groups (not just selected items)
- Ensures required selections are enforced for nested modifier groups
- Modifier groups with children now always get validated
- Prevents adding items without required selections
Cart Improvements:
- Better modifier display in cart items
- Improved line item quantity handling
- Enhanced order submission flow
Beacon Scanning:
- Improved beacon detection reliability
- Better handling of multiple beacons
- Enhanced error messaging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Reduce polling interval from 30s to 6s for faster updates
- Add global ScaffoldMessengerKey for app-wide snackbar notifications
- Fix notifications showing after cart screen is dismissed
- Add JSON parsing fallback to handle server debug output
- Standardize all gradient heights to 16px
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Restaurant Select Screen:
- Horizontal bars with logos (text fallback with first letter)
- Tap to expand and preview menu with horizontal item cards
- Dark theme with subtle header backgrounds
Menu Browse Screen:
- Removed redundant business info overlay from header
- Sharp gradient bars on top/bottom edges of headers
- Accordion categories with animated expand/collapse
- Hide checkboxes on container/interim items
- Track user-modified selections separately from defaults
Beacon Scan Screen:
- Rotating status messages during 5 scan cycles
- Removed manual selection link for cleaner UX
Cart/Checkout:
- Only show delivery fee for delivery orders (OrderTypeID=3)
- Fixed total calculation to exclude fee for dine-in
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Infer radio button behavior when group has exactly one default-checked item
- Both visual (Radio widget) and behavior (_toggleSelection) now consistent
- Fixes issue where selecting different option kept both default and selected
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add business header hero image with logo overlay
- Add business logo in app bar
- Add category header images with gradient overlay
- Add item thumbnail images (64x64)
- Images load from server with PNG/JPG fallbacks
- Placeholder icons shown when images unavailable
Image sources:
- Business headers: /uploads/headers/{BusinessID}
- Business logos: /uploads/logos/{BusinessID}
- Category images: /uploads/categories/{CategoryID}
- Item images: /uploads/items/{ItemID}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Filter out inactive items (ItemIsActive=0) in menu modifier display
- Fix radio button groups to prevent deselection (can only switch)
- Add cart clearing on "order not found" errors
- Simplify API base URL configuration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Client-side implementation:
- New service: order_polling_service.dart - Timer-based polling every 30s
- Updated AppState: track active order ID and current status
- Cart integration: start polling after order submission
- In-app notifications: color-coded SnackBar for status changes
- Notification widget: animated banner (created for future use)
Status notification colors:
- Blue = Submitted (1)
- Orange = Preparing (2)
- Green = Ready (3)
- Purple = Completed (4)
Polling workflow:
1. User submits order → polling starts with status=1
2. Every 30s: check backend for status changes
3. On update: show notification + update AppState
4. Continues until order completed or app closed
Simple polling approach (Option 2) with planned migration to self-hosted WebSocket push for instant updates.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Configure production API URL (biz.payfrit.com) as default
- Add INTERNET permission to AndroidManifest for API calls
- Remove login requirement from restaurant selection (allow anonymous browsing)
- Add enhanced logging for beacon scanning diagnostics
- Add splash screen logging for auth flow debugging
Technical changes:
- api.dart: Default baseUrl to production instead of throwing error
- restaurant_select_screen.dart: Remove userId requirement for browsing
- beacon_scan_screen.dart: Replace debugPrint with print for better log capture
- splash_screen.dart: Add diagnostic logging for auth restoration
- AndroidManifest.xml: Add INTERNET permission
Known issue:
- Beacon detection not working - app receives beacon data from API (3 beacons)
but BLE scanning not detecting physical beacons. Needs investigation of:
* Physical beacon UUID configuration
* Android BLE permissions at runtime
* Beacon plugin initialization
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Removed all debug print statements from menu_browse_screen.dart
- Removed all debug print statements from api.dart
- Deleted unused beacon_scan_screen_broken.dart backup file
- Kept debugPrint statements in beacon_scan_screen.dart and beacon_permissions.dart for debugging beacon issues
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
UI Improvements:
- Menu items displayed as attractive cards with icons and better typography
- Restaurant selection upgraded to card-based layout with shadows
- Animated pulsing beacon scanner with gradient effect
- Enhanced item customization sheet with drag handle and pill-style pricing
- Category headers with highlighted background and borders
- Business and service point names now shown in app bar
Persistent Login:
- Created AuthStorage service for credential persistence using SharedPreferences
- Auto-restore authentication on app launch
- Seamless login flow: scan → browse → login on cart add
- Users stay logged in across app restarts
Cart Functionality Fixes:
- Fixed duplicate item handling: now properly increments quantity
- Prevented adding inactive items by skipping unselected modifiers
- Fixed self-referential items (item cannot be its own child)
- Added debug logging for cart state tracking
- Success messages now show accurate item counts
Technical Improvements:
- AppState tracks business/service point names for display
- Beacon scanner passes location names through navigation
- Quantity calculation checks existing cart items before adding
- Better null safety with firstOrNull pattern
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Multi-cycle BLE scanning (5 cycles x 2 seconds) overcomes Android detection limits
- RSSI averaging and variance calculation for confident beacon selection
- Detects all 3 test beacons with 100% accuracy
- Login flow optimized: beacon scan → browse menu → login on cart add
- Anonymous users can browse full menu before authentication
- Beacon scanning now occurs before login requirement
Technical improvements:
- Added API endpoints for beacon listing and business mapping
- Updated AppState to handle business/service point selection
- Implemented intelligent beacon scoring with proximity ranking
- Added graceful fallbacks for no-beacon scenarios
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Fixed _addModifiersRecursively to track OrderLineItemID through recursion
- Changed from hardcoded parentOrderLineItemId: 0 to actual parent IDs
- Added logic to find root item's OrderLineItemID before starting recursion
- Added logic to find each modifier's OrderLineItemID for its children
- Fixed API_BASE_URL to AALISTS_API_BASE_URL for environment consistency
- Added comprehensive debug logging for troubleshooting
This fix ensures nested modifiers (e.g., Customize Spread > Extra) are
properly saved to the database with correct parent-child relationships.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add full cart functionality with API integration:
- Created Cart and OrderLineItem models with robust JSON parsing
- Implemented cart API methods (getOrCreateCart, setLineItem, getCart, submitOrder)
- Added cart state management to AppState with item count tracking
- Built cart view screen with item display, quantity editing, and removal
- Added cart badge to menu screen showing item count
- Implemented real add-to-cart logic with recursive modifier handling
- Added category name display in menu browsing
- Fixed API response case sensitivity (ORDER/ORDERLINEITEMS)
- Enhanced MenuItem model with categoryName field
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add MenuItem model with hierarchical structure support
- Implement recursive menu browsing with infinite depth support
- Add ExpansionTile for collapsible modifier sections
- Implement radio/checkbox logic based on ItemMaxNumSelectionReq
- Add automatic pre-selection for ItemIsCheckedByDefault items
- Implement validation for ItemRequiresChildSelection and max limits
- Add recursive price calculation across all depth levels
- Support intelligent selection behavior (radio groups, parent/child deselection)
- Add proper error messaging for validation failures
- Connect menu items API endpoint
- Update navigation flow to menu browse after service point selection
- Add LoginScreen with form validation and error handling
- Add Api.login() method with LoginResponse model
- Add login route to AppRouter
- Update SplashScreen to check auth status and route to login if needed
- Store auth token in Api service for authenticated requests
- Fix restaurant selection to work with authenticated users