create order
This commit is contained in:
@@ -5,16 +5,18 @@ 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 StatelessWidget {
|
||||
class CheckoutSubmitButton extends HookConsumerWidget {
|
||||
const CheckoutSubmitButton({
|
||||
super.key,
|
||||
required this.formKey,
|
||||
@@ -23,6 +25,8 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
required this.selectedAddress,
|
||||
required this.paymentMethod,
|
||||
required this.total,
|
||||
required this.cartItems,
|
||||
this.notes,
|
||||
});
|
||||
|
||||
final GlobalKey<FormState> formKey;
|
||||
@@ -31,9 +35,11 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
final Address? selectedAddress;
|
||||
final String paymentMethod;
|
||||
final double total;
|
||||
final List<Map<String, dynamic>> cartItems;
|
||||
final String? notes;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
|
||||
@@ -52,7 +58,7 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
if (formKey.currentState?.validate() ?? false) {
|
||||
_handlePlaceOrder(context);
|
||||
_handlePlaceOrder(context, ref);
|
||||
}
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
@@ -78,48 +84,98 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Handle place order
|
||||
void _handlePlaceOrder(BuildContext context) {
|
||||
// TODO: Implement actual order placement with backend
|
||||
Future<void> _handlePlaceOrder(BuildContext context, WidgetRef ref) async {
|
||||
// Show loading indicator
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
|
||||
if (needsNegotiation) {
|
||||
// Show negotiation request sent message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Yêu cầu đàm phán giá đã được gửi!'),
|
||||
backgroundColor: AppColors.success,
|
||||
duration: Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
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,
|
||||
};
|
||||
|
||||
// Navigate back after a short delay
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
// 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,
|
||||
needsNegotiation: needsNegotiation,
|
||||
notes: notes,
|
||||
).future);
|
||||
|
||||
// Close loading dialog
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
// Extract order number from response
|
||||
final orderNumber = result['orderNumber'] as String? ??
|
||||
result['orderId'] as String? ??
|
||||
'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
||||
|
||||
if (needsNegotiation) {
|
||||
// Navigate to order success page with negotiation flag
|
||||
if (context.mounted) {
|
||||
context.pop();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Generate order ID (mock - replace with actual from backend)
|
||||
final orderId =
|
||||
'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
||||
|
||||
// Show order success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text('Đặt hàng thành công! Chuyển đến thanh toán...'),
|
||||
backgroundColor: AppColors.success,
|
||||
duration: Duration(seconds: 1),
|
||||
),
|
||||
);
|
||||
|
||||
// Navigate to payment QR page after a short delay
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (context.mounted) {
|
||||
context.pushNamed(
|
||||
RouteNames.paymentQr,
|
||||
queryParameters: {'orderId': orderId, 'amount': total.toString()},
|
||||
context.pushReplacementNamed(
|
||||
RouteNames.orderSuccess,
|
||||
queryParameters: {
|
||||
'orderNumber': orderNumber,
|
||||
'total': total.toString(),
|
||||
'isNegotiation': 'true',
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// Navigate to payment QR page
|
||||
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),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user