286 lines
8.5 KiB
Dart
286 lines
8.5 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 GlobalKey? startKey;
|
|
|
|
const MobileAttributeSelection({required this.product, required this.business, Key? key, this.startKey})
|
|
: super(key: key);
|
|
|
|
@override
|
|
State<StatefulWidget> createState() {
|
|
return new MobileAttributeSelectionState();
|
|
}
|
|
|
|
}
|
|
|
|
class MobileAttributeSelectionState extends State<MobileAttributeSelection> {
|
|
Product? product;
|
|
int? index;
|
|
TextButton? previousButton;
|
|
TextButton? nextButton;
|
|
bool previousButtonEnable = false;
|
|
bool nextButtonEnable = false;
|
|
|
|
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 = TextButton(
|
|
onPressed: previousButtonEnable ? _goPrevious : null,
|
|
child: new Text(S.of(context).previous),
|
|
);
|
|
|
|
nextButton = TextButton(
|
|
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);
|
|
}
|
|
}
|
|
} |