fix checkout/cart

This commit is contained in:
Phuoc Nguyen
2025-11-20 10:44:51 +07:00
parent 0708ed7d6f
commit 1fcef52d5e
7 changed files with 271 additions and 100 deletions

View File

@@ -34,61 +34,45 @@ class CheckoutSubmitButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
return Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(horizontal: AppSpacing.md),
child: Column(
children: [
// Terms Agreement Text
const Text(
'Bằng việc đặt hàng, bạn đồng ý với các điều khoản và điều kiện của chúng tôi',
style: TextStyle(fontSize: 12, color: AppColors.grey500),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.md),
// Place Order / Send Negotiation Button
SizedBox(
width: double.infinity,
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);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: needsNegotiation
? AppColors.warning
: AppColors.primaryBlue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.button),
),
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),
),
child: Text(
needsNegotiation ? 'Gửi yêu cầu đàm phán' : 'Đặt hàng',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
);
return;
}
if (formKey.currentState?.validate() ?? false) {
_handlePlaceOrder(context);
}
},
style: ElevatedButton.styleFrom(
backgroundColor: needsNegotiation
? AppColors.warning
: AppColors.primaryBlue,
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 16),
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppRadius.button),
),
],
),
child: Text(
needsNegotiation ? 'Gửi yêu cầu đàm phán' : 'Đặt hàng',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
);
}

View File

@@ -105,11 +105,11 @@ class OrderSummarySection extends StatelessWidget {
/// Build cart item with conversion details on two lines
Widget _buildCartItemWithConversion(Map<String, dynamic> item) {
// Mock conversion data (in real app, this comes from CartItemData)
final quantity = item['quantity'] as int;
final quantityM2 = quantity.toDouble(); // User input
final quantityConverted = (quantityM2 * 1.008 * 100).ceil() / 100; // Rounded up
final boxes = (quantityM2 * 2.8).ceil(); // Tiles count
// Get real conversion data from CartItemData
final quantity = item['quantity'] as double;
final quantityConverted = item['quantityConverted'] as double;
final boxes = item['boxes'] as int;
final price = item['price'] as double;
return Padding(
padding: const EdgeInsets.only(bottom: 12),
@@ -136,7 +136,7 @@ class OrderSummarySection extends StatelessWidget {
const SizedBox(height: 4),
// Line 2: Conversion details (muted text)
Text(
'$quantityM2 m² ($boxes viên / ${quantityConverted.toStringAsFixed(2)} m²)',
'${quantity.toStringAsFixed(2)} m² ($boxes viên / ${quantityConverted.toStringAsFixed(2)} m²)',
style: const TextStyle(
fontSize: 13,
color: AppColors.grey500,
@@ -148,11 +148,9 @@ class OrderSummarySection extends StatelessWidget {
const SizedBox(width: 12),
// Price (right side)
// Price (right side) - using converted quantity for accurate billing
Text(
_formatCurrency(
((item['price'] as int) * quantityConverted).toDouble(),
),
_formatCurrency(price * quantityConverted),
style: const TextStyle(
fontSize: 14,
fontWeight: FontWeight.w600,

View File

@@ -12,9 +12,9 @@ import 'package:worker/core/theme/colors.dart';
///
/// Allows user to request price negotiation instead of direct order.
class PriceNegotiationSection extends HookWidget {
final ValueNotifier<bool> needsNegotiation;
const PriceNegotiationSection({super.key, required this.needsNegotiation});
final ValueNotifier<bool> needsNegotiation;
@override
Widget build(BuildContext context) {