326 lines
10 KiB
Dart
326 lines
10 KiB
Dart
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../generated/l10n.dart';
|
|
import '../../models/business.dart';
|
|
import '../../models/cart_info.dart';
|
|
import '../../models/cart_line_item.dart';
|
|
import '../../routes.dart';
|
|
import '../../store/actions.dart';
|
|
import '../../store/store.dart';
|
|
import '../../utils/utils.dart';
|
|
import '../../widgets/general/add_remove_button.dart';
|
|
import '../../widgets/general/style.dart';
|
|
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
|
|
|
typedef OnEmptyCartListener();
|
|
typedef OnPanelOpenCloseRequest();
|
|
|
|
class ShoppingCartBar extends StatefulWidget {
|
|
final GlobalKey endKey;
|
|
final Business business;
|
|
final OnEmptyCartListener onEmptyCartListener;
|
|
final OnPanelOpenCloseRequest onPanelOpenCloseRequest;
|
|
final bool barAtBottom;
|
|
final bool hasPicture;
|
|
ShoppingCartBar({@required this.business, this.endKey,
|
|
this.onEmptyCartListener, this.onPanelOpenCloseRequest,
|
|
this.barAtBottom = false, this.hasPicture = false
|
|
});
|
|
|
|
@override
|
|
State<StatefulWidget> createState() {
|
|
return new ShoppingCartBarState();
|
|
}
|
|
}
|
|
|
|
class ShoppingCartBarState extends State<ShoppingCartBar> {
|
|
CartInfo cartInfo;
|
|
double totalPrice = 0.0;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
totalPrice = 0.0;
|
|
cartInfo = Utils.getCartInfoByBusiness(store.state.cartInfos, widget.business);
|
|
if (cartInfo != null && cartInfo.businessInfo.id == widget.business.id) {
|
|
totalPrice = cartInfo.getTotalPrice();
|
|
}
|
|
|
|
Widget cartContent;
|
|
|
|
if (cartInfo == null || (cartInfo.businessInfo.id != widget.business.id)
|
|
|| (totalPrice == 0.0 && cartInfo.productList.length == 0)) {
|
|
cartContent = Center(
|
|
child: Container(
|
|
padding: EdgeInsets.all(20.0),
|
|
child: Text(S.of(context).your_basket_is_empty),
|
|
),
|
|
);
|
|
} else {
|
|
cartContent = Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[],
|
|
);
|
|
(cartContent as Column).children.add(
|
|
GestureDetector(
|
|
child: Container(
|
|
padding: EdgeInsets.only(top: 12.0, left: 10.0, bottom: 12.0),
|
|
color: Colors.transparent,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[
|
|
Icon(Icons.delete,
|
|
size: 14.0,
|
|
color: Colors.black38,
|
|
),
|
|
Text(
|
|
S.of(context).empty_basket,
|
|
style: TextStyle(
|
|
fontSize: 13.0,
|
|
color: Colors.black38
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
onTap: () {
|
|
Utils.clearCart(context, cartInfo, onComplete: (_) {
|
|
if (widget.onEmptyCartListener != null) {
|
|
widget.onEmptyCartListener();
|
|
}
|
|
});
|
|
},
|
|
),
|
|
);
|
|
for (var i = 0; i < cartInfo.productList.length; i++) {
|
|
(cartContent as Column).children.add(cartLineItem(cartInfo.productList[i], i));
|
|
}
|
|
}
|
|
|
|
Stack stack = Stack(
|
|
clipBehavior: Clip.hardEdge,
|
|
children: <Widget>[
|
|
Container(
|
|
width: double.maxFinite,
|
|
height: 50.0,
|
|
child: Row(
|
|
children: <Widget>[
|
|
new Expanded(
|
|
flex: 2,
|
|
child: Container(
|
|
padding: new EdgeInsets.symmetric(vertical: 5).copyWith(left: 80.0),
|
|
color: new Color(0xFF3D3D3F),
|
|
child: new Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: <Widget>[
|
|
new Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
new Text(
|
|
'\$',
|
|
style: new TextStyle(
|
|
fontSize: 12.0,
|
|
color: Style.backgroundColor
|
|
),
|
|
),
|
|
new Text(
|
|
'${totalPrice.toStringAsFixed(2)}',
|
|
style: new TextStyle(
|
|
fontSize: 22.0,
|
|
color: Style.backgroundColor
|
|
),
|
|
),
|
|
],
|
|
),
|
|
new Text(
|
|
S.of(context).delivery_fee(widget.business.shippingFee.toStringAsFixed(2)),
|
|
style: new TextStyle(
|
|
fontSize: 9.0,
|
|
color: Style.backgroundColor,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
)
|
|
),
|
|
new Expanded(
|
|
flex: 1,
|
|
child: GestureDetector(
|
|
child: Container(
|
|
padding: EdgeInsets.all(10.0),
|
|
color: widget.business.minPrice - totalPrice >= 0 ? new Color(0xFF535356) : Colors.lightGreen,
|
|
child: Center(
|
|
child: Text(
|
|
widget.business.minPrice - totalPrice >= 0 ? S.of(context).order_more((widget.business.minPrice - totalPrice).toStringAsFixed(2)) : S.of(context).checkout,
|
|
style: TextStyle(
|
|
fontSize: 14.0,
|
|
color: Style.backgroundColor,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
onTap: widget.business.minPrice >= totalPrice ? null : () {
|
|
if (store.state.user != null) {
|
|
Routes.router.navigateTo(context, '/checkout/${widget.business.id}');
|
|
} else {
|
|
store.dispatch(UpdateRedirectRoute('/checkout/${widget.business.id}'));
|
|
Routes.router.navigateTo(context, '/login');
|
|
}
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Positioned(
|
|
top: -10.0,
|
|
left: 20.0,
|
|
child: GestureDetector(
|
|
child: Container(
|
|
padding: new EdgeInsets.all(5.0),
|
|
decoration: new BoxDecoration(
|
|
color: new Color(0xFF3D3D3F),
|
|
shape: BoxShape.circle,
|
|
border: new Border.all(
|
|
color: new Color(0xFF3D3D3F),
|
|
width: 5.0,
|
|
)
|
|
),
|
|
child: Center(
|
|
child: Icon(
|
|
Icons.shopping_basket,
|
|
key: widget.endKey,
|
|
color: totalPrice > 0 ? Colors.orange : new Color(0xFF656565),
|
|
size: 36.0,
|
|
),
|
|
),
|
|
),
|
|
onTap: () {
|
|
if (widget.onPanelOpenCloseRequest != null) {
|
|
widget.onPanelOpenCloseRequest();
|
|
}
|
|
},
|
|
),
|
|
),
|
|
],
|
|
);
|
|
|
|
List<Widget> widgets = [];
|
|
if (widget.barAtBottom) {
|
|
widgets.add(Container(
|
|
width: double.maxFinite,
|
|
height: 200.0,
|
|
child: SingleChildScrollView(
|
|
child: cartContent,
|
|
),
|
|
));
|
|
widgets.add(stack);
|
|
} else {
|
|
widgets.add(stack);
|
|
widgets.add(Container(
|
|
width: double.maxFinite,
|
|
height: 200.0,
|
|
child: SingleChildScrollView(
|
|
child: cartContent,
|
|
),
|
|
));
|
|
}
|
|
|
|
return Material(
|
|
type: MaterialType.transparency,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: widgets,
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget cartLineItem(CartLineItem item, int pidx) {
|
|
Widget lineItem = Container(
|
|
padding: EdgeInsets.only(top: 10.0),
|
|
height: 78.0,
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
bottom: new BorderSide(
|
|
color: new Color(0xFFEBEBEB),
|
|
),
|
|
),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
widget.hasPicture ? Container(
|
|
padding: EdgeInsets.all(6.0),
|
|
child: Util.showImage(
|
|
'${item.product.imagePath}',
|
|
width: 80,
|
|
height: 80,
|
|
fit: BoxFit.cover,
|
|
),
|
|
) : SizedBox.shrink(),
|
|
Expanded(
|
|
child: Container(
|
|
padding: EdgeInsets.only(left: 10.0, right: 10.0),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
Container(
|
|
child: Text(
|
|
item.name,
|
|
maxLines: 1,
|
|
style: TextStyle(
|
|
color: Colors.black87,
|
|
fontSize: 14.0
|
|
),
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
Container(
|
|
child: Text(
|
|
item.description,
|
|
style: TextStyle(
|
|
color: Colors.black38,
|
|
fontSize: 10.0
|
|
),
|
|
maxLines: 3,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: <Widget>[
|
|
Container(
|
|
child: Text(
|
|
'${item.totalPrice.toStringAsFixed(2)}',
|
|
style: TextStyle(
|
|
color: Colors.redAccent,
|
|
fontSize: 14.0,
|
|
),
|
|
),
|
|
),
|
|
Container(
|
|
padding: EdgeInsets.only(right: 10.0),
|
|
child: AddRemoveButton(
|
|
product: item.product,
|
|
business: widget.business,
|
|
cartLineItemIndex: pidx,
|
|
),
|
|
)
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
return lineItem;
|
|
}
|
|
} |