320 lines
8.8 KiB
Markdown
320 lines
8.8 KiB
Markdown
# Cart Feature Update Summary
|
|
|
|
## Overview
|
|
Updated the cart feature to match the new HTML design with selection checkboxes, sticky footer, and conversion quantity display.
|
|
|
|
## Files Modified
|
|
|
|
### 1. Cart State (`lib/features/cart/presentation/providers/cart_state.dart`)
|
|
|
|
**Changes:**
|
|
- Added `quantityConverted` (double) and `boxes` (int) fields to `CartItemData`
|
|
- Updated `lineTotal` calculation to use `quantityConverted` instead of `quantity`
|
|
- Added `selectedItems` map (productId -> isSelected) to `CartState`
|
|
- Added getters:
|
|
- `selectedCount` - Number of selected items
|
|
- `isAllSelected` - Check if all items are selected
|
|
- `selectedTotal` - Total price of selected items only
|
|
|
|
**Impact:**
|
|
- Cart items now track both user-entered quantity and converted (rounded-up) quantity
|
|
- Supports per-item selection for deletion and checkout
|
|
|
|
---
|
|
|
|
### 2. Cart Provider (`lib/features/cart/presentation/providers/cart_provider.dart`)
|
|
|
|
**New Methods:**
|
|
- `_calculateConversion(quantity)` - Simulates 8% markup for rounding up tiles
|
|
- Returns `(convertedQuantity, boxes)` tuple
|
|
- `toggleSelection(productId)` - Toggle single item selection
|
|
- `toggleSelectAll()` - Select/deselect all items
|
|
- `deleteSelected()` - Remove all selected items from cart
|
|
|
|
**Updated Methods:**
|
|
- `addToCart()` - Auto-selects new items, calculates conversion
|
|
- `removeFromCart()` - Also removes from selection map
|
|
- `updateQuantity()` - Recalculates conversion on quantity change
|
|
- `_recalculateTotal()` - Only includes selected items in total calculation
|
|
|
|
**Key Logic:**
|
|
```dart
|
|
// Conversion calculation (simulated)
|
|
final converted = (quantity * 1.008 * 100).ceilToDouble() / 100;
|
|
final boxes = (quantity * 2.8).ceil();
|
|
```
|
|
|
|
---
|
|
|
|
### 3. Cart Item Widget (`lib/features/cart/presentation/widgets/cart_item_widget.dart`)
|
|
|
|
**New Features:**
|
|
- Checkbox on left side (20x20px, 6px radius)
|
|
- Checkbox aligned 34px from top to match HTML design
|
|
- Converted quantity display below quantity controls:
|
|
```
|
|
(Quy đổi: 10.08 m² = 28 viên)
|
|
```
|
|
|
|
**Layout:**
|
|
```
|
|
[Checkbox] [Image 80x80] [Product Info]
|
|
├─ Name
|
|
├─ Price/unit
|
|
├─ Quantity Controls (-, value, +, unit)
|
|
└─ Conversion Display
|
|
```
|
|
|
|
---
|
|
|
|
### 4. Cart Page (`lib/features/cart/presentation/pages/cart_page.dart`)
|
|
|
|
**Major Changes:**
|
|
|
|
#### Removed:
|
|
- Warehouse selection (moved to checkout as per HTML)
|
|
- Discount code section (moved to checkout)
|
|
- Order summary breakdown
|
|
|
|
#### Added:
|
|
- **Select All Section** (line 114-167)
|
|
- Checkbox + "Chọn tất cả" label
|
|
- "Đã chọn: X/Y" count display
|
|
|
|
- **Sticky Footer** (line 170-288)
|
|
- Delete button (48x48, red border, disabled when no selection)
|
|
- Total info: "Tổng tạm tính (X sản phẩm)" + amount
|
|
- Checkout button (disabled when no selection)
|
|
|
|
- **AppBar Changes:**
|
|
- Title shows total items: "Giỏ hàng (3)"
|
|
- Right action: Select all checkbox icon button
|
|
|
|
**Layout:**
|
|
```
|
|
Stack:
|
|
├─ ScrollView
|
|
│ ├─ Select All Section
|
|
│ └─ Cart Items (with checkboxes)
|
|
└─ Sticky Footer (Positioned at bottom)
|
|
└─ [Delete] [Total Info] [Checkout Button]
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Payment Method Section (`lib/features/cart/presentation/widgets/payment_method_section.dart`)
|
|
|
|
**Updated Options:**
|
|
1. **Full Payment** (value: `'full_payment'`)
|
|
- Icon: `Icons.account_balance_outlined`
|
|
- Label: "Thanh toán hoàn toàn"
|
|
- Description: "Thanh toán qua tài khoản ngân hàng"
|
|
|
|
2. **Partial Payment** (value: `'partial_payment'`)
|
|
- Icon: `Icons.payments_outlined`
|
|
- Label: "Thanh toán một phần"
|
|
- Description: "Trả trước(≥20%), còn lại thanh toán trong vòng 30 ngày"
|
|
|
|
**Removed:**
|
|
- COD option (Cash on Delivery)
|
|
|
|
---
|
|
|
|
### 6. Order Summary Section (`lib/features/cart/presentation/widgets/order_summary_section.dart`)
|
|
|
|
**Updated Item Display:**
|
|
- **Line 1:** Product name (14px, medium weight)
|
|
- **Line 2:** Conversion details (13px, muted)
|
|
```
|
|
20 m² (56 viên / 20.16 m²)
|
|
```
|
|
|
|
**Updated Discount:**
|
|
- Changed from generic "Giảm giá (5%)" to "Giảm giá Diamond"
|
|
- Color changed to `AppColors.success` (green)
|
|
|
|
**Price Calculation:**
|
|
- Now uses `quantityConverted` for accurate billing
|
|
- Mock implementation: `price * quantityConverted`
|
|
|
|
---
|
|
|
|
### 7. Checkout Page (`lib/features/cart/presentation/pages/checkout_page.dart`)
|
|
|
|
**Minor Changes:**
|
|
- Default payment method changed from `'bank_transfer'` to `'full_payment'`
|
|
|
|
---
|
|
|
|
## Mock Data Structure
|
|
|
|
### Updated CartItemData
|
|
```dart
|
|
CartItemData(
|
|
product: Product(...),
|
|
quantity: 10.0, // User-entered quantity
|
|
quantityConverted: 10.08, // Rounded-up for billing
|
|
boxes: 28, // Number of tiles/boxes
|
|
)
|
|
```
|
|
|
|
### Cart State
|
|
```dart
|
|
CartState(
|
|
items: [CartItemData(...)],
|
|
selectedItems: {
|
|
'product-1': true,
|
|
'product-2': false,
|
|
'product-3': true,
|
|
},
|
|
selectedWarehouse: 'Kho Hà Nội - Nguyễn Trãi',
|
|
memberTier: 'Diamond',
|
|
memberDiscountPercent: 15.0,
|
|
subtotal: 17107200.0, // Only selected items
|
|
total: 14541120.0, // After discount
|
|
...
|
|
)
|
|
```
|
|
|
|
---
|
|
|
|
## Design Alignment with HTML
|
|
|
|
### cart.html (lines 24-176)
|
|
✅ Select all section with checkbox and count
|
|
✅ Cart items with checkboxes on left
|
|
✅ Converted quantity display: "(Quy đổi: X.XX m² = Y viên)"
|
|
✅ Sticky footer with delete button
|
|
✅ Total calculated for selected items only
|
|
✅ Checkout button disabled when no selection
|
|
❌ Warehouse selection removed (commented out in HTML)
|
|
|
|
### checkout.html (lines 115-138, 154-196)
|
|
✅ Two payment options (full/partial)
|
|
✅ Order summary with conversion on line 2
|
|
✅ Member tier discount shown inline
|
|
✅ Shipping shown as "Miễn phí" when 0
|
|
|
|
---
|
|
|
|
## Key Features Implemented
|
|
|
|
1. **Item Selection System**
|
|
- Per-item checkboxes
|
|
- Select all functionality
|
|
- Selection count display
|
|
- Only selected items included in total
|
|
|
|
2. **Conversion Tracking**
|
|
- User-entered quantity (e.g., 10 m²)
|
|
- Converted quantity (e.g., 10.08 m²) for billing
|
|
- Box/tile count (e.g., 28 viên)
|
|
- Displayed in cart and checkout
|
|
|
|
3. **Sticky Footer**
|
|
- Fixed at bottom with shadow
|
|
- Delete button for selected items
|
|
- Total for selected items
|
|
- Checkout button
|
|
|
|
4. **Updated Payment Methods**
|
|
- Full payment via bank
|
|
- Partial payment (≥20%, 30 days)
|
|
- Removed COD option
|
|
|
|
5. **Accurate Pricing**
|
|
- Calculations use `quantityConverted`
|
|
- Member tier discount (Diamond 15%)
|
|
- Free shipping display
|
|
|
|
---
|
|
|
|
## Testing Notes
|
|
|
|
### Manual Test Scenarios:
|
|
|
|
1. **Selection**
|
|
- [ ] Add 3 items to cart
|
|
- [ ] Toggle individual checkboxes
|
|
- [ ] Use "Select All" button in AppBar
|
|
- [ ] Use "Chọn tất cả" in select all section
|
|
- [ ] Verify count: "Đã chọn: X/Y"
|
|
|
|
2. **Deletion**
|
|
- [ ] Select 2 items
|
|
- [ ] Click delete button
|
|
- [ ] Confirm deletion
|
|
- [ ] Verify items removed and total updated
|
|
|
|
3. **Conversion Display**
|
|
- [ ] Add item with quantity 10
|
|
- [ ] Verify conversion shows: "(Quy đổi: 10.08 m² = 28 viên)"
|
|
- [ ] Change quantity to 15
|
|
- [ ] Verify conversion updates
|
|
|
|
4. **Checkout Flow**
|
|
- [ ] Select items
|
|
- [ ] Click "Tiến hành đặt hàng"
|
|
- [ ] Verify checkout page shows conversion details
|
|
- [ ] Check payment method options (2 radios)
|
|
- [ ] Verify Diamond discount shown
|
|
|
|
5. **Empty States**
|
|
- [ ] Delete all items
|
|
- [ ] Verify empty cart message
|
|
- [ ] Select 0 items
|
|
- [ ] Verify checkout button disabled
|
|
- [ ] Verify delete button disabled
|
|
|
|
---
|
|
|
|
## Migration Notes
|
|
|
|
### Breaking Changes:
|
|
- `CartItemData` constructor now requires `quantityConverted` and `boxes`
|
|
- Existing cart data will need migration
|
|
- Any code reading cart items must handle new fields
|
|
|
|
### Backward Compatibility:
|
|
- Old cart items won't have conversion data
|
|
- Consider adding migration in cart provider initialization
|
|
- Default conversion: `quantityConverted = quantity * 1.01`, `boxes = 0`
|
|
|
|
### TODO for Production:
|
|
1. Replace mock conversion calculation with backend API
|
|
2. Get conversion rate from product specifications (tile size)
|
|
3. Persist selection state in Hive (optional)
|
|
4. Add loading states for delete operation
|
|
5. Implement undo for accidental deletions
|
|
6. Add analytics for selection patterns
|
|
|
|
---
|
|
|
|
## Performance Considerations
|
|
|
|
- Selection state stored in Map for O(1) lookups
|
|
- Total recalculated on every selection change
|
|
- Consider debouncing if performance issues arise
|
|
- Sticky footer uses Stack/Positioned for smooth scroll
|
|
|
|
---
|
|
|
|
## Accessibility
|
|
|
|
- All checkboxes have proper touch targets (22x22 minimum)
|
|
- Delete button has tooltip
|
|
- Disabled states have visual feedback (opacity)
|
|
- Selection count announced for screen readers
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. Test on physical devices
|
|
2. Verify conversion calculations with business team
|
|
3. Update API integration for conversion data
|
|
4. Add unit tests for selection logic
|
|
5. Add widget tests for cart page
|
|
6. Consider adding animation for item deletion
|
|
|