Check for existing cart when selecting child business from beacon

When a user taps on a child business from the business selector (beacon flow),
now checks if they have an existing cart for that specific business before
proceeding. Shows "Existing Order Found" dialog with options to continue
or start fresh, matching the behavior from login flow.

Fixes bug where existing cart wasn't detected because we were clearing
cart state without checking the database first.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
John Mizerek 2026-01-26 10:37:41 -08:00
parent 821eae4170
commit 3e68a3282b

View file

@ -3,7 +3,9 @@ import "package:provider/provider.dart";
import "../app/app_router.dart";
import "../app/app_state.dart";
import "../models/cart.dart";
import "../services/api.dart";
import "../services/auth_storage.dart";
import "../widgets/rescan_button.dart";
class BusinessSelectorScreen extends StatefulWidget {
@ -172,7 +174,6 @@ class _BusinessSelectorScreenState extends State<BusinessSelectorScreen> {
}
Widget _buildHeaderBanner(BuildContext context, int? parentBusinessId, String parentName) {
const imageBaseUrl = _imageBaseUrl;
return SizedBox(
height: 200,
width: double.infinity,
@ -255,10 +256,94 @@ class _BusinessSelectorScreenState extends State<BusinessSelectorScreen> {
);
}
void _selectBusiness(BuildContext context, _BusinessItem business, int? parentBusinessId, String? parentBusinessName) {
void _selectBusiness(BuildContext context, _BusinessItem business, int? parentBusinessId, String? parentBusinessName) async {
// Check if user is logged in and has an existing cart for this business
final auth = await AuthStorage.loadAuth();
if (auth != null && auth.userId > 0) {
try {
final existingCart = await Api.getActiveCart(userId: auth.userId);
if (existingCart != null && existingCart.hasItems && existingCart.businessId == business.businessId) {
// Show existing cart dialog
if (!mounted) return;
_showExistingCartDialog(existingCart, business, parentBusinessId, parentBusinessName);
return;
}
} catch (e) {
// Ignore - proceed without cart check
}
}
if (!mounted) return;
_proceedToMenu(business, parentBusinessId, parentBusinessName);
}
void _showExistingCartDialog(ActiveCartInfo cart, _BusinessItem business, int? parentBusinessId, String? parentBusinessName) {
showDialog(
context: context,
barrierDismissible: false,
builder: (ctx) => AlertDialog(
title: const Text("Existing Order Found"),
content: Text(
"You have ${cart.itemCount} item${cart.itemCount == 1 ? '' : 's'} in your cart at ${cart.businessName}.\n\nWould you like to continue that order or start fresh?",
),
actions: [
TextButton(
onPressed: () async {
Navigator.of(ctx).pop();
// Abandon the old order and proceed with clean cart
try {
await Api.abandonOrder(orderId: cart.orderId);
} catch (e) {
// Ignore - proceed anyway
}
if (!mounted) return;
final appState = context.read<AppState>();
appState.clearCart();
_proceedToMenu(business, parentBusinessId, parentBusinessName);
},
child: const Text("Start Fresh"),
),
ElevatedButton(
onPressed: () {
Navigator.of(ctx).pop();
// Continue existing order - load cart and go to menu
if (!mounted) return;
final appState = context.read<AppState>();
appState.setBusinessAndServicePoint(
cart.businessId,
cart.servicePointId,
businessName: cart.businessName,
servicePointName: cart.servicePointName,
parentBusinessId: parentBusinessId,
parentBusinessName: parentBusinessName,
);
appState.setCartOrder(
orderId: cart.orderId,
orderUuid: cart.orderUuid,
itemCount: cart.itemCount,
);
appState.setOrderType(OrderType.dineIn);
Api.setBusinessId(cart.businessId);
Navigator.of(context).pushReplacementNamed(
AppRoutes.menuBrowse,
arguments: {
"businessId": cart.businessId,
"servicePointId": cart.servicePointId,
},
);
},
child: const Text("Continue Order"),
),
],
),
);
}
void _proceedToMenu(_BusinessItem business, int? parentBusinessId, String? parentBusinessName) {
final appState = context.read<AppState>();
// Clear any existing cart
// Clear any existing cart (for different business)
appState.clearCart();
// Set the selected business and service point (with parent info for back navigation)