Clean up debug code and unused files
- 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>
This commit is contained in:
parent
0a8c12c1d3
commit
114401c130
3 changed files with 0 additions and 304 deletions
|
|
@ -1,243 +0,0 @@
|
|||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:beacons_plugin/beacons_plugin.dart';
|
||||
|
||||
import '../app/app_router.dart';
|
||||
import '../app/app_state.dart';
|
||||
import '../services/beacon_permissions.dart';
|
||||
import '../services/api.dart';
|
||||
|
||||
class BeaconScanScreen extends StatefulWidget {
|
||||
const BeaconScanScreen({super.key});
|
||||
|
||||
@override
|
||||
State<BeaconScanScreen> createState() => _BeaconScanScreenState();
|
||||
}
|
||||
|
||||
class _BeaconScanScreenState extends State<BeaconScanScreen> {
|
||||
String _status = 'Initializing...';
|
||||
bool _scanning = false;
|
||||
bool _permissionsGranted = false;
|
||||
|
||||
// Track beacons by UUID -> (BeaconID, RSSI)
|
||||
final Map<String, MapEntry<int, int>> _detectedBeacons = {};
|
||||
Map<String, int> _uuidToBeaconId = {};
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_startScanFlow();
|
||||
}
|
||||
|
||||
Future<void> _startScanFlow() async {
|
||||
// Step 1: Request permissions
|
||||
setState(() => _status = 'Requesting permissions...');
|
||||
|
||||
final granted = await BeaconPermissions.requestPermissions();
|
||||
|
||||
if (!granted) {
|
||||
setState(() {
|
||||
_status = 'Permissions denied';
|
||||
_permissionsGranted = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() => _permissionsGranted = true);
|
||||
|
||||
// Step 2: Fetch all active beacons from server
|
||||
setState(() => _status = 'Loading beacon data...');
|
||||
|
||||
try {
|
||||
_uuidToBeaconId = await Api.listAllBeacons();
|
||||
} catch (e) {
|
||||
debugPrint('[BeaconScan] Error loading beacons: $e');
|
||||
_uuidToBeaconId = {};
|
||||
}
|
||||
|
||||
if (_uuidToBeaconId.isEmpty) {
|
||||
// No beacons in database, skip scan and go straight to manual selection
|
||||
debugPrint('[BeaconScan] No beacons in database, going to restaurant select');
|
||||
if (mounted) _navigateToRestaurantSelect();
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3: Perform initial scan
|
||||
setState(() {
|
||||
_status = 'Scanning for nearby beacons...';
|
||||
_scanning = true;
|
||||
});
|
||||
|
||||
await _performInitialScan();
|
||||
}
|
||||
|
||||
Future<void> _performInitialScan() async {
|
||||
try {
|
||||
// Setup beacon monitoring
|
||||
await BeaconsPlugin.listenToBeacons(
|
||||
_beaconDataReceived,
|
||||
);
|
||||
|
||||
// Start beacon monitoring
|
||||
await BeaconsPlugin.addRegion(
|
||||
"PayfritBeacons",
|
||||
"00000000-0000-0000-0000-000000000000", // Placeholder UUID
|
||||
);
|
||||
|
||||
await BeaconsPlugin.startMonitoring();
|
||||
|
||||
// Scan for 3 seconds
|
||||
await Future.delayed(const Duration(seconds: 3));
|
||||
|
||||
// Stop scanning
|
||||
await BeaconsPlugin.stopMonitoring();
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (_detectedBeacons.isEmpty) {
|
||||
// No beacons found
|
||||
setState(() => _status = 'No beacons nearby');
|
||||
await Future.delayed(const Duration(milliseconds: 800));
|
||||
if (mounted) _navigateToRestaurantSelect();
|
||||
} else {
|
||||
// Find beacon with highest RSSI
|
||||
final best = _findBestBeacon();
|
||||
if (best != null) {
|
||||
setState(() => _status = 'Beacon detected! Loading menu...');
|
||||
await _autoSelectBusinessFromBeacon(best);
|
||||
} else {
|
||||
_navigateToRestaurantSelect();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('[BeaconScan] Error during scan: $e');
|
||||
if (mounted) {
|
||||
setState(() => _status = 'Scan error: ${e.toString()}');
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
if (mounted) _navigateToRestaurantSelect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _beaconDataReceived(dynamic result) {
|
||||
if (result is Map) {
|
||||
try {
|
||||
final uuid = (result["uuid"] ?? "").toString().trim().toUpperCase().replaceAll('-', '');
|
||||
final rssi = int.tryParse((result["rssi"] ?? "-100").toString()) ?? -100;
|
||||
|
||||
if (uuid.isNotEmpty && _uuidToBeaconId.containsKey(uuid)) {
|
||||
final beaconId = _uuidToBeaconId[uuid]!;
|
||||
|
||||
// Update if this is a new beacon or better RSSI
|
||||
if (!_detectedBeacons.containsKey(uuid) || _detectedBeacons[uuid]!.value < rssi) {
|
||||
setState(() {
|
||||
_detectedBeacons[uuid] = MapEntry(beaconId, rssi);
|
||||
});
|
||||
debugPrint('[BeaconScan] Detected: UUID=$uuid, BeaconID=$beaconId, RSSI=$rssi');
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('[BeaconScan] Error parsing beacon data: $e');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MapEntry<String, int>? _findBestBeacon() {
|
||||
if (_detectedBeacons.isEmpty) return null;
|
||||
|
||||
String? bestUUID;
|
||||
int bestRSSI = -200;
|
||||
|
||||
for (final entry in _detectedBeacons.entries) {
|
||||
if (entry.value.value > bestRSSI) {
|
||||
bestRSSI = entry.value.value;
|
||||
bestUUID = entry.key;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestUUID != null) {
|
||||
final beaconId = _detectedBeacons[bestUUID]!.key;
|
||||
return MapEntry(bestUUID, beaconId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<void> _autoSelectBusinessFromBeacon(MapEntry<String, int> beacon) async {
|
||||
final beaconId = beacon.value;
|
||||
debugPrint('[BeaconScan] Found beacon! BeaconID=$beaconId, UUID=${beacon.key}');
|
||||
|
||||
// TODO: Fetch Business + ServicePoint info from BeaconID
|
||||
// For now, navigate to restaurant select
|
||||
_navigateToRestaurantSelect();
|
||||
}
|
||||
|
||||
void _navigateToRestaurantSelect() {
|
||||
Navigator.of(context).pushReplacementNamed(AppRoutes.restaurantSelect);
|
||||
}
|
||||
|
||||
void _retryPermissions() async {
|
||||
await BeaconPermissions.openSettings();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
BeaconsPlugin.stopMonitoring();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.black,
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
if (_scanning)
|
||||
const CircularProgressIndicator(color: Colors.white)
|
||||
else if (!_permissionsGranted)
|
||||
const Icon(Icons.bluetooth_disabled, color: Colors.white70, size: 64)
|
||||
else
|
||||
const Icon(Icons.bluetooth_searching, color: Colors.white70, size: 64),
|
||||
|
||||
const SizedBox(height: 24),
|
||||
|
||||
Text(
|
||||
_status,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
|
||||
if (_detectedBeacons.isNotEmpty) ...[
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Found ${_detectedBeacons.length} beacon(s)',
|
||||
style: const TextStyle(color: Colors.white70, fontSize: 12),
|
||||
),
|
||||
],
|
||||
|
||||
if (!_permissionsGranted && _status.contains('denied')) ...[
|
||||
const SizedBox(height: 24),
|
||||
FilledButton(
|
||||
onPressed: _retryPermissions,
|
||||
child: const Text('Open Settings'),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextButton(
|
||||
onPressed: _navigateToRestaurantSelect,
|
||||
style: TextButton.styleFrom(foregroundColor: Colors.white70),
|
||||
child: const Text('Skip and select manually'),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -339,10 +339,6 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
}
|
||||
|
||||
Future<void> _addToCart(MenuItem item, Set<int> selectedModifierIds) async {
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: _addToCart called for item ${item.name} (ItemID=${item.itemId})");
|
||||
print("DEBUG: Selected modifier IDs: $selectedModifierIds");
|
||||
|
||||
// Check if user is logged in - if not, navigate to login
|
||||
if (_userId == null) {
|
||||
final shouldLogin = await showDialog<bool>(
|
||||
|
|
@ -388,8 +384,6 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
servicePointId: _servicePointId!,
|
||||
orderTypeId: 1, // Dine-in
|
||||
);
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Created cart with orderId=${cart.orderId}");
|
||||
appState.setCartOrder(
|
||||
orderId: cart.orderId,
|
||||
orderUuid: cart.orderUuid,
|
||||
|
|
@ -398,13 +392,8 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
} else {
|
||||
// We have an existing cart ID
|
||||
cart = await Api.getCart(orderId: appState.cartOrderId!);
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Loaded existing cart with orderId=${cart.orderId}");
|
||||
}
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: About to add root item ${item.itemId} to cart ${cart.orderId}");
|
||||
|
||||
// Check if this item already exists in the cart (as a root item)
|
||||
final existingItem = cart.lineItems.where(
|
||||
(li) => li.itemId == item.itemId && li.parentOrderLineItemId == 0 && !li.isDeleted
|
||||
|
|
@ -412,9 +401,6 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
|
||||
final newQuantity = (existingItem?.quantity ?? 0) + 1;
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Existing quantity: ${existingItem?.quantity ?? 0}, new quantity: $newQuantity");
|
||||
|
||||
// Add root item (or update quantity if it exists)
|
||||
cart = await Api.setLineItem(
|
||||
orderId: cart.orderId,
|
||||
|
|
@ -424,22 +410,12 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
quantity: newQuantity,
|
||||
);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Added root item, cart now has ${cart.lineItems.length} line items");
|
||||
|
||||
// Find the OrderLineItemID of the root item we just added
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Looking for root item with ItemID=${item.itemId} in ${cart.lineItems.length} line items");
|
||||
print("DEBUG: Line items: ${cart.lineItems.map((li) => 'ID=${li.orderLineItemId}, ItemID=${li.itemId}, ParentID=${li.parentOrderLineItemId}').join(', ')}");
|
||||
|
||||
final rootLineItem = cart.lineItems.lastWhere(
|
||||
(li) => li.itemId == item.itemId && li.parentOrderLineItemId == 0 && !li.isDeleted,
|
||||
orElse: () => throw StateError('Root line item not found for ItemID=${item.itemId}'),
|
||||
);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Root item found - OrderLineItemID=${rootLineItem.orderLineItemId}");
|
||||
|
||||
// Add all selected modifiers recursively
|
||||
await _addModifiersRecursively(
|
||||
cart.orderId,
|
||||
|
|
@ -451,10 +427,6 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
// Refresh cart to get final state
|
||||
cart = await Api.getCart(orderId: cart.orderId);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Final cart state - itemCount=${cart.itemCount}, lineItems=${cart.lineItems.length}");
|
||||
print("DEBUG: Root items: ${cart.lineItems.where((li) => li.parentOrderLineItemId == 0 && !li.isDeleted).map((li) => 'ItemID=${li.itemId}, Qty=${li.quantity}, Deleted=${li.isDeleted}').join(', ')}");
|
||||
|
||||
appState.updateCartItemCount(cart.itemCount);
|
||||
|
||||
if (!mounted) return;
|
||||
|
|
@ -483,25 +455,14 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
) async {
|
||||
final children = _itemsByParent[parentItemId] ?? [];
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: _addModifiersRecursively called with ParentItemID=$parentItemId, ParentOrderLineItemID=$parentOrderLineItemId");
|
||||
print("DEBUG: Found ${children.length} children for ItemID=$parentItemId");
|
||||
print("DEBUG: Children ItemIDs: ${children.map((c) => c.itemId).join(', ')}");
|
||||
print("DEBUG: Selected ItemIDs: ${selectedItemIds.join(', ')}");
|
||||
|
||||
for (final child in children) {
|
||||
final isSelected = selectedItemIds.contains(child.itemId);
|
||||
|
||||
// Only add selected items to the cart
|
||||
if (!isSelected) {
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Skipping unselected child ItemID=${child.itemId} (${child.name})");
|
||||
continue;
|
||||
}
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Processing child ItemID=${child.itemId} (${child.name}), isSelected=$isSelected");
|
||||
|
||||
// Add this modifier with the correct parent OrderLineItemID
|
||||
final cart = await Api.setLineItem(
|
||||
orderId: orderId,
|
||||
|
|
@ -510,18 +471,12 @@ class _MenuBrowseScreenState extends State<MenuBrowseScreen> {
|
|||
isSelected: true,
|
||||
);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: setLineItem response: cart has ${cart.lineItems.length} line items");
|
||||
|
||||
// Find the OrderLineItemID of this modifier we just added
|
||||
final childLineItem = cart.lineItems.lastWhere(
|
||||
(li) => li.itemId == child.itemId && li.parentOrderLineItemId == parentOrderLineItemId && !li.isDeleted,
|
||||
orElse: () => throw StateError('Child line item not found for ItemID=${child.itemId}'),
|
||||
);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("DEBUG: Child modifier OrderLineItemID=${childLineItem.orderLineItemId}");
|
||||
|
||||
// Recursively add grandchildren
|
||||
await _addModifiersRecursively(
|
||||
orderId,
|
||||
|
|
|
|||
|
|
@ -104,13 +104,6 @@ class Api {
|
|||
final body = resp.body;
|
||||
final j = _tryDecodeJsonMap(body);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("API GET => $url");
|
||||
// ignore: avoid_print
|
||||
print("STATUS => ${resp.statusCode}");
|
||||
// ignore: avoid_print
|
||||
print("BODY => ${body.length > 2000 ? body.substring(0, 2000) : body}");
|
||||
|
||||
return ApiRawResponse(statusCode: resp.statusCode, rawBody: body, json: j);
|
||||
}
|
||||
|
||||
|
|
@ -129,15 +122,6 @@ class Api {
|
|||
final body = resp.body;
|
||||
final j = _tryDecodeJsonMap(body);
|
||||
|
||||
// ignore: avoid_print
|
||||
print("API POST => $url");
|
||||
// ignore: avoid_print
|
||||
print("BODY IN => ${jsonEncode(payload)}");
|
||||
// ignore: avoid_print
|
||||
print("STATUS => ${resp.statusCode}");
|
||||
// ignore: avoid_print
|
||||
print("BODY OUT => ${body.length > 2000 ? body.substring(0, 2000) : body}");
|
||||
|
||||
return ApiRawResponse(statusCode: resp.statusCode, rawBody: body, json: j);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue