Commit 327d974d authored by Hans Muller's avatar Hans Muller Committed by GitHub

Added shopping cart and sorting to Shrine (#4616)

parent 415324f2
......@@ -15,7 +15,8 @@ import 'shrine_types.dart';
const double unitSize = kToolBarHeight;
Map<Product, Order> shoppingCart = <Product, Order>{};
final List<Product> _products = new List<Product>.from(allProducts());
final Map<Product, Order> _shoppingCart = <Product, Order>{};
/// Displays the Vendor's name and avatar.
class VendorItem extends StatelessWidget {
......@@ -63,7 +64,7 @@ abstract class PriceItem extends StatelessWidget {
Widget buildItem(BuildContext context, TextStyle style, EdgeInsets padding) {
BoxDecoration decoration;
if (shoppingCart[product] != null)
if (_shoppingCart[product] != null)
decoration = new BoxDecoration(backgroundColor: const Color(0xFFFFE0E0));
return new Container(
......@@ -259,18 +260,16 @@ class ShrineHome extends StatefulWidget {
}
class _ShrineHomeState extends State<ShrineHome> {
final List<Product> _products = allProducts();
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: 'Order page');
void handleCompletedOrder(Order completedOrder) {
assert(completedOrder.product != null);
if (completedOrder.inCart && completedOrder.quantity > 0)
shoppingCart[completedOrder.product] = completedOrder;
else
shoppingCart[completedOrder.product] = null;
if (completedOrder.quantity == 0)
_shoppingCart.remove(completedOrder.product);
}
void showOrderPage(Product product) {
final Order order = shoppingCart[product] ?? new Order(product: product);
final Order order = _shoppingCart[product] ?? new Order(product: product);
final Completer<Order> completer = new Completer<Order>();
final Key productKey = new ObjectKey(product);
final Set<Key> mostValuableKeys = new HashSet<Key>();
......@@ -282,7 +281,8 @@ class _ShrineHomeState extends State<ShrineHome> {
builder: (BuildContext context) {
return new OrderPage(
order: order,
products: _products
products: _products,
shoppingCart: _shoppingCart
);
}
));
......@@ -293,6 +293,9 @@ class _ShrineHomeState extends State<ShrineHome> {
Widget build(BuildContext context) {
final Product featured = _products.firstWhere((Product product) => product.featureDescription != null);
return new ShrinePage(
scaffoldKey: scaffoldKey,
products: _products,
shoppingCart: _shoppingCart,
body: new ScrollableViewport(
child: new RepaintBoundary(
child: new Column(
......
......@@ -118,13 +118,15 @@ class OrderItem extends StatelessWidget {
}
class OrderPage extends StatefulWidget {
OrderPage({ Key key, this.order, this.products }) : super(key: key) {
OrderPage({ Key key, this.order, this.products, this.shoppingCart }) : super(key: key) {
assert(order != null);
assert(products != null && products.length > 0);
assert(shoppingCart != null);
}
final Order order;
final List<Product> products;
final Map<Product, Order> shoppingCart;
@override
_OrderPageState createState() => new _OrderPageState();
......@@ -134,7 +136,7 @@ class OrderPage extends StatefulWidget {
/// arranged in two columns. Enables the user to specify a quantity and add an
/// order to the shopping cart.
class _OrderPageState extends State<OrderPage> {
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: 'Order Page');
static final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>(debugLabel: 'Order page');
Order get currentOrder => ShrineOrderRoute.of(context).order;
......@@ -146,6 +148,7 @@ class _OrderPageState extends State<OrderPage> {
Order newOrder = currentOrder.copyWith(quantity: quantity, inCart: inCart);
if (currentOrder != newOrder) {
setState(() {
config.shoppingCart[newOrder.product] = newOrder;
currentOrder = newOrder;
});
}
......@@ -159,12 +162,15 @@ class _OrderPageState extends State<OrderPage> {
Widget build(BuildContext context) {
return new ShrinePage(
scaffoldKey: scaffoldKey,
products: config.products,
shoppingCart: config.shoppingCart,
floatingActionButton: new FloatingActionButton(
onPressed: () {
updateOrder(inCart: true);
final int n = currentOrder.quantity;
final String item = currentOrder.product.name;
showSnackBarMessage(
'There ${ n == 1 ? "is one item" : "are $n items" } in the shopping cart.'
'There ${ n == 1 ? "is one $item item" : "are $n $item items" } in the shopping cart.'
);
},
backgroundColor: const Color(0xFF16F0F0),
......
......@@ -5,6 +5,7 @@
import 'package:flutter/material.dart';
import 'shrine_theme.dart';
import 'shrine_types.dart';
enum ShrineAction {
sortByPrice,
......@@ -13,11 +14,23 @@ enum ShrineAction {
}
class ShrinePage extends StatefulWidget {
ShrinePage({ Key key, this.scaffoldKey, this.body, this.floatingActionButton }) : super(key: key);
ShrinePage({
Key key,
this.scaffoldKey,
this.body,
this.floatingActionButton,
this.products,
this.shoppingCart
}) : super(key: key) {
assert(body != null);
assert(scaffoldKey != null);
}
final Key scaffoldKey;
final GlobalKey<ScaffoldState> scaffoldKey;
final Widget body;
final Widget floatingActionButton;
final List<Product> products;
final Map<Product, Order> shoppingCart;
@override
ShrinePageState createState() => new ShrinePageState();
......@@ -37,6 +50,37 @@ class ShrinePageState extends State<ShrinePage> {
return false;
}
void _showShoppingCart() {
showModalBottomSheet/*<Null>*/(context: context, builder: (BuildContext context) {
if (config.shoppingCart.isEmpty) {
return new Padding(
padding: const EdgeInsets.all(24.0),
child: new Text('The shopping cart is empty')
);
}
return new MaterialList(children: config.shoppingCart.values.map((Order order) {
return new ListItem(
title: new Text(order.product.name),
leading: new Text('${order.quantity}'),
subtitle: new Text(order.product.vendor.name)
);
}).toList());
});
}
void _sortByPrice() {
config.products.sort((Product a, Product b) => a.price.compareTo(b.price));
}
void _sortByProduct() {
config.products.sort((Product a, Product b) => a.name.compareTo(b.name));
}
void _emptyCart() {
config.shoppingCart.clear();
config.scaffoldKey.currentState.showSnackBar(new SnackBar(content: new Text('Shopping cart is empty')));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
......@@ -59,7 +103,7 @@ class ShrinePageState extends State<ShrinePage> {
icon: Icons.shopping_cart,
tooltip: 'Shopping cart',
onPressed: () {
// TODO(hansmuller): implement the action.
_showShoppingCart();
}
),
new PopupMenuButton<ShrineAction>(
......@@ -80,13 +124,13 @@ class ShrinePageState extends State<ShrinePage> {
onSelected: (ShrineAction action) {
switch (action) {
case ShrineAction.sortByPrice:
// TODO(hansmuller): implement the action.
setState(_sortByPrice);
break;
case ShrineAction.sortByProduct:
// TODO(hansmuller): implement the action.
setState(_sortByProduct);
break;
case ShrineAction.emptyCart:
// TODO(hansmuller): implement the action.
setState(_emptyCart);
break;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment