parent
1a53d7b583
commit
1defa889dc
@ -1,17 +1,20 @@ |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_riverpod/flutter_riverpod.dart'; |
||||
import 'package:thesis_shop/benchmark_counter.dart'; |
||||
import 'package:thesis_shop/route_key.dart'; |
||||
import 'package:thesis_shop/stores/cart_store.dart'; |
||||
|
||||
class CartButton extends StatelessWidget { |
||||
class CartButton extends ConsumerWidget { |
||||
const CartButton() : super(key: const Key('cart_button')); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
Widget build(BuildContext context, ref) { |
||||
final count = ref.watch(totalProductInCartCountProvider); |
||||
BenchmarkCounters.cartButton++; |
||||
return ElevatedButton.icon( |
||||
onPressed: () => Navigator.of(context).pushRouteKey(RouteKey.cart), |
||||
icon: const Icon(Icons.shopping_basket), |
||||
label: const Text('Warenkorb (3 Produkte)'), |
||||
label: Text('Warenkorb ($count Produkte)'), |
||||
); |
||||
} |
||||
} |
||||
|
@ -1,16 +1,27 @@ |
||||
import 'package:flutter/material.dart'; |
||||
import 'package:flutter_riverpod/flutter_riverpod.dart'; |
||||
import 'package:thesis_shop/models/product.dart'; |
||||
import 'package:thesis_shop/stores/cart_store.dart'; |
||||
import 'package:thesis_shop/widgets/number_picker.dart'; |
||||
|
||||
class ProductItem extends StatelessWidget { |
||||
class ProductItem extends ConsumerWidget { |
||||
final Product product; |
||||
const ProductItem({Key? key, required this.product}) : super(key: key); |
||||
|
||||
@override |
||||
Widget build(BuildContext context) { |
||||
Widget build(BuildContext context, ref) { |
||||
final count = ref.watch(cartStoreProvider)[product.title] ?? 0; |
||||
return ListTile( |
||||
title: Text('${product.title} (${product.priceAsString}€/Stück)'), |
||||
trailing: NumberPicker(value: 5, onUp: () {}, onDown: () {}), |
||||
trailing: NumberPicker( |
||||
value: count, |
||||
onUp: () => ref |
||||
.read(cartStoreProvider.notifier) |
||||
.increaseAmountOfProduct(product), |
||||
onDown: () => ref |
||||
.read(cartStoreProvider.notifier) |
||||
.decreaseAmountOfProduct(product), |
||||
), |
||||
); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,53 @@ |
||||
import 'package:riverpod/riverpod.dart'; |
||||
import 'package:thesis_shop/models/cart_item.dart'; |
||||
import 'package:thesis_shop/models/product.dart'; |
||||
import 'package:thesis_shop/stores/product_list_provider.dart'; |
||||
|
||||
class CartStore extends StateNotifier<Map<String, int>> { |
||||
CartStore() : super({}); |
||||
|
||||
void _addAmountOfProduct(Product product, int amount) { |
||||
final value = state[product.title] ?? 0; |
||||
if (value + amount < 0) { |
||||
return; |
||||
} else if (value + amount == 0) { |
||||
state.remove(product.title); |
||||
state = {...state}; |
||||
return; |
||||
} |
||||
state = {...state, product.title: value + amount}; |
||||
} |
||||
|
||||
void increaseAmountOfProduct(Product product) => |
||||
_addAmountOfProduct(product, 1); |
||||
void decreaseAmountOfProduct(Product product) => |
||||
_addAmountOfProduct(product, -1); |
||||
} |
||||
|
||||
final totalProductInCartCountProvider = Provider( |
||||
(ref) => ref.watch(cartItemListProvider).length, |
||||
dependencies: [cartItemListProvider], |
||||
); |
||||
|
||||
final totalPriceProvider = Provider( |
||||
(ref) => ref.watch(cartItemListProvider).fold<double>( |
||||
0.0, |
||||
(previousValue, element) => |
||||
previousValue + element.amount * element.product.price), |
||||
dependencies: [cartItemListProvider]); |
||||
|
||||
final cartStoreProvider = |
||||
StateNotifierProvider<CartStore, Map<String, int>>((ref) => CartStore()); |
||||
|
||||
final cartItemListProvider = Provider((ref) { |
||||
final cart = ref.watch(cartStoreProvider); |
||||
final productsByTitle = ref.watch(productListProvider).whenOrNull( |
||||
data: (products) => |
||||
{for (final product in products) product.title: product}); |
||||
if (productsByTitle == null) return <CartItem>[]; |
||||
return cart.entries |
||||
.where((entry) => productsByTitle.containsKey(entry.key)) |
||||
.map((entry) => |
||||
CartItem(product: productsByTitle[entry.key]!, amount: entry.value)) |
||||
.toList(); |
||||
}, dependencies: [cartStoreProvider, productListProvider]); |
Loading…
Reference in new issue