v2.0.9 changes, new UI for home products, pubspec.yaml update, latest Flutter version support

This commit is contained in:
WooSignal 2020-06-19 22:51:17 +01:00
parent 8deaf17524
commit 79ba52f515
28 changed files with 736 additions and 392 deletions

View File

@ -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 ## [2.0.8] - 2020-06-04
* Added pull to refresh * Added pull to refresh

View File

@ -0,0 +1 @@
b98ea22bbb9eb082f24a2f56c80c348a

View File

@ -169,6 +169,7 @@
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1; CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = YPEM49WRL2;
LastSwiftMigration = 0910; LastSwiftMigration = 0910;
}; };
}; };
@ -337,7 +338,6 @@
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = { 249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -392,7 +392,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = YPEM49WRL2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -416,7 +416,6 @@
}; };
97C147031CF9000F007C117D /* Debug */ = { 97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -472,7 +471,6 @@
}; };
97C147041CF9000F007C117D /* Release */ = { 97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO; ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NONNULL = YES;
@ -528,7 +526,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = YPEM49WRL2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
@ -558,7 +556,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = ""; DEVELOPMENT_TEAM = YPEM49WRL2;
ENABLE_BITCODE = NO; ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = ( FRAMEWORK_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "Die Rechnungsadresse ist unvollständig", "Billing address is incomplete": "Die Rechnungsadresse ist unvollständig",
"Order": "Auftrag", "Order": "Auftrag",
"Date Ordered": "Bestelldatum", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "Billing address is incomplete", "Billing address is incomplete": "Billing address is incomplete",
"Order": "Order", "Order": "Order",
"Date Ordered": "Date Ordered", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "La dirección de facturación está incompleta", "Billing address is incomplete": "La dirección de facturación está incompleta",
"Order": "Orden", "Order": "Orden",
"Date Ordered": "fecha del pedido", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "L'adresse de facturation est incomplète", "Billing address is incomplete": "L'adresse de facturation est incomplète",
"Order": "Ordre", "Order": "Ordre",
"Date Ordered": "Date de commande", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "biling pata adhoora hai", "Billing address is incomplete": "biling pata adhoora hai",
"Order": "gan", "Order": "gan",
"Date Ordered": "ordar ka dinaank", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "L'indirizzo di fatturazione è incompleto", "Billing address is incomplete": "L'indirizzo di fatturazione è incompleto",
"Order": "Ordine", "Order": "Ordine",
"Date Ordered": "Data ordinata", "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"
} }

View File

@ -159,5 +159,15 @@
"Billing address is incomplete": "O endereço de cobrança está incompleto", "Billing address is incomplete": "O endereço de cobrança está incompleto",
"Order": "Ordem", "Order": "Ordem",
"Date Ordered": "Data da Encomenda", "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"
} }

View File

@ -8,6 +8,8 @@
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:label_storemax/app_payment_methods.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); double parseWcPrice(String price) => (double.tryParse(price) ?? 0);
void appLogOutput(dynamic message) => (app_debug == true ? log(message) : null);
Widget refreshableScroll(context, Widget refreshableScroll(context,
{@required refreshController, {@required refreshController,
@required VoidCallback onRefresh, @required VoidCallback onRefresh,
@ -507,7 +511,6 @@ Widget refreshableScroll(context,
child: (products.length != null && products.length > 0 child: (products.length != null && products.length > 0
? GridView.count( ? GridView.count(
crossAxisCount: 2, crossAxisCount: 2,
childAspectRatio: calAspectRatio(context),
shrinkWrap: true, shrinkWrap: true,
children: List.generate( children: List.generate(
products.length, products.length,
@ -521,11 +524,11 @@ Widget refreshableScroll(context,
double calAspectRatio(BuildContext context) { double calAspectRatio(BuildContext context) {
if (MediaQuery.of(context).size.height > 800) { if (MediaQuery.of(context).size.height > 800) {
return MediaQuery.of(context).size.width / 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) { if (MediaQuery.of(context).size.height > 700) {
return MediaQuery.of(context).size.width / 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 / return MediaQuery.of(context).size.width /
(MediaQuery.of(context).size.height / 1.3); (MediaQuery.of(context).size.height / 1.3);

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.8 VERSION - 2.0.9
https://woosignal.com https://woosignal.com
*/ */

View File

@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.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:label_storemax/widgets/woosignal_ui.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/models/responses/WCCustomerUpdatedResponse.dart'; import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart';
import 'package:wp_json_api/wp_json_api.dart'; import 'package:wp_json_api/wp_json_api.dart';
class AccountBillingDetailsPage extends StatefulWidget { class AccountBillingDetailsPage extends StatefulWidget {
@ -182,7 +182,6 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
BoxShadow( BoxShadow(
color: HexColor("#e8e8e8"), color: HexColor("#e8e8e8"),
blurRadius: 15.0, blurRadius: 15.0,
// has the effect of softening the shadow
spreadRadius: 0, spreadRadius: 0,
offset: Offset( offset: Offset(
0, 0,
@ -228,9 +227,10 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
_isUpdating = true; _isUpdating = true;
}); });
WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI WCCustomerUpdatedResponse wcCustomerUpdatedResponse;
.instance try {
.api((request) => request.wcUpdateCustomerInfo(userToken, wcCustomerUpdatedResponse = await WPJsonAPI.instance.api((request) =>
request.wcUpdateCustomerInfo(userToken,
billingFirstName: firstName, billingFirstName: firstName,
billingLastName: lastName, billingLastName: lastName,
billingAddress1: addressLine, billingAddress1: addressLine,
@ -238,18 +238,24 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
billingState: state, billingState: state,
billingPostcode: postalCode, billingPostcode: postalCode,
billingCountry: country)); billingCountry: country));
} on Exception catch (_) {
setState(() {
_isUpdating = false;
});
if (wcCustomerUpdatedResponse.status != 200) {
showEdgeAlertWith(context, showEdgeAlertWith(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), desc: trans(context, "Something went wrong"),
style: EdgeAlertStyle.WARNING); style: EdgeAlertStyle.DANGER);
return; } 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);
} }
} }
}

View File

@ -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/helpers/tools.dart';
import 'package:label_storemax/widgets/app_loader.dart'; import 'package:label_storemax/widgets/app_loader.dart';
import 'package:label_storemax/widgets/woosignal_ui.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: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'; import 'package:wp_json_api/wp_json_api.dart';
class AccountDetailPage extends StatefulWidget { class AccountDetailPage extends StatefulWidget {
@ -27,6 +28,12 @@ class AccountDetailPage extends StatefulWidget {
class _AccountDetailPageState extends State<AccountDetailPage> class _AccountDetailPageState extends State<AccountDetailPage>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
RefreshController _refreshController =
RefreshController(initialRefresh: false);
bool _shouldStopRequests;
bool waitForNextRequest;
int _page; int _page;
List<Order> _orders; List<Order> _orders;
WCCustomerInfoResponse _wcCustomerInfoResponse; WCCustomerInfoResponse _wcCustomerInfoResponse;
@ -41,6 +48,9 @@ class _AccountDetailPageState extends State<AccountDetailPage>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_shouldStopRequests = false;
waitForNextRequest = false;
_isLoading = true; _isLoading = true;
_isLoadingOrders = true; _isLoadingOrders = true;
_page = 1; _page = 1;
@ -56,19 +66,33 @@ class _AccountDetailPageState extends State<AccountDetailPage>
} }
_fetchWpUserData() async { _fetchWpUserData() async {
WCCustomerInfoResponse wcCustomerInfoResponse = String userToken = await readAuthToken();
await WPJsonAPI.instance.api((request) async {
return request.wcCustomerInfo(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(() { setState(() {
_isLoading = false; _isLoading = false;
}); });
} }
if (wcCustomerInfoResponse != null &&
wcCustomerInfoResponse.status == 200) {
setState(() {
_wcCustomerInfoResponse = wcCustomerInfoResponse;
});
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_tabs = [ _tabs = [
@ -113,7 +137,9 @@ class _AccountDetailPageState extends State<AccountDetailPage>
margin: EdgeInsets.only(top: 10), margin: EdgeInsets.only(top: 10),
child: CircleAvatar( child: CircleAvatar(
backgroundImage: NetworkImage( backgroundImage: NetworkImage(
_wcCustomerInfoResponse.data.avatar, _wcCustomerInfoResponse != null
? _wcCustomerInfoResponse.data.avatar
: "",
), ),
), ),
height: 90, height: 90,
@ -252,18 +278,27 @@ class _AccountDetailPageState extends State<AccountDetailPage>
_fetchOrders() async { _fetchOrders() async {
String userId = await readUserId(); String userId = await readUserId();
if (userId == null) { if (userId == null || _shouldStopRequests == true) {
setState(() { setState(() {
_isLoadingOrders = false; _isLoadingOrders = false;
_activeBody = _widgetOrders(); _activeBody = _widgetOrders();
}); });
return; return;
} }
_orders = await appWooSignal((api) {
return api.getOrders( List<Order> orders = await appWooSignal((api) =>
customer: int.parse(userId), page: _page, perPage: 100); api.getOrders(customer: int.parse(userId), page: _page, perPage: 50));
});
if (orders.length <= 0) {
setState(() { setState(() {
_shouldStopRequests = true;
});
return;
}
setState(() {
_page += 1;
_orders.addAll(orders);
_isLoadingOrders = false; _isLoadingOrders = false;
_activeBody = _widgetOrders(); _activeBody = _widgetOrders();
}); });
@ -272,29 +307,39 @@ class _AccountDetailPageState extends State<AccountDetailPage>
Widget _widgetOrders() { Widget _widgetOrders() {
return _isLoadingOrders return _isLoadingOrders
? showAppLoader() ? showAppLoader()
: _orders.length <= 0 : SmartRefresher(
? Center( enablePullDown: true,
child: Column( enablePullUp: true,
crossAxisAlignment: CrossAxisAlignment.center, footer: CustomFooter(
mainAxisAlignment: MainAxisAlignment.center, builder: (BuildContext context, LoadStatus mode) {
children: <Widget>[ Widget body;
Icon( if (mode == LoadStatus.idle) {
Icons.shopping_cart, body = Text(trans(context, "pull up load"));
color: Colors.black54, } else if (mode == LoadStatus.loading) {
size: 40, 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),
);
},
), ),
Text( controller: _refreshController,
trans(context, "No orders found"), onRefresh: _onRefresh,
), onLoading: _onLoading,
], child: (_orders.length != null && _orders.length > 0
), ? ListView.builder(
)
: ListView.builder(
itemBuilder: (cxt, i) { itemBuilder: (cxt, i) {
return Card( return Card(
child: ListTile( child: ListTile(
contentPadding: contentPadding: EdgeInsets.only(
EdgeInsets.only(top: 5, bottom: 5, left: 8, right: 6), top: 5, bottom: 5, left: 8, right: 6),
title: Container( title: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
border: Border( border: Border(
@ -332,7 +377,8 @@ class _AccountDetailPageState extends State<AccountDetailPage>
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text( Text(
formatStringCurrency(total: _orders[i].total), formatStringCurrency(
total: _orders[i].total),
style: Theme.of(context) style: Theme.of(context)
.primaryTextTheme .primaryTextTheme
.bodyText2 .bodyText2
@ -373,7 +419,8 @@ class _AccountDetailPageState extends State<AccountDetailPage>
.bodyText1 .bodyText1
.copyWith( .copyWith(
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
color: Colors.black), color: Colors.black,
),
), ),
], ],
), ),
@ -384,15 +431,59 @@ class _AccountDetailPageState extends State<AccountDetailPage>
Icon(Icons.chevron_right), Icon(Icons.chevron_right),
], ],
), ),
onTap: () { onTap: () => _viewProfileDetail(i),
int orderId = _orders[i].id;
Navigator.pushNamed(context, "/account-order-detail",
arguments: orderId);
},
), ),
); );
}, },
itemCount: _orders.length, itemCount: _orders.length,
)
: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.shopping_cart,
color: Colors.black54,
size: 40,
),
Text(
trans(context, "No orders found"),
),
],
),
)),
);
}
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,
); );
} }
} }

View File

@ -17,7 +17,11 @@ import 'package:label_storemax/labelconfig.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:label_storemax/widgets/woosignal_ui.dart';
import 'package:url_launcher/url_launcher.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'; import 'package:wp_json_api/wp_json_api.dart';
class AccountLandingPage extends StatefulWidget { class AccountLandingPage extends StatefulWidget {
@ -148,16 +152,69 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
String email = _tfEmailController.text; String email = _tfEmailController.text;
String password = _tfPasswordController.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) { if (_hasTappedLogin == false) {
setState(() { setState(() {
_hasTappedLogin = true; _hasTappedLogin = true;
}); });
WPUserLoginResponse wpUserLoginResponse = await WPJsonAPI.instance WPUserLoginResponse wpUserLoginResponse;
.api((request) => request.wpLogin(email: email, password: password)); 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; _hasTappedLogin = false;
});
}
if (wpUserLoginResponse != null) { if (wpUserLoginResponse != null && wpUserLoginResponse.status == 200) {
String token = wpUserLoginResponse.data.userToken; String token = wpUserLoginResponse.data.userToken;
authUser(token); authUser(token);
storeUserId(wpUserLoginResponse.data.userId.toString()); storeUserId(wpUserLoginResponse.data.userId.toString());
@ -169,15 +226,6 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
icon: Icons.account_circle); icon: Icons.account_circle);
navigatorPush(context, navigatorPush(context,
routeName: UserAuth.instance.redirect, forgetLast: 1); 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;
});
} }
} }
} }

View File

@ -134,8 +134,10 @@ class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
), ),
), ),
Text( Text(
capitalize(formatStringCurrency( capitalize(
total: _order.lineItems[i].price)), formatStringCurrency(
total: _order.lineItems[i].price),
),
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.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:label_storemax/widgets/woosignal_ui.dart';
import 'package:wp_json_api/models/responses/WPUserInfoResponse.dart'; import 'package:wp_json_api/models/responses/wp_user_info_response.dart';
import 'package:wp_json_api/models/responses/WPUserInfoUpdatedResponse.dart'; import 'package:wp_json_api/models/responses/wp_user_info_updated_response.dart';
import 'package:wp_json_api/wp_json_api.dart'; import 'package:wp_json_api/wp_json_api.dart';
class AccountProfileUpdatePage extends StatefulWidget { class AccountProfileUpdatePage extends StatefulWidget {
@ -132,22 +132,31 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
); );
} }
bool _isNetworking = false;
_updateDetails() async { _updateDetails() async {
String firstName = _tfFirstName.text; String firstName = _tfFirstName.text;
String lastName = _tfLastName.text; String lastName = _tfLastName.text;
if (_isNetworking == false) { if (isLoading == false) {
setState(() { setState(() {
_isNetworking = true;
isLoading = true; isLoading = true;
}); });
WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = String userToken = await readAuthToken();
await WPJsonAPI.instance.api((request) async { WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse;
return request.wpUpdateUserInfo(await readAuthToken(), try {
firstName: firstName, lastName: lastName); 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 && if (wpUserInfoUpdatedResponse != null &&
wpUserInfoUpdatedResponse.status == 200) { wpUserInfoUpdatedResponse.status == 200) {
@ -155,16 +164,8 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
title: trans(context, "Success"), title: trans(context, "Success"),
desc: trans(context, "Account updated"), desc: trans(context, "Account updated"),
style: EdgeAlertStyle.SUCCESS); style: EdgeAlertStyle.SUCCESS);
} else { Navigator.pop(context);
showEdgeAlertWith(context, }
title: trans(context, "Invalid details"),
desc: trans(context, "Please check your email and password"),
style: EdgeAlertStyle.WARNING);
}
setState(() {
_isNetworking = false;
isLoading = false;
});
} }
} }
} }

View File

@ -16,7 +16,13 @@ import 'package:label_storemax/labelconfig.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:label_storemax/widgets/woosignal_ui.dart';
import 'package:woosignal/helpers/shared_pref.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'; import 'package:wp_json_api/wp_json_api.dart';
class AccountRegistrationPage extends StatefulWidget { class AccountRegistrationPage extends StatefulWidget {
@ -72,18 +78,22 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Flexible( Flexible(
child: wsTextEditingRow(context, child: wsTextEditingRow(
context,
heading: trans(context, "First Name"), heading: trans(context, "First Name"),
controller: _tfFirstNameController, controller: _tfFirstNameController,
shouldAutoFocus: true, shouldAutoFocus: true,
keyboardType: TextInputType.text), keyboardType: TextInputType.text,
),
), ),
Flexible( Flexible(
child: wsTextEditingRow(context, child: wsTextEditingRow(
context,
heading: trans(context, "Last Name"), heading: trans(context, "Last Name"),
controller: _tfLastNameController, controller: _tfLastNameController,
shouldAutoFocus: false, shouldAutoFocus: false,
keyboardType: TextInputType.text), keyboardType: TextInputType.text,
),
), ),
], ],
)), )),
@ -144,6 +154,10 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
String firstName = _tfFirstNameController.text; String firstName = _tfFirstNameController.text;
String lastName = _tfLastNameController.text; String lastName = _tfLastNameController.text;
if (email != null) {
email = email.trim();
}
if (!isEmail(email)) { if (!isEmail(email)) {
showEdgeAlertWith(context, showEdgeAlertWith(context,
title: trans(context, "Oops"), title: trans(context, "Oops"),
@ -168,13 +182,59 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
String username = String username =
(email.replaceAll(new RegExp(r'(@|\.)'), "")) + randomStr(4); (email.replaceAll(new RegExp(r'(@|\.)'), "")) + randomStr(4);
WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance WPUserRegisterResponse wpUserRegisterResponse;
.api((request) => request.wpRegister( try {
wpUserRegisterResponse = await WPJsonAPI.instance.api(
(request) => request.wpRegister(
email: email.toLowerCase(), email: email.toLowerCase(),
password: password, password: password,
username: username)); 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; String token = wpUserRegisterResponse.data.userToken;
authUser(token); authUser(token);
storeUserId(wpUserRegisterResponse.data.userId.toString()); storeUserId(wpUserRegisterResponse.data.userId.toString());
@ -189,14 +249,6 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
icon: Icons.account_circle); icon: Icons.account_circle);
navigatorPush(context, navigatorPush(context,
routeName: UserAuth.instance.redirect, forgetLast: 2); 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;
});
} }
} }
} }

View File

@ -15,8 +15,8 @@ import 'package:label_storemax/helpers/tools.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:label_storemax/widgets/woosignal_ui.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/models/responses/WCCustomerUpdatedResponse.dart'; import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart';
import 'package:wp_json_api/wp_json_api.dart'; import 'package:wp_json_api/wp_json_api.dart';
class AccountShippingDetailsPage extends StatefulWidget { class AccountShippingDetailsPage extends StatefulWidget {
@ -62,11 +62,29 @@ class _AccountShippingDetailsPageState
} }
_fetchUserDetails() async { _fetchUserDetails() async {
WCCustomerInfoResponse wcCustomerInfoResponse = String userToken = await readAuthToken();
await WPJsonAPI.instance.api((request) async {
return request.wcCustomerInfo(await readAuthToken());
});
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;
});
}
if (wcCustomerInfoResponse != null &&
wcCustomerInfoResponse.status == 200) {
Shipping shipping = wcCustomerInfoResponse.data.shipping; Shipping shipping = wcCustomerInfoResponse.data.shipping;
_txtShippingFirstName.text = shipping.firstName; _txtShippingFirstName.text = shipping.firstName;
_txtShippingLastName.text = shipping.lastName; _txtShippingLastName.text = shipping.lastName;
@ -76,10 +94,7 @@ class _AccountShippingDetailsPageState
_txtShippingState.text = shipping.state; _txtShippingState.text = shipping.state;
_txtShippingPostalCode.text = shipping.postcode; _txtShippingPostalCode.text = shipping.postcode;
_txtShippingCountry.text = shipping.country; _txtShippingCountry.text = shipping.country;
}
setState(() {
_isLoading = false;
});
} }
@override @override
@ -228,28 +243,46 @@ class _AccountShippingDetailsPageState
String userToken = await readAuthToken(); String userToken = await readAuthToken();
if (_isUpdating == true) {
return;
}
setState(() { setState(() {
_isUpdating = true; _isUpdating = true;
}); });
WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI WCCustomerUpdatedResponse wcCustomerUpdatedResponse;
.instance try {
.api((request) => request.wcUpdateCustomerInfo(userToken, wcCustomerUpdatedResponse = await WPJsonAPI.instance.api(
(request) => request.wcUpdateCustomerInfo(
userToken,
shippingFirstName: firstName, shippingFirstName: firstName,
shippingLastName: lastName, shippingLastName: lastName,
shippingAddress1: addressLine, shippingAddress1: addressLine,
shippingCity: city, shippingCity: city,
shippingState: state, shippingState: state,
shippingPostcode: postalCode, shippingPostcode: postalCode,
shippingCountry: country)); shippingCountry: country,
),
if (wcCustomerUpdatedResponse.status != 200) { );
} on Exception catch (_) {
showEdgeAlertWith(context, showEdgeAlertWith(context,
title: trans(context, "Oops!"), title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"), desc: trans(context, "Something went wrong"),
style: EdgeAlertStyle.WARNING); style: EdgeAlertStyle.DANGER);
return; } 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);
} }
} }
}

View File

@ -10,6 +10,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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/checkout_session.dart';
import 'package:woosignal/models/response/products.dart' as WS; import 'package:woosignal/models/response/products.dart' as WS;
import 'package:woosignal/models/response/order.dart' as WS; import 'package:woosignal/models/response/order.dart' as WS;
@ -31,6 +33,9 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
Cart.getInstance.clear();
CheckoutSession.getInstance.clear();
} }
@override @override
@ -151,7 +156,8 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
), ),
Text( Text(
formatStringCurrency( formatStringCurrency(
total: lineItem.total.toString()), total: lineItem.total.toString(),
),
style: style:
Theme.of(context).primaryTextTheme.bodyText1, Theme.of(context).primaryTextTheme.bodyText1,
) )

View File

@ -29,8 +29,6 @@ cashOnDeliveryPay(context,
Order order = await appWooSignal((api) => api.createOrder(orderWC)); Order order = await appWooSignal((api) => api.createOrder(orderWC));
if (order != null) { if (order != null) {
Cart.getInstance.clear();
CheckoutSession.getInstance.clear();
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showEdgeAlertWith(

View File

@ -48,7 +48,6 @@ examplePay(context,
// CHECK IF ORDER IS NULL // CHECK IF ORDER IS NULL
if (order != null) { if (order != null) {
Cart.getInstance.clear();
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showEdgeAlertWith(

View File

@ -34,8 +34,6 @@ razorPay(context,
Order order = await appWooSignal((api) => api.createOrder(orderWC)); Order order = await appWooSignal((api) => api.createOrder(orderWC));
if (order != null) { if (order != null) {
Cart.getInstance.clear();
CheckoutSession.getInstance.clear();
_razorpay.clear(); _razorpay.clear();
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {

View File

@ -78,8 +78,6 @@ stripePay(context,
Order order = await appWooSignal((api) => api.createOrder(orderWC)); Order order = await appWooSignal((api) => api.createOrder(orderWC));
if (order != null) { if (order != null) {
Cart.getInstance.clear();
CheckoutSession.getInstance.clear();
Navigator.pushNamed(context, "/checkout-status", arguments: order); Navigator.pushNamed(context, "/checkout-status", arguments: order);
} else { } else {
showEdgeAlertWith( showEdgeAlertWith(

View File

@ -8,6 +8,7 @@
// distributed under the License is distributed on an "AS IS" BASIS, // distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // 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:flutter/material.dart';
import 'package:label_storemax/labelconfig.dart'; import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/models/cart.dart'; import 'package:label_storemax/models/cart.dart';
@ -211,12 +212,15 @@ Widget wsCardProductItem(BuildContext context,
margin: EdgeInsets.all(4), margin: EdgeInsets.all(4),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[ children: <Widget>[
Container( Container(
height: constraints.maxHeight / 1.75, height: constraints.maxHeight / 2,
child: ClipRRect( child: ClipRRect(
borderRadius: BorderRadius.circular(3.0), borderRadius: BorderRadius.circular(3.0),
child: CachedNetworkImage( child: Stack(
children: [
CachedNetworkImage(
imageUrl: (product.images.length > 0 imageUrl: (product.images.length > 0
? product.images.first.src ? product.images.first.src
: ""), : ""),
@ -224,47 +228,77 @@ Widget wsCardProductItem(BuildContext context,
child: Center( child: Center(
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
), ),
height: constraints.maxHeight / 1.75, height: constraints.maxHeight / 2,
), ),
errorWidget: (context, url, error) => new Icon(Icons.error), errorWidget: (context, url, error) => new Icon(Icons.error),
fit: BoxFit.fitWidth, fit: BoxFit.contain,
height: constraints.maxHeight / 1.75, height: constraints.maxHeight / 2,
width: double.infinity, 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>[
TextSpan(
text:
"${workoutSaleDiscount(salePrice: product.salePrice, priceBefore: product.regularPrice)}% ${trans(context, "off")}",
style: Theme.of(context)
.textTheme
.bodyText1
.copyWith(
color: Colors.black87,
fontSize: 11,
), ),
), ),
Padding( ],
padding: const EdgeInsets.only(top: 1), ),
),
),
)
: null),
].where((e) => e != null).toList()),
),
),
Container(
margin: const EdgeInsets.only(top: 8, bottom: 8),
child: Text( child: Text(
product.name, product.name,
style: Theme.of(context).textTheme.bodyText2, style: Theme.of(context).textTheme.bodyText2,
overflow: TextOverflow.ellipsis,
maxLines: 2, maxLines: 2,
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis,
), ),
), ),
Flexible( Flexible(
child: Padding( child: Container(
padding: const EdgeInsets.only(top: 1), height: 50,
child: Text( child: Row(
formatStringCurrency(total: product.price), crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
AutoSizeText(
formatStringCurrency(total: product.price) + " ",
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.bodyText2 .bodyText2
.copyWith(fontWeight: FontWeight.w600), .copyWith(fontWeight: FontWeight.w600),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
), (product.onSale && product.type != "variable"
),
Flexible(
child: Container(
child: (product.onSale && product.type != "variable"
? RichText( ? RichText(
textAlign: TextAlign.left, text: TextSpan(children: [
text: TextSpan(
text: '',
style: Theme.of(context).textTheme.bodyText1,
children: <TextSpan>[
TextSpan( TextSpan(
text: '${trans(context, "Was")}: ', text: '${trans(context, "Was")}: ',
style: Theme.of(context) style: Theme.of(context)
@ -275,7 +309,8 @@ Widget wsCardProductItem(BuildContext context,
), ),
TextSpan( TextSpan(
text: formatStringCurrency( text: formatStringCurrency(
total: product.regularPrice), total: product.regularPrice,
),
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.bodyText1 .bodyText1
@ -284,20 +319,11 @@ Widget wsCardProductItem(BuildContext context,
color: Colors.grey, color: Colors.grey,
fontSize: 11), 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), : null),
width: double.infinity, ].where((e) => e != null).toList(),
),
), ),
), ),
].where((e) => e != null).toList(), ].where((e) => e != null).toList(),

View File

@ -105,7 +105,7 @@ packages:
name: device_info name: device_info
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.2+3" version: "0.4.2+4"
dio: dio:
dependency: transitive dependency: transitive
description: description:
@ -133,7 +133,7 @@ packages:
name: file name: file
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.1.0" version: "5.2.0"
flare_dart: flare_dart:
dependency: transitive dependency: transitive
description: description:
@ -159,7 +159,7 @@ packages:
name: flutter_cache_manager name: flutter_cache_manager
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.2" version: "1.4.1"
flutter_launcher_icons: flutter_launcher_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@ -252,13 +252,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.16.1"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1+1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -286,7 +279,7 @@ packages:
name: package_info name: package_info
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.0+18" version: "0.4.1"
page_transition: page_transition:
dependency: "direct main" dependency: "direct main"
description: description:
@ -307,21 +300,28 @@ packages:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: path_provider_macos:
dependency: transitive dependency: transitive
description: description:
name: path_provider_macos name: path_provider_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4+2" version: "0.0.4+3"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2"
pedantic: pedantic:
dependency: transitive dependency: transitive
description: description:
@ -350,6 +350,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.0+2" 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: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -357,6 +364,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" 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: pull_to_refresh:
dependency: "direct main" dependency: "direct main"
description: description:
@ -384,7 +405,7 @@ packages:
name: rxdart name: rxdart
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.24.0" version: "0.24.1"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
@ -398,21 +419,21 @@ packages:
name: shared_preferences_macos name: shared_preferences_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+8" version: "0.0.1+10"
shared_preferences_platform_interface: shared_preferences_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_platform_interface name: shared_preferences_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "1.0.4"
shared_preferences_web: shared_preferences_web:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_web name: shared_preferences_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2+5" version: "0.1.2+7"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -431,14 +452,14 @@ packages:
name: sqflite name: sqflite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0+1" version: "1.3.1"
sqflite_common: sqflite_common:
dependency: transitive dependency: transitive
description: description:
name: sqflite_common name: sqflite_common
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.2+1"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
@ -473,7 +494,7 @@ packages:
name: synchronized name: synchronized
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.0" version: "2.2.0+1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -508,35 +529,35 @@ packages:
name: url_launcher name: url_launcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.4.7" version: "5.4.11"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+5" version: "0.0.1+7"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.6" version: "1.0.7"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.1+4" version: "0.1.1+6"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
name: uuid name: uuid
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.4" version: "2.1.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -550,21 +571,28 @@ packages:
name: woosignal name: woosignal
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.9" version: "1.1.0"
woosignal_stripe: woosignal_stripe:
dependency: "direct main" dependency: "direct main"
description: description:
name: woosignal_stripe name: woosignal_stripe
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4" version: "0.0.6"
wp_json_api: wp_json_api:
dependency: "direct main" dependency: "direct main"
description: description:
name: wp_json_api name: wp_json_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted 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: xml:
dependency: transitive dependency: transitive
description: description:
@ -580,5 +608,5 @@ packages:
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
sdks: sdks:
dart: ">=2.7.0 <3.0.0" dart: ">=2.8.0 <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0" flutter: ">=1.12.13+hotfix.5 <2.0.0"

View File

@ -1,5 +1,5 @@
# Label StoreMax # Label StoreMax
# Version 2.0.8 # Version 2.0.9
#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/
@ -24,15 +24,15 @@ environment:
sdk: ">=2.1.0 <3.0.0" sdk: ">=2.1.0 <3.0.0"
dependencies: dependencies:
woosignal: ^1.0.9 woosignal: ^1.1.0
woosignal_stripe: ^0.0.4 woosignal_stripe: ^0.0.6
razorpay_flutter: ^1.2.1 razorpay_flutter: ^1.2.1
wp_json_api: ^0.1.3 wp_json_api: ^0.1.4
shared_preferences: ^0.5.7+3 shared_preferences: ^0.5.7+3
cached_network_image: ^2.2.0+1 cached_network_image: ^2.2.0+1
page_transition: ^1.1.5 page_transition: ^1.1.5
package_info: ^0.4.0+16 package_info: ^0.4.0+16
url_launcher: ^5.4.7 url_launcher: ^5.4.11
flutter_money_formatter: ^0.8.3 flutter_money_formatter: ^0.8.3
platform_alert_dialog: ^1.0.0+2 platform_alert_dialog: ^1.0.0+2
flutter_web_browser: ^0.11.0 flutter_web_browser: ^0.11.0

View File

@ -5,26 +5,4 @@
// gestures. You can also use WidgetTester to find child widgets in the widget // 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. // tree, read text, and verify that the values of widget properties are correct.
import 'package:flutter/material.dart'; void main() {}
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);
});
}