create order

This commit is contained in:
Phuoc Nguyen
2025-11-21 16:50:43 +07:00
parent f2f95849d4
commit 4913a4e04b
31 changed files with 1696 additions and 187 deletions

View File

@@ -0,0 +1,280 @@
/// Order Success Page
///
/// Displays order confirmation after successful order placement.
/// Features:
/// - Success icon and message
/// - Order information (order number, date, total, payment method, status)
/// - Different message for negotiation requests
/// - Navigation to order details or home
library;
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:go_router/go_router.dart';
import 'package:intl/intl.dart';
import 'package:worker/core/constants/ui_constants.dart';
import 'package:worker/core/router/app_router.dart';
import 'package:worker/core/theme/colors.dart';
/// Order Success Page
class OrderSuccessPage extends StatelessWidget {
const OrderSuccessPage({
super.key,
required this.orderNumber,
this.total,
this.paymentMethod,
this.isNegotiation = false,
});
final String orderNumber;
final double? total;
final String? paymentMethod;
final bool isNegotiation;
@override
Widget build(BuildContext context) {
final now = DateTime.now();
final dateFormat = DateFormat('dd/MM/yyyy HH:mm');
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(AppSpacing.lg),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Success Icon
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: AppColors.success.withValues(alpha: 0.1),
shape: BoxShape.circle,
),
child: const Icon(
FontAwesomeIcons.check,
color: AppColors.success,
size: 40,
),
),
const SizedBox(height: AppSpacing.lg),
// Success Title
Text(
isNegotiation
? 'Gửi yêu cầu thành công!'
: 'Tạo đơn hàng thành công!',
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: Color(0xFF212121),
),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.sm),
// Success Message
Text(
isNegotiation
? 'Chúng tôi sẽ liên hệ với bạn để đàm phán giá trong vòng 24 giờ.'
: 'Cảm ơn bạn đã đặt hàng. Chúng tôi sẽ liên hệ xác nhận trong vòng 24 giờ.',
style: const TextStyle(
fontSize: 14,
color: AppColors.grey500,
),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.xl),
// Order Info Card
Container(
width: double.infinity,
padding: const EdgeInsets.all(AppSpacing.md),
decoration: BoxDecoration(
color: const Color(0xFFF4F6F8),
borderRadius: BorderRadius.circular(AppRadius.card),
),
child: Column(
children: [
// Order Number
Column(
children: [
const Text(
'Mã đơn hàng',
style: TextStyle(
fontSize: 12,
color: AppColors.grey500,
),
),
const SizedBox(height: 4),
Text(
orderNumber,
style: const TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: AppColors.primaryBlue,
),
),
],
),
const SizedBox(height: AppSpacing.md),
// Order Date
_buildInfoRow(
'Ngày đặt',
dateFormat.format(now),
),
const SizedBox(height: AppSpacing.sm),
// Total Amount
if (total != null)
_buildInfoRow(
'Tổng tiền',
_formatCurrency(total!),
valueStyle: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Color(0xFF212121),
),
),
if (total != null) const SizedBox(height: AppSpacing.sm),
// Payment Method
if (paymentMethod != null && !isNegotiation)
_buildInfoRow(
'Phương thức thanh toán',
paymentMethod!,
),
if (paymentMethod != null && !isNegotiation)
const SizedBox(height: AppSpacing.sm),
// Status
_buildInfoRow(
'Trạng thái',
isNegotiation ? 'Chờ đàm phán' : 'Chờ xác nhận',
valueStyle: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: isNegotiation
? AppColors.warning
: AppColors.warning,
),
),
],
),
),
const SizedBox(height: AppSpacing.xl),
// View Order Details Button
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: () {
// Navigate to order details page
context.pushReplacementNamed(
RouteNames.orderDetail,
pathParameters: {'orderId': orderNumber},
);
},
icon: const FaIcon(FontAwesomeIcons.eye, size: 18),
label: const Text(
'Xem chi tiết đơn hàng',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.primaryBlue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.button),
),
),
),
),
const SizedBox(height: AppSpacing.sm),
// Back to Home Button
SizedBox(
width: double.infinity,
child: OutlinedButton.icon(
onPressed: () {
// Navigate to home page
context.goNamed(RouteNames.home);
},
icon: const FaIcon(FontAwesomeIcons.house, size: 18),
label: const Text(
'Quay về trang chủ',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
style: OutlinedButton.styleFrom(
foregroundColor: AppColors.grey900,
side: BorderSide(
color: AppColors.grey100,
width: 1.5,
),
padding: const EdgeInsets.symmetric(vertical: 16),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.button),
),
),
),
),
],
),
),
),
),
);
}
/// Build info row
Widget _buildInfoRow(
String label,
String value, {
TextStyle? valueStyle,
}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
label,
style: const TextStyle(
fontSize: 14,
color: AppColors.grey500,
),
),
Text(
value,
style: valueStyle ??
const TextStyle(
fontSize: 14,
color: Color(0xFF212121),
),
),
],
);
}
/// Format currency
String _formatCurrency(double amount) {
return '${amount.toStringAsFixed(0).replaceAllMapped(RegExp(r'(\d)(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.')}';
}
}