New state options for taxes/shipping, Handle variations better, Code clean up, Bug fixes
This commit is contained in:
parent
2ae50623d6
commit
cc9d5d75cb
@ -1,3 +1,10 @@
|
||||
## [2.0.3] - 2020-05-12
|
||||
|
||||
* New state options for taxes/shipping
|
||||
* Handle variations better
|
||||
* Code clean up
|
||||
* Bug fixes
|
||||
|
||||
## [2.0.2] - 2020-05-08
|
||||
|
||||
* Flutter 1.17.0 support
|
||||
|
||||
@ -142,5 +142,8 @@
|
||||
"Sort results": "Sort results",
|
||||
"you're now logged in": "You're now logged in",
|
||||
"Hello": "Hello",
|
||||
"Welcome back": "Welcome back"
|
||||
"Welcome back": "Welcome back",
|
||||
"Quantity": "Quantity",
|
||||
"Select a state": "Select a state",
|
||||
"Select state": "Select state"
|
||||
}
|
||||
74
LabelStoreMax/lib/app_state_options.dart
Normal file
74
LabelStoreMax/lib/app_state_options.dart
Normal file
@ -0,0 +1,74 @@
|
||||
// Label StoreMAX
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// 2020, WooSignal Ltd. All rights reserved.
|
||||
//
|
||||
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
// STATE OPTIONS
|
||||
// ONLY USED IF COUNTRY IS US
|
||||
|
||||
var appStateOptions = [
|
||||
{"code": "AL", "name": "Alabama"},
|
||||
{"code": "AK", "name": "Alaska"},
|
||||
{"code": "AS", "name": "American Samoa"},
|
||||
{"code": "AZ", "name": "Arizona"},
|
||||
{"code": "AR", "name": "Arkansas"},
|
||||
{"code": "CA", "name": "California"},
|
||||
{"code": "CO", "name": "Colorado"},
|
||||
{"code": "CT", "name": "Connecticut"},
|
||||
{"code": "DE", "name": "Delaware"},
|
||||
{"code": "DC", "name": "District Of Columbia"},
|
||||
{"code": "FM", "name": "Federated States Of Micronesia"},
|
||||
{"code": "FL", "name": "Florida"},
|
||||
{"code": "GA", "name": "Georgia"},
|
||||
{"code": "GU", "name": "Guam"},
|
||||
{"code": "HI", "name": "Hawaii"},
|
||||
{"code": "ID", "name": "Idaho"},
|
||||
{"code": "IL", "name": "Illinois"},
|
||||
{"code": "IN", "name": "Indiana"},
|
||||
{"code": "IA", "name": "Iowa"},
|
||||
{"code": "KS", "name": "Kansas"},
|
||||
{"code": "KY", "name": "Kentucky"},
|
||||
{"code": "LA", "name": "Louisiana"},
|
||||
{"code": "ME", "name": "Maine"},
|
||||
{"code": "MH", "name": "Marshall Islands"},
|
||||
{"code": "MD", "name": "Maryland"},
|
||||
{"code": "MA", "name": "Massachusetts"},
|
||||
{"code": "MI", "name": "Michigan"},
|
||||
{"code": "MN", "name": "Minnesota"},
|
||||
{"code": "MS", "name": "Mississippi"},
|
||||
{"code": "MO", "name": "Missouri"},
|
||||
{"code": "MT", "name": "Montana"},
|
||||
{"code": "NE", "name": "Nebraska"},
|
||||
{"code": "NV", "name": "Nevada"},
|
||||
{"code": "NH", "name": "New Hampshire"},
|
||||
{"code": "NJ", "name": "New Jersey"},
|
||||
{"code": "NM", "name": "New Mexico"},
|
||||
{"code": "NY", "name": "New York"},
|
||||
{"code": "NC", "name": "North Carolina"},
|
||||
{"code": "ND", "name": "North Dakota"},
|
||||
{"code": "MP", "name": "Northern Mariana Islands"},
|
||||
{"code": "OH", "name": "Ohio"},
|
||||
{"code": "OK", "name": "Oklahoma"},
|
||||
{"code": "OR", "name": "Oregon"},
|
||||
{"code": "PW", "name": "Palau"},
|
||||
{"code": "PA", "name": "Pennsylvania"},
|
||||
{"code": "PR", "name": "Puerto Rico"},
|
||||
{"code": "RI", "name": "Rhode Island"},
|
||||
{"code": "SC", "name": "South Carolina"},
|
||||
{"code": "SD", "name": "South Dakota"},
|
||||
{"code": "TN", "name": "Tennessee"},
|
||||
{"code": "TX", "name": "Texas"},
|
||||
{"code": "UT", "name": "Utah"},
|
||||
{"code": "VT", "name": "Vermont"},
|
||||
{"code": "VI", "name": "Virgin Islands"},
|
||||
{"code": "VA", "name": "Virginia"},
|
||||
{"code": "WA", "name": "Washington"},
|
||||
{"code": "WV", "name": "West Virginia"},
|
||||
{"code": "WI", "name": "Wisconsin"},
|
||||
{"code": "WY", "name": "Wyoming"}
|
||||
];
|
||||
@ -63,7 +63,7 @@ TextTheme textThemeAccent() {
|
||||
|
||||
TextTheme textThemePrimary() {
|
||||
return TextTheme(
|
||||
headline4: new TextStyle(
|
||||
headline4: new TextStyle(
|
||||
color: Colors.black,
|
||||
fontFamily: appFontFamily,
|
||||
fontWeight: FontWeight.w800,
|
||||
@ -112,7 +112,7 @@ TextTheme textThemePrimary() {
|
||||
|
||||
TextTheme textThemeMain() {
|
||||
return TextTheme(
|
||||
headline4: new TextStyle(
|
||||
headline4: new TextStyle(
|
||||
color: Colors.black,
|
||||
fontFamily: appFontFamily,
|
||||
),
|
||||
@ -132,7 +132,7 @@ TextTheme textThemeMain() {
|
||||
|
||||
TextTheme textThemeAppBar() {
|
||||
return TextTheme(
|
||||
headline4: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||
headline4: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||
headline3: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||
headline2: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||
headline1: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||
|
||||
@ -16,7 +16,7 @@ import 'dart:ui';
|
||||
Developer Notes
|
||||
|
||||
SUPPORT EMAIL - support@woosignal.com
|
||||
VERSION - 2.0.2
|
||||
VERSION - 2.0.3
|
||||
https://woosignal.com
|
||||
*/
|
||||
|
||||
@ -24,7 +24,9 @@ import 'dart:ui';
|
||||
|
||||
const app_name = "MyApp";
|
||||
|
||||
const app_key = "Your app key from WooSingal";
|
||||
//const app_key = "Your app key from WooSignal";
|
||||
const app_key =
|
||||
"app_affb6434339b34443a297c2e40a3edab7102137e6d67de9abfe612b749bd";
|
||||
// Your App key from WooSignal
|
||||
// link: https://woosignal.com/dashboard/apps
|
||||
|
||||
@ -33,7 +35,6 @@ const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
|
||||
const app_terms_url = "https://yourdomain.com/terms";
|
||||
const app_privacy_url = "https://yourdomain.com/privacy";
|
||||
|
||||
|
||||
/*<! ------ APP SETTINGS ------!>*/
|
||||
|
||||
const app_currency_symbol = "\£";
|
||||
@ -45,7 +46,6 @@ const app_locales_supported = [
|
||||
// then create a new lang json file using keys from en.json
|
||||
// e.g. lang/es.json
|
||||
|
||||
|
||||
/*<! ------ PAYMENT GATEWAYS ------!>*/
|
||||
|
||||
// Available: "Stripe", "CashOnDelivery",
|
||||
@ -53,7 +53,6 @@ const app_locales_supported = [
|
||||
|
||||
const app_payment_methods = ["Stripe"];
|
||||
|
||||
|
||||
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
||||
|
||||
// Your StripeAccount key from WooSignal
|
||||
@ -67,7 +66,6 @@ const app_stripe_live_mode = false;
|
||||
// #2 Next visit https://woosignal.com/dashboard
|
||||
// #3 Then change "Environment for Stripe" to Live mode
|
||||
|
||||
|
||||
/*<! ------ WP LOGIN (OPTIONAL) ------!>*/
|
||||
|
||||
// Allows customers to login/register, view account, purchase items as a user.
|
||||
@ -81,7 +79,6 @@ const app_forgot_password_url =
|
||||
"https://mysite.com/my-account/lost-password"; // change to your forgot password url
|
||||
const app_wp_api_path = "/wp-json"; // By default "/wp-json" should work
|
||||
|
||||
|
||||
/*<! ------ DEBUGGER ENABLED ------!>*/
|
||||
|
||||
const app_debug = true;
|
||||
|
||||
@ -41,15 +41,22 @@ class Cart {
|
||||
|
||||
void addToCart({CartLineItem cartLineItem}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
var firstCartItem = cartLineItems.firstWhere(
|
||||
(i) =>
|
||||
i.productId == cartLineItem.productId ||
|
||||
i.productId == cartLineItem.productId &&
|
||||
i.variationId == cartLineItem.variationId, orElse: () {
|
||||
return null;
|
||||
});
|
||||
if (firstCartItem != null) {
|
||||
return;
|
||||
|
||||
if (cartLineItem.variationId != null) {
|
||||
if (cartLineItems.firstWhere(
|
||||
(i) => (i.productId == cartLineItem.productId &&
|
||||
i.variationId == cartLineItem.variationId),
|
||||
orElse: () => null) !=
|
||||
null) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
var firstCartItem = cartLineItems.firstWhere(
|
||||
(i) => i.productId == cartLineItem.productId,
|
||||
orElse: () => null);
|
||||
if (firstCartItem != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
cartLineItems.add(cartLineItem);
|
||||
|
||||
@ -60,7 +67,7 @@ class Cart {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double total = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
total += (double.parse(cartItem.total) * cartItem.quantity);
|
||||
total += (parseWcPrice(cartItem.total) * cartItem.quantity);
|
||||
});
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
@ -73,7 +80,7 @@ class Cart {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
double subtotal = 0;
|
||||
cartLineItems.forEach((cartItem) {
|
||||
subtotal += (double.parse(cartItem.subtotal) * cartItem.quantity);
|
||||
subtotal += (parseWcPrice(cartItem.subtotal) * cartItem.quantity);
|
||||
});
|
||||
if (withFormat != null && withFormat == true) {
|
||||
return formatDoubleCurrency(total: subtotal);
|
||||
@ -133,6 +140,7 @@ class Cart {
|
||||
double shippingTotal = 0;
|
||||
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
|
||||
if (cartItems.every((c) => c.taxStatus == 'none')) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ class CustomerAddress {
|
||||
String addressLine;
|
||||
String city;
|
||||
String postalCode;
|
||||
String state;
|
||||
String country;
|
||||
String emailAddress;
|
||||
|
||||
@ -23,6 +24,7 @@ class CustomerAddress {
|
||||
this.addressLine,
|
||||
this.city,
|
||||
this.postalCode,
|
||||
this.state,
|
||||
this.country,
|
||||
this.emailAddress});
|
||||
|
||||
@ -32,30 +34,35 @@ class CustomerAddress {
|
||||
addressLine = "";
|
||||
city = "";
|
||||
postalCode = "";
|
||||
state = "";
|
||||
country = "";
|
||||
emailAddress = "";
|
||||
}
|
||||
|
||||
bool hasMissingFields() {
|
||||
return (this.firstName.isEmpty ||
|
||||
this.lastName.isEmpty ||
|
||||
this.addressLine.isEmpty ||
|
||||
this.city.isEmpty ||
|
||||
this.postalCode.isEmpty);
|
||||
this.lastName.isEmpty ||
|
||||
this.addressLine.isEmpty ||
|
||||
this.city.isEmpty ||
|
||||
this.postalCode.isEmpty) &&
|
||||
(this.country == "United States" ? this.state.isEmpty : false);
|
||||
}
|
||||
|
||||
String addressFull() {
|
||||
List<String> tmpArrAddress = new List<String>();
|
||||
if (addressLine != "") {
|
||||
if (addressLine != null && addressLine != "") {
|
||||
tmpArrAddress.add(addressLine);
|
||||
}
|
||||
if (city != "") {
|
||||
if (city != null && city != "") {
|
||||
tmpArrAddress.add(city);
|
||||
}
|
||||
if (postalCode != "") {
|
||||
if (postalCode != null && postalCode != "") {
|
||||
tmpArrAddress.add(postalCode);
|
||||
}
|
||||
if (country != "") {
|
||||
if (state != null && state != "") {
|
||||
tmpArrAddress.add(state);
|
||||
}
|
||||
if (country != null && country != "") {
|
||||
tmpArrAddress.add(country);
|
||||
}
|
||||
return tmpArrAddress.join(", ");
|
||||
@ -78,6 +85,7 @@ class CustomerAddress {
|
||||
addressLine = json['address_line'];
|
||||
city = json['city'];
|
||||
postalCode = json['postal_code'];
|
||||
state = json['state'];
|
||||
country = json['country'];
|
||||
emailAddress = json['email_address'];
|
||||
}
|
||||
@ -89,6 +97,7 @@ class CustomerAddress {
|
||||
data['address_line'] = this.addressLine;
|
||||
data['city'] = this.city;
|
||||
data['postal_code'] = this.postalCode;
|
||||
data['state'] = this.state;
|
||||
data['country'] = this.country;
|
||||
data['email_address'] = this.emailAddress;
|
||||
return data;
|
||||
|
||||
@ -37,9 +37,7 @@ class _AboutPageState extends State<AboutPage> {
|
||||
backgroundColor: Colors.transparent,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Text(trans(context, "About"),
|
||||
style: Theme.of(context).primaryTextTheme.headline6),
|
||||
@ -60,14 +58,18 @@ class _AboutPageState extends State<AboutPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
wsMenuItem(context,
|
||||
title: trans(context, "Privacy policy"),
|
||||
leading: Icon(Icons.people),
|
||||
action: _actionPrivacy),
|
||||
wsMenuItem(context,
|
||||
title: trans(context, "Terms and conditions"),
|
||||
leading: Icon(Icons.description),
|
||||
action: _actionTerms),
|
||||
wsMenuItem(
|
||||
context,
|
||||
title: trans(context, "Privacy policy"),
|
||||
leading: Icon(Icons.people),
|
||||
action: _actionPrivacy,
|
||||
),
|
||||
wsMenuItem(
|
||||
context,
|
||||
title: trans(context, "Terms and conditions"),
|
||||
leading: Icon(Icons.description),
|
||||
action: _actionTerms,
|
||||
),
|
||||
FutureBuilder<PackageInfo>(
|
||||
future: PackageInfo.fromPlatform(),
|
||||
builder: (BuildContext context,
|
||||
@ -93,7 +95,7 @@ class _AboutPageState extends State<AboutPage> {
|
||||
}
|
||||
return null; // unreachable
|
||||
},
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
flex: 2,
|
||||
|
||||
@ -96,9 +96,7 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
},
|
||||
onTap: () => FocusScope.of(context).requestFocus(new FocusNode()),
|
||||
child: _isLoading
|
||||
? showAppLoader()
|
||||
: LayoutBuilder(
|
||||
|
||||
@ -77,9 +77,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
leading: Container(
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
),
|
||||
@ -211,32 +209,29 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.account_circle),
|
||||
title: Text(trans(context, "Update details")),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, "/account-update").then((onValue) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
_fetchWpUserData();
|
||||
onTap: () =>
|
||||
Navigator.pushNamed(context, "/account-update").then((onValue) {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
},
|
||||
_fetchWpUserData();
|
||||
}),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.local_shipping),
|
||||
title: Text(trans(context, "Shipping Details")),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, "/account-shipping-details");
|
||||
},
|
||||
onTap: () =>
|
||||
Navigator.pushNamed(context, "/account-shipping-details"),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
child: ListTile(
|
||||
leading: Icon(Icons.credit_card),
|
||||
title: Text(trans(context, "Billing Details")),
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, "/account-billing-details");
|
||||
},
|
||||
onTap: () =>
|
||||
Navigator.pushNamed(context, "/account-billing-details"),
|
||||
),
|
||||
),
|
||||
Card(
|
||||
@ -300,7 +295,9 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: HexColor("#fcfcfc"), width: 1),
|
||||
color: HexColor("#fcfcfc"),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
@ -356,14 +353,16 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
),
|
||||
Text(
|
||||
dateFormatted(
|
||||
date: _orders[i].dateCreated,
|
||||
formatType:
|
||||
formatForDateTime(FormatType.Date)) +
|
||||
date: _orders[i].dateCreated,
|
||||
formatType:
|
||||
formatForDateTime(FormatType.Date),
|
||||
) +
|
||||
"\n" +
|
||||
dateFormatted(
|
||||
date: _orders[i].dateCreated,
|
||||
formatType:
|
||||
formatForDateTime(FormatType.Time)),
|
||||
date: _orders[i].dateCreated,
|
||||
formatType:
|
||||
formatForDateTime(FormatType.Time),
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
|
||||
@ -78,9 +78,10 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: wsBoxShadow(),
|
||||
color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
boxShadow: wsBoxShadow(),
|
||||
color: Colors.white,
|
||||
),
|
||||
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 8),
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Column(
|
||||
@ -134,9 +135,9 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
launch(app_forgot_password_url);
|
||||
}),
|
||||
Divider(),
|
||||
wsLinkButton(context, title: trans(context, "Back"), action: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
wsLinkButton(context,
|
||||
title: trans(context, "Back"),
|
||||
action: () => Navigator.pop(context)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -47,9 +47,7 @@ class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
|
||||
leading: Container(
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
margin: EdgeInsets.only(left: 0),
|
||||
),
|
||||
|
||||
@ -80,7 +80,6 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
|
||||
body: isLoading
|
||||
? showAppLoader()
|
||||
: SafeArea(
|
||||
// minimum: safeAreaDefault(),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
@ -93,15 +92,20 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: wsTextEditingRow(context,
|
||||
heading: trans(context, "First Name"),
|
||||
controller: _tfFirstName,
|
||||
keyboardType: TextInputType.text)),
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "First Name"),
|
||||
controller: _tfFirstName,
|
||||
keyboardType: TextInputType.text,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: wsTextEditingRow(context,
|
||||
heading: trans(context, "Last Name"),
|
||||
controller: _tfLastName,
|
||||
keyboardType: TextInputType.text),
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "Last Name"),
|
||||
controller: _tfLastName,
|
||||
keyboardType: TextInputType.text,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -54,9 +54,7 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
backgroundColor: Colors.transparent,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Text(
|
||||
"Register",
|
||||
|
||||
@ -91,7 +91,7 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||
children: <Widget>[
|
||||
Text(trans(context, "Browse"),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||
Text(_selectedCategory.name,
|
||||
Text(parseHtmlString(_selectedCategory.name),
|
||||
style: Theme.of(context).primaryTextTheme.headline6)
|
||||
],
|
||||
),
|
||||
@ -145,20 +145,26 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||
_sortProducts({@required SortByType by}) {
|
||||
switch (by) {
|
||||
case SortByType.LowToHigh:
|
||||
_products.sort((product1, product2) => (parseWcPrice(product1.price))
|
||||
.compareTo((double.tryParse(product2.price) ?? 0)));
|
||||
_products.sort(
|
||||
(product1, product2) => (parseWcPrice(product1.price))
|
||||
.compareTo((parseWcPrice(product2.price))),
|
||||
);
|
||||
break;
|
||||
case SortByType.HighToLow:
|
||||
_products.sort((product1, product2) => (parseWcPrice(product2.price))
|
||||
.compareTo((double.tryParse(product1.price) ?? 0)));
|
||||
_products.sort(
|
||||
(product1, product2) => (parseWcPrice(product2.price))
|
||||
.compareTo((parseWcPrice(product1.price))),
|
||||
);
|
||||
break;
|
||||
case SortByType.NameAZ:
|
||||
_products.sort(
|
||||
(product1, product2) => product1.name.compareTo(product2.name));
|
||||
(product1, product2) => product1.name.compareTo(product2.name),
|
||||
);
|
||||
break;
|
||||
case SortByType.NameZA:
|
||||
_products.sort(
|
||||
(product1, product2) => product2.name.compareTo(product1.name));
|
||||
(product1, product2) => product2.name.compareTo(product1.name),
|
||||
);
|
||||
break;
|
||||
}
|
||||
setState(() {
|
||||
|
||||
@ -48,12 +48,14 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||
|
||||
_fetchProductsForSearch() async {
|
||||
waitForNextRequest = true;
|
||||
List<WS.Product> products = await appWooSignal((api) => api.getProducts(
|
||||
perPage: 100,
|
||||
search: _search,
|
||||
page: _page,
|
||||
status: "publish",
|
||||
stockStatus: "instock"));
|
||||
List<WS.Product> products = await appWooSignal(
|
||||
(api) => api.getProducts(
|
||||
perPage: 100,
|
||||
search: _search,
|
||||
page: _page,
|
||||
status: "publish",
|
||||
stockStatus: "instock"),
|
||||
);
|
||||
_products.addAll(products);
|
||||
waitForNextRequest = false;
|
||||
_page = _page + 1;
|
||||
|
||||
@ -55,9 +55,16 @@ class _CartPageState extends State<CartPage> {
|
||||
|
||||
List<Map<String, dynamic>> cartJSON = cart.map((c) => c.toJson()).toList();
|
||||
|
||||
List<dynamic> cartRes = await appWooSignal((api) {
|
||||
return api.cartCheck(cartJSON);
|
||||
});
|
||||
List<dynamic> cartRes =
|
||||
await appWooSignal((api) => api.cartCheck(cartJSON));
|
||||
if (cartRes.length <= 0) {
|
||||
Cart.getInstance.saveCartToPref(cartLineItems: []);
|
||||
setState(() {
|
||||
_isCartEmpty = true;
|
||||
_isLoading = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
||||
if (_cartLines.length > 0) {
|
||||
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
||||
@ -110,11 +117,13 @@ class _CartPageState extends State<CartPage> {
|
||||
actionIncrementQuantity({CartLineItem cartLineItem}) {
|
||||
if (cartLineItem.isManagedStock &&
|
||||
cartLineItem.quantity + 1 > cartLineItem.stockQuantity) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Cart"),
|
||||
desc: trans(context, trans(context, "Maximum stock reached")),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.shopping_cart);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Cart"),
|
||||
desc: trans(context, trans(context, "Maximum stock reached")),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.shopping_cart,
|
||||
);
|
||||
return;
|
||||
}
|
||||
Cart.getInstance
|
||||
@ -136,11 +145,13 @@ class _CartPageState extends State<CartPage> {
|
||||
actionRemoveItem({int index}) {
|
||||
Cart.getInstance.removeCartItemForIndex(index: index);
|
||||
_cartLines.removeAt(index);
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Updated"),
|
||||
desc: trans(context, "Item removed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.remove_shopping_cart);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Updated"),
|
||||
desc: trans(context, "Item removed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.remove_shopping_cart,
|
||||
);
|
||||
if (_cartLines.length == 0) {
|
||||
_isCartEmpty = true;
|
||||
}
|
||||
@ -194,26 +205,28 @@ class _CartPageState extends State<CartPage> {
|
||||
_isCartEmpty
|
||||
? Expanded(
|
||||
child: FractionallySizedBox(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.shopping_cart,
|
||||
size: 100,
|
||||
color: Colors.black45,
|
||||
),
|
||||
Padding(
|
||||
child: Text(trans(context, "Empty Basket"),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.bodyText2),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
)
|
||||
],
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
Icons.shopping_cart,
|
||||
size: 100,
|
||||
color: Colors.black45,
|
||||
),
|
||||
Padding(
|
||||
child: Text(trans(context, "Empty Basket"),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText2),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
)
|
||||
],
|
||||
),
|
||||
heightFactor: 0.5,
|
||||
widthFactor: 1,
|
||||
),
|
||||
heightFactor: 0.5,
|
||||
widthFactor: 1,
|
||||
))
|
||||
)
|
||||
: (_isLoading
|
||||
? Expanded(child: showAppLoader())
|
||||
: Expanded(
|
||||
@ -222,17 +235,18 @@ class _CartPageState extends State<CartPage> {
|
||||
itemCount: _cartLines.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
CartLineItem cartLineItem = _cartLines[index];
|
||||
return wsCardCartItem(context,
|
||||
cartLineItem: cartLineItem,
|
||||
actionIncrementQuantity: () {
|
||||
actionIncrementQuantity(
|
||||
cartLineItem: cartLineItem);
|
||||
}, actionDecrementQuantity: () {
|
||||
actionDecrementQuantity(
|
||||
cartLineItem: cartLineItem);
|
||||
}, actionRemoveItem: () {
|
||||
actionRemoveItem(index: index);
|
||||
});
|
||||
return wsCardCartItem(
|
||||
context,
|
||||
cartLineItem: cartLineItem,
|
||||
actionIncrementQuantity: () =>
|
||||
actionIncrementQuantity(
|
||||
cartLineItem: cartLineItem),
|
||||
actionDecrementQuantity: () =>
|
||||
actionDecrementQuantity(
|
||||
cartLineItem: cartLineItem),
|
||||
actionRemoveItem: () =>
|
||||
actionRemoveItem(index: index),
|
||||
);
|
||||
}),
|
||||
flex: 3,
|
||||
)),
|
||||
@ -258,9 +272,11 @@ class _CartPageState extends State<CartPage> {
|
||||
}
|
||||
},
|
||||
),
|
||||
wsPrimaryButton(context,
|
||||
title: trans(context, "PROCEED TO CHECKOUT"),
|
||||
action: _actionProceedToCheckout),
|
||||
wsPrimaryButton(
|
||||
context,
|
||||
title: trans(context, "PROCEED TO CHECKOUT"),
|
||||
action: _actionProceedToCheckout,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/app_payment_methods.dart';
|
||||
import 'package:label_storemax/app_state_options.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
import 'package:label_storemax/models/customer_address.dart';
|
||||
@ -39,7 +40,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
_taxRates = [];
|
||||
_showFullLoader = true;
|
||||
_isProcessingPayment = false;
|
||||
if (CheckoutSession.getInstance.paymentType == null) {
|
||||
@ -56,9 +57,28 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
}
|
||||
|
||||
_getTaxes() async {
|
||||
_taxRates = await appWooSignal((api) {
|
||||
return api.getTaxRates(page: 1, perPage: 100);
|
||||
});
|
||||
int pageIndex = 1;
|
||||
bool fetchMore = true;
|
||||
while (fetchMore == true) {
|
||||
List<TaxRate> tmpTaxRates = await appWooSignal(
|
||||
(api) => api.getTaxRates(page: pageIndex, perPage: 100));
|
||||
|
||||
if (tmpTaxRates != null && tmpTaxRates.length > 0) {
|
||||
_taxRates.addAll(tmpTaxRates);
|
||||
}
|
||||
if (tmpTaxRates.length >= 100) {
|
||||
pageIndex += 1;
|
||||
} else {
|
||||
fetchMore = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_taxRates == null || _taxRates.length == 0) {
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckoutSession.getInstance.billingDetails.shippingAddress == null) {
|
||||
setState(() {
|
||||
@ -68,17 +88,54 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
}
|
||||
String country =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress.country;
|
||||
String state =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress.state;
|
||||
String postalCode =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress.postalCode;
|
||||
|
||||
Map<String, dynamic> countryMap = appCountryOptions
|
||||
.firstWhere((c) => c['name'] == country, orElse: () => null);
|
||||
|
||||
if (countryMap == null) {
|
||||
_showFullLoader = false;
|
||||
setState(() {});
|
||||
return;
|
||||
}
|
||||
String countryCode = countryMap["code"];
|
||||
|
||||
TaxRate taxRate = _taxRates.firstWhere((t) => t.country == countryCode,
|
||||
orElse: () => null);
|
||||
TaxRate taxRate;
|
||||
|
||||
Map<String, dynamic> stateMap;
|
||||
if (state != null) {
|
||||
stateMap = appStateOptions.firstWhere((c) => c['name'] == state,
|
||||
orElse: () => null);
|
||||
}
|
||||
|
||||
if (stateMap != null) {
|
||||
taxRate = _taxRates.firstWhere(
|
||||
(t) =>
|
||||
t.country == countryMap["code"] &&
|
||||
t.state == stateMap["code"] &&
|
||||
t.postcode == postalCode,
|
||||
orElse: () => null);
|
||||
|
||||
if (taxRate == null) {
|
||||
taxRate = _taxRates.firstWhere(
|
||||
(t) =>
|
||||
t.country == countryMap["code"] && t.state == stateMap["code"],
|
||||
orElse: () => null);
|
||||
}
|
||||
}
|
||||
|
||||
if (taxRate == null) {
|
||||
taxRate = _taxRates.firstWhere(
|
||||
(t) => t.country == countryMap["code"] && t.postcode == postalCode,
|
||||
orElse: () => null);
|
||||
|
||||
if (taxRate == null) {
|
||||
taxRate = _taxRates.firstWhere((t) => t.country == countryMap["code"],
|
||||
orElse: () => null);
|
||||
}
|
||||
}
|
||||
|
||||
if (taxRate != null) {
|
||||
_taxRate = taxRate;
|
||||
@ -90,13 +147,16 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
|
||||
_actionCheckoutDetails() {
|
||||
Navigator.pushNamed(context, "/checkout-details").then((e) {
|
||||
_showFullLoader = true;
|
||||
setState(() {
|
||||
_showFullLoader = true;
|
||||
});
|
||||
_getTaxes();
|
||||
});
|
||||
}
|
||||
|
||||
_actionPayWith() {
|
||||
Navigator.pushNamed(context, "/checkout-payment-type");
|
||||
Navigator.pushNamed(context, "/checkout-payment-type")
|
||||
.then((value) => setState(() {}));
|
||||
}
|
||||
|
||||
_actionSelectShipping() {
|
||||
@ -131,16 +191,19 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Center(
|
||||
child: Text(trans(context, "Checkout"),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||
child: Text(
|
||||
trans(context, "Checkout"),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: wsBoxShadow()),
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: wsBoxShadow(),
|
||||
),
|
||||
margin: EdgeInsets.only(top: 5, bottom: 5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@ -197,12 +260,14 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
.getInstance.shippingType
|
||||
.getTitle(),
|
||||
action: _actionSelectShipping)
|
||||
: wsCheckoutRow(context,
|
||||
: wsCheckoutRow(
|
||||
context,
|
||||
heading: trans(context, "Select shipping"),
|
||||
leadImage: Icon(Icons.local_shipping),
|
||||
leadTitle: trans(
|
||||
context, "Select a shipping option"),
|
||||
action: _actionSelectShipping)),
|
||||
action: _actionSelectShipping,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -235,11 +300,13 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
),
|
||||
],
|
||||
),
|
||||
wsPrimaryButton(context,
|
||||
title: _isProcessingPayment
|
||||
? "PROCESSING..."
|
||||
: trans(context, "CHECKOUT"),
|
||||
action: _isProcessingPayment ? null : _handleCheckout),
|
||||
wsPrimaryButton(
|
||||
context,
|
||||
title: _isProcessingPayment
|
||||
? "PROCESSING..."
|
||||
: trans(context, "CHECKOUT"),
|
||||
action: _isProcessingPayment ? null : _handleCheckout,
|
||||
),
|
||||
],
|
||||
)
|
||||
: Center(
|
||||
@ -263,40 +330,48 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
|
||||
_handleCheckout() async {
|
||||
if (CheckoutSession.getInstance.billingDetails.billingAddress == null) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context,
|
||||
"Please select add your billing/shipping address to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context,
|
||||
"Please select add your billing/shipping address to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckoutSession.getInstance.billingDetails.billingAddress
|
||||
.hasMissingFields()) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Your billing/shipping details are incomplete"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Your billing/shipping details are incomplete"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckoutSession.getInstance.shippingType == null) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select a shipping method to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select a shipping method to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (CheckoutSession.getInstance.paymentType == null) {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select a payment method to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.payment);
|
||||
showEdgeAlertWith(
|
||||
context,
|
||||
title: trans(context, "Oops"),
|
||||
desc: trans(context, "Please select a payment method to proceed"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.payment,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/app_state_options.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/billing_details.dart';
|
||||
import 'package:label_storemax/models/checkout_session.dart';
|
||||
@ -35,6 +36,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
TextEditingController _txtShippingPostalCode;
|
||||
TextEditingController _txtShippingEmailAddress;
|
||||
String _strBillingCountry;
|
||||
String _strBillingState;
|
||||
|
||||
var valRememberDetails = true;
|
||||
|
||||
@ -62,6 +64,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
_txtShippingPostalCode.text = billingDetails.billingAddress.postalCode;
|
||||
_txtShippingEmailAddress.text = billingDetails.billingAddress.emailAddress;
|
||||
_strBillingCountry = billingDetails.billingAddress.country;
|
||||
_strBillingState = billingDetails.billingAddress.state;
|
||||
|
||||
valRememberDetails = billingDetails.rememberDetails ?? true;
|
||||
_sfCustomerAddress();
|
||||
@ -78,41 +81,78 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
_txtShippingCity.text = customerAddress.city;
|
||||
_txtShippingPostalCode.text = customerAddress.postalCode;
|
||||
_txtShippingEmailAddress.text = customerAddress.emailAddress;
|
||||
_strBillingState = customerAddress.state;
|
||||
_strBillingCountry = customerAddress.country;
|
||||
}
|
||||
}
|
||||
|
||||
_showSelectCountryModal() {
|
||||
wsModalBottom(context,
|
||||
title: trans(context, "Select a country"),
|
||||
bodyWidget: ListView.separated(
|
||||
itemCount: appCountryOptions.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Map<String, String> strName = appCountryOptions[index];
|
||||
wsModalBottom(
|
||||
context,
|
||||
title: trans(context, "Select a country"),
|
||||
bodyWidget: ListView.separated(
|
||||
itemCount: appCountryOptions.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Map<String, String> strName = appCountryOptions[index];
|
||||
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(strName["name"],
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(strName["name"],
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
),
|
||||
splashColor: Colors.grey,
|
||||
highlightColor: Colors.black12,
|
||||
onTap: () => setState(() {
|
||||
_strBillingCountry = strName["name"];
|
||||
Navigator.of(context).pop();
|
||||
if (strName["code"] == "US") {
|
||||
_showSelectStateModal();
|
||||
} else {
|
||||
_strBillingState = "";
|
||||
}
|
||||
}),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) => Divider(
|
||||
height: 0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_showSelectStateModal() {
|
||||
wsModalBottom(
|
||||
context,
|
||||
title: trans(context, "Select a state"),
|
||||
bodyWidget: ListView.separated(
|
||||
itemCount: appStateOptions.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Map<String, String> strName = appStateOptions[index];
|
||||
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(
|
||||
strName["name"],
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||
),
|
||||
splashColor: Colors.grey,
|
||||
highlightColor: Colors.black12,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_strBillingCountry = strName["name"];
|
||||
Navigator.of(context).pop();
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) {
|
||||
return Divider(
|
||||
height: 0,
|
||||
color: Colors.black12,
|
||||
);
|
||||
},
|
||||
));
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
),
|
||||
splashColor: Colors.grey,
|
||||
highlightColor: Colors.black12,
|
||||
onTap: () => setState(() {
|
||||
_strBillingState = strName["name"];
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) => Divider(
|
||||
height: 0,
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -130,9 +170,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
},
|
||||
onTap: () => FocusScope.of(context).requestFocus(new FocusNode()),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -140,6 +178,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
@ -165,48 +204,76 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
),
|
||||
wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "Address Line"),
|
||||
controller: _txtShippingAddressLine,
|
||||
),
|
||||
Row(children: <Widget>[
|
||||
Flexible(
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "City"),
|
||||
controller: _txtShippingCity,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "Postal code"),
|
||||
controller: _txtShippingPostalCode,
|
||||
),
|
||||
),
|
||||
]),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "Address Line"),
|
||||
controller: _txtShippingAddressLine,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "City"),
|
||||
controller: _txtShippingCity,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: wsTextEditingRow(
|
||||
context,
|
||||
heading: trans(context, "Postal code"),
|
||||
controller: _txtShippingPostalCode,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: wsTextEditingRow(context,
|
||||
heading: trans(context, "Email address"),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
controller: _txtShippingEmailAddress),
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
(_strBillingCountry == "United States"
|
||||
? Flexible(
|
||||
child: Padding(
|
||||
child: wsSecondaryButton(
|
||||
context,
|
||||
title: (_strBillingState != null &&
|
||||
_strBillingState.isNotEmpty
|
||||
? trans(context, "Selected") +
|
||||
"\n" +
|
||||
_strBillingState
|
||||
: trans(context, "Select state")),
|
||||
action: _showSelectStateModal,
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
),
|
||||
)
|
||||
: null),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
child: wsSecondaryButton(context,
|
||||
child: Padding(
|
||||
child: wsSecondaryButton(
|
||||
context,
|
||||
title: (_strBillingCountry != null &&
|
||||
_strBillingCountry.isNotEmpty
|
||||
? trans(context, "Selected") +
|
||||
"\n" +
|
||||
_strBillingCountry
|
||||
: trans(context, "Select country")),
|
||||
action: _showSelectCountryModal),
|
||||
padding: EdgeInsets.all(8),
|
||||
))
|
||||
],
|
||||
action: _showSelectCountryModal,
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
),
|
||||
)
|
||||
].where((element) => element != null).toList(),
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
)
|
||||
@ -215,22 +282,11 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: HexColor("#e8e8e8"),
|
||||
blurRadius: 15.0,
|
||||
// has the effect of softening the shadow
|
||||
spreadRadius: 0,
|
||||
offset: Offset(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
)
|
||||
],
|
||||
boxShadow: wsBoxShadow(),
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
),
|
||||
height: (constraints.maxHeight - constraints.minHeight) * 0.6,
|
||||
height: (constraints.maxHeight - constraints.minHeight) * 0.5,
|
||||
),
|
||||
Column(
|
||||
children: <Widget>[
|
||||
@ -238,9 +294,10 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text(trans(context, "Remember my details"),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.bodyText2),
|
||||
Text(
|
||||
trans(context, "Remember my details"),
|
||||
style: Theme.of(context).primaryTextTheme.bodyText2,
|
||||
),
|
||||
Checkbox(
|
||||
value: valRememberDetails,
|
||||
onChanged: (bool value) {
|
||||
@ -261,6 +318,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
_txtShippingAddressLine.text;
|
||||
customerAddress.city = _txtShippingCity.text;
|
||||
customerAddress.postalCode = _txtShippingPostalCode.text;
|
||||
customerAddress.state = _strBillingState;
|
||||
customerAddress.country = _strBillingCountry;
|
||||
customerAddress.emailAddress =
|
||||
_txtShippingEmailAddress.text;
|
||||
|
||||
@ -50,9 +50,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
},
|
||||
onTap: () => FocusScope.of(context).requestFocus(new FocusNode()),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -103,17 +101,16 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
},
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) {
|
||||
return Divider(
|
||||
color: Colors.black12,
|
||||
);
|
||||
},
|
||||
separatorBuilder: (cxt, i) => Divider(
|
||||
color: Colors.black12,
|
||||
),
|
||||
),
|
||||
),
|
||||
wsLinkButton(context, title: trans(context, "CANCEL"),
|
||||
action: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
wsLinkButton(
|
||||
context,
|
||||
title: trans(context, "CANCEL"),
|
||||
action: () => Navigator.pop(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/app_state_options.dart';
|
||||
import 'package:label_storemax/helpers/tools.dart';
|
||||
import 'package:label_storemax/models/cart.dart';
|
||||
import 'package:label_storemax/models/cart_line_item.dart';
|
||||
@ -17,6 +18,7 @@ import 'package:label_storemax/models/customer_address.dart';
|
||||
import 'package:label_storemax/models/shipping_type.dart';
|
||||
import 'package:label_storemax/widgets/app_loader.dart';
|
||||
import 'package:label_storemax/widgets/buttons.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
import 'package:label_storemax/app_country_options.dart';
|
||||
|
||||
@ -54,12 +56,21 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||
String postalCode = customerAddress.postalCode;
|
||||
String country = customerAddress.country;
|
||||
String state = customerAddress.state;
|
||||
|
||||
String countryCode = appCountryOptions
|
||||
.firstWhere((c) => c['name'] == country, orElse: () => null)["code"];
|
||||
|
||||
Map<String, dynamic> stateMap = appStateOptions
|
||||
.firstWhere((c) => c['name'] == state, orElse: () => null);
|
||||
|
||||
for (final shipping in wsShipping) {
|
||||
Locations location = shipping.locations.firstWhere(
|
||||
(ws) => (ws.code == postalCode || ws.code == countryCode),
|
||||
(ws) => (ws.type == "state" &&
|
||||
stateMap["code"] != null &&
|
||||
ws.code == "$countryCode:" + stateMap["code"] ||
|
||||
ws.code == postalCode ||
|
||||
ws.code == countryCode),
|
||||
orElse: () => null);
|
||||
|
||||
if (location != null) {
|
||||
@ -198,9 +209,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
body: SafeArea(
|
||||
minimum: safeAreaDefault(),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
FocusScope.of(context).requestFocus(new FocusNode());
|
||||
},
|
||||
onTap: () => FocusScope.of(context).requestFocus(new FocusNode()),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -226,80 +235,79 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
: (_isShippingSupported
|
||||
? Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: _wsShippingOptions.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
Divider(
|
||||
color: Colors.black12,
|
||||
),
|
||||
itemBuilder:
|
||||
(BuildContext context, int index) {
|
||||
return ListTile(
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: 16, right: 16),
|
||||
title: Text(
|
||||
_wsShippingOptions[index]
|
||||
['title'],
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle1),
|
||||
selected: true,
|
||||
subtitle: FutureBuilder<String>(
|
||||
future: _getShippingPrice(index),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<String>
|
||||
snapshot) {
|
||||
switch (
|
||||
snapshot.connectionState) {
|
||||
case ConnectionState.none:
|
||||
itemCount: _wsShippingOptions.length,
|
||||
separatorBuilder: (context, index) =>
|
||||
Divider(
|
||||
color: Colors.black12,
|
||||
),
|
||||
itemBuilder:
|
||||
(BuildContext context, int index) {
|
||||
return ListTile(
|
||||
contentPadding: EdgeInsets.only(
|
||||
left: 16, right: 16),
|
||||
title: Text(
|
||||
_wsShippingOptions[index]
|
||||
['title'],
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle1),
|
||||
selected: true,
|
||||
subtitle: FutureBuilder<String>(
|
||||
future: _getShippingPrice(index),
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<String>
|
||||
snapshot) {
|
||||
switch (
|
||||
snapshot.connectionState) {
|
||||
case ConnectionState.none:
|
||||
return Text('');
|
||||
case ConnectionState.active:
|
||||
case ConnectionState.waiting:
|
||||
return Text('');
|
||||
case ConnectionState.done:
|
||||
if (snapshot.hasError)
|
||||
return Text('');
|
||||
case ConnectionState.active:
|
||||
case ConnectionState.waiting:
|
||||
return Text('');
|
||||
case ConnectionState.done:
|
||||
if (snapshot.hasError)
|
||||
return Text('');
|
||||
return Text(trans(
|
||||
context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(
|
||||
total:
|
||||
snapshot.data));
|
||||
}
|
||||
return null; // unreachable
|
||||
},
|
||||
),
|
||||
trailing: (CheckoutSession
|
||||
.getInstance
|
||||
.shippingType !=
|
||||
null &&
|
||||
CheckoutSession
|
||||
.getInstance
|
||||
.shippingType
|
||||
.object ==
|
||||
_wsShippingOptions[
|
||||
index]["object"]
|
||||
? Icon(Icons.check)
|
||||
: null),
|
||||
onTap: () async {
|
||||
ShippingType shippingType =
|
||||
ShippingType();
|
||||
shippingType.object =
|
||||
_wsShippingOptions[index]
|
||||
['object'];
|
||||
shippingType.methodId =
|
||||
_wsShippingOptions[index]
|
||||
['method_id'];
|
||||
shippingType.cost =
|
||||
await _getShippingPrice(
|
||||
index);
|
||||
|
||||
CheckoutSession.getInstance
|
||||
.shippingType = shippingType;
|
||||
|
||||
Navigator.pop(context);
|
||||
return Text(
|
||||
trans(context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(
|
||||
total: snapshot
|
||||
.data));
|
||||
}
|
||||
return null; // unreachable
|
||||
},
|
||||
);
|
||||
}),
|
||||
),
|
||||
trailing: (CheckoutSession.getInstance
|
||||
.shippingType !=
|
||||
null &&
|
||||
CheckoutSession
|
||||
.getInstance
|
||||
.shippingType
|
||||
.object ==
|
||||
_wsShippingOptions[index]
|
||||
["object"]
|
||||
? Icon(Icons.check)
|
||||
: null),
|
||||
onTap: () async {
|
||||
ShippingType shippingType =
|
||||
ShippingType();
|
||||
shippingType.object =
|
||||
_wsShippingOptions[index]
|
||||
['object'];
|
||||
shippingType.methodId =
|
||||
_wsShippingOptions[index]
|
||||
['method_id'];
|
||||
shippingType.cost =
|
||||
await _getShippingPrice(index);
|
||||
|
||||
CheckoutSession.getInstance
|
||||
.shippingType = shippingType;
|
||||
|
||||
Navigator.pop(context);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
trans(context,
|
||||
@ -308,27 +316,17 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
.primaryTextTheme
|
||||
.headline6,
|
||||
textAlign: TextAlign.center))),
|
||||
wsLinkButton(context, title: trans(context, "CANCEL"),
|
||||
action: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
wsLinkButton(
|
||||
context,
|
||||
title: trans(context, "CANCEL"),
|
||||
action: () => Navigator.pop(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: HexColor("#e8e8e8"),
|
||||
blurRadius: 15.0,
|
||||
// has the effect of softening the shadow
|
||||
spreadRadius: 0,
|
||||
offset: Offset(
|
||||
0,
|
||||
0,
|
||||
),
|
||||
)
|
||||
],
|
||||
boxShadow: wsBoxShadow(),
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
),
|
||||
|
||||
@ -87,19 +87,20 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom:
|
||||
BorderSide(color: Colors.black12, width: 1.0)),
|
||||
bottom: BorderSide(color: Colors.black12, width: 1.0),
|
||||
),
|
||||
),
|
||||
padding: EdgeInsets.only(bottom: 20),
|
||||
),
|
||||
Container(
|
||||
child: Image(
|
||||
image: new AssetImage("assets/images/camion.gif"),
|
||||
height: 170),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
width: double.infinity),
|
||||
child: Image(
|
||||
image: new AssetImage("assets/images/camion.gif"),
|
||||
height: 170),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
),
|
||||
width: double.infinity,
|
||||
),
|
||||
],
|
||||
),
|
||||
Align(
|
||||
@ -136,10 +137,12 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||
softWrap: false,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis),
|
||||
Text("x" + lineItem.quantity.toString(),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText2),
|
||||
Text(
|
||||
"x" + lineItem.quantity.toString(),
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -162,9 +165,7 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||
Align(
|
||||
child: MaterialButton(
|
||||
child: Text(trans(context, "Back to Home")),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "/home");
|
||||
},
|
||||
onPressed: () => Navigator.pushNamed(context, "/home"),
|
||||
),
|
||||
alignment: Alignment.bottomCenter,
|
||||
),
|
||||
|
||||
@ -50,9 +50,9 @@ class _ErrorPageState extends State<ErrorPage> {
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
wsLinkButton(context, title: trans(context, "Back"), action: () {
|
||||
Navigator.pop(context);
|
||||
}),
|
||||
wsLinkButton(context,
|
||||
title: trans(context, "Back"),
|
||||
action: () => Navigator.pop(context)),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -37,13 +37,13 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
elevation: 0.0,
|
||||
title: Text(trans(context, "Menu"),
|
||||
style: Theme.of(context).primaryTextTheme.headline6),
|
||||
title: Text(
|
||||
trans(context, "Menu"),
|
||||
style: Theme.of(context).primaryTextTheme.headline6,
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
centerTitle: true,
|
||||
),
|
||||
@ -60,19 +60,25 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
(use_wp_login
|
||||
? wsMenuItem(context,
|
||||
? wsMenuItem(
|
||||
context,
|
||||
title: trans(context, "Profile"),
|
||||
leading: Icon(Icons.account_circle),
|
||||
action: _actionProfile)
|
||||
action: _actionProfile,
|
||||
)
|
||||
: Container()),
|
||||
wsMenuItem(context,
|
||||
title: trans(context, "Cart"),
|
||||
leading: Icon(Icons.shopping_cart),
|
||||
action: _actionCart),
|
||||
wsMenuItem(context,
|
||||
title: trans(context, "About Us"),
|
||||
leading: Icon(Icons.account_balance),
|
||||
action: _actionAboutUs),
|
||||
wsMenuItem(
|
||||
context,
|
||||
title: trans(context, "Cart"),
|
||||
leading: Icon(Icons.shopping_cart),
|
||||
action: _actionCart,
|
||||
),
|
||||
wsMenuItem(
|
||||
context,
|
||||
title: trans(context, "About Us"),
|
||||
leading: Icon(Icons.account_balance),
|
||||
action: _actionAboutUs,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -55,12 +55,15 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
|
||||
bool isFetching = true;
|
||||
while (isFetching) {
|
||||
List<WS.ProductVariation> tmp = await appWooSignal((api) {
|
||||
return api.getProductVariations(_product.id,
|
||||
perPage: 100, page: currentPage);
|
||||
});
|
||||
List<WS.ProductVariation> tmp = await appWooSignal(
|
||||
(api) => api.getProductVariations(_product.id,
|
||||
perPage: 100, page: currentPage),
|
||||
);
|
||||
if (tmp != null && tmp.length > 0) {
|
||||
tmpVariations.addAll(tmp);
|
||||
}
|
||||
|
||||
if (tmp != null && tmp.length >= 100) {
|
||||
currentPage += 1;
|
||||
} else {
|
||||
isFetching = false;
|
||||
@ -166,9 +169,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Icon(Icons.check, color: Colors.blueAccent)
|
||||
: null,
|
||||
onTap: () {
|
||||
_modalBottomSheetOptionsForAttribute(index);
|
||||
},
|
||||
onTap: () => _modalBottomSheetOptionsForAttribute(index),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -179,17 +180,17 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(findProductVariation() != null
|
||||
? trans(context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(
|
||||
total: findProductVariation().price)
|
||||
: (((_product.attributes.length ==
|
||||
_tmpAttributeObj.values.length) &&
|
||||
findProductVariation() == null)
|
||||
? trans(context, "This variation is unavailable")
|
||||
: trans(context, "Choose your options"))),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||
(findProductVariation() != null
|
||||
? trans(context, "Price") +
|
||||
": " +
|
||||
formatStringCurrency(total: findProductVariation().price)
|
||||
: (((_product.attributes.length ==
|
||||
_tmpAttributeObj.values.length) &&
|
||||
findProductVariation() == null)
|
||||
? trans(context, "This variation is unavailable")
|
||||
: trans(context, "Choose your options"))),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
),
|
||||
Text(
|
||||
(findProductVariation() != null
|
||||
? findProductVariation().stockStatus != "instock"
|
||||
@ -378,9 +379,10 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: wsBoxShadow(),
|
||||
borderRadius: BorderRadius.circular(4)),
|
||||
color: Colors.white,
|
||||
boxShadow: wsBoxShadow(),
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
height: 180,
|
||||
@ -457,7 +459,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"Quantity",
|
||||
trans(context, "Quantity"),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.bodyText1,
|
||||
),
|
||||
@ -556,15 +558,15 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
||||
_modalBottomSheetAttributes();
|
||||
return;
|
||||
}
|
||||
if (_product.stockStatus == "instock") {
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
} else {
|
||||
if (_product.stockStatus != "instock") {
|
||||
showEdgeAlertWith(context,
|
||||
title: trans(context, "Sorry"),
|
||||
desc: trans(context, "This item is out of stock"),
|
||||
style: EdgeAlertStyle.WARNING,
|
||||
icon: Icons.local_shipping);
|
||||
return;
|
||||
}
|
||||
_itemAddToCart(cartLineItem: cartLineItem);
|
||||
}
|
||||
|
||||
_productImageTapped(int i) {
|
||||
|
||||
@ -68,9 +68,7 @@ class _ProductImageViewerPageState extends State<ProductImageViewerPage> {
|
||||
Container(
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.close),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||
|
||||
import '../helpers/tools.dart';
|
||||
|
||||
@ -36,13 +37,18 @@ Widget wsSecondaryButton(BuildContext context,
|
||||
height: 60,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: RaisedButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||
textAlign: TextAlign.center),
|
||||
onPressed: action,
|
||||
color: HexColor("#f6f6f9"),
|
||||
elevation: 0),
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1.copyWith(
|
||||
color: Colors.black87,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
onPressed: action,
|
||||
color: HexColor("#f6f6f9"),
|
||||
elevation: 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -53,9 +59,11 @@ Widget wsLinkButton(BuildContext context,
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: MaterialButton(
|
||||
padding: EdgeInsets.all(10),
|
||||
child: Text(title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||
textAlign: TextAlign.left),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
onPressed: action,
|
||||
elevation: 0,
|
||||
),
|
||||
|
||||
@ -51,9 +51,8 @@ Widget wsCartIcon(BuildContext context, {Key key}) {
|
||||
top: 0)
|
||||
],
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, "/cart");
|
||||
},
|
||||
onPressed: () => Navigator.pushNamed(context, "/cart")
|
||||
.then((value) => setState(() {})),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -23,8 +23,10 @@ Widget wsMenuItem(BuildContext context,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
leading,
|
||||
Text(" " + title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText2),
|
||||
Text(
|
||||
" " + title,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -34,11 +34,13 @@ Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
||||
),
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: Text(text2,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText1
|
||||
.copyWith(fontSize: 16, color: Colors.black87)),
|
||||
child: Text(
|
||||
text2,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText1
|
||||
.copyWith(fontSize: 16, color: Colors.black87),
|
||||
),
|
||||
),
|
||||
flex: 3,
|
||||
)
|
||||
@ -87,22 +89,24 @@ Widget wsCheckoutRow(BuildContext context,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
leadImage,
|
||||
Flexible(
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Text(leadTitle,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.subtitle1,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false),
|
||||
child: Text(
|
||||
leadTitle,
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.subtitle1,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: false,
|
||||
),
|
||||
padding: EdgeInsets.only(left: 15),
|
||||
margin: EdgeInsets.only(right: 10),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Icon(Icons.arrow_forward_ios)
|
||||
Icon(Icons.arrow_forward_ios),
|
||||
],
|
||||
),
|
||||
)
|
||||
@ -111,8 +115,10 @@ Widget wsCheckoutRow(BuildContext context,
|
||||
padding: EdgeInsets.all(8),
|
||||
decoration: showBorderBottom == true
|
||||
? BoxDecoration(
|
||||
border:
|
||||
Border(bottom: BorderSide(color: Colors.black12, width: 1)))
|
||||
border: Border(
|
||||
bottom: BorderSide(color: Colors.black12, width: 1),
|
||||
),
|
||||
)
|
||||
: BoxDecoration(),
|
||||
),
|
||||
onTap: action,
|
||||
@ -135,20 +141,23 @@ Widget wsTextEditingRow(BuildContext context,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Padding(
|
||||
child: Text(heading,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||
child: Text(
|
||||
heading,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||
),
|
||||
padding: EdgeInsets.only(bottom: 2),
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
keyboardType: keyboardType ?? TextInputType.text,
|
||||
autocorrect: false,
|
||||
autofocus: shouldAutoFocus ?? false,
|
||||
obscureText: obscureText ?? false,
|
||||
textCapitalization: TextCapitalization.sentences),
|
||||
controller: controller,
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
keyboardType: keyboardType ?? TextInputType.text,
|
||||
autocorrect: false,
|
||||
autofocus: shouldAutoFocus ?? false,
|
||||
obscureText: obscureText ?? false,
|
||||
textCapitalization: TextCapitalization.sentences,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
@ -210,11 +219,12 @@ Widget wsCardProductItem(BuildContext context,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl:
|
||||
(product.images.length > 0 ? product.images.first.src : ""),
|
||||
placeholder: (context, url) => new CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => new Icon(Icons.error),
|
||||
fit: BoxFit.contain),
|
||||
imageUrl:
|
||||
(product.images.length > 0 ? product.images.first.src : ""),
|
||||
placeholder: (context, url) => new CircularProgressIndicator(),
|
||||
errorWidget: (context, url, error) => new Icon(Icons.error),
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
flex: 4,
|
||||
),
|
||||
Flexible(
|
||||
@ -233,8 +243,9 @@ Widget wsCardProductItem(BuildContext context,
|
||||
child: Text(
|
||||
formatStringCurrency(total: product.regularPrice),
|
||||
style: Theme.of(context).textTheme.bodyText1.copyWith(
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: Colors.grey),
|
||||
decoration: TextDecoration.lineThrough,
|
||||
color: Colors.grey,
|
||||
),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
)
|
||||
@ -283,23 +294,27 @@ void wsModalBottom(BuildContext context,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 16),
|
||||
child: Text(title,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline4
|
||||
.copyWith(fontSize: 20),
|
||||
textAlign: TextAlign.left),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.headline4
|
||||
.copyWith(fontSize: 20),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: wsBoxShadow(),
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8)),
|
||||
child: bodyWidget),
|
||||
padding:
|
||||
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
boxShadow: wsBoxShadow(),
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: bodyWidget,
|
||||
),
|
||||
),
|
||||
extraWidget ?? null
|
||||
].where((t) => t != null).toList(),
|
||||
@ -390,8 +405,11 @@ FutureBuilder wsCheckoutSubtotalWidgetFB({String title}) {
|
||||
return Text("");
|
||||
else
|
||||
return new Padding(
|
||||
child: widgetCheckoutMeta(context,
|
||||
title: title, amount: snapshot.data),
|
||||
child: widgetCheckoutMeta(
|
||||
context,
|
||||
title: title,
|
||||
amount: snapshot.data,
|
||||
),
|
||||
padding: EdgeInsets.only(bottom: 0, top: 0),
|
||||
);
|
||||
}
|
||||
@ -436,109 +454,108 @@ Widget wsCardCartItem(BuildContext context,
|
||||
void Function() actionDecrementQuantity,
|
||||
void Function() actionRemoveItem}) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 7),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black12,
|
||||
width: 1,
|
||||
))),
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: cartLineItem.imageSrc,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fit: BoxFit.contain,
|
||||
margin: EdgeInsets.only(bottom: 7),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black12,
|
||||
width: 1,
|
||||
))),
|
||||
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: CachedNetworkImage(
|
||||
imageUrl: cartLineItem.imageSrc,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
flex: 2,
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
cartLineItem.name,
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
(cartLineItem.variationOptions != null
|
||||
? Text(cartLineItem.variationOptions,
|
||||
style: Theme.of(context).primaryTextTheme.bodyText1)
|
||||
: Container()),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(cartLineItem.stockStatus == "outofstock"
|
||||
? trans(context, "Out of stock")
|
||||
: trans(context, "In Stock")),
|
||||
style: (cartLineItem.stockStatus == "outofstock"
|
||||
? Theme.of(context).textTheme.caption
|
||||
: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText2)),
|
||||
Text(
|
||||
formatDoubleCurrency(
|
||||
total: double.parse(cartLineItem.total)),
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
textAlign: TextAlign.center)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
flex: 2,
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
),
|
||||
Flexible(
|
||||
child: Padding(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
cartLineItem.name,
|
||||
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 3,
|
||||
),
|
||||
(cartLineItem.variationOptions != null
|
||||
? Text(cartLineItem.variationOptions,
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.bodyText1)
|
||||
: Container()),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
(cartLineItem.stockStatus == "outofstock"
|
||||
? trans(context, "Out of stock")
|
||||
: trans(context, "In Stock")),
|
||||
style: (cartLineItem.stockStatus == "outofstock"
|
||||
? Theme.of(context).textTheme.caption
|
||||
: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.bodyText2)),
|
||||
Text(
|
||||
formatDoubleCurrency(
|
||||
total: double.parse(cartLineItem.total)),
|
||||
style:
|
||||
Theme.of(context).primaryTextTheme.subtitle1,
|
||||
textAlign: TextAlign.center)
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: EdgeInsets.only(left: 8),
|
||||
flex: 5,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_circle_outline),
|
||||
onPressed: actionIncrementQuantity,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
flex: 5,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_circle_outline),
|
||||
onPressed: actionIncrementQuantity,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
Text(cartLineItem.quantity.toString(),
|
||||
style: Theme.of(context).primaryTextTheme.headline6),
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove_circle_outline),
|
||||
onPressed: actionDecrementQuantity,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
alignment: Alignment.centerRight,
|
||||
icon: Icon(Icons.delete_outline,
|
||||
color: Colors.deepOrangeAccent, size: 20),
|
||||
onPressed: actionRemoveItem,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
));
|
||||
Text(cartLineItem.quantity.toString(),
|
||||
style: Theme.of(context).primaryTextTheme.headline6),
|
||||
IconButton(
|
||||
icon: Icon(Icons.remove_circle_outline),
|
||||
onPressed: actionDecrementQuantity,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
],
|
||||
),
|
||||
IconButton(
|
||||
alignment: Alignment.centerRight,
|
||||
icon: Icon(Icons.delete_outline,
|
||||
color: Colors.deepOrangeAccent, size: 20),
|
||||
onPressed: actionRemoveItem,
|
||||
highlightColor: Colors.transparent,
|
||||
),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget storeLogo({double height, double width}) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
# Label StoreMax
|
||||
# Version 2.0.2
|
||||
# Version 2.0.3
|
||||
#authors: - "Anthony Gordon"
|
||||
#documentation: https://woosignal.com/docs/app/ios/label-storemax
|
||||
#homepage: https://woosignal.com/
|
||||
|
||||
Loading…
Reference in New Issue
Block a user