/// Checkout Submit Button Widget /// /// Place order or send negotiation request button. library; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:worker/core/constants/ui_constants.dart'; import 'package:worker/core/router/app_router.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/account/domain/entities/address.dart'; import 'package:worker/features/orders/presentation/providers/order_repository_provider.dart'; /// Checkout Submit Button /// /// Button that changes based on negotiation checkbox state. class CheckoutSubmitButton extends HookConsumerWidget { const CheckoutSubmitButton({ super.key, required this.formKey, required this.ignorePricingRule, required this.contractRequest, required this.needsInvoice, required this.selectedAddress, required this.paymentMethod, required this.total, required this.cartItems, this.notes, }); final GlobalKey formKey; final bool ignorePricingRule; final bool contractRequest; final bool needsInvoice; final Address? selectedAddress; final String paymentMethod; final double total; final List> cartItems; final String? notes; @override Widget build(BuildContext context, WidgetRef ref) { final colorScheme = Theme.of(context).colorScheme; return Container( width: double.infinity, padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md), child: ElevatedButton( onPressed: () { // Validate address is selected if (selectedAddress == null) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Vui lòng chọn địa chỉ giao hàng'), backgroundColor: AppColors.danger, duration: Duration(seconds: 2), ), ); return; } if (formKey.currentState?.validate() ?? false) { _handlePlaceOrder(context, ref); } }, style: ElevatedButton.styleFrom( backgroundColor: ignorePricingRule ? AppColors.warning : colorScheme.primary, foregroundColor: colorScheme.surface, padding: const EdgeInsets.symmetric(vertical: 16), elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppRadius.button), ), ), child: Text( ignorePricingRule ? 'Gửi yêu cầu đàm phán' : 'Đặt hàng', style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ); } /// Handle place order Future _handlePlaceOrder(BuildContext context, WidgetRef ref) async { // Show loading indicator showDialog( context: context, barrierDismissible: false, builder: (context) => const Center( child: CircularProgressIndicator(), ), ); try { // Prepare delivery address data final deliveryAddressData = { 'name': selectedAddress!.name, 'phone': selectedAddress!.phone, 'street': selectedAddress!.addressLine1, 'ward': selectedAddress!.wardName ?? selectedAddress!.wardCode, 'city': selectedAddress!.cityName ?? selectedAddress!.cityCode, }; // Prepare items data for API // quantity = boxes/pieces (viên), quantityConverted = m² // price = quantityConverted * basePrice final itemsData = cartItems.map((item) { return { 'item_id': item['sku'] as String, 'quantity': item['quantity'] as double, 'quantityConverted': item['quantityConverted'] as double, 'price': (item['quantityConverted'] as double) * (item['price'] as double), }; }).toList(); // Call create order API final result = await ref.read(createOrderProvider( items: itemsData, deliveryAddress: deliveryAddressData, paymentMethod: paymentMethod, needsInvoice: needsInvoice, ignorePricingRule: ignorePricingRule, contractRequest: contractRequest, notes: notes, ).future); // Extract order number from response final orderNumber = result['orderNumber'] as String? ?? result['orderId'] as String? ?? 'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}'; if (ignorePricingRule) { // Navigate to order success page with negotiation flag if (context.mounted) { Navigator.of(context).pop(); context.pushReplacementNamed( RouteNames.orderSuccess, queryParameters: { 'orderNumber': orderNumber, 'total': total.toString(), 'isNegotiation': 'true', }, ); } } else { // Close loading dialog if (context.mounted) { Navigator.of(context).pop(); } // Navigate to payment QR page (it will fetch QR code data itself) if (context.mounted) { context.pushReplacementNamed( RouteNames.paymentQr, queryParameters: { 'orderId': orderNumber, 'amount': total.toString(), }, ); } } } catch (e) { // Close loading dialog if (context.mounted) { Navigator.of(context).pop(); } // Show error message if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Lỗi khi tạo đơn hàng: ${e.toString()}'), backgroundColor: AppColors.danger, duration: const Duration(seconds: 3), ), ); } } } }