New state options for taxes/shipping, Handle variations better, Code clean up, Bug fixes

This commit is contained in:
WooSignal 2020-05-12 00:06:42 +01:00
parent 2ae50623d6
commit cc9d5d75cb
31 changed files with 878 additions and 595 deletions

View File

@ -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

View File

@ -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"
} }

View 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"}
];

View File

@ -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),

View File

@ -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;

View File

@ -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";
} }

View File

@ -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;

View File

@ -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,

View File

@ -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(

View File

@ -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

View File

@ -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)),
], ],
), ),
), ),

View File

@ -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),
), ),

View File

@ -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,
),
), ),
], ],
), ),

View File

@ -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",

View File

@ -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(() {

View File

@ -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;

View File

@ -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,
),
], ],
), ),
), ),

View File

@ -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;
} }

View File

@ -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;

View File

@ -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(

View File

@ -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),
), ),

View File

@ -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,
), ),

View File

@ -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)),
], ],
), ),
), ),

View File

@ -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,
),
], ],
), ),
), ),

View File

@ -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) {

View File

@ -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);
},
), ),
) )
], ],

View File

@ -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,
), ),

View File

@ -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(() {})),
},
), ),
); );
} }

View File

@ -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,
),
], ],
), ),
), ),

View File

@ -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}) {

View File

@ -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/