add cart
This commit is contained in:
177
lib/features/cart/presentation/providers/cart_provider.dart
Normal file
177
lib/features/cart/presentation/providers/cart_provider.dart
Normal file
@@ -0,0 +1,177 @@
|
||||
/// Cart Provider
|
||||
///
|
||||
/// State management for shopping cart using Riverpod.
|
||||
library;
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:worker/features/cart/presentation/providers/cart_state.dart';
|
||||
import 'package:worker/features/products/domain/entities/product.dart';
|
||||
|
||||
part 'cart_provider.g.dart';
|
||||
|
||||
/// Cart Notifier
|
||||
///
|
||||
/// Manages cart state including:
|
||||
/// - Adding/removing items
|
||||
/// - Updating quantities
|
||||
/// - Warehouse selection
|
||||
/// - Discount code application
|
||||
/// - Cart summary calculations
|
||||
@riverpod
|
||||
class Cart extends _$Cart {
|
||||
@override
|
||||
CartState build() {
|
||||
final initialState = CartState.initial();
|
||||
// Initialize with Diamond tier discount (15%)
|
||||
// TODO: Get actual tier from user profile
|
||||
return initialState.copyWith(
|
||||
memberTier: 'Diamond',
|
||||
memberDiscountPercent: 15.0,
|
||||
);
|
||||
}
|
||||
|
||||
/// Add product to cart
|
||||
void addToCart(Product product, {double quantity = 1.0}) {
|
||||
final existingItemIndex = state.items.indexWhere(
|
||||
(item) => item.product.productId == product.productId,
|
||||
);
|
||||
|
||||
if (existingItemIndex >= 0) {
|
||||
// Update quantity if item already exists
|
||||
updateQuantity(
|
||||
product.productId,
|
||||
state.items[existingItemIndex].quantity + quantity,
|
||||
);
|
||||
} else {
|
||||
// Add new item
|
||||
final newItem = CartItemData(
|
||||
product: product,
|
||||
quantity: quantity,
|
||||
);
|
||||
|
||||
state = state.copyWith(
|
||||
items: [...state.items, newItem],
|
||||
);
|
||||
_recalculateTotal();
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove product from cart
|
||||
void removeFromCart(String productId) {
|
||||
state = state.copyWith(
|
||||
items: state.items.where((item) => item.product.productId != productId).toList(),
|
||||
);
|
||||
_recalculateTotal();
|
||||
}
|
||||
|
||||
/// Update item quantity
|
||||
void updateQuantity(String productId, double newQuantity) {
|
||||
if (newQuantity <= 0) {
|
||||
removeFromCart(productId);
|
||||
return;
|
||||
}
|
||||
|
||||
final updatedItems = state.items.map((item) {
|
||||
if (item.product.productId == productId) {
|
||||
return item.copyWith(quantity: newQuantity);
|
||||
}
|
||||
return item;
|
||||
}).toList();
|
||||
|
||||
state = state.copyWith(items: updatedItems);
|
||||
_recalculateTotal();
|
||||
}
|
||||
|
||||
/// Increment quantity
|
||||
void incrementQuantity(String productId) {
|
||||
final item = state.items.firstWhere(
|
||||
(item) => item.product.productId == productId,
|
||||
);
|
||||
updateQuantity(productId, item.quantity + 1);
|
||||
}
|
||||
|
||||
/// Decrement quantity
|
||||
void decrementQuantity(String productId) {
|
||||
final item = state.items.firstWhere(
|
||||
(item) => item.product.productId == productId,
|
||||
);
|
||||
updateQuantity(productId, item.quantity - 1);
|
||||
}
|
||||
|
||||
/// Clear entire cart
|
||||
void clearCart() {
|
||||
state = CartState.initial();
|
||||
}
|
||||
|
||||
/// Select warehouse
|
||||
void selectWarehouse(String warehouse) {
|
||||
state = state.copyWith(selectedWarehouse: warehouse);
|
||||
}
|
||||
|
||||
/// Apply discount code
|
||||
void applyDiscountCode(String code) {
|
||||
// TODO: Validate with backend
|
||||
// For now, simulate discount application
|
||||
if (code.isNotEmpty) {
|
||||
state = state.copyWith(
|
||||
discountCode: code,
|
||||
discountCodeApplied: true,
|
||||
);
|
||||
_recalculateTotal();
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove discount code
|
||||
void removeDiscountCode() {
|
||||
state = state.copyWith(
|
||||
discountCode: null,
|
||||
discountCodeApplied: false,
|
||||
);
|
||||
_recalculateTotal();
|
||||
}
|
||||
|
||||
/// Recalculate cart totals
|
||||
void _recalculateTotal() {
|
||||
// Calculate subtotal
|
||||
final subtotal = state.items.fold<double>(
|
||||
0.0,
|
||||
(sum, item) => sum + (item.product.basePrice * item.quantity),
|
||||
);
|
||||
|
||||
// Calculate member tier discount
|
||||
final memberDiscount = subtotal * (state.memberDiscountPercent / 100);
|
||||
|
||||
// Calculate shipping (free for now)
|
||||
const shippingFee = 0.0;
|
||||
|
||||
// Calculate total
|
||||
final total = subtotal - memberDiscount + shippingFee;
|
||||
|
||||
state = state.copyWith(
|
||||
subtotal: subtotal,
|
||||
memberDiscount: memberDiscount,
|
||||
shippingFee: shippingFee,
|
||||
total: total,
|
||||
);
|
||||
}
|
||||
|
||||
/// Get total quantity of all items
|
||||
double get totalQuantity {
|
||||
return state.items.fold<double>(
|
||||
0.0,
|
||||
(sum, item) => sum + item.quantity,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Cart item count provider
|
||||
@riverpod
|
||||
int cartItemCount(Ref ref) {
|
||||
return ref.watch(cartProvider).items.length;
|
||||
}
|
||||
|
||||
/// Cart total provider
|
||||
@riverpod
|
||||
double cartTotal(Ref ref) {
|
||||
return ref.watch(cartProvider).total;
|
||||
}
|
||||
Reference in New Issue
Block a user