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