add auth, format
This commit is contained in:
@@ -22,10 +22,7 @@ import 'package:worker/features/cart/presentation/providers/cart_state.dart';
|
||||
class CartItemWidget extends ConsumerWidget {
|
||||
final CartItemData item;
|
||||
|
||||
const CartItemWidget({
|
||||
super.key,
|
||||
required this.item,
|
||||
});
|
||||
const CartItemWidget({super.key, required this.item});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -65,9 +62,7 @@ class CartItemWidget extends ConsumerWidget {
|
||||
height: 80,
|
||||
color: AppColors.grey100,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
),
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
),
|
||||
errorWidget: (context, url, error) => Container(
|
||||
@@ -129,9 +124,9 @@ class CartItemWidget extends ConsumerWidget {
|
||||
_QuantityButton(
|
||||
icon: Icons.remove,
|
||||
onPressed: () {
|
||||
ref.read(cartProvider.notifier).decrementQuantity(
|
||||
item.product.productId,
|
||||
);
|
||||
ref
|
||||
.read(cartProvider.notifier)
|
||||
.decrementQuantity(item.product.productId);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -151,9 +146,9 @@ class CartItemWidget extends ConsumerWidget {
|
||||
_QuantityButton(
|
||||
icon: Icons.add,
|
||||
onPressed: () {
|
||||
ref.read(cartProvider.notifier).incrementQuantity(
|
||||
item.product.productId,
|
||||
);
|
||||
ref
|
||||
.read(cartProvider.notifier)
|
||||
.incrementQuantity(item.product.productId);
|
||||
},
|
||||
),
|
||||
|
||||
@@ -184,10 +179,7 @@ class _QuantityButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
final VoidCallback onPressed;
|
||||
|
||||
const _QuantityButton({
|
||||
required this.icon,
|
||||
required this.onPressed,
|
||||
});
|
||||
const _QuantityButton({required this.icon, required this.onPressed});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -201,11 +193,7 @@ class _QuantityButton extends StatelessWidget {
|
||||
color: AppColors.grey100,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 18,
|
||||
color: AppColors.grey900,
|
||||
),
|
||||
child: Icon(icon, size: 18, color: AppColors.grey900),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -68,8 +68,11 @@ class CheckoutDatePickerField extends HookWidget {
|
||||
: AppColors.grey500.withValues(alpha: 0.6),
|
||||
),
|
||||
),
|
||||
const Icon(Icons.calendar_today,
|
||||
size: 20, color: AppColors.grey500),
|
||||
const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 20,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -75,10 +75,7 @@ class CheckoutDropdownField extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
items: items.map((item) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: item,
|
||||
child: Text(item),
|
||||
);
|
||||
return DropdownMenuItem<String>(value: item, child: Text(item));
|
||||
}).toList(),
|
||||
onChanged: onChanged,
|
||||
validator: (value) {
|
||||
|
||||
@@ -114,7 +114,8 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
});
|
||||
} else {
|
||||
// Generate order ID (mock - replace with actual from backend)
|
||||
final orderId = 'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
||||
final orderId =
|
||||
'DH${DateTime.now().millisecondsSinceEpoch.toString().substring(7)}';
|
||||
|
||||
// Show order success message
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -130,10 +131,7 @@ class CheckoutSubmitButton extends StatelessWidget {
|
||||
if (context.mounted) {
|
||||
context.pushNamed(
|
||||
RouteNames.paymentQr,
|
||||
queryParameters: {
|
||||
'orderId': orderId,
|
||||
'amount': total.toString(),
|
||||
},
|
||||
queryParameters: {'orderId': orderId, 'amount': total.toString()},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -103,13 +103,7 @@ class DeliveryInformationSection extends HookWidget {
|
||||
label: 'Tỉnh/Thành phố',
|
||||
value: selectedProvince.value,
|
||||
required: true,
|
||||
items: const [
|
||||
'TP.HCM',
|
||||
'Hà Nội',
|
||||
'Đà Nẵng',
|
||||
'Cần Thơ',
|
||||
'Biên Hòa',
|
||||
],
|
||||
items: const ['TP.HCM', 'Hà Nội', 'Đà Nẵng', 'Cần Thơ', 'Biên Hòa'],
|
||||
onChanged: (value) {
|
||||
selectedProvince.value = value;
|
||||
},
|
||||
|
||||
@@ -132,8 +132,9 @@ class InvoiceSection extends HookWidget {
|
||||
return 'Vui lòng nhập email';
|
||||
}
|
||||
if (needsInvoice.value &&
|
||||
!RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$')
|
||||
.hasMatch(value!)) {
|
||||
!RegExp(
|
||||
r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$',
|
||||
).hasMatch(value!)) {
|
||||
return 'Email không hợp lệ';
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -148,8 +148,10 @@ class OrderSummarySection extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
'Mã: ${item['sku']}',
|
||||
style:
|
||||
const TextStyle(fontSize: 12, color: AppColors.grey500),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -168,8 +170,9 @@ class OrderSummarySection extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
_formatCurrency(
|
||||
((item['price'] as int) * (item['quantity'] as int))
|
||||
.toDouble()),
|
||||
((item['price'] as int) * (item['quantity'] as int))
|
||||
.toDouble(),
|
||||
),
|
||||
style: const TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
@@ -184,8 +187,11 @@ class OrderSummarySection extends StatelessWidget {
|
||||
}
|
||||
|
||||
/// Build summary row
|
||||
Widget _buildSummaryRow(String label, double amount,
|
||||
{bool isDiscount = false}) {
|
||||
Widget _buildSummaryRow(
|
||||
String label,
|
||||
double amount, {
|
||||
bool isDiscount = false,
|
||||
}) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@@ -207,9 +213,6 @@ class OrderSummarySection extends StatelessWidget {
|
||||
|
||||
/// Format currency
|
||||
String _formatCurrency(double amount) {
|
||||
return '${amount.toStringAsFixed(0).replaceAllMapped(
|
||||
RegExp(r'(\d)(?=(\d{3})+(?!\d))'),
|
||||
(Match m) => '${m[1]}.',
|
||||
)}₫';
|
||||
return '${amount.toStringAsFixed(0).replaceAllMapped(RegExp(r'(\d)(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]}.')}₫';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,10 +14,7 @@ import 'package:worker/core/theme/colors.dart';
|
||||
class PaymentMethodSection extends HookWidget {
|
||||
final ValueNotifier<String> paymentMethod;
|
||||
|
||||
const PaymentMethodSection({
|
||||
super.key,
|
||||
required this.paymentMethod,
|
||||
});
|
||||
const PaymentMethodSection({super.key, required this.paymentMethod});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -72,13 +69,17 @@ class PaymentMethodSection extends HookWidget {
|
||||
Text(
|
||||
'Chuyển khoản ngân hàng',
|
||||
style: TextStyle(
|
||||
fontSize: 15, fontWeight: FontWeight.w500),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Thanh toán qua chuyển khoản',
|
||||
style:
|
||||
TextStyle(fontSize: 13, color: AppColors.grey500),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -112,13 +113,17 @@ class PaymentMethodSection extends HookWidget {
|
||||
Text(
|
||||
'Thanh toán khi nhận hàng (COD)',
|
||||
style: TextStyle(
|
||||
fontSize: 15, fontWeight: FontWeight.w500),
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
'Thanh toán bằng tiền mặt khi nhận hàng',
|
||||
style:
|
||||
TextStyle(fontSize: 13, color: AppColors.grey500),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: AppColors.grey500,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -14,10 +14,7 @@ import 'package:worker/core/theme/colors.dart';
|
||||
class PriceNegotiationSection extends HookWidget {
|
||||
final ValueNotifier<bool> needsNegotiation;
|
||||
|
||||
const PriceNegotiationSection({
|
||||
super.key,
|
||||
required this.needsNegotiation,
|
||||
});
|
||||
const PriceNegotiationSection({super.key, required this.needsNegotiation});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Reference in New Issue
Block a user