diff --git a/LabelStoreMax/CHANGELOG.md b/LabelStoreMax/CHANGELOG.md index c8e996a..c647fe6 100644 --- a/LabelStoreMax/CHANGELOG.md +++ b/LabelStoreMax/CHANGELOG.md @@ -1,3 +1,11 @@ +## [2.0.9] - 2020-06-19 + +* New UI for home products +* Added pull to refresh to user orders +* Pubspec.yaml updates +* Flutter v1.17.3 support +* Bug fixes + ## [2.0.8] - 2020-06-04 * Added pull to refresh diff --git a/LabelStoreMax/ios/Flutter/.last_build_id b/LabelStoreMax/ios/Flutter/.last_build_id new file mode 100644 index 0000000..166ef32 --- /dev/null +++ b/LabelStoreMax/ios/Flutter/.last_build_id @@ -0,0 +1 @@ +b98ea22bbb9eb082f24a2f56c80c348a \ No newline at end of file diff --git a/LabelStoreMax/ios/Runner.xcodeproj/project.pbxproj b/LabelStoreMax/ios/Runner.xcodeproj/project.pbxproj index 1e9b492..7d298ff 100644 --- a/LabelStoreMax/ios/Runner.xcodeproj/project.pbxproj +++ b/LabelStoreMax/ios/Runner.xcodeproj/project.pbxproj @@ -169,6 +169,7 @@ TargetAttributes = { 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; + DevelopmentTeam = YPEM49WRL2; LastSwiftMigration = 0910; }; }; @@ -337,7 +338,6 @@ /* Begin XCBuildConfiguration section */ 249021D3217E4FDB00AE95B9 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -392,7 +392,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YPEM49WRL2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -416,7 +416,6 @@ }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -472,7 +471,6 @@ }; 97C147041CF9000F007C117D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -528,7 +526,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YPEM49WRL2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -558,7 +556,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = YPEM49WRL2; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/LabelStoreMax/lang/de.json b/LabelStoreMax/lang/de.json index 44a1e00..737c17a 100644 --- a/LabelStoreMax/lang/de.json +++ b/LabelStoreMax/lang/de.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "Die Rechnungsadresse ist unvollständig", "Order": "Auftrag", "Date Ordered": "Bestelldatum", - "Ships to": "Schiffe nach" + "Ships to": "Schiffe nach", + "That email does not match our records": "Diese E-Mail stimmt nicht mit unseren Aufzeichnungen überein", + "That username does not match our records": "Dieser Benutzername stimmt nicht mit unseren Datensätzen überein", + "That password does not match our records": "Dieses Passwort stimmt nicht mit unseren Aufzeichnungen überein", + "The email and password field cannot be empty": "Das Feld für E-Mail und Passwort darf nicht leer sein", + "Username taken, try another.": "Benutzername genommen, versuchen Sie es mit einem anderen.", + "A user already exists": "Ein Benutzer existiert bereits", + "That email is taken, try another": "Diese E-Mail wird genommen, versuchen Sie es mit einer anderen", + "The email field is empty": "Das E-Mail-Feld ist leer", + "No more orders": "Keine Bestellungen mehr", + "Account updated": "Konto aktualisiert" } \ No newline at end of file diff --git a/LabelStoreMax/lang/en.json b/LabelStoreMax/lang/en.json index 3ffa943..48eccd3 100644 --- a/LabelStoreMax/lang/en.json +++ b/LabelStoreMax/lang/en.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "Billing address is incomplete", "Order": "Order", "Date Ordered": "Date Ordered", - "Ships to": "Ships to" + "Ships to": "Ships to", + "That email does not match our records": "That email does not match our records", + "That username does not match our records": "That username does not match our records", + "That password does not match our records": "That password does not match our records", + "The email and password field cannot be empty": "The email and password field cannot be empty", + "Username taken, try another.": "That username is taken, try another.", + "A user already exists": "A user already exists", + "That email is taken, try another": "That email is taken, try another", + "The email field is empty": "The email field is empty", + "No more orders": "No more orders", + "Account updated": "Account updated" } \ No newline at end of file diff --git a/LabelStoreMax/lang/es.json b/LabelStoreMax/lang/es.json index 6a7ad54..2243345 100644 --- a/LabelStoreMax/lang/es.json +++ b/LabelStoreMax/lang/es.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "La dirección de facturación está incompleta", "Order": "Orden", "Date Ordered": "fecha del pedido", - "Ships to": "Realiza envíos a" + "Ships to": "Realiza envíos a", + "That email does not match our records": "Ese correo electrónico no coincide con nuestros registros.", + "That username does not match our records": "Ese nombre de usuario no coincide con nuestros registros.", + "That password does not match our records": "Esa contraseña no coincide con nuestros registros.", + "The email and password field cannot be empty": "El campo de correo electrónico y contraseña no puede estar vacío", + "Username taken, try another.": "Nombre de usuario tomado, intente con otro..", + "A user already exists": "Ya existe un usuario", + "That email is taken, try another": "Ese correo electrónico está tomado, prueba con otro", + "The email field is empty": "El campo de correo electrónico está vacío.", + "No more orders": "No mas pedidos", + "Account updated": "Cuenta actualizada" } \ No newline at end of file diff --git a/LabelStoreMax/lang/fr.json b/LabelStoreMax/lang/fr.json index 152d672..708be8b 100644 --- a/LabelStoreMax/lang/fr.json +++ b/LabelStoreMax/lang/fr.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "L'adresse de facturation est incomplète", "Order": "Ordre", "Date Ordered": "Date de commande", - "Ships to": "Expédié à" + "Ships to": "Expédié à", + "That email does not match our records": "Cet e-mail ne correspond pas à nos enregistrements", + "That username does not match our records": "Ce nom d'utilisateur ne correspond pas à nos enregistrements", + "That password does not match our records": "Ce mot de passe ne correspond pas à nos enregistrements", + "The email and password field cannot be empty": "Le champ e-mail et mot de passe ne peut pas être vide", + "Username taken, try another.": "Ce nom d'utilisateur est pris, essayez-en un autre.", + "A user already exists": "Un utilisateur existe déjà", + "That email is taken, try another": "Cet e-mail est pris, essayez un autre", + "The email field is empty": "Le champ e-mail est vide", + "No more orders": "Plus de commandes", + "Account updated": "Compte mis à jour" } \ No newline at end of file diff --git a/LabelStoreMax/lang/hi.json b/LabelStoreMax/lang/hi.json index c75e767..ba991c9 100644 --- a/LabelStoreMax/lang/hi.json +++ b/LabelStoreMax/lang/hi.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "biling pata adhoora hai", "Order": "gan", "Date Ordered": "ordar ka dinaank", - "Ships to": "ko bheje" + "Ships to": "ko bheje", + "That email does not match our records": "vah eemel hamaare rikord se mel nahin khaata hai", + "That username does not match our records": "vah upayogakarta naam hamaare rikord se mel nahin khaata hai", + "That password does not match our records": "vah paasavard hamaare rikord se mel nahin khaata hai", + "The email and password field cannot be empty": "eemel aur paasavard feeld khaalee nahin ho sakata", + "Username taken, try another.": "vah upayogakarta naam liya gaya hai, doosara prayaas karen.", + "A user already exists": "ek upayogakarta pahale se maujood hai", + "That email is taken, try another": "vah eemel liya gaya hai, doosara prayaas karen", + "The email field is empty": "eemel feeld khaalee hai", + "No more orders": "aur koee aadesh nahin", + "Account updated": "khaata apadet kiya gaya" } \ No newline at end of file diff --git a/LabelStoreMax/lang/it.json b/LabelStoreMax/lang/it.json index 9095877..896dd7b 100644 --- a/LabelStoreMax/lang/it.json +++ b/LabelStoreMax/lang/it.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "L'indirizzo di fatturazione è incompleto", "Order": "Ordine", "Date Ordered": "Data ordinata", - "Ships to": "Spedire a" + "Ships to": "Spedire a", + "That email does not match our records": "Quell'email non corrisponde ai nostri record", + "That username does not match our records": "Quel nome utente non corrisponde ai nostri record", + "That password does not match our records": "Quella password non corrisponde ai nostri record", + "The email and password field cannot be empty": "Il campo e-mail e password non possono essere vuoti", + "Username taken, try another.": "Quel nome utente è preso, provane un altro.", + "A user already exists": "Un utente esiste già", + "That email is taken, try another": "Quell'e-mail è stata presa, provane un'altra", + "The email field is empty": "Il campo email è vuoto", + "No more orders": "Niente più ordini", + "Account updated": "Account aggiornato" } \ No newline at end of file diff --git a/LabelStoreMax/lang/pt.json b/LabelStoreMax/lang/pt.json index 148cb2d..8623879 100644 --- a/LabelStoreMax/lang/pt.json +++ b/LabelStoreMax/lang/pt.json @@ -159,5 +159,15 @@ "Billing address is incomplete": "O endereço de cobrança está incompleto", "Order": "Ordem", "Date Ordered": "Data da Encomenda", - "Ships to": "Envia para" + "Ships to": "Envia para", + "That email does not match our records": "Esse email não corresponde aos nossos registros", + "That username does not match our records": "Esse nome de usuário não corresponde aos nossos registros", + "That password does not match our records": "Essa senha não corresponde aos nossos registros", + "The email and password field cannot be empty": "O campo de email e senha não pode estar vazio", + "Username taken, try another.": "Esse nome de usuário é usado, tente outro.", + "A user already exists": "Um usuário já existe", + "That email is taken, try another": "Esse e-mail foi recebido, tente outro", + "The email field is empty": "O campo de email está vazio", + "No more orders": "Não há mais pedidos", + "Account updated": "Conta atualizada" } \ No newline at end of file diff --git a/LabelStoreMax/lib/helpers/tools.dart b/LabelStoreMax/lib/helpers/tools.dart index 8577a4a..d7d79fd 100644 --- a/LabelStoreMax/lib/helpers/tools.dart +++ b/LabelStoreMax/lib/helpers/tools.dart @@ -8,6 +8,8 @@ // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +import 'dart:developer'; + import 'package:flutter/cupertino.dart'; import 'package:intl/intl.dart'; import 'package:label_storemax/app_payment_methods.dart'; @@ -471,6 +473,8 @@ String capitalize(String s) => s[0].toUpperCase() + s.substring(1); double parseWcPrice(String price) => (double.tryParse(price) ?? 0); +void appLogOutput(dynamic message) => (app_debug == true ? log(message) : null); + Widget refreshableScroll(context, {@required refreshController, @required VoidCallback onRefresh, @@ -507,7 +511,6 @@ Widget refreshableScroll(context, child: (products.length != null && products.length > 0 ? GridView.count( crossAxisCount: 2, - childAspectRatio: calAspectRatio(context), shrinkWrap: true, children: List.generate( products.length, @@ -521,11 +524,11 @@ Widget refreshableScroll(context, double calAspectRatio(BuildContext context) { if (MediaQuery.of(context).size.height > 800) { return MediaQuery.of(context).size.width / - (MediaQuery.of(context).size.height / 1.75); + (MediaQuery.of(context).size.height / 1.65); } if (MediaQuery.of(context).size.height > 700) { return MediaQuery.of(context).size.width / - (MediaQuery.of(context).size.height / 1.5); + (MediaQuery.of(context).size.height / 1.35); } return MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 1.3); diff --git a/LabelStoreMax/lib/labelconfig.dart b/LabelStoreMax/lib/labelconfig.dart index 3ee95f0..e89d792 100644 --- a/LabelStoreMax/lib/labelconfig.dart +++ b/LabelStoreMax/lib/labelconfig.dart @@ -16,7 +16,7 @@ import 'dart:ui'; Developer Notes SUPPORT EMAIL - support@woosignal.com - VERSION - 2.0.8 + VERSION - 2.0.9 https://woosignal.com */ diff --git a/LabelStoreMax/lib/pages/account_billing_details.dart b/LabelStoreMax/lib/pages/account_billing_details.dart index bb1d7de..384ab21 100644 --- a/LabelStoreMax/lib/pages/account_billing_details.dart +++ b/LabelStoreMax/lib/pages/account_billing_details.dart @@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.dart'; import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/buttons.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; -import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart'; -import 'package:wp_json_api/models/responses/WCCustomerUpdatedResponse.dart'; +import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; +import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountBillingDetailsPage extends StatefulWidget { @@ -182,7 +182,6 @@ class _AccountBillingDetailsPageState extends State { BoxShadow( color: HexColor("#e8e8e8"), blurRadius: 15.0, - // has the effect of softening the shadow spreadRadius: 0, offset: Offset( 0, @@ -228,28 +227,35 @@ class _AccountBillingDetailsPageState extends State { _isUpdating = true; }); - WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI - .instance - .api((request) => request.wcUpdateCustomerInfo(userToken, - billingFirstName: firstName, - billingLastName: lastName, - billingAddress1: addressLine, - billingCity: city, - billingState: state, - billingPostcode: postalCode, - billingCountry: country)); - - setState(() { - _isUpdating = false; - }); - - if (wcCustomerUpdatedResponse.status != 200) { + WCCustomerUpdatedResponse wcCustomerUpdatedResponse; + try { + wcCustomerUpdatedResponse = await WPJsonAPI.instance.api((request) => + request.wcUpdateCustomerInfo(userToken, + billingFirstName: firstName, + billingLastName: lastName, + billingAddress1: addressLine, + billingCity: city, + billingState: state, + billingPostcode: postalCode, + billingCountry: country)); + } on Exception catch (_) { showEdgeAlertWith(context, title: trans(context, "Oops!"), desc: trans(context, "Something went wrong"), - style: EdgeAlertStyle.WARNING); - return; + style: EdgeAlertStyle.DANGER); + } finally { + setState(() { + _isUpdating = false; + }); + } + + if (wcCustomerUpdatedResponse != null && + wcCustomerUpdatedResponse.status == 200) { + showEdgeAlertWith(context, + title: trans(context, "Success"), + desc: trans(context, "Account updated"), + style: EdgeAlertStyle.SUCCESS); + Navigator.pop(context); } - Navigator.pop(context); } } diff --git a/LabelStoreMax/lib/pages/account_detail.dart b/LabelStoreMax/lib/pages/account_detail.dart index e619eec..fca2a93 100644 --- a/LabelStoreMax/lib/pages/account_detail.dart +++ b/LabelStoreMax/lib/pages/account_detail.dart @@ -16,8 +16,9 @@ import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart'; import 'package:label_storemax/helpers/tools.dart'; import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; +import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:woosignal/models/response/order.dart'; -import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart'; +import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountDetailPage extends StatefulWidget { @@ -27,6 +28,12 @@ class AccountDetailPage extends StatefulWidget { class _AccountDetailPageState extends State with SingleTickerProviderStateMixin { + RefreshController _refreshController = + RefreshController(initialRefresh: false); + + bool _shouldStopRequests; + bool waitForNextRequest; + int _page; List _orders; WCCustomerInfoResponse _wcCustomerInfoResponse; @@ -41,6 +48,9 @@ class _AccountDetailPageState extends State @override void initState() { super.initState(); + _shouldStopRequests = false; + waitForNextRequest = false; + _isLoading = true; _isLoadingOrders = true; _page = 1; @@ -56,17 +66,31 @@ class _AccountDetailPageState extends State } _fetchWpUserData() async { - WCCustomerInfoResponse wcCustomerInfoResponse = - await WPJsonAPI.instance.api((request) async { - return request.wcCustomerInfo(await readAuthToken()); - }); + String userToken = await readAuthToken(); - if (wcCustomerInfoResponse != null) { - _wcCustomerInfoResponse = wcCustomerInfoResponse; + WCCustomerInfoResponse wcCustomerInfoResponse; + try { + wcCustomerInfoResponse = await WPJsonAPI.instance + .api((request) => request.wcCustomerInfo(userToken)); + } on Exception catch (_) { + showEdgeAlertWith( + context, + title: trans(context, "Oops!"), + desc: trans(context, "Something went wrong"), + style: EdgeAlertStyle.DANGER, + ); + } finally { + setState(() { + _isLoading = false; + }); + } + + if (wcCustomerInfoResponse != null && + wcCustomerInfoResponse.status == 200) { + setState(() { + _wcCustomerInfoResponse = wcCustomerInfoResponse; + }); } - setState(() { - _isLoading = false; - }); } @override @@ -113,7 +137,9 @@ class _AccountDetailPageState extends State margin: EdgeInsets.only(top: 10), child: CircleAvatar( backgroundImage: NetworkImage( - _wcCustomerInfoResponse.data.avatar, + _wcCustomerInfoResponse != null + ? _wcCustomerInfoResponse.data.avatar + : "", ), ), height: 90, @@ -252,18 +278,27 @@ class _AccountDetailPageState extends State _fetchOrders() async { String userId = await readUserId(); - if (userId == null) { + if (userId == null || _shouldStopRequests == true) { setState(() { _isLoadingOrders = false; _activeBody = _widgetOrders(); }); return; } - _orders = await appWooSignal((api) { - return api.getOrders( - customer: int.parse(userId), page: _page, perPage: 100); - }); + + List orders = await appWooSignal((api) => + api.getOrders(customer: int.parse(userId), page: _page, perPage: 50)); + + if (orders.length <= 0) { + setState(() { + _shouldStopRequests = true; + }); + return; + } + setState(() { + _page += 1; + _orders.addAll(orders); _isLoadingOrders = false; _activeBody = _widgetOrders(); }); @@ -272,127 +307,183 @@ class _AccountDetailPageState extends State Widget _widgetOrders() { return _isLoadingOrders ? showAppLoader() - : _orders.length <= 0 - ? Center( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon( - Icons.shopping_cart, - color: Colors.black54, - size: 40, - ), - Text( - trans(context, "No orders found"), - ), - ], - ), - ) - : ListView.builder( - itemBuilder: (cxt, i) { - return Card( - child: ListTile( - contentPadding: - EdgeInsets.only(top: 5, bottom: 5, left: 8, right: 6), - title: Container( - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: HexColor("#fcfcfc"), - width: 1, + : SmartRefresher( + enablePullDown: true, + enablePullUp: true, + footer: CustomFooter( + builder: (BuildContext context, LoadStatus mode) { + Widget body; + if (mode == LoadStatus.idle) { + body = Text(trans(context, "pull up load")); + } else if (mode == LoadStatus.loading) { + body = CupertinoActivityIndicator(); + } else if (mode == LoadStatus.failed) { + body = Text(trans(context, "Load Failed! Click retry!")); + } else if (mode == LoadStatus.canLoading) { + body = Text(trans(context, "release to load more")); + } else { + body = Text(trans(context, "No more orders")); + } + return Container( + height: 55.0, + child: Center(child: body), + ); + }, + ), + controller: _refreshController, + onRefresh: _onRefresh, + onLoading: _onLoading, + child: (_orders.length != null && _orders.length > 0 + ? ListView.builder( + itemBuilder: (cxt, i) { + return Card( + child: ListTile( + contentPadding: EdgeInsets.only( + top: 5, bottom: 5, left: 8, right: 6), + title: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: HexColor("#fcfcfc"), + width: 1, + ), + ), ), - ), - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "#" + _orders[i].id.toString(), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - Text( - capitalize(_orders[i].status), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), - ), - subtitle: Padding( - padding: const EdgeInsets.only(top: 10), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - formatStringCurrency(total: _orders[i].total), - style: Theme.of(context) - .primaryTextTheme - .bodyText2 - .copyWith( - fontWeight: FontWeight.w600, - color: Colors.black), - textAlign: TextAlign.left, + "#" + _orders[i].id.toString(), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), Text( - _orders[i].lineItems.length.toString() + - " " + - trans(context, "items"), + capitalize(_orders[i].status), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + subtitle: Padding( + padding: const EdgeInsets.only(top: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + formatStringCurrency( + total: _orders[i].total), + style: Theme.of(context) + .primaryTextTheme + .bodyText2 + .copyWith( + fontWeight: FontWeight.w600, + color: Colors.black), + textAlign: TextAlign.left, + ), + Text( + _orders[i].lineItems.length.toString() + + " " + + trans(context, "items"), + style: Theme.of(context) + .primaryTextTheme + .bodyText1 + .copyWith( + fontWeight: FontWeight.w600, + color: Colors.black), + textAlign: TextAlign.left, + ), + ], + ), + Text( + dateFormatted( + date: _orders[i].dateCreated, + formatType: + formatForDateTime(FormatType.Date), + ) + + "\n" + + dateFormatted( + date: _orders[i].dateCreated, + formatType: + formatForDateTime(FormatType.Time), + ), + textAlign: TextAlign.right, style: Theme.of(context) .primaryTextTheme .bodyText1 .copyWith( - fontWeight: FontWeight.w600, - color: Colors.black), - textAlign: TextAlign.left, + fontWeight: FontWeight.w400, + color: Colors.black, + ), ), ], ), - Text( - dateFormatted( - date: _orders[i].dateCreated, - formatType: - formatForDateTime(FormatType.Date), - ) + - "\n" + - dateFormatted( - date: _orders[i].dateCreated, - formatType: - formatForDateTime(FormatType.Time), - ), - textAlign: TextAlign.right, - style: Theme.of(context) - .primaryTextTheme - .bodyText1 - .copyWith( - fontWeight: FontWeight.w400, - color: Colors.black), - ), - ], + ), + trailing: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.chevron_right), + ], + ), + onTap: () => _viewProfileDetail(i), ), - ), - trailing: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.chevron_right), - ], - ), - onTap: () { - int orderId = _orders[i].id; - Navigator.pushNamed(context, "/account-order-detail", - arguments: orderId); - }, + ); + }, + itemCount: _orders.length, + ) + : Center( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon( + Icons.shopping_cart, + color: Colors.black54, + size: 40, + ), + Text( + trans(context, "No orders found"), + ), + ], ), - ); - }, - itemCount: _orders.length, - ); + )), + ); + } + + void _onRefresh() async { + _orders = []; + _page = 1; + _shouldStopRequests = false; + waitForNextRequest = false; + await _fetchOrders(); + _refreshController.refreshCompleted(); + } + + void _onLoading() async { + await _fetchOrders(); + + if (mounted) { + setState(() {}); + if (_shouldStopRequests) { + _refreshController.loadNoData(); + } else { + _refreshController.loadComplete(); + } + } + } + + _viewProfileDetail(int i) { + int orderId = _orders[i].id; + Navigator.pushNamed( + context, + "/account-order-detail", + arguments: orderId, + ); } } diff --git a/LabelStoreMax/lib/pages/account_landing.dart b/LabelStoreMax/lib/pages/account_landing.dart index c03c1e2..654b4cc 100644 --- a/LabelStoreMax/lib/pages/account_landing.dart +++ b/LabelStoreMax/lib/pages/account_landing.dart @@ -17,7 +17,11 @@ import 'package:label_storemax/labelconfig.dart'; import 'package:label_storemax/widgets/buttons.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; import 'package:url_launcher/url_launcher.dart'; -import 'package:wp_json_api/models/responses/WPUserLoginResponse.dart'; +import 'package:wp_json_api/exceptions/incorrect_password_exception.dart'; +import 'package:wp_json_api/exceptions/invalid_email_exception.dart'; +import 'package:wp_json_api/exceptions/invalid_nonce_exception.dart'; +import 'package:wp_json_api/exceptions/invalid_username_exception.dart'; +import 'package:wp_json_api/models/responses/wp_user_login_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountLandingPage extends StatefulWidget { @@ -148,16 +152,69 @@ class _AccountLandingPageState extends State { String email = _tfEmailController.text; String password = _tfPasswordController.text; + if (email != null) { + email = email.trim(); + } + + if (email == "" || password == "") { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans(context, "The email and password field cannot be empty"), + style: EdgeAlertStyle.DANGER); + return; + } + + if (!isEmail(email)) { + showEdgeAlertWith(context, + title: trans(context, "Oops"), + desc: trans(context, "That email address is not valid"), + style: EdgeAlertStyle.DANGER); + return; + } + if (_hasTappedLogin == false) { setState(() { _hasTappedLogin = true; }); - WPUserLoginResponse wpUserLoginResponse = await WPJsonAPI.instance - .api((request) => request.wpLogin(email: email, password: password)); - _hasTappedLogin = false; + WPUserLoginResponse wpUserLoginResponse; + try { + wpUserLoginResponse = await WPJsonAPI.instance.api( + (request) => request.wpLogin(email: email, password: password)); + } on InvalidNonceException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans( + context, "Something went wrong, please contact our store"), + style: EdgeAlertStyle.DANGER); + } on InvalidEmailException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans(context, "That email does not match our records"), + style: EdgeAlertStyle.DANGER); + } on InvalidUsernameException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans(context, "That username does not match our records"), + style: EdgeAlertStyle.DANGER); + } on IncorrectPasswordException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans(context, "That password does not match our records"), + style: EdgeAlertStyle.DANGER); + } on Exception catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, "Invalid login credentials"), + style: EdgeAlertStyle.DANGER, + icon: Icons.account_circle); + } finally { + setState(() { + _hasTappedLogin = false; + }); + } - if (wpUserLoginResponse != null) { + if (wpUserLoginResponse != null && wpUserLoginResponse.status == 200) { String token = wpUserLoginResponse.data.userToken; authUser(token); storeUserId(wpUserLoginResponse.data.userId.toString()); @@ -169,15 +226,6 @@ class _AccountLandingPageState extends State { icon: Icons.account_circle); navigatorPush(context, routeName: UserAuth.instance.redirect, forgetLast: 1); - } else { - showEdgeAlertWith(context, - title: trans(context, "Oops!"), - desc: trans(context, "Invalid login credentials"), - style: EdgeAlertStyle.WARNING, - icon: Icons.account_circle); - setState(() { - _hasTappedLogin = false; - }); } } } diff --git a/LabelStoreMax/lib/pages/account_order_detail.dart b/LabelStoreMax/lib/pages/account_order_detail.dart index a495842..bae6acf 100644 --- a/LabelStoreMax/lib/pages/account_order_detail.dart +++ b/LabelStoreMax/lib/pages/account_order_detail.dart @@ -134,8 +134,10 @@ class _AccountOrderDetailPageState extends State { ), ), Text( - capitalize(formatStringCurrency( - total: _order.lineItems[i].price)), + capitalize( + formatStringCurrency( + total: _order.lineItems[i].price), + ), maxLines: 1, overflow: TextOverflow.ellipsis, ), diff --git a/LabelStoreMax/lib/pages/account_profile_update.dart b/LabelStoreMax/lib/pages/account_profile_update.dart index f9e807a..7ae2ea9 100644 --- a/LabelStoreMax/lib/pages/account_profile_update.dart +++ b/LabelStoreMax/lib/pages/account_profile_update.dart @@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.dart'; import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/buttons.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; -import 'package:wp_json_api/models/responses/WPUserInfoResponse.dart'; -import 'package:wp_json_api/models/responses/WPUserInfoUpdatedResponse.dart'; +import 'package:wp_json_api/models/responses/wp_user_info_response.dart'; +import 'package:wp_json_api/models/responses/wp_user_info_updated_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountProfileUpdatePage extends StatefulWidget { @@ -132,22 +132,31 @@ class _AccountProfileUpdatePageState extends State { ); } - bool _isNetworking = false; _updateDetails() async { String firstName = _tfFirstName.text; String lastName = _tfLastName.text; - if (_isNetworking == false) { + if (isLoading == false) { setState(() { - _isNetworking = true; isLoading = true; }); - WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = - await WPJsonAPI.instance.api((request) async { - return request.wpUpdateUserInfo(await readAuthToken(), - firstName: firstName, lastName: lastName); - }); + String userToken = await readAuthToken(); + WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse; + try { + wpUserInfoUpdatedResponse = await WPJsonAPI.instance.api((request) => + request.wpUpdateUserInfo(userToken, + firstName: firstName, lastName: lastName)); + } on Exception catch (e) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans(context, "Please check your email and password"), + style: EdgeAlertStyle.DANGER); + } finally { + setState(() { + isLoading = false; + }); + } if (wpUserInfoUpdatedResponse != null && wpUserInfoUpdatedResponse.status == 200) { @@ -155,16 +164,8 @@ class _AccountProfileUpdatePageState extends State { title: trans(context, "Success"), desc: trans(context, "Account updated"), style: EdgeAlertStyle.SUCCESS); - } else { - showEdgeAlertWith(context, - title: trans(context, "Invalid details"), - desc: trans(context, "Please check your email and password"), - style: EdgeAlertStyle.WARNING); + Navigator.pop(context); } - setState(() { - _isNetworking = false; - isLoading = false; - }); } } } diff --git a/LabelStoreMax/lib/pages/account_register.dart b/LabelStoreMax/lib/pages/account_register.dart index ea60704..0c7629c 100644 --- a/LabelStoreMax/lib/pages/account_register.dart +++ b/LabelStoreMax/lib/pages/account_register.dart @@ -16,7 +16,13 @@ import 'package:label_storemax/labelconfig.dart'; import 'package:label_storemax/widgets/buttons.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; import 'package:woosignal/helpers/shared_pref.dart'; -import 'package:wp_json_api/models/responses/WPUserRegisterResponse.dart'; +import 'package:wp_json_api/exceptions/empty_username_exception.dart'; +import 'package:wp_json_api/exceptions/existing_user_email_exception.dart'; +import 'package:wp_json_api/exceptions/existing_user_login_exception.dart'; +import 'package:wp_json_api/exceptions/invalid_nonce_exception.dart'; +import 'package:wp_json_api/exceptions/user_already_exist_exception.dart'; +import 'package:wp_json_api/exceptions/username_taken_exception.dart'; +import 'package:wp_json_api/models/responses/wp_user_register_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountRegistrationPage extends StatefulWidget { @@ -72,18 +78,22 @@ class _AccountRegistrationPageState extends State { child: Row( children: [ Flexible( - child: wsTextEditingRow(context, - heading: trans(context, "First Name"), - controller: _tfFirstNameController, - shouldAutoFocus: true, - keyboardType: TextInputType.text), + child: wsTextEditingRow( + context, + heading: trans(context, "First Name"), + controller: _tfFirstNameController, + shouldAutoFocus: true, + keyboardType: TextInputType.text, + ), ), Flexible( - child: wsTextEditingRow(context, - heading: trans(context, "Last Name"), - controller: _tfLastNameController, - shouldAutoFocus: false, - keyboardType: TextInputType.text), + child: wsTextEditingRow( + context, + heading: trans(context, "Last Name"), + controller: _tfLastNameController, + shouldAutoFocus: false, + keyboardType: TextInputType.text, + ), ), ], )), @@ -144,6 +154,10 @@ class _AccountRegistrationPageState extends State { String firstName = _tfFirstNameController.text; String lastName = _tfLastNameController.text; + if (email != null) { + email = email.trim(); + } + if (!isEmail(email)) { showEdgeAlertWith(context, title: trans(context, "Oops"), @@ -168,13 +182,59 @@ class _AccountRegistrationPageState extends State { String username = (email.replaceAll(new RegExp(r'(@|\.)'), "")) + randomStr(4); - WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance - .api((request) => request.wpRegister( - email: email.toLowerCase(), - password: password, - username: username)); + WPUserRegisterResponse wpUserRegisterResponse; + try { + wpUserRegisterResponse = await WPJsonAPI.instance.api( + (request) => request.wpRegister( + email: email.toLowerCase(), + password: password, + username: username, + ), + ); + } on UsernameTakenException catch (e) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, e.message), + style: EdgeAlertStyle.DANGER); + } on InvalidNonceException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Invalid details"), + desc: trans( + context, "Something went wrong, please contact our store"), + style: EdgeAlertStyle.DANGER); + } on ExistingUserLoginException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, "A user already exists"), + style: EdgeAlertStyle.DANGER); + } on ExistingUserEmailException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, "That email is taken, try another"), + style: EdgeAlertStyle.DANGER); + } on UserAlreadyExistException catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, "A user already exists"), + style: EdgeAlertStyle.DANGER); + } on EmptyUsernameException catch (e) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, e.message), + style: EdgeAlertStyle.DANGER); + } on Exception catch (_) { + showEdgeAlertWith(context, + title: trans(context, "Oops!"), + desc: trans(context, "Something went wrong"), + style: EdgeAlertStyle.DANGER); + } finally { + setState(() { + _hasTappedRegister = false; + }); + } - if (wpUserRegisterResponse != null) { + if (wpUserRegisterResponse != null && + wpUserRegisterResponse.status == 200) { String token = wpUserRegisterResponse.data.userToken; authUser(token); storeUserId(wpUserRegisterResponse.data.userId.toString()); @@ -189,14 +249,6 @@ class _AccountRegistrationPageState extends State { icon: Icons.account_circle); navigatorPush(context, routeName: UserAuth.instance.redirect, forgetLast: 2); - } else { - setState(() { - showEdgeAlertWith(context, - title: trans(context, "Invalid"), - desc: trans(context, "Please check your details"), - style: EdgeAlertStyle.WARNING); - _hasTappedRegister = false; - }); } } } diff --git a/LabelStoreMax/lib/pages/account_shipping_details.dart b/LabelStoreMax/lib/pages/account_shipping_details.dart index 8680049..79acc2e 100644 --- a/LabelStoreMax/lib/pages/account_shipping_details.dart +++ b/LabelStoreMax/lib/pages/account_shipping_details.dart @@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.dart'; import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/buttons.dart'; import 'package:label_storemax/widgets/woosignal_ui.dart'; -import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart'; -import 'package:wp_json_api/models/responses/WCCustomerUpdatedResponse.dart'; +import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; +import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart'; import 'package:wp_json_api/wp_json_api.dart'; class AccountShippingDetailsPage extends StatefulWidget { @@ -62,24 +62,39 @@ class _AccountShippingDetailsPageState } _fetchUserDetails() async { - WCCustomerInfoResponse wcCustomerInfoResponse = - await WPJsonAPI.instance.api((request) async { - return request.wcCustomerInfo(await readAuthToken()); - }); + String userToken = await readAuthToken(); - Shipping shipping = wcCustomerInfoResponse.data.shipping; - _txtShippingFirstName.text = shipping.firstName; - _txtShippingLastName.text = shipping.lastName; + WCCustomerInfoResponse wcCustomerInfoResponse; + try { + wcCustomerInfoResponse = await WPJsonAPI.instance + .api((request) => request.wcCustomerInfo(userToken)); + } on Exception catch (_) { + showEdgeAlertWith( + context, + title: trans(context, "Oops!"), + desc: trans(context, "Something went wrong"), + style: EdgeAlertStyle.DANGER, + ); + Navigator.pop(context); + return; + } finally { + setState(() { + _isLoading = false; + }); + } - _txtShippingAddressLine.text = shipping.address1; - _txtShippingCity.text = shipping.city; - _txtShippingState.text = shipping.state; - _txtShippingPostalCode.text = shipping.postcode; - _txtShippingCountry.text = shipping.country; + if (wcCustomerInfoResponse != null && + wcCustomerInfoResponse.status == 200) { + Shipping shipping = wcCustomerInfoResponse.data.shipping; + _txtShippingFirstName.text = shipping.firstName; + _txtShippingLastName.text = shipping.lastName; - setState(() { - _isLoading = false; - }); + _txtShippingAddressLine.text = shipping.address1; + _txtShippingCity.text = shipping.city; + _txtShippingState.text = shipping.state; + _txtShippingPostalCode.text = shipping.postcode; + _txtShippingCountry.text = shipping.country; + } } @override @@ -228,28 +243,46 @@ class _AccountShippingDetailsPageState String userToken = await readAuthToken(); + if (_isUpdating == true) { + return; + } + setState(() { _isUpdating = true; }); - WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI - .instance - .api((request) => request.wcUpdateCustomerInfo(userToken, - shippingFirstName: firstName, - shippingLastName: lastName, - shippingAddress1: addressLine, - shippingCity: city, - shippingState: state, - shippingPostcode: postalCode, - shippingCountry: country)); - - if (wcCustomerUpdatedResponse.status != 200) { + WCCustomerUpdatedResponse wcCustomerUpdatedResponse; + try { + wcCustomerUpdatedResponse = await WPJsonAPI.instance.api( + (request) => request.wcUpdateCustomerInfo( + userToken, + shippingFirstName: firstName, + shippingLastName: lastName, + shippingAddress1: addressLine, + shippingCity: city, + shippingState: state, + shippingPostcode: postalCode, + shippingCountry: country, + ), + ); + } on Exception catch (_) { showEdgeAlertWith(context, title: trans(context, "Oops!"), desc: trans(context, "Something went wrong"), - style: EdgeAlertStyle.WARNING); - return; + style: EdgeAlertStyle.DANGER); + } finally { + setState(() { + _isUpdating = true; + }); + } + + if (wcCustomerUpdatedResponse != null && + wcCustomerUpdatedResponse.status == 200) { + showEdgeAlertWith(context, + title: trans(context, "Success"), + desc: trans(context, "Account updated"), + style: EdgeAlertStyle.SUCCESS); + Navigator.pop(context); } - Navigator.pop(context); } } diff --git a/LabelStoreMax/lib/pages/checkout_status.dart b/LabelStoreMax/lib/pages/checkout_status.dart index a20a823..0d16162 100644 --- a/LabelStoreMax/lib/pages/checkout_status.dart +++ b/LabelStoreMax/lib/pages/checkout_status.dart @@ -10,6 +10,8 @@ import 'package:flutter/material.dart'; import 'package:label_storemax/helpers/tools.dart'; +import 'package:label_storemax/models/cart.dart'; +import 'package:label_storemax/models/checkout_session.dart'; import 'package:woosignal/models/response/products.dart' as WS; import 'package:woosignal/models/response/order.dart' as WS; @@ -31,6 +33,9 @@ class _CheckoutStatusState extends State { @override void initState() { super.initState(); + + Cart.getInstance.clear(); + CheckoutSession.getInstance.clear(); } @override @@ -151,7 +156,8 @@ class _CheckoutStatusState extends State { ), Text( formatStringCurrency( - total: lineItem.total.toString()), + total: lineItem.total.toString(), + ), style: Theme.of(context).primaryTextTheme.bodyText1, ) diff --git a/LabelStoreMax/lib/providers/cash_on_delivery.dart b/LabelStoreMax/lib/providers/cash_on_delivery.dart index 0d6ecd5..6dedaad 100644 --- a/LabelStoreMax/lib/providers/cash_on_delivery.dart +++ b/LabelStoreMax/lib/providers/cash_on_delivery.dart @@ -29,8 +29,6 @@ cashOnDeliveryPay(context, Order order = await appWooSignal((api) => api.createOrder(orderWC)); if (order != null) { - Cart.getInstance.clear(); - CheckoutSession.getInstance.clear(); Navigator.pushNamed(context, "/checkout-status", arguments: order); } else { showEdgeAlertWith( diff --git a/LabelStoreMax/lib/providers/example_pay.dart b/LabelStoreMax/lib/providers/example_pay.dart index bf80751..8cb03b4 100644 --- a/LabelStoreMax/lib/providers/example_pay.dart +++ b/LabelStoreMax/lib/providers/example_pay.dart @@ -48,7 +48,6 @@ examplePay(context, // CHECK IF ORDER IS NULL if (order != null) { - Cart.getInstance.clear(); Navigator.pushNamed(context, "/checkout-status", arguments: order); } else { showEdgeAlertWith( diff --git a/LabelStoreMax/lib/providers/razor_pay.dart b/LabelStoreMax/lib/providers/razor_pay.dart index eda7b0d..5bfb4d2 100644 --- a/LabelStoreMax/lib/providers/razor_pay.dart +++ b/LabelStoreMax/lib/providers/razor_pay.dart @@ -34,8 +34,6 @@ razorPay(context, Order order = await appWooSignal((api) => api.createOrder(orderWC)); if (order != null) { - Cart.getInstance.clear(); - CheckoutSession.getInstance.clear(); _razorpay.clear(); Navigator.pushNamed(context, "/checkout-status", arguments: order); } else { diff --git a/LabelStoreMax/lib/providers/stripe_pay.dart b/LabelStoreMax/lib/providers/stripe_pay.dart index c1a8f6d..cb7ecee 100644 --- a/LabelStoreMax/lib/providers/stripe_pay.dart +++ b/LabelStoreMax/lib/providers/stripe_pay.dart @@ -78,8 +78,6 @@ stripePay(context, Order order = await appWooSignal((api) => api.createOrder(orderWC)); if (order != null) { - Cart.getInstance.clear(); - CheckoutSession.getInstance.clear(); Navigator.pushNamed(context, "/checkout-status", arguments: order); } else { showEdgeAlertWith( diff --git a/LabelStoreMax/lib/widgets/woosignal_ui.dart b/LabelStoreMax/lib/widgets/woosignal_ui.dart index 693d433..a5e1eae 100644 --- a/LabelStoreMax/lib/widgets/woosignal_ui.dart +++ b/LabelStoreMax/lib/widgets/woosignal_ui.dart @@ -8,6 +8,7 @@ // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:label_storemax/labelconfig.dart'; import 'package:label_storemax/models/cart.dart'; @@ -211,93 +212,118 @@ Widget wsCardProductItem(BuildContext context, margin: EdgeInsets.all(4), child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Container( - height: constraints.maxHeight / 1.75, + height: constraints.maxHeight / 2, child: ClipRRect( borderRadius: BorderRadius.circular(3.0), - child: CachedNetworkImage( - imageUrl: (product.images.length > 0 - ? product.images.first.src - : ""), - placeholder: (context, url) => Container( - child: Center( - child: CircularProgressIndicator(), + child: Stack( + children: [ + CachedNetworkImage( + imageUrl: (product.images.length > 0 + ? product.images.first.src + : ""), + placeholder: (context, url) => Container( + child: Center( + child: CircularProgressIndicator(), + ), + height: constraints.maxHeight / 2, ), - height: constraints.maxHeight / 1.75, + errorWidget: (context, url, error) => new Icon(Icons.error), + fit: BoxFit.contain, + height: constraints.maxHeight / 2, + width: double.infinity, ), - errorWidget: (context, url, error) => new Icon(Icons.error), - fit: BoxFit.fitWidth, - height: constraints.maxHeight / 1.75, - width: double.infinity, - ), + (product.onSale && product.type != "variable" + ? Positioned( + bottom: 5, + left: 8, + right: 8, + child: Container( + padding: EdgeInsets.all(2), + decoration: BoxDecoration( + color: Colors.white70, + borderRadius: BorderRadius.circular(4), + ), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + text: '', + style: Theme.of(context).textTheme.bodyText1, + children: [ + TextSpan( + text: + "${workoutSaleDiscount(salePrice: product.salePrice, priceBefore: product.regularPrice)}% ${trans(context, "off")}", + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith( + color: Colors.black87, + fontSize: 11, + ), + ), + ], + ), + ), + ), + ) + : null), + ].where((e) => e != null).toList()), ), ), - Padding( - padding: const EdgeInsets.only(top: 1), + Container( + margin: const EdgeInsets.only(top: 8, bottom: 8), child: Text( product.name, style: Theme.of(context).textTheme.bodyText2, - overflow: TextOverflow.ellipsis, maxLines: 2, - textAlign: TextAlign.left, - ), - ), - Flexible( - child: Padding( - padding: const EdgeInsets.only(top: 1), - child: Text( - formatStringCurrency(total: product.price), - style: Theme.of(context) - .textTheme - .bodyText2 - .copyWith(fontWeight: FontWeight.w600), - textAlign: TextAlign.left, - ), + overflow: TextOverflow.ellipsis, ), ), Flexible( child: Container( - child: (product.onSale && product.type != "variable" - ? RichText( - textAlign: TextAlign.left, - text: TextSpan( - text: '', - style: Theme.of(context).textTheme.bodyText1, - children: [ - TextSpan( - text: '${trans(context, "Was")}: ', - style: Theme.of(context) - .textTheme - .bodyText1 - .copyWith( - color: Colors.black54, fontSize: 11), - ), - TextSpan( - text: formatStringCurrency( - total: product.regularPrice), - style: Theme.of(context) - .textTheme - .bodyText1 - .copyWith( - decoration: TextDecoration.lineThrough, - color: Colors.grey, - fontSize: 11), - ), - TextSpan( - text: - " | ${workoutSaleDiscount(salePrice: product.salePrice, priceBefore: product.regularPrice)}% ${trans(context, "off")}", - style: Theme.of(context) - .textTheme - .bodyText1 - .copyWith( - color: Colors.black87, fontSize: 11), - ), - ], - ), - ) - : null), - width: double.infinity, + height: 50, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + AutoSizeText( + formatStringCurrency(total: product.price) + " ", + style: Theme.of(context) + .textTheme + .bodyText2 + .copyWith(fontWeight: FontWeight.w600), + textAlign: TextAlign.left, + ), + (product.onSale && product.type != "variable" + ? RichText( + text: TextSpan(children: [ + TextSpan( + text: '${trans(context, "Was")}: ', + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith( + color: Colors.black54, fontSize: 11), + ), + TextSpan( + text: formatStringCurrency( + total: product.regularPrice, + ), + style: Theme.of(context) + .textTheme + .bodyText1 + .copyWith( + decoration: TextDecoration.lineThrough, + color: Colors.grey, + fontSize: 11), + ), + ]), + ) + : null), + ].where((e) => e != null).toList(), + ), ), ), ].where((e) => e != null).toList(), diff --git a/LabelStoreMax/pubspec.lock b/LabelStoreMax/pubspec.lock index 7938a56..bae1fba 100644 --- a/LabelStoreMax/pubspec.lock +++ b/LabelStoreMax/pubspec.lock @@ -105,7 +105,7 @@ packages: name: device_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.2+3" + version: "0.4.2+4" dio: dependency: transitive description: @@ -133,7 +133,7 @@ packages: name: file url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "5.2.0" flare_dart: dependency: transitive description: @@ -159,7 +159,7 @@ packages: name: flutter_cache_manager url: "https://pub.dartlang.org" source: hosted - version: "1.2.2" + version: "1.4.1" flutter_launcher_icons: dependency: "direct main" description: @@ -252,13 +252,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.16.1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" matcher: dependency: transitive description: @@ -286,7 +279,7 @@ packages: name: package_info url: "https://pub.dartlang.org" source: hosted - version: "0.4.0+18" + version: "0.4.1" page_transition: dependency: "direct main" description: @@ -307,21 +300,28 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "1.6.7" + version: "1.6.11" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+1" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.4+2" + version: "0.0.4+3" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" pedantic: dependency: transitive description: @@ -350,6 +350,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0+2" + platform_detect: + dependency: transitive + description: + name: platform_detect + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" plugin_platform_interface: dependency: transitive description: @@ -357,6 +364,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.2" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.13" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.4" pull_to_refresh: dependency: "direct main" description: @@ -384,7 +405,7 @@ packages: name: rxdart url: "https://pub.dartlang.org" source: hosted - version: "0.24.0" + version: "0.24.1" shared_preferences: dependency: "direct main" description: @@ -398,21 +419,21 @@ packages: name: shared_preferences_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+8" + version: "0.0.1+10" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" shared_preferences_web: dependency: transitive description: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.2+5" + version: "0.1.2+7" sky_engine: dependency: transitive description: flutter @@ -431,14 +452,14 @@ packages: name: sqflite url: "https://pub.dartlang.org" source: hosted - version: "1.3.0+1" + version: "1.3.1" sqflite_common: dependency: transitive description: name: sqflite_common url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2+1" stack_trace: dependency: transitive description: @@ -473,7 +494,7 @@ packages: name: synchronized url: "https://pub.dartlang.org" source: hosted - version: "2.2.0" + version: "2.2.0+1" term_glyph: dependency: transitive description: @@ -508,35 +529,35 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "5.4.7" + version: "5.4.11" url_launcher_macos: dependency: transitive description: name: url_launcher_macos url: "https://pub.dartlang.org" source: hosted - version: "0.0.1+5" + version: "0.0.1+7" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.0.6" + version: "1.0.7" url_launcher_web: dependency: transitive description: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "0.1.1+4" + version: "0.1.1+6" uuid: dependency: transitive description: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.1.0" vector_math: dependency: transitive description: @@ -550,21 +571,28 @@ packages: name: woosignal url: "https://pub.dartlang.org" source: hosted - version: "1.0.9" + version: "1.1.0" woosignal_stripe: dependency: "direct main" description: name: woosignal_stripe url: "https://pub.dartlang.org" source: hosted - version: "0.0.4" + version: "0.0.6" wp_json_api: dependency: "direct main" description: name: wp_json_api url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" xml: dependency: transitive description: @@ -580,5 +608,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.8.0 <3.0.0" flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/LabelStoreMax/pubspec.yaml b/LabelStoreMax/pubspec.yaml index 5f6a0f2..7a195cb 100644 --- a/LabelStoreMax/pubspec.yaml +++ b/LabelStoreMax/pubspec.yaml @@ -1,5 +1,5 @@ # Label StoreMax -# Version 2.0.8 +# Version 2.0.9 #authors: - "Anthony Gordon" #documentation: https://woosignal.com/docs/app/ios/label-storemax #homepage: https://woosignal.com/ @@ -24,15 +24,15 @@ environment: sdk: ">=2.1.0 <3.0.0" dependencies: - woosignal: ^1.0.9 - woosignal_stripe: ^0.0.4 + woosignal: ^1.1.0 + woosignal_stripe: ^0.0.6 razorpay_flutter: ^1.2.1 - wp_json_api: ^0.1.3 + wp_json_api: ^0.1.4 shared_preferences: ^0.5.7+3 cached_network_image: ^2.2.0+1 page_transition: ^1.1.5 package_info: ^0.4.0+16 - url_launcher: ^5.4.7 + url_launcher: ^5.4.11 flutter_money_formatter: ^0.8.3 platform_alert_dialog: ^1.0.0+2 flutter_web_browser: ^0.11.0 diff --git a/LabelStoreMax/test/widget_test.dart b/LabelStoreMax/test/widget_test.dart index 355d110..570e0e4 100644 --- a/LabelStoreMax/test/widget_test.dart +++ b/LabelStoreMax/test/widget_test.dart @@ -5,26 +5,4 @@ // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:label_storemax/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MaterialApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +void main() {}