-
Notifications
You must be signed in to change notification settings - Fork 0
analytics events #80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
analytics events #80
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| import 'package:cloud_firestore/cloud_firestore.dart'; | ||
| import 'package:firebase_auth/firebase_auth.dart'; | ||
|
|
||
| class AnalyticsLogger { | ||
| const AnalyticsLogger._(); | ||
|
|
||
| static Future<void> logEvent({ | ||
| required String eventName, | ||
| Map<String, dynamic>? additionalData, | ||
| int? milliseconds, | ||
| bool? authenticated, | ||
| }) async { | ||
| try { | ||
| await FirebaseFirestore.instance.collection('logs').add(<String, dynamic>{ | ||
| 'eventName': eventName, | ||
| 'timestamp': FieldValue.serverTimestamp(), | ||
| 'userId': await _getCurrentUserId(), | ||
| if (milliseconds != null) 'milliseconds': milliseconds, | ||
| if (authenticated != null) 'authenticated': authenticated, | ||
| if (additionalData != null) ...additionalData, | ||
| }); | ||
| } catch (e) { | ||
| // Silently fail if logging fails | ||
| } | ||
|
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance error handling for analytics failures The current implementation silently fails, which could mask critical issues. Consider logging errors to a monitoring service or debug console to help identify and resolve integration problems. } catch (e) {
- // Silently fail if logging fails
+ debugPrint('Analytics logging failed: $e');
+ // Consider reporting to error monitoring service
}
|
||
| } | ||
|
|
||
| static Future<String?> _getCurrentUserId() async { | ||
| try { | ||
| final String? userId = FirebaseAuth.instance.currentUser?.uid; | ||
| return userId; | ||
| } catch (e) { | ||
| return null; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,5 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/blocs/resettable_mixin.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/analytics_logger.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/cart/domain/models/cart_item_data.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/cart/presentation/bloc/cart_event.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/cart/presentation/bloc/cart_state.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -18,21 +19,19 @@ class CartBloc extends Bloc<CartEvent, CartState> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on<CartItemQuantityChanged>(_onCartItemQuantityChanged); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on<CartItemRemoved>(_onCartItemRemoved); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on<ClearCart>(_onClearCart); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on<CompletePurchase>(_onCompletePurchase); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on<PurchaseCartEvent>(_onPurchaseCart); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final OrderBloc orderBloc; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _onClearCart(ClearCart event, Emitter<CartState> emit) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CartState(items: <CartItemData>[]), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); // Set items to an empty list | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _onCompletePurchase(CompletePurchase event, Emitter<CartState> emit) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Here you could add logic to process the purchase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // For now, it clears the cart to simulate a completed purchase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'clear_cart', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_count': state.items.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'total_amount': state.subtotal, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit(const CartState(items: <CartItemData>[])); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -45,23 +44,30 @@ class CartBloc extends Bloc<CartEvent, CartState> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| existingItem = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final List<CartItemData> updatedItems = <CartItemData>[...state.items]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (existingItem != null) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final List<CartItemData> updatedItems = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state.items.map((CartItemData item) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (item.id == event.item.id) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return item.copyWith(quantity: item.quantity + event.item.quantity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return item; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }).toList(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit(CartState(items: updatedItems)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final int index = updatedItems.indexOf(existingItem); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updatedItems[index] = existingItem.copyWith( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| quantity: existingItem.quantity + 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final List<CartItemData> updatedItems = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<CartItemData>.from(state.items)..add(event.item); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit(CartState(items: updatedItems)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| updatedItems.add(event.item); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'add_to_cart', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_id': event.item.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_name': event.item.title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'business_id': event.item.businessId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'price': event.item.offerPrice, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'is_new_item': existingItem == null, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit(CartState(items: updatedItems)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Existing handlers (no changes needed for these) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _onCartItemQuantityChanged( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CartItemQuantityChanged event, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Emitter<CartState> emit, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -73,10 +79,36 @@ class CartBloc extends Bloc<CartEvent, CartState> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return item; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }).toList(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'update_cart_quantity', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_id': event.itemId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'new_quantity': event.quantity, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'previous_quantity': state.items | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .firstWhere((CartItemData item) => item.id == event.itemId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .quantity, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| emit(CartState(items: updatedItems)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _onCartItemRemoved(CartItemRemoved event, Emitter<CartState> emit) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final CartItemData removedItem = | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state.items.firstWhere((CartItemData item) => item.id == event.itemId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'remove_from_cart', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_id': event.itemId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_name': removedItem.title, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'business_id': removedItem.businessId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'quantity': removedItem.quantity, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'price': removedItem.offerPrice, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+98
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add null safety for removed item analytics. The - final CartItemData removedItem =
- state.items.firstWhere((CartItemData item) => item.id == event.itemId);
+ final CartItemData? removedItem =
+ state.items.firstWhereOrNull((CartItemData item) => item.id == event.itemId);
+
+ if (removedItem != null) {
+ AnalyticsLogger.logEvent(
+ eventName: 'remove_from_cart',
+ additionalData: <String, dynamic>{
+ 'item_id': event.itemId,
+ 'item_name': removedItem.title,
+ 'business_id': removedItem.businessId,
+ 'quantity': removedItem.quantity,
+ 'price': removedItem.offerPrice,
+ },
+ );
+ }📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final List<CartItemData> updatedItems = state.items | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .where((CartItemData item) => item.id != event.itemId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .toList(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -118,6 +150,15 @@ class CartBloc extends Bloc<CartEvent, CartState> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createdAt: DateTime.now(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'create_order', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'business_id': order.businessId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'item_count': order.items.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'total_amount': order.totalAmount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| orderBloc.add(CreateOrderEvent(order: order)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Clear cart after successful purchase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,6 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'dart:async'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/analytics_logger.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/analytics_service.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/distance.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/address/domain/entities/address.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -114,6 +116,13 @@ class _HomeScreenContentState extends State<HomeScreenContent> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _handleTabSelection() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (_tabController.indexIsChanging) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| context.read<HomeBloc>().add(TabChanged(_tabController.index)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'tab_change', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'tab': _getTabName(_tabController.index), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'previous_tab': _getTabName(_tabController.previousIndex), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -341,4 +350,17 @@ class _HomeScreenContentState extends State<HomeScreenContent> | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| String _getTabName(int index) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final List<String> tabNames = <String>[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'for_you', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'dietary', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'restaurant', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'ingredients', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'store', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'diary', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'drink', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return tabNames[index]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+354
to
+365
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance robustness and maintainability of tab name mapping The current implementation has several potential issues:
Consider this more robust implementation: - String _getTabName(int index) {
- final List<String> tabNames = <String>[
- 'for_you',
- 'dietary',
- 'restaurant',
- 'ingredients',
- 'store',
- 'diary',
- 'drink',
- ];
- return tabNames[index];
- }
+ String _getTabName(int index) {
+ // Define tab names as static const to ensure consistency
+ static const Map<int, String> tabNames = <int, String>{
+ 0: 'for_you',
+ 1: 'dietary',
+ 2: 'restaurant',
+ 3: 'ingredients',
+ 4: 'store',
+ 5: 'diary',
+ 6: 'drink',
+ };
+
+ // Validate index and return a default value if invalid
+ if (!tabNames.containsKey(index)) {
+ debugPrint('Invalid tab index: $index');
+ return 'unknown';
+ }
+
+ return tabNames[index]!;
+ }This implementation:
📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,8 +1,13 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/ui/widgets/custom_appbar.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/analytics_logger.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/core/utils/date_utils.dart' as date_utils; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/orders/data/models/order_model.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/orders/domain/entities/order.dart' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| as order_entity; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/orders/presentation/bloc/order_bloc.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:eco_bites/features/orders/presentation/bloc/order_event.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:flutter/material.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import 'package:flutter_bloc/flutter_bloc.dart'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class OrderDetailsScreen extends StatelessWidget { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const OrderDetailsScreen({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -12,6 +17,44 @@ class OrderDetailsScreen extends StatelessWidget { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final order_entity.Order order; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _handleOrderAgain(BuildContext context) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create a new order with the same items | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final OrderModel newOrder = OrderModel( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: '', // ID will be generated by Firestore | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| businessId: order.businessId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| businessName: order.businessName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| items: order.items, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| totalAmount: order.totalAmount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status: order_entity.OrderStatus.pending, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| createdAt: DateTime.now(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Log the Order Again feature usage | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AnalyticsLogger.logEvent( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| eventName: 'order_again', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| additionalData: <String, dynamic>{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'businessId': order.businessId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'originalOrderId': order.id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'itemCount': order.items.length, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'totalAmount': order.totalAmount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Dispatch create order event | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| context.read<OrderBloc>().add(CreateOrderEvent(order: newOrder)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Show a snackbar to indicate the order is being processed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ScaffoldMessenger.of(context).showSnackBar( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SnackBar( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| content: Text('Creating new order...'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| duration: Duration(seconds: 2), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Navigate back to the orders list | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Navigator.of(context).pop(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+20
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for Order Again feature. The void _handleOrderAgain(BuildContext context) {
+ try {
final OrderModel newOrder = OrderModel(
id: '', // ID will be generated by Firestore
businessId: order.businessId,
businessName: order.businessName,
items: order.items,
totalAmount: order.totalAmount,
status: order_entity.OrderStatus.pending,
createdAt: DateTime.now(),
);
AnalyticsLogger.logEvent(
eventName: 'order_again',
additionalData: <String, dynamic>{
'businessId': order.businessId,
'originalOrderId': order.id,
'itemCount': order.items.length,
'totalAmount': order.totalAmount,
},
);
context.read<OrderBloc>().add(CreateOrderEvent(order: newOrder));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Creating new order...'),
duration: Duration(seconds: 2),
),
);
Navigator.of(context).pop();
+ } catch (e) {
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('Failed to create order: $e'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ }
}📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Widget build(BuildContext context) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| final ThemeData theme = Theme.of(context); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -104,6 +147,19 @@ class OrderDetailsScreen extends StatelessWidget { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| color: theme.textTheme.bodyMedium?.color?.withOpacity(0.7), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const SizedBox(height: 32), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Order Again Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ElevatedButton( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onPressed: () => _handleOrderAgain(context), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style: ElevatedButton.styleFrom( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| padding: const EdgeInsets.symmetric(vertical: 16), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shape: RoundedRectangleBorder( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| borderRadius: BorderRadius.circular(16), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| child: const Text('Order Again'), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add error boundary for analytics logging
Navigation should continue even if analytics logging fails. Consider wrapping the logging call in a try-catch block.
📝 Committable suggestion