add auth, format

This commit is contained in:
Phuoc Nguyen
2025-11-07 11:52:06 +07:00
parent 24a8508fce
commit 3803bd26e0
173 changed files with 8505 additions and 7116 deletions

View File

@@ -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),
),
);
}

View File

@@ -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,
),
],
),
),

View File

@@ -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) {

View File

@@ -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()},
);
}
});

View File

@@ -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;
},

View File

@@ -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;

View File

@@ -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]}.')}';
}
}

View File

@@ -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,
),
),
],
),

View File

@@ -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) {