From 1defa889dc28539c2b0bf6bbf47fa3c0dd011763 Mon Sep 17 00:00:00 2001 From: Jonas Franz Date: Thu, 24 Feb 2022 02:15:54 +0100 Subject: [PATCH] Add remaining providers --- lib/screens/cart/cart_screen.dart | 20 +++----- lib/screens/cart/total_price_text.dart | 9 ++-- lib/screens/product_list/cart_button.dart | 9 ++-- lib/screens/product_list/product_item.dart | 17 +++++-- lib/stores/cart_store.dart | 53 ++++++++++++++++++++++ lib/stores/product_list_provider.dart | 2 +- 6 files changed, 87 insertions(+), 23 deletions(-) create mode 100644 lib/stores/cart_store.dart diff --git a/lib/screens/cart/cart_screen.dart b/lib/screens/cart/cart_screen.dart index e369485..747bce2 100644 --- a/lib/screens/cart/cart_screen.dart +++ b/lib/screens/cart/cart_screen.dart @@ -1,22 +1,16 @@ import 'package:flutter/material.dart'; -import 'package:thesis_shop/models/cart_item.dart'; -import 'package:thesis_shop/models/product.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:thesis_shop/screens/cart/total_price_text.dart'; +import 'package:thesis_shop/stores/cart_store.dart'; import 'package:thesis_shop/widgets/user_switch.dart'; import 'cart_item_list.dart'; -const _placeHolderItems = [ - CartItem(product: Product(title: 'Äpfel', price: 3), amount: 3), - CartItem(product: Product(title: 'Äpfel', price: 3), amount: 3), - CartItem(product: Product(title: 'Äpfel', price: 3), amount: 3), -]; - -class CartScreen extends StatelessWidget { +class CartScreen extends ConsumerWidget { const CartScreen({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, ref) { return Scaffold( appBar: AppBar( title: const Text('Warenkorb'), @@ -24,9 +18,9 @@ class CartScreen extends StatelessWidget { ), body: Column( mainAxisSize: MainAxisSize.max, - children: const [ - Expanded(child: CartItemList(items: _placeHolderItems)), - TotalPriceText(), + children: [ + Expanded(child: CartItemList(items: ref.watch(cartItemListProvider))), + const TotalPriceText(), ], ), ); diff --git a/lib/screens/cart/total_price_text.dart b/lib/screens/cart/total_price_text.dart index a08b1e6..f724815 100644 --- a/lib/screens/cart/total_price_text.dart +++ b/lib/screens/cart/total_price_text.dart @@ -1,15 +1,18 @@ import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:thesis_shop/stores/cart_store.dart'; -class TotalPriceText extends StatelessWidget { +class TotalPriceText extends ConsumerWidget { const TotalPriceText({Key? key}) : super(key: key); @override - Widget build(BuildContext context) { + Widget build(BuildContext context, ref) { + final totalPrice = ref.watch(totalPriceProvider).toStringAsFixed(2); return SafeArea( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( - 'Gesamtpreis: 27€', + 'Gesamtpreis: $totalPrice€', style: Theme.of(context).textTheme.labelLarge?.copyWith(fontSize: 24), ), ), diff --git a/lib/screens/product_list/cart_button.dart b/lib/screens/product_list/cart_button.dart index 5256e5e..17b31c4 100644 --- a/lib/screens/product_list/cart_button.dart +++ b/lib/screens/product_list/cart_button.dart @@ -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)'), ); } } diff --git a/lib/screens/product_list/product_item.dart b/lib/screens/product_list/product_item.dart index 62e813d..f7359c6 100644 --- a/lib/screens/product_list/product_item.dart +++ b/lib/screens/product_list/product_item.dart @@ -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), + ), ); } } diff --git a/lib/stores/cart_store.dart b/lib/stores/cart_store.dart new file mode 100644 index 0000000..becf5c2 --- /dev/null +++ b/lib/stores/cart_store.dart @@ -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> { + 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( + 0.0, + (previousValue, element) => + previousValue + element.amount * element.product.price), + dependencies: [cartItemListProvider]); + +final cartStoreProvider = + StateNotifierProvider>((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 []; + return cart.entries + .where((entry) => productsByTitle.containsKey(entry.key)) + .map((entry) => + CartItem(product: productsByTitle[entry.key]!, amount: entry.value)) + .toList(); +}, dependencies: [cartStoreProvider, productListProvider]); diff --git a/lib/stores/product_list_provider.dart b/lib/stores/product_list_provider.dart index efbaafa..361481f 100644 --- a/lib/stores/product_list_provider.dart +++ b/lib/stores/product_list_provider.dart @@ -10,4 +10,4 @@ final productListProvider = Provider>>((ref) { } return ref.watch(productLoadingProvider).whenData( (products) => products.map((pro) => pro.copyWithDiscount()).toList()); -}); +}, dependencies: [productLoadingProvider, userStoreProvider]);