287 lines
8.4 KiB
Dart
287 lines
8.4 KiB
Dart
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../events/eventbus.dart';
|
|
import '../../events/events.dart';
|
|
import '../../generated/l10n.dart';
|
|
import '../../models/business.dart';
|
|
import '../../models/product.dart';
|
|
import '../../models/product_attribute.dart';
|
|
import '../../store/actions.dart';
|
|
import '../../store/store.dart';
|
|
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
|
import '../../utils/utils.dart';
|
|
import '../../widgets/general/attribute/check_options.dart';
|
|
import '../../widgets/general/attribute/qty_options.dart';
|
|
import '../../widgets/general/attribute/radio_options.dart';
|
|
|
|
class MobileAttributeSelection extends StatefulWidget {
|
|
final Product product;
|
|
final Business business;
|
|
final Key key;
|
|
final GlobalKey startKey;
|
|
|
|
const MobileAttributeSelection({@required this.product, @required this.business, this.key, this.startKey})
|
|
: super(key: key);
|
|
|
|
@override
|
|
State<StatefulWidget> createState() {
|
|
return new MobileAttributeSelectionState();
|
|
}
|
|
|
|
}
|
|
|
|
class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
|
Product product;
|
|
int index;
|
|
FlatButton previousButton;
|
|
FlatButton nextButton;
|
|
bool previousButtonEnable;
|
|
bool nextButtonEnable;
|
|
|
|
String productDesc;
|
|
double productPrice;
|
|
|
|
String nextText;
|
|
String finishText;
|
|
|
|
Map<String, dynamic> selections = new Map();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
store.dispatch(UpdateContext(context));
|
|
|
|
return Scaffold(
|
|
appBar: AppBar(
|
|
leading: IconButton(
|
|
icon: Icon(Icons.arrow_back_ios),
|
|
onPressed: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
title: Text(S.of(context).select_options),
|
|
backgroundColor: Theme.of(context).primaryColor,
|
|
actions: [],
|
|
),
|
|
body: new Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
_getProductContent(),
|
|
Expanded(
|
|
child: _getOptionsView(),
|
|
),
|
|
],
|
|
),
|
|
bottomNavigationBar: new Container(
|
|
padding: new EdgeInsets.all(10.0),
|
|
color: new Color(0xFFA8A8A8),
|
|
child: new Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: <Widget>[
|
|
previousButton,
|
|
nextButton
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
setState(() {
|
|
index = 0;
|
|
product = widget.product;
|
|
previousButtonEnable = false;
|
|
nextButtonEnable = false;
|
|
productDesc = product.description;
|
|
productPrice = product.price;
|
|
});
|
|
|
|
eventBus.on<OnAttributeSelectionsChanged>().listen((event) {
|
|
this.selections = event.selections;
|
|
List<String> extendDescription = [];
|
|
double extendPrice = 0.0;
|
|
event.selections.forEach((key, value) {
|
|
List<String> opt = [];
|
|
for (var i = 0; i < (value as List).length; i++) {
|
|
if (value[i]['quantity'] == 0) {
|
|
extendPrice += value[i]['adjust_amount'];
|
|
opt.add(value[i]['name']);
|
|
} else {
|
|
extendPrice += value[i]['adjust_amount'] * value[i]['quantity'];
|
|
opt.add(value[i]['name'] + '*' + value[i]['quantity'].toString());
|
|
}
|
|
}
|
|
extendDescription.add(key + ': ' + opt.join(', '));
|
|
});
|
|
|
|
ProductAttribute pa = product.productAttributes[index];
|
|
if (pa.required && Utils.selectionsNotEmptyAt(selections, pa.name)) {
|
|
setState(() {
|
|
nextButtonEnable = true;
|
|
productDesc = product.description + ', ' + extendDescription.join('; ');
|
|
productPrice = product.price + extendPrice;
|
|
});
|
|
} else if (!pa.required){
|
|
setState(() {
|
|
nextButtonEnable = true;
|
|
productDesc = product.description + ', ' + extendDescription.join('; ');
|
|
productPrice = product.price + extendPrice;
|
|
});
|
|
} else {
|
|
setState(() {
|
|
nextButtonEnable = false;
|
|
productDesc = product.description + ', ' + extendDescription.join('; ');
|
|
productPrice = product.price + extendPrice;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
bool _checkCanGoNext() {
|
|
ProductAttribute pa = product.productAttributes[index];
|
|
if (pa.required && Utils.selectionsNotEmptyAt(selections, pa.name)) {
|
|
return true;
|
|
} else if (!pa.required){
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@override
|
|
void didChangeDependencies() {
|
|
super.didChangeDependencies();
|
|
nextText = S.of(context).next;
|
|
finishText = S.of(context).finish;
|
|
}
|
|
|
|
Widget _getProductContent() {
|
|
previousButton = new FlatButton(
|
|
onPressed: previousButtonEnable ? _goPrevious : null,
|
|
child: new Text(S.of(context).previous),
|
|
);
|
|
|
|
nextButton = new FlatButton(
|
|
onPressed: nextButtonEnable ? _goNext : null,
|
|
child: new Text(
|
|
product.productAttributes.length > index + 1 ? nextText : finishText
|
|
),
|
|
);
|
|
|
|
var productContent = new SizedBox(
|
|
child: new Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
new Container(
|
|
padding: new EdgeInsets.all(10.0),
|
|
width: 70.0,
|
|
height: 70.0,
|
|
child: Util.showImage(product.imagePath,
|
|
width: 70.0,
|
|
height: 70.0,
|
|
fit: BoxFit.fill,
|
|
),
|
|
),
|
|
new Expanded(
|
|
child: new Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
new Container(
|
|
padding: new EdgeInsets.all(10.0).copyWith(left: 0.0).copyWith(bottom: 0.0),
|
|
child: new Text(
|
|
product.name,
|
|
style: new TextStyle(
|
|
fontSize: 15.0,
|
|
),
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
new Container(
|
|
padding: new EdgeInsets.only(right: 10.0),
|
|
child: new Text(
|
|
productDesc,
|
|
style: new TextStyle(
|
|
fontSize: 9.0,
|
|
color: new Color(0xFFCDCDCD)
|
|
),
|
|
maxLines: 4,
|
|
softWrap: true,
|
|
overflow: TextOverflow.ellipsis,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
new Container(
|
|
padding: new EdgeInsets.all(10.0).copyWith(left: 0.0),
|
|
width: 70.0,
|
|
child:
|
|
new Text(
|
|
productPrice.toStringAsFixed(2),
|
|
textAlign: TextAlign.right,
|
|
style: new TextStyle(
|
|
fontSize: 18.0,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
return productContent;
|
|
}
|
|
|
|
Widget _getOptionsView() {
|
|
Widget optionsView;
|
|
|
|
ProductAttribute productAttribute = product.productAttributes[index];
|
|
if (productAttribute.byQuantity) {
|
|
optionsView = new QtyOptions(product: product, index: index, selections: selections);
|
|
} else {
|
|
if (productAttribute.singleSelection) {
|
|
optionsView = new RadioOptions(product: product, index: index, selections: selections);
|
|
} else {
|
|
optionsView = new CheckOptions(product: product, index: index, selections: selections);
|
|
}
|
|
}
|
|
|
|
return optionsView;
|
|
}
|
|
|
|
void _goNext() {
|
|
if (index + 1 < product.productAttributes.length) {
|
|
setState(() {
|
|
index = index + 1;
|
|
previousButtonEnable = index >= 1;
|
|
nextButtonEnable = _checkCanGoNext();
|
|
});
|
|
} else if (product.productAttributes.length == index + 1) {
|
|
eventBus.fire(new OnProductWillAddToCart(product, selections, productPrice, productDesc, widget.business, buttonKey: widget.startKey));
|
|
Navigator.pop(context);
|
|
}
|
|
eventBus.fire(new OnAttributePageChanged(index));
|
|
}
|
|
|
|
void _goPrevious() {
|
|
if (index - 1 >= 0) {
|
|
setState(() {
|
|
index = index - 1;
|
|
previousButtonEnable = index > 0;
|
|
nextButtonEnable = _checkCanGoNext();
|
|
});
|
|
eventBus.fire(new OnAttributePageChanged(index));
|
|
}
|
|
}
|
|
|
|
@override
|
|
void setState(VoidCallback fn) {
|
|
if(mounted) {
|
|
super.setState(fn);
|
|
}
|
|
}
|
|
} |