Flutter 1.17.0 support, Sort by feature, Cash on delivery added, Login/register flow change for Apple user guidelines, Bug fixes, Pubspec.yaml update, AndroidManifest.xml bug fix
This commit is contained in:
parent
54e215507f
commit
8cd7118b0b
@ -1,5 +1,12 @@
|
|||||||
## [2.0.2] - 2020-05-04
|
## [2.0.2] - 2020-05-08
|
||||||
|
|
||||||
|
* Flutter 1.17.0 support
|
||||||
|
* Sort by feature
|
||||||
|
* Cash on delivery added
|
||||||
|
* RazorPay added
|
||||||
|
* Login/register flow change for Apple user guidelines
|
||||||
|
* Bug fixes
|
||||||
|
* Pubspec.yaml update
|
||||||
* AndroidManifest.xml bug fix
|
* AndroidManifest.xml bug fix
|
||||||
|
|
||||||
## [2.0.1] - 2020-04-30
|
## [2.0.1] - 2020-04-30
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.2 KiB |
BIN
LabelStoreMax/assets/images/cash_on_delivery.jpeg
Normal file
BIN
LabelStoreMax/assets/images/cash_on_delivery.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@ -264,9 +264,6 @@
|
|||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${BUILT_PRODUCTS_DIR}/Braintree/Braintree.framework",
|
|
||||||
"${PODS_ROOT}/Braintree/Frameworks/CardinalMobile.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/BraintreeDropIn/BraintreeDropIn.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
|
"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
|
||||||
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/Stripe/Stripe.framework",
|
"${BUILT_PRODUCTS_DIR}/Stripe/Stripe.framework",
|
||||||
@ -275,6 +272,8 @@
|
|||||||
"${BUILT_PRODUCTS_DIR}/flutter_web_browser/flutter_web_browser.framework",
|
"${BUILT_PRODUCTS_DIR}/flutter_web_browser/flutter_web_browser.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/package_info/package_info.framework",
|
"${BUILT_PRODUCTS_DIR}/package_info/package_info.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||||
|
"${PODS_ROOT}/razorpay-pod/Pod/Razorpay.framework",
|
||||||
|
"${BUILT_PRODUCTS_DIR}/razorpay_flutter/razorpay_flutter.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
|
||||||
@ -282,9 +281,6 @@
|
|||||||
);
|
);
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Braintree.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CardinalMobile.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BraintreeDropIn.framework",
|
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Stripe.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Stripe.framework",
|
||||||
@ -293,6 +289,8 @@
|
|||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_web_browser.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_web_browser.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||||
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Razorpay.framework",
|
||||||
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/razorpay_flutter.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Flutter
|
import Flutter
|
||||||
import Braintree
|
|
||||||
|
|
||||||
@UIApplicationMain
|
@UIApplicationMain
|
||||||
@objc class AppDelegate: FlutterAppDelegate {
|
@objc class AppDelegate: FlutterAppDelegate {
|
||||||
|
|||||||
@ -129,5 +129,18 @@
|
|||||||
"Shipping Details": "Shipping Details",
|
"Shipping Details": "Shipping Details",
|
||||||
"State": "State",
|
"State": "State",
|
||||||
"Country": "Country",
|
"Country": "Country",
|
||||||
"UPDATE DETAILS": "UPDATE DETAILS"
|
"UPDATE DETAILS": "UPDATE DETAILS",
|
||||||
|
"No more products": "No more products",
|
||||||
|
"release to load more": "release to load more",
|
||||||
|
"Load Failed! Click retry!": "Load Failed! Click retry!",
|
||||||
|
"pull up load": "pull up load",
|
||||||
|
"Sort: Low to high": "Sort: Low to high",
|
||||||
|
"Sort: High to low": "Sort: High to low",
|
||||||
|
"Sort: Name A-Z": "Sort: Name A-Z",
|
||||||
|
"Sort: Name Z-A": "Sort: Name Z-A",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Sort results": "Sort results",
|
||||||
|
"you're now logged in": "You're now logged in",
|
||||||
|
"Hello": "Hello",
|
||||||
|
"Welcome back": "Welcome back"
|
||||||
}
|
}
|
||||||
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/models/payment_type.dart';
|
import 'package:label_storemax/models/payment_type.dart';
|
||||||
|
import 'package:label_storemax/providers/cash_on_delivery.dart';
|
||||||
import 'package:label_storemax/providers/stripe_pay.dart';
|
import 'package:label_storemax/providers/stripe_pay.dart';
|
||||||
|
|
||||||
// Payment methods available for uses in the app
|
// Payment methods available for uses in the app
|
||||||
@ -25,11 +26,21 @@ List<PaymentType> arrPaymentMethods = [
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
addPayment(
|
||||||
|
PaymentType(
|
||||||
|
id: 2,
|
||||||
|
name: "CashOnDelivery",
|
||||||
|
desc: "Cash on delivery",
|
||||||
|
assetImage: "cash_on_delivery.jpeg",
|
||||||
|
pay: cashOnDeliveryPay,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
// e.g. add more here
|
// e.g. add more here
|
||||||
|
|
||||||
// addPayment(
|
// addPayment(
|
||||||
// PaymentType(
|
// PaymentType(
|
||||||
// id: 2,
|
// id: 3,
|
||||||
// name: "MyNewPaymentMethod",
|
// name: "MyNewPaymentMethod",
|
||||||
// desc: "Debit or Credit Card",
|
// desc: "Debit or Credit Card",
|
||||||
// assetImage: "add icon image to assets/images/myimage.png",
|
// assetImage: "add icon image to assets/images/myimage.png",
|
||||||
|
|||||||
@ -50,8 +50,10 @@ class _AppLocalizationsDelegate
|
|||||||
const _AppLocalizationsDelegate();
|
const _AppLocalizationsDelegate();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSupported(Locale locale) =>
|
bool isSupported(Locale locale) => app_locales_supported
|
||||||
app_locales_supported.contains(locale.languageCode);
|
.map((e) => e.languageCode)
|
||||||
|
.toList()
|
||||||
|
.contains(locale.languageCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||||
|
|||||||
@ -82,9 +82,9 @@ TextTheme textThemePrimary() {
|
|||||||
fontWeight: FontWeight.w600),
|
fontWeight: FontWeight.w600),
|
||||||
headline: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
headline: new TextStyle(color: Colors.black, fontFamily: appFontFamily),
|
||||||
title: new TextStyle(
|
title: new TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black87,
|
||||||
fontFamily: appFontFamily,
|
fontFamily: appFontFamily,
|
||||||
),
|
fontWeight: FontWeight.w600),
|
||||||
subhead: new TextStyle(
|
subhead: new TextStyle(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
fontFamily: appFontFamily,
|
fontFamily: appFontFamily,
|
||||||
|
|||||||
@ -19,7 +19,7 @@ import 'package:label_storemax/models/checkout_session.dart';
|
|||||||
import 'package:woosignal/models/payload/order_wc.dart';
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
|
Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
|
||||||
OrderWC orderWC = OrderWC();
|
OrderWC orderWC = OrderWC();
|
||||||
|
|
||||||
String paymentMethodName = CheckoutSession.getInstance.paymentType.name ?? "";
|
String paymentMethodName = CheckoutSession.getInstance.paymentType.name ?? "";
|
||||||
@ -30,7 +30,7 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
|
|||||||
|
|
||||||
orderWC.paymentMethodTitle = paymentMethodName.toLowerCase();
|
orderWC.paymentMethodTitle = paymentMethodName.toLowerCase();
|
||||||
|
|
||||||
orderWC.setPaid = true;
|
orderWC.setPaid = markPaid;
|
||||||
orderWC.status = "pending";
|
orderWC.status = "pending";
|
||||||
orderWC.currency = app_currency_iso.toUpperCase();
|
orderWC.currency = app_currency_iso.toUpperCase();
|
||||||
orderWC.customerId =
|
orderWC.customerId =
|
||||||
|
|||||||
16
LabelStoreMax/lib/helpers/enums/sort_enums.dart
Normal file
16
LabelStoreMax/lib/helpers/enums/sort_enums.dart
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// 2020, WooSignal Ltd. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
enum SortByType {
|
||||||
|
LowToHigh,
|
||||||
|
HighToLow,
|
||||||
|
NameAZ,
|
||||||
|
NameZA,
|
||||||
|
}
|
||||||
@ -38,5 +38,5 @@ authLogout(BuildContext context) async {
|
|||||||
await sharedPref.save(keyAuthCheck, null);
|
await sharedPref.save(keyAuthCheck, null);
|
||||||
destroyUserId(context);
|
destroyUserId(context);
|
||||||
Cart.getInstance.clear();
|
Cart.getInstance.clear();
|
||||||
navigatorPush(context, routeName: "/account-landing", forgetAll: true);
|
navigatorPush(context, routeName: "/home", forgetAll: true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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: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';
|
||||||
import 'package:label_storemax/helpers/app_localizations.dart';
|
import 'package:label_storemax/helpers/app_localizations.dart';
|
||||||
@ -22,9 +23,12 @@ import 'package:label_storemax/models/payment_type.dart';
|
|||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:flutter_web_browser/flutter_web_browser.dart';
|
import 'package:flutter_web_browser/flutter_web_browser.dart';
|
||||||
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
|
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
|
||||||
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:math_expressions/math_expressions.dart';
|
import 'package:math_expressions/math_expressions.dart';
|
||||||
import 'package:platform_alert_dialog/platform_alert_dialog.dart';
|
import 'package:platform_alert_dialog/platform_alert_dialog.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:status_alert/status_alert.dart';
|
import 'package:status_alert/status_alert.dart';
|
||||||
|
import 'package:woosignal/models/response/products.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
import 'package:woosignal/woosignal.dart';
|
import 'package:woosignal/woosignal.dart';
|
||||||
|
|
||||||
@ -65,11 +69,6 @@ showStatusAlert(context,
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaymentMethodType {
|
|
||||||
static final int STRIPE = 1;
|
|
||||||
static final int APPLEPAY = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
class EdgeAlertStyle {
|
class EdgeAlertStyle {
|
||||||
static final int SUCCESS = 1;
|
static final int SUCCESS = 1;
|
||||||
static final int WARNING = 2;
|
static final int WARNING = 2;
|
||||||
@ -142,7 +141,7 @@ String formatStringCurrency({@required String total}) {
|
|||||||
if (total == null || total == "") {
|
if (total == null || total == "") {
|
||||||
tmpVal = 0;
|
tmpVal = 0;
|
||||||
} else {
|
} else {
|
||||||
tmpVal = double.parse(total);
|
tmpVal = parseWcPrice(total);
|
||||||
}
|
}
|
||||||
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
||||||
amount: tmpVal,
|
amount: tmpVal,
|
||||||
@ -185,6 +184,9 @@ checkout(
|
|||||||
}
|
}
|
||||||
|
|
||||||
double strCal({@required String sum}) {
|
double strCal({@required String sum}) {
|
||||||
|
if (sum == null || sum == "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Parser p = Parser();
|
Parser p = Parser();
|
||||||
Expression exp = p.parse(sum);
|
Expression exp = p.parse(sum);
|
||||||
ContextModel cm = ContextModel();
|
ContextModel cm = ContextModel();
|
||||||
@ -192,6 +194,9 @@ double strCal({@required String sum}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<double> workoutShippingCostWC({@required String sum}) async {
|
Future<double> workoutShippingCostWC({@required String sum}) async {
|
||||||
|
if (sum == null || sum == "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
||||||
sum = sum.replaceAllMapped(defaultRegex(r'\[qty\]', strict: true), (replace) {
|
sum = sum.replaceAllMapped(defaultRegex(r'\[qty\]', strict: true), (replace) {
|
||||||
return cartLineItem
|
return cartLineItem
|
||||||
@ -263,6 +268,9 @@ Future<double> workoutShippingCostWC({@required String sum}) async {
|
|||||||
|
|
||||||
Future<double> workoutShippingClassCostWC(
|
Future<double> workoutShippingClassCostWC(
|
||||||
{@required String sum, List<CartLineItem> cartLineItem}) async {
|
{@required String sum, List<CartLineItem> cartLineItem}) async {
|
||||||
|
if (sum == null || sum == "") {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
sum = sum.replaceAllMapped(defaultRegex(r'\[qty\]', strict: true), (replace) {
|
sum = sum.replaceAllMapped(defaultRegex(r'\[qty\]', strict: true), (replace) {
|
||||||
return cartLineItem
|
return cartLineItem
|
||||||
.map((f) => f.quantity)
|
.map((f) => f.quantity)
|
||||||
@ -357,14 +365,22 @@ bool validPassword(String pw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
navigatorPush(BuildContext context,
|
navigatorPush(BuildContext context,
|
||||||
{@required String routeName, Object arguments, bool forgetAll = false}) {
|
{@required String routeName,
|
||||||
|
Object arguments,
|
||||||
|
bool forgetAll = false,
|
||||||
|
int forgetLast}) {
|
||||||
if (forgetAll) {
|
if (forgetAll) {
|
||||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||||
routeName, (Route<dynamic> route) => false,
|
routeName, (Route<dynamic> route) => false,
|
||||||
arguments: arguments ?? null);
|
arguments: arguments ?? null);
|
||||||
} else {
|
|
||||||
Navigator.of(context).pushNamed(routeName, arguments: arguments ?? null);
|
|
||||||
}
|
}
|
||||||
|
if (forgetLast != null) {
|
||||||
|
int count = 0;
|
||||||
|
Navigator.of(context).popUntil((route) {
|
||||||
|
return count++ == forgetLast;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Navigator.of(context).pushNamed(routeName, arguments: arguments ?? null);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlatformDialogAction dialogAction(BuildContext context,
|
PlatformDialogAction dialogAction(BuildContext context,
|
||||||
@ -450,3 +466,58 @@ String formatForDateTime(FormatType formatType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
|
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
|
||||||
|
|
||||||
|
double parseWcPrice(String price) => (double.tryParse(price) ?? 0);
|
||||||
|
|
||||||
|
Widget refreshableScroll(context,
|
||||||
|
{@required refreshController,
|
||||||
|
@required VoidCallback onRefresh,
|
||||||
|
@required VoidCallback onLoading,
|
||||||
|
@required List<Product> products,
|
||||||
|
@required onTap,
|
||||||
|
key}) {
|
||||||
|
return SmartRefresher(
|
||||||
|
enablePullDown: false,
|
||||||
|
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 products"));
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
height: 55.0,
|
||||||
|
child: Center(child: body),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
controller: refreshController,
|
||||||
|
onRefresh: onRefresh,
|
||||||
|
onLoading: onLoading,
|
||||||
|
child: (products.length != null && products.length > 0
|
||||||
|
? GridView.count(
|
||||||
|
crossAxisCount: 2,
|
||||||
|
children: List.generate(
|
||||||
|
products.length,
|
||||||
|
(index) {
|
||||||
|
return wsCardProductItem(context,
|
||||||
|
index: index, product: products[index], onTap: onTap);
|
||||||
|
},
|
||||||
|
))
|
||||||
|
: wsNoResults(context)));
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserAuth {
|
||||||
|
UserAuth._privateConstructor();
|
||||||
|
static final UserAuth instance = UserAuth._privateConstructor();
|
||||||
|
|
||||||
|
String redirect = "/home";
|
||||||
|
}
|
||||||
|
|||||||
@ -10,11 +10,13 @@
|
|||||||
// 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:ui';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Developer Notes
|
Developer Notes
|
||||||
|
|
||||||
SUPPORT EMAIL - support@woosignal.com
|
SUPPORT EMAIL - support@woosignal.com
|
||||||
VERSION - 2.0.1
|
VERSION - 2.0.2
|
||||||
https://woosignal.com
|
https://woosignal.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -22,15 +24,51 @@
|
|||||||
|
|
||||||
const app_name = "MyApp";
|
const app_name = "MyApp";
|
||||||
|
|
||||||
const app_key = "your app key";
|
const app_key =
|
||||||
|
"Your app key from WooSingal";
|
||||||
// Your App key from WooSignal
|
// Your App key from WooSignal
|
||||||
// link: https://woosignal.com/dashboard/apps
|
// link: https://woosignal.com/dashboard/apps
|
||||||
|
|
||||||
const app_logo_url = "https://is5-ssl.mzstatic.com/image/thumb/Purple115/v4/4b/e8/9a/4be89a5a-607e-1fb3-c45a-3261e84a061b/source/512x512bb.jpg";
|
const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
|
||||||
|
|
||||||
const app_terms_url = "https://yourdomain.com/terms";
|
const app_terms_url = "https://yourdomain.com/terms";
|
||||||
const app_privacy_url = "https://yourdomain.com/privacy";
|
const app_privacy_url = "https://yourdomain.com/privacy";
|
||||||
|
|
||||||
|
|
||||||
|
/*<! ------ APP SETTINGS ------!>*/
|
||||||
|
|
||||||
|
const app_currency_symbol = "\£";
|
||||||
|
const app_currency_iso = "gbp";
|
||||||
|
const app_locales_supported = [
|
||||||
|
Locale('en'),
|
||||||
|
];
|
||||||
|
// If you want to localize the app, add the locale above
|
||||||
|
// then create a new lang json file using keys from en.json
|
||||||
|
// e.g. lang/es.json
|
||||||
|
|
||||||
|
|
||||||
|
/*<! ------ PAYMENT GATEWAYS ------!>*/
|
||||||
|
|
||||||
|
// Available: "Stripe", "CashOnDelivery",
|
||||||
|
// Add the method to the array below e.g. ["Stripe", "CashOnDelivery"]
|
||||||
|
|
||||||
|
const app_payment_methods = ["Stripe"];
|
||||||
|
|
||||||
|
|
||||||
|
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
||||||
|
|
||||||
|
// Your StripeAccount key from WooSignal
|
||||||
|
// link: https://woosignal.com/dashboard
|
||||||
|
|
||||||
|
const app_stripe_account = "Your StripeAccount from WooSignal";
|
||||||
|
|
||||||
|
const app_stripe_live_mode = false;
|
||||||
|
// For Live Payments follow the below steps
|
||||||
|
// #1 SET the above to true for live payments
|
||||||
|
// #2 Next visit https://woosignal.com/dashboard
|
||||||
|
// #3 Then change "Environment for Stripe" to Live mode
|
||||||
|
|
||||||
|
|
||||||
/*<! ------ WP LOGIN (OPTIONAL) ------!>*/
|
/*<! ------ WP LOGIN (OPTIONAL) ------!>*/
|
||||||
|
|
||||||
// Allows customers to login/register, view account, purchase items as a user.
|
// Allows customers to login/register, view account, purchase items as a user.
|
||||||
@ -40,29 +78,10 @@ const app_privacy_url = "https://yourdomain.com/privacy";
|
|||||||
|
|
||||||
const use_wp_login = false;
|
const use_wp_login = false;
|
||||||
const app_base_url = "https://mysite.com"; // change to your url
|
const app_base_url = "https://mysite.com"; // change to your url
|
||||||
const app_forgot_password_url = "https://mysite.com/my-account/lost-password"; // change to your forgot password url
|
const app_forgot_password_url =
|
||||||
|
"https://mysite.com/my-account/lost-password"; // change to your forgot password url
|
||||||
const app_wp_api_path = "/wp-json"; // By default "/wp-json" should work
|
const app_wp_api_path = "/wp-json"; // By default "/wp-json" should work
|
||||||
|
|
||||||
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
|
||||||
|
|
||||||
// Your StripeAccount key from WooSignal
|
|
||||||
// link: https://woosignal.com/dashboard
|
|
||||||
|
|
||||||
const app_stripe_account = "Stripe Key from WooSignal";
|
|
||||||
|
|
||||||
const app_stripe_live_mode = false;
|
|
||||||
// For Live Payments follow the below steps
|
|
||||||
// #1 SET the above to true for live payments
|
|
||||||
// #2 Next visit https://woosignal.com/dashboard
|
|
||||||
// #3 Then change "Environment for Stripe" to Live mode
|
|
||||||
|
|
||||||
/*<! ------ APP CURRENCY ------!>*/
|
|
||||||
|
|
||||||
const app_currency_symbol = "\£";
|
|
||||||
const app_currency_iso = "gbp";
|
|
||||||
const app_locales_supported = ['en'];
|
|
||||||
|
|
||||||
const app_payment_methods = ["Stripe"];
|
|
||||||
|
|
||||||
/*<! ------ DEBUGGER ENABLED ------!>*/
|
/*<! ------ DEBUGGER ENABLED ------!>*/
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
|
|
||||||
import 'package:label_storemax/pages/account_billing_details.dart';
|
import 'package:label_storemax/pages/account_billing_details.dart';
|
||||||
import 'package:label_storemax/pages/account_detail.dart';
|
import 'package:label_storemax/pages/account_detail.dart';
|
||||||
import 'package:label_storemax/pages/account_landing.dart';
|
import 'package:label_storemax/pages/account_landing.dart';
|
||||||
@ -51,13 +50,12 @@ void main() async {
|
|||||||
DeviceOrientation.portraitUp,
|
DeviceOrientation.portraitUp,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
String initialRoute = (use_wp_login) ? "/account-landing" : "/home";
|
String initialRoute = "/home";
|
||||||
WPJsonAPI.instance.initWith(
|
if (use_wp_login == true) {
|
||||||
baseUrl: app_base_url,
|
WPJsonAPI.instance.initWith(
|
||||||
shouldDebug: app_debug,
|
baseUrl: app_base_url,
|
||||||
wpJsonPath: app_wp_api_path);
|
shouldDebug: app_debug,
|
||||||
if (await authCheck() == true) {
|
wpJsonPath: app_wp_api_path);
|
||||||
initialRoute = "/home";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
@ -71,7 +69,6 @@ void main() async {
|
|||||||
'/cart': (BuildContext context) => new CartPage(),
|
'/cart': (BuildContext context) => new CartPage(),
|
||||||
'/error': (BuildContext context) => new ErrorPage(),
|
'/error': (BuildContext context) => new ErrorPage(),
|
||||||
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
|
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
|
||||||
'/account-landing': (BuildContext context) => new AccountLandingPage(),
|
|
||||||
'/account-register': (BuildContext context) =>
|
'/account-register': (BuildContext context) =>
|
||||||
new AccountRegistrationPage(),
|
new AccountRegistrationPage(),
|
||||||
'/account-detail': (BuildContext context) => new AccountDetailPage(),
|
'/account-detail': (BuildContext context) => new AccountDetailPage(),
|
||||||
@ -84,6 +81,12 @@ void main() async {
|
|||||||
},
|
},
|
||||||
onGenerateRoute: (settings) {
|
onGenerateRoute: (settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
|
case '/account-landing':
|
||||||
|
return PageTransition(
|
||||||
|
child: AccountLandingPage(),
|
||||||
|
type: PageTransitionType.downToUp,
|
||||||
|
);
|
||||||
|
|
||||||
case '/browse-category':
|
case '/browse-category':
|
||||||
if (settings.arguments != null) {
|
if (settings.arguments != null) {
|
||||||
final ProductCategory category =
|
final ProductCategory category =
|
||||||
@ -200,9 +203,7 @@ void main() async {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
supportedLocales: [
|
supportedLocales: app_locales_supported,
|
||||||
Locale('en'),
|
|
||||||
],
|
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
AppLocalizations.delegate,
|
AppLocalizations.delegate,
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
|||||||
@ -142,7 +142,7 @@ class Cart {
|
|||||||
|
|
||||||
if (taxableCartLines.length > 0) {
|
if (taxableCartLines.length > 0) {
|
||||||
cartSubtotal = taxableCartLines
|
cartSubtotal = taxableCartLines
|
||||||
.map<double>((m) => double.parse(m.subtotal))
|
.map<double>((m) => parseWcPrice(m.subtotal))
|
||||||
.reduce((a, b) => a + b);
|
.reduce((a, b) => a + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,13 +155,19 @@ class Cart {
|
|||||||
case "flat_rate":
|
case "flat_rate":
|
||||||
FlatRate flatRate = (shippingType.object as FlatRate);
|
FlatRate flatRate = (shippingType.object as FlatRate);
|
||||||
if (flatRate.taxable != null && flatRate.taxable) {
|
if (flatRate.taxable != null && flatRate.taxable) {
|
||||||
shippingTotal += double.parse(shippingType.cost);
|
shippingTotal += parseWcPrice(
|
||||||
|
shippingType.cost == null || shippingType.cost == ""
|
||||||
|
? "0"
|
||||||
|
: shippingType.cost);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "local_pickup":
|
case "local_pickup":
|
||||||
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
||||||
if (localPickup.taxable != null && localPickup.taxable) {
|
if (localPickup.taxable != null && localPickup.taxable) {
|
||||||
shippingTotal += double.parse(localPickup.cost);
|
shippingTotal += parseWcPrice(
|
||||||
|
(localPickup.cost == null || localPickup.cost == ""
|
||||||
|
? "0"
|
||||||
|
: localPickup.cost));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -171,10 +177,10 @@ class Cart {
|
|||||||
|
|
||||||
double total = 0;
|
double total = 0;
|
||||||
if (subtotal != 0) {
|
if (subtotal != 0) {
|
||||||
total += ((double.parse(taxRate.rate) * subtotal) / 100);
|
total += ((parseWcPrice(taxRate.rate) * subtotal) / 100);
|
||||||
}
|
}
|
||||||
if (shippingTotal != 0) {
|
if (shippingTotal != 0) {
|
||||||
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
|
total += ((parseWcPrice(taxRate.rate) * shippingTotal) / 100);
|
||||||
}
|
}
|
||||||
return (total).toStringAsFixed(2);
|
return (total).toStringAsFixed(2);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 'package:label_storemax/helpers/tools.dart';
|
||||||
|
|
||||||
class CartLineItem {
|
class CartLineItem {
|
||||||
String name;
|
String name;
|
||||||
int productId;
|
int productId;
|
||||||
@ -45,7 +47,7 @@ class CartLineItem {
|
|||||||
this.metaData});
|
this.metaData});
|
||||||
|
|
||||||
String getCartTotal() {
|
String getCartTotal() {
|
||||||
return (quantity * double.parse(subtotal)).toString();
|
return (quantity * parseWcPrice(subtotal)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
CartLineItem.fromJson(Map<String, dynamic> json)
|
CartLineItem.fromJson(Map<String, dynamic> json)
|
||||||
@ -56,7 +58,10 @@ class CartLineItem {
|
|||||||
shippingClassId = json['shipping_class_id'].toString(),
|
shippingClassId = json['shipping_class_id'].toString(),
|
||||||
taxStatus = json['tax_status'],
|
taxStatus = json['tax_status'],
|
||||||
stockQuantity = json['stock_quantity'],
|
stockQuantity = json['stock_quantity'],
|
||||||
isManagedStock = json['is_managed_stock'],
|
isManagedStock = (json['is_managed_stock'] != null &&
|
||||||
|
json['is_managed_stock'] is bool)
|
||||||
|
? json['is_managed_stock']
|
||||||
|
: false,
|
||||||
shippingIsTaxable = json['shipping_is_taxable'],
|
shippingIsTaxable = json['shipping_is_taxable'],
|
||||||
subtotal = json['subtotal'],
|
subtotal = json['subtotal'],
|
||||||
total = json['total'],
|
total = json['total'],
|
||||||
|
|||||||
@ -61,18 +61,18 @@ class CheckoutSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
||||||
double totalCart = double.parse(await Cart.getInstance.getTotal());
|
double totalCart = parseWcPrice(await Cart.getInstance.getTotal());
|
||||||
double totalShipping = 0;
|
double totalShipping = 0;
|
||||||
if (shippingType != null && shippingType.object != null) {
|
if (shippingType != null && shippingType.object != null) {
|
||||||
switch (shippingType.methodId) {
|
switch (shippingType.methodId) {
|
||||||
case "flat_rate":
|
case "flat_rate":
|
||||||
totalShipping = double.parse(shippingType.cost);
|
totalShipping = parseWcPrice(shippingType.cost);
|
||||||
break;
|
break;
|
||||||
case "free_shipping":
|
case "free_shipping":
|
||||||
totalShipping = double.parse(shippingType.cost);
|
totalShipping = parseWcPrice(shippingType.cost);
|
||||||
break;
|
break;
|
||||||
case "local_pickup":
|
case "local_pickup":
|
||||||
totalShipping = double.parse(shippingType.cost);
|
totalShipping = parseWcPrice(shippingType.cost);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -83,12 +83,12 @@ class CheckoutSession {
|
|||||||
|
|
||||||
if (taxRate != null) {
|
if (taxRate != null) {
|
||||||
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
||||||
total += double.parse(taxAmount);
|
total += parseWcPrice(taxAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withFormat != null && withFormat == true) {
|
if (withFormat != null && withFormat == true) {
|
||||||
return formatDoubleCurrency(total: total);
|
return formatDoubleCurrency(total: total);
|
||||||
}
|
}
|
||||||
return total.toString();
|
return total.toStringAsFixed(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class _AboutPageState extends State<AboutPage> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
title: Text(trans(context, "About"),
|
title: Text(trans(context, "About"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.headline6),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
@ -85,8 +85,9 @@ class _AboutPageState extends State<AboutPage> {
|
|||||||
trans(context, "Version") +
|
trans(context, "Version") +
|
||||||
": " +
|
": " +
|
||||||
snapshot.data.version,
|
snapshot.data.version,
|
||||||
style:
|
style: Theme.of(context)
|
||||||
Theme.of(context).primaryTextTheme.body2),
|
.primaryTextTheme
|
||||||
|
.bodyText1),
|
||||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,7 +89,7 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: Text(
|
title: Text(
|
||||||
trans(context, "Billing Details"),
|
trans(context, "Billing Details"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -85,7 +85,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
trans(context, "Account"),
|
trans(context, "Account"),
|
||||||
style: Theme.of(context).primaryTextTheme.title,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
@ -212,7 +212,12 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
leading: Icon(Icons.account_circle),
|
leading: Icon(Icons.account_circle),
|
||||||
title: Text(trans(context, "Update details")),
|
title: Text(trans(context, "Update details")),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pushNamed(context, "/account-update");
|
Navigator.pushNamed(context, "/account-update").then((onValue) {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
_fetchWpUserData();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -238,9 +243,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
child: ListTile(
|
child: ListTile(
|
||||||
leading: Icon(Icons.exit_to_app),
|
leading: Icon(Icons.exit_to_app),
|
||||||
title: Text(trans(context, "Logout")),
|
title: Text(trans(context, "Logout")),
|
||||||
onTap: () {
|
onTap: () => authLogout(context),
|
||||||
authLogout(context);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -331,7 +334,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
formatStringCurrency(total: _orders[i].total),
|
formatStringCurrency(total: _orders[i].total),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body1
|
.bodyText2
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Colors.black),
|
color: Colors.black),
|
||||||
@ -343,7 +346,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
trans(context, "items"),
|
trans(context, "items"),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body2
|
.bodyText1
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Colors.black),
|
color: Colors.black),
|
||||||
@ -364,7 +367,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
|||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body2
|
.bodyText1
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
color: Colors.black),
|
color: Colors.black),
|
||||||
|
|||||||
@ -68,7 +68,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
|||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.display1
|
.headline4
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
@ -119,7 +119,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
|||||||
Padding(
|
Padding(
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Create an account"),
|
trans(context, "Create an account"),
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.only(left: 8),
|
padding: EdgeInsets.only(left: 8),
|
||||||
)
|
)
|
||||||
@ -133,6 +133,10 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
|||||||
action: () {
|
action: () {
|
||||||
launch(app_forgot_password_url);
|
launch(app_forgot_password_url);
|
||||||
}),
|
}),
|
||||||
|
Divider(),
|
||||||
|
wsLinkButton(context, title: trans(context, "Back"), action: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -157,7 +161,13 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
|||||||
authUser(token);
|
authUser(token);
|
||||||
storeUserId(wpUserLoginResponse.data.userId.toString());
|
storeUserId(wpUserLoginResponse.data.userId.toString());
|
||||||
|
|
||||||
navigatorPush(context, routeName: "/home", forgetAll: true);
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Hello"),
|
||||||
|
desc: trans(context, "Welcome back"),
|
||||||
|
style: EdgeAlertStyle.SUCCESS,
|
||||||
|
icon: Icons.account_circle);
|
||||||
|
navigatorPush(context,
|
||||||
|
routeName: UserAuth.instance.redirect, forgetLast: 1);
|
||||||
} else {
|
} else {
|
||||||
showEdgeAlertWith(context,
|
showEdgeAlertWith(context,
|
||||||
title: trans(context, "Oops!"),
|
title: trans(context, "Oops!"),
|
||||||
|
|||||||
@ -55,7 +55,7 @@ class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Order #" + _orderId.toString(),
|
"Order #" + _orderId.toString(),
|
||||||
style: Theme.of(context).primaryTextTheme.title,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
@ -157,7 +157,7 @@ class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
|
|||||||
total: _order.lineItems[i].total),
|
total: _order.lineItems[i].total),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body1
|
.bodyText2
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Colors.black),
|
color: Colors.black),
|
||||||
@ -169,7 +169,7 @@ class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
|
|||||||
.toString(),
|
.toString(),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body2
|
.bodyText1
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontWeight: FontWeight.w600,
|
fontWeight: FontWeight.w600,
|
||||||
color: Colors.black),
|
color: Colors.black),
|
||||||
|
|||||||
@ -16,7 +16,6 @@ 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/WPUserInfoUpdatedResponse.dart';
|
|
||||||
import 'package:wp_json_api/models/responses/WPUserRegisterResponse.dart';
|
import 'package:wp_json_api/models/responses/WPUserRegisterResponse.dart';
|
||||||
import 'package:wp_json_api/wp_json_api.dart';
|
import 'package:wp_json_api/wp_json_api.dart';
|
||||||
|
|
||||||
@ -61,7 +60,7 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
|||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
"Register",
|
"Register",
|
||||||
style: Theme.of(context).primaryTextTheme.title,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
@ -173,19 +172,25 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
|||||||
|
|
||||||
WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance
|
WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance
|
||||||
.api((request) => request.wpRegister(
|
.api((request) => request.wpRegister(
|
||||||
email: email, password: password, username: username));
|
email: email.toLowerCase(),
|
||||||
|
password: password,
|
||||||
|
username: username));
|
||||||
|
|
||||||
if (wpUserRegisterResponse != null) {
|
if (wpUserRegisterResponse != null) {
|
||||||
String token = wpUserRegisterResponse.data.userToken;
|
String token = wpUserRegisterResponse.data.userToken;
|
||||||
authUser(token);
|
authUser(token);
|
||||||
storeUserId(wpUserRegisterResponse.data.userId.toString());
|
storeUserId(wpUserRegisterResponse.data.userId.toString());
|
||||||
|
|
||||||
WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = await WPJsonAPI
|
await WPJsonAPI.instance.api((request) => request
|
||||||
.instance
|
.wpUpdateUserInfo(token, firstName: firstName, lastName: lastName));
|
||||||
.api((request) => request.wpUpdateUserInfo(token,
|
|
||||||
firstName: firstName, lastName: lastName));
|
|
||||||
|
|
||||||
navigatorPush(context, routeName: "/home", forgetAll: true);
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Hello") + " $firstName",
|
||||||
|
desc: trans(context, "you're now logged in"),
|
||||||
|
style: EdgeAlertStyle.SUCCESS,
|
||||||
|
icon: Icons.account_circle);
|
||||||
|
navigatorPush(context,
|
||||||
|
routeName: UserAuth.instance.redirect, forgetLast: 2);
|
||||||
} else {
|
} else {
|
||||||
setState(() {
|
setState(() {
|
||||||
showEdgeAlertWith(context,
|
showEdgeAlertWith(context,
|
||||||
|
|||||||
@ -90,7 +90,7 @@ class _AccountShippingDetailsPageState
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: Text(
|
title: Text(
|
||||||
trans(context, "Shipping Details"),
|
trans(context, "Shipping Details"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -8,9 +8,13 @@
|
|||||||
// 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:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/helpers/enums/sort_enums.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/buttons.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart';
|
import 'package:woosignal/models/response/product_category.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
@ -29,8 +33,9 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
_BrowseCategoryPageState(this._selectedCategory);
|
_BrowseCategoryPageState(this._selectedCategory);
|
||||||
|
|
||||||
List<WS.Product> _products = [];
|
List<WS.Product> _products = [];
|
||||||
var _productsController = ScrollController();
|
|
||||||
|
|
||||||
|
RefreshController _refreshController =
|
||||||
|
RefreshController(initialRefresh: false);
|
||||||
ProductCategory _selectedCategory;
|
ProductCategory _selectedCategory;
|
||||||
bool _isLoading;
|
bool _isLoading;
|
||||||
int _page;
|
int _page;
|
||||||
@ -46,34 +51,17 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
_page = 1;
|
_page = 1;
|
||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
_fetchMoreProducts();
|
||||||
_fetchProductsForCategory();
|
|
||||||
_addScrollListener();
|
|
||||||
}
|
|
||||||
|
|
||||||
_addScrollListener() async {
|
|
||||||
_productsController.addListener(() {
|
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
|
||||||
double currentScroll = _productsController.position.pixels;
|
|
||||||
double delta = 50.0;
|
|
||||||
if (maxScroll - currentScroll <= delta) {
|
|
||||||
if (_shouldStopRequests) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (waitForNextRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_fetchMoreProducts();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchMoreProducts() async {
|
_fetchMoreProducts() async {
|
||||||
waitForNextRequest = true;
|
waitForNextRequest = true;
|
||||||
List<WS.Product> products = await appWooSignal((api) {
|
List<WS.Product> products = await appWooSignal((api) => api.getProducts(
|
||||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
perPage: 50,
|
||||||
});
|
category: _selectedCategory.id.toString(),
|
||||||
|
page: _page,
|
||||||
|
status: "publish",
|
||||||
|
stockStatus: "instock"));
|
||||||
_products.addAll(products);
|
_products.addAll(products);
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
_page = _page + 1;
|
_page = _page + 1;
|
||||||
@ -82,13 +70,6 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
if (products.length == 0) {
|
if (products.length == 0) {
|
||||||
_shouldStopRequests = true;
|
_shouldStopRequests = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_fetchProductsForCategory() async {
|
|
||||||
_products = await appWooSignal((api) {
|
|
||||||
return api.getProducts(
|
|
||||||
category: _selectedCategory.id.toString(), perPage: 50);
|
|
||||||
});
|
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
@ -109,12 +90,18 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans(context, "Browse"),
|
Text(trans(context, "Browse"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
Text(_selectedCategory.name,
|
Text(_selectedCategory.name,
|
||||||
style: Theme.of(context).primaryTextTheme.title)
|
style: Theme.of(context).primaryTextTheme.headline6)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
|
actions: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(Icons.tune),
|
||||||
|
onPressed: _modalSheetTune,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
minimum: safeAreaDefault(),
|
minimum: safeAreaDefault(),
|
||||||
@ -122,25 +109,105 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
? Center(
|
? Center(
|
||||||
child: showAppLoader(),
|
child: showAppLoader(),
|
||||||
)
|
)
|
||||||
: Column(
|
: refreshableScroll(context,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
refreshController: _refreshController,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
onRefresh: _onRefresh,
|
||||||
children: <Widget>[
|
onLoading: _onLoading,
|
||||||
Expanded(
|
products: _products,
|
||||||
child: (_products.length != null && _products.length > 0
|
onTap: _showProduct),
|
||||||
? GridView.count(
|
|
||||||
crossAxisCount: 2,
|
|
||||||
controller: _productsController,
|
|
||||||
children: List.generate(_products.length, (index) {
|
|
||||||
return wsCardProductItem(context,
|
|
||||||
index: index, product: _products[index]);
|
|
||||||
}))
|
|
||||||
: wsNoResults(context)),
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onRefresh() async {
|
||||||
|
await _fetchMoreProducts();
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.resetNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.refreshCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLoading() async {
|
||||||
|
await _fetchMoreProducts();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.loadNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.loadComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_sortProducts({@required SortByType by}) {
|
||||||
|
switch (by) {
|
||||||
|
case SortByType.LowToHigh:
|
||||||
|
_products.sort((product1, product2) => (parseWcPrice(product1.price))
|
||||||
|
.compareTo((double.tryParse(product2.price) ?? 0)));
|
||||||
|
break;
|
||||||
|
case SortByType.HighToLow:
|
||||||
|
_products.sort((product1, product2) => (parseWcPrice(product2.price))
|
||||||
|
.compareTo((double.tryParse(product1.price) ?? 0)));
|
||||||
|
break;
|
||||||
|
case SortByType.NameAZ:
|
||||||
|
_products.sort(
|
||||||
|
(product1, product2) => product1.name.compareTo(product2.name));
|
||||||
|
break;
|
||||||
|
case SortByType.NameZA:
|
||||||
|
_products.sort(
|
||||||
|
(product1, product2) => product2.name.compareTo(product1.name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
Navigator.pop(context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_modalSheetTune() {
|
||||||
|
wsModalBottom(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Sort results"),
|
||||||
|
bodyWidget: ListView(
|
||||||
|
children: <Widget>[
|
||||||
|
wsLinkButton(context,
|
||||||
|
title: trans(context, "Sort: Low to high"),
|
||||||
|
action: () => _sortProducts(by: SortByType.LowToHigh)),
|
||||||
|
Divider(
|
||||||
|
height: 0,
|
||||||
|
),
|
||||||
|
wsLinkButton(context,
|
||||||
|
title: trans(context, "Sort: High to low"),
|
||||||
|
action: () => _sortProducts(by: SortByType.HighToLow)),
|
||||||
|
Divider(
|
||||||
|
height: 0,
|
||||||
|
),
|
||||||
|
wsLinkButton(context,
|
||||||
|
title: trans(context, "Sort: Name A-Z"),
|
||||||
|
action: () => _sortProducts(by: SortByType.NameAZ)),
|
||||||
|
Divider(
|
||||||
|
height: 0,
|
||||||
|
),
|
||||||
|
wsLinkButton(context,
|
||||||
|
title: trans(context, "Sort: Name Z-A"),
|
||||||
|
action: () => _sortProducts(by: SortByType.NameZA)),
|
||||||
|
Divider(
|
||||||
|
height: 0,
|
||||||
|
),
|
||||||
|
wsLinkButton(context,
|
||||||
|
title: trans(context, "Cancel"), action: _dismissModal)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_dismissModal() {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
_showProduct(WS.Product product) {
|
||||||
|
Navigator.pushNamed(context, "/product-detail", arguments: product);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,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/widgets/app_loader.dart';
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
|
||||||
|
|
||||||
class BrowseSearchPage extends StatefulWidget {
|
class BrowseSearchPage extends StatefulWidget {
|
||||||
final String search;
|
final String search;
|
||||||
@ -25,7 +25,8 @@ class BrowseSearchPage extends StatefulWidget {
|
|||||||
class _BrowseSearchState extends State<BrowseSearchPage> {
|
class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||||
_BrowseSearchState(this._search);
|
_BrowseSearchState(this._search);
|
||||||
|
|
||||||
var _productsController = ScrollController();
|
RefreshController _refreshController =
|
||||||
|
RefreshController(initialRefresh: false);
|
||||||
List<WS.Product> _products = [];
|
List<WS.Product> _products = [];
|
||||||
String _search;
|
String _search;
|
||||||
bool _isLoading;
|
bool _isLoading;
|
||||||
@ -42,39 +43,26 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
|
||||||
_fetchProductsForSearch(_page);
|
_fetchProductsForSearch();
|
||||||
_addScrollListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_addScrollListener() async {
|
_fetchProductsForSearch() async {
|
||||||
_productsController.addListener(() {
|
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
|
||||||
double currentScroll = _productsController.position.pixels;
|
|
||||||
double delta = 50.0;
|
|
||||||
if (maxScroll - currentScroll <= delta) {
|
|
||||||
if (_shouldStopRequests) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (waitForNextRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_fetchProductsForSearch(_page);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_fetchProductsForSearch(int page) async {
|
|
||||||
waitForNextRequest = true;
|
waitForNextRequest = true;
|
||||||
List<WS.Product> products = await appWooSignal((api) {
|
List<WS.Product> products = await appWooSignal((api) => api.getProducts(
|
||||||
_page = _page + 1;
|
perPage: 100,
|
||||||
return api.getProducts(
|
search: _search,
|
||||||
search: _search, perPage: 100, page: page, status: "publish");
|
page: _page,
|
||||||
});
|
status: "publish",
|
||||||
|
stockStatus: "instock"));
|
||||||
|
_products.addAll(products);
|
||||||
|
waitForNextRequest = false;
|
||||||
|
_page = _page + 1;
|
||||||
|
|
||||||
|
waitForNextRequest = false;
|
||||||
if (products.length == 0) {
|
if (products.length == 0) {
|
||||||
_shouldStopRequests = true;
|
_shouldStopRequests = true;
|
||||||
}
|
}
|
||||||
setState(() {
|
setState(() {
|
||||||
_products.addAll(products.toList());
|
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -94,9 +82,9 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans(context, "Search results for"),
|
Text(trans(context, "Search results for"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
Text("\"" + _search + "\"",
|
Text("\"" + _search + "\"",
|
||||||
style: Theme.of(context).primaryTextTheme.title)
|
style: Theme.of(context).primaryTextTheme.headline6)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
@ -107,29 +95,40 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
? Center(
|
? Center(
|
||||||
child: showAppLoader(),
|
child: showAppLoader(),
|
||||||
)
|
)
|
||||||
: Column(
|
: refreshableScroll(context,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
refreshController: _refreshController,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
onRefresh: _onRefresh,
|
||||||
children: <Widget>[
|
onLoading: _onLoading,
|
||||||
Expanded(
|
products: _products,
|
||||||
child: (_products.length != null && _products.length > 0
|
onTap: _showProduct),
|
||||||
? GridView.count(
|
|
||||||
crossAxisCount: 2,
|
|
||||||
controller: _productsController,
|
|
||||||
children: List.generate(
|
|
||||||
_products.length,
|
|
||||||
(index) {
|
|
||||||
return wsCardProductItem(context,
|
|
||||||
index: index, product: _products[index]);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: wsNoResults(context)),
|
|
||||||
flex: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onRefresh() async {
|
||||||
|
await _fetchProductsForSearch();
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.resetNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.refreshCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLoading() async {
|
||||||
|
await _fetchProductsForSearch();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.loadNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.loadComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_showProduct(WS.Product product) {
|
||||||
|
Navigator.pushNamed(context, "/product-detail", arguments: product);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
import 'package:label_storemax/models/cart.dart';
|
import 'package:label_storemax/models/cart.dart';
|
||||||
import 'package:label_storemax/models/cart_line_item.dart';
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
import 'package:label_storemax/models/checkout_session.dart';
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
@ -67,6 +69,9 @@ class _CartPageState extends State<CartPage> {
|
|||||||
|
|
||||||
void _actionProceedToCheckout() async {
|
void _actionProceedToCheckout() async {
|
||||||
List<CartLineItem> cartLineItems = await Cart.getInstance.getCart();
|
List<CartLineItem> cartLineItems = await Cart.getInstance.getCart();
|
||||||
|
if (_isLoading == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (cartLineItems.length <= 0) {
|
if (cartLineItems.length <= 0) {
|
||||||
showEdgeAlertWith(context,
|
showEdgeAlertWith(context,
|
||||||
title: trans(context, "Cart"),
|
title: trans(context, "Cart"),
|
||||||
@ -94,6 +99,11 @@ class _CartPageState extends State<CartPage> {
|
|||||||
CheckoutSession.getInstance.billingDetails.shippingAddress =
|
CheckoutSession.getInstance.billingDetails.shippingAddress =
|
||||||
sfCustomerAddress;
|
sfCustomerAddress;
|
||||||
}
|
}
|
||||||
|
if (use_wp_login == true && !(await authCheck())) {
|
||||||
|
UserAuth.instance.redirect = "/checkout";
|
||||||
|
Navigator.pushNamed(context, "/account-landing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
Navigator.pushNamed(context, "/checkout");
|
Navigator.pushNamed(context, "/checkout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,6 +141,9 @@ class _CartPageState extends State<CartPage> {
|
|||||||
desc: trans(context, "Item removed"),
|
desc: trans(context, "Item removed"),
|
||||||
style: EdgeAlertStyle.WARNING,
|
style: EdgeAlertStyle.WARNING,
|
||||||
icon: Icons.remove_shopping_cart);
|
icon: Icons.remove_shopping_cart);
|
||||||
|
if (_cartLines.length == 0) {
|
||||||
|
_isCartEmpty = true;
|
||||||
|
}
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +155,7 @@ class _CartPageState extends State<CartPage> {
|
|||||||
desc: trans(context, "Cart cleared"),
|
desc: trans(context, "Cart cleared"),
|
||||||
style: EdgeAlertStyle.SUCCESS,
|
style: EdgeAlertStyle.SUCCESS,
|
||||||
icon: Icons.delete_outline);
|
icon: Icons.delete_outline);
|
||||||
|
_isCartEmpty = true;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +165,7 @@ class _CartPageState extends State<CartPage> {
|
|||||||
resizeToAvoidBottomPadding: false,
|
resizeToAvoidBottomPadding: false,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(trans(context, "Shopping Cart"),
|
title: Text(trans(context, "Shopping Cart"),
|
||||||
style: Theme.of(context).appBarTheme.textTheme.title),
|
style: Theme.of(context).appBarTheme.textTheme.headline6),
|
||||||
textTheme: Theme.of(context).textTheme,
|
textTheme: Theme.of(context).textTheme,
|
||||||
elevation: 1,
|
elevation: 1,
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
@ -161,7 +175,7 @@ class _CartPageState extends State<CartPage> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
child: Text(trans(context, "Clear Cart"),
|
child: Text(trans(context, "Clear Cart"),
|
||||||
style: Theme.of(context).primaryTextTheme.body2),
|
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||||
padding: EdgeInsets.only(right: 8),
|
padding: EdgeInsets.only(right: 8),
|
||||||
),
|
),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
@ -191,7 +205,8 @@ class _CartPageState extends State<CartPage> {
|
|||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
child: Text(trans(context, "Empty Basket"),
|
child: Text(trans(context, "Empty Basket"),
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.bodyText2),
|
||||||
padding: EdgeInsets.only(top: 10),
|
padding: EdgeInsets.only(top: 10),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@ -30,19 +30,18 @@ class CheckoutConfirmationPage extends StatefulWidget {
|
|||||||
class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||||
CheckoutConfirmationPageState();
|
CheckoutConfirmationPageState();
|
||||||
|
|
||||||
GlobalKey<CheckoutConfirmationPageState> _key =
|
|
||||||
GlobalKey<CheckoutConfirmationPageState>();
|
|
||||||
|
|
||||||
bool _showFullLoader;
|
bool _showFullLoader;
|
||||||
|
|
||||||
List<TaxRate> _taxRates;
|
List<TaxRate> _taxRates;
|
||||||
TaxRate _taxRate;
|
TaxRate _taxRate;
|
||||||
|
bool _isProcessingPayment;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_showFullLoader = true;
|
_showFullLoader = true;
|
||||||
|
_isProcessingPayment = false;
|
||||||
if (CheckoutSession.getInstance.paymentType == null) {
|
if (CheckoutSession.getInstance.paymentType == null) {
|
||||||
CheckoutSession.getInstance.paymentType = arrPaymentMethods.first;
|
CheckoutSession.getInstance.paymentType = arrPaymentMethods.first;
|
||||||
}
|
}
|
||||||
@ -50,8 +49,6 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
_getTaxes();
|
_getTaxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchUserId() {}
|
|
||||||
|
|
||||||
void reloadState({bool showLoader}) {
|
void reloadState({bool showLoader}) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_showFullLoader = showLoader ?? false;
|
_showFullLoader = showLoader ?? false;
|
||||||
@ -135,7 +132,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Center(
|
Center(
|
||||||
child: Text(trans(context, "Checkout"),
|
child: Text(trans(context, "Checkout"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -239,8 +236,10 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
wsPrimaryButton(context,
|
wsPrimaryButton(context,
|
||||||
title: trans(context, "CHECKOUT"),
|
title: _isProcessingPayment
|
||||||
action: _handleCheckout),
|
? "PROCESSING..."
|
||||||
|
: trans(context, "CHECKOUT"),
|
||||||
|
action: _isProcessingPayment ? null : _handleCheckout),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Center(
|
: Center(
|
||||||
@ -252,7 +251,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
padding: const EdgeInsets.only(top: 15),
|
padding: const EdgeInsets.only(top: 15),
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "One moment") + "...",
|
trans(context, "One moment") + "...",
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
@ -301,7 +300,21 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_isProcessingPayment == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_isProcessingPayment = true;
|
||||||
|
});
|
||||||
|
|
||||||
CheckoutSession.getInstance.paymentType
|
CheckoutSession.getInstance.paymentType
|
||||||
.pay(context, state: this, taxRate: _taxRate);
|
.pay(context, state: this, taxRate: _taxRate);
|
||||||
|
|
||||||
|
Future.delayed(Duration(milliseconds: 5000), () {
|
||||||
|
setState(() {
|
||||||
|
_isProcessingPayment = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,35 +85,33 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
|||||||
_showSelectCountryModal() {
|
_showSelectCountryModal() {
|
||||||
wsModalBottom(context,
|
wsModalBottom(context,
|
||||||
title: trans(context, "Select a country"),
|
title: trans(context, "Select a country"),
|
||||||
bodyWidget: Expanded(
|
bodyWidget: ListView.separated(
|
||||||
child: ListView.separated(
|
itemCount: appCountryOptions.length,
|
||||||
itemCount: appCountryOptions.length,
|
itemBuilder: (BuildContext context, int index) {
|
||||||
itemBuilder: (BuildContext context, int index) {
|
Map<String, String> strName = appCountryOptions[index];
|
||||||
Map<String, String> strName = appCountryOptions[index];
|
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(strName["name"],
|
child: Text(strName["name"],
|
||||||
style: Theme.of(context).primaryTextTheme.body2),
|
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||||
),
|
),
|
||||||
splashColor: Colors.grey,
|
splashColor: Colors.grey,
|
||||||
highlightColor: Colors.black12,
|
highlightColor: Colors.black12,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_strBillingCountry = strName["name"];
|
_strBillingCountry = strName["name"];
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
separatorBuilder: (cxt, i) {
|
separatorBuilder: (cxt, i) {
|
||||||
return Divider(
|
return Divider(
|
||||||
height: 0,
|
height: 0,
|
||||||
color: Colors.black12,
|
color: Colors.black12,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +123,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: Text(
|
title: Text(
|
||||||
trans(context, "Billing & Shipping Details"),
|
trans(context, "Billing & Shipping Details"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
@ -241,7 +239,8 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans(context, "Remember my details"),
|
Text(trans(context, "Remember my details"),
|
||||||
style: Theme.of(context).primaryTextTheme.body2),
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.bodyText2),
|
||||||
Checkbox(
|
Checkbox(
|
||||||
value: valRememberDetails,
|
value: valRememberDetails,
|
||||||
onChanged: (bool value) {
|
onChanged: (bool value) {
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: Text(trans(context, "Payment Method"),
|
title: Text(trans(context, "Payment Method"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.headline6),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
@ -74,35 +74,41 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.separated(
|
||||||
itemCount: getPaymentTypes().length,
|
itemCount: getPaymentTypes().length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
contentPadding: EdgeInsets.only(
|
contentPadding: EdgeInsets.only(
|
||||||
top: 10, bottom: 10, left: 8, right: 8),
|
top: 10, bottom: 10, left: 8, right: 8),
|
||||||
leading: Image(
|
leading: Image(
|
||||||
image: AssetImage("assets/images/" +
|
image: AssetImage("assets/images/" +
|
||||||
getPaymentTypes()[index].assetImage),
|
getPaymentTypes()[index].assetImage),
|
||||||
width: 60,
|
width: 60,
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.contain,
|
||||||
alignment: Alignment.center),
|
alignment: Alignment.center),
|
||||||
title: Text(getPaymentTypes()[index].desc,
|
title: Text(getPaymentTypes()[index].desc,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.subhead),
|
.subtitle1),
|
||||||
selected: true,
|
selected: true,
|
||||||
trailing: (CheckoutSession
|
trailing:
|
||||||
.getInstance.paymentType ==
|
(CheckoutSession.getInstance.paymentType ==
|
||||||
getPaymentTypes()[index]
|
getPaymentTypes()[index]
|
||||||
? Icon(Icons.check)
|
? Icon(Icons.check)
|
||||||
: null),
|
: null),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
CheckoutSession.getInstance.paymentType =
|
CheckoutSession.getInstance.paymentType =
|
||||||
getPaymentTypes()[index];
|
getPaymentTypes()[index];
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
separatorBuilder: (cxt, i) {
|
||||||
|
return Divider(
|
||||||
|
color: Colors.black12,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
wsLinkButton(context, title: trans(context, "CANCEL"),
|
wsLinkButton(context, title: trans(context, "CANCEL"),
|
||||||
action: () {
|
action: () {
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import 'package:label_storemax/models/customer_address.dart';
|
|||||||
import 'package:label_storemax/models/shipping_type.dart';
|
import 'package:label_storemax/models/shipping_type.dart';
|
||||||
import 'package:label_storemax/widgets/app_loader.dart';
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
import 'package:label_storemax/widgets/buttons.dart';
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:math_expressions/math_expressions.dart';
|
|
||||||
import 'package:woosignal/models/response/shipping_method.dart';
|
import 'package:woosignal/models/response/shipping_method.dart';
|
||||||
import 'package:label_storemax/app_country_options.dart';
|
import 'package:label_storemax/app_country_options.dart';
|
||||||
|
|
||||||
@ -49,9 +48,8 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getShippingMethods() async {
|
_getShippingMethods() async {
|
||||||
List<WSShipping> wsShipping = await appWooSignal((api) {
|
List<WSShipping> wsShipping =
|
||||||
return api.getShippingMethods();
|
await appWooSignal((api) => api.getShippingMethods());
|
||||||
});
|
|
||||||
CustomerAddress customerAddress =
|
CustomerAddress customerAddress =
|
||||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||||
String postalCode = customerAddress.postalCode;
|
String postalCode = customerAddress.postalCode;
|
||||||
@ -70,9 +68,12 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_shipping != null) {
|
if (_shipping != null && _shipping.methods != null) {
|
||||||
if (_shipping.methods.flatRate != null) {
|
if (_shipping.methods.flatRate != null) {
|
||||||
_shipping.methods.flatRate.forEach((flatRate) {
|
_shipping.methods.flatRate
|
||||||
|
.where((t) => t != null)
|
||||||
|
.toList()
|
||||||
|
.forEach((flatRate) {
|
||||||
Map<String, dynamic> tmpShippingOption = {};
|
Map<String, dynamic> tmpShippingOption = {};
|
||||||
tmpShippingOption = {
|
tmpShippingOption = {
|
||||||
"id": flatRate.id,
|
"id": flatRate.id,
|
||||||
@ -86,7 +87,10 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_shipping.methods.localPickup != null) {
|
if (_shipping.methods.localPickup != null) {
|
||||||
_shipping.methods.localPickup.forEach((localPickup) {
|
_shipping.methods.localPickup
|
||||||
|
.where((t) => t != null)
|
||||||
|
.toList()
|
||||||
|
.forEach((localPickup) {
|
||||||
Map<String, dynamic> tmpShippingOption = {};
|
Map<String, dynamic> tmpShippingOption = {};
|
||||||
tmpShippingOption = {
|
tmpShippingOption = {
|
||||||
"id": localPickup.id,
|
"id": localPickup.id,
|
||||||
@ -100,7 +104,10 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_shipping.methods.freeShipping != null) {
|
if (_shipping.methods.freeShipping != null) {
|
||||||
_shipping.methods.freeShipping.forEach((freeShipping) {
|
_shipping.methods.freeShipping
|
||||||
|
.where((t) => t != null)
|
||||||
|
.toList()
|
||||||
|
.forEach((freeShipping) {
|
||||||
if (isNumeric(freeShipping.cost)) {
|
if (isNumeric(freeShipping.cost)) {
|
||||||
Map<String, dynamic> tmpShippingOption = {};
|
Map<String, dynamic> tmpShippingOption = {};
|
||||||
tmpShippingOption = {
|
tmpShippingOption = {
|
||||||
@ -183,7 +190,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
context,
|
context,
|
||||||
"Shipping Methods",
|
"Shipping Methods",
|
||||||
),
|
),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
),
|
),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
@ -234,7 +241,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
['title'],
|
['title'],
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.subhead),
|
.subtitle1),
|
||||||
selected: true,
|
selected: true,
|
||||||
subtitle: FutureBuilder<String>(
|
subtitle: FutureBuilder<String>(
|
||||||
future: _getShippingPrice(index),
|
future: _getShippingPrice(index),
|
||||||
@ -299,7 +306,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
"Shipping is not supported for your country, sorry"),
|
"Shipping is not supported for your country, sorry"),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.title,
|
.headline6,
|
||||||
textAlign: TextAlign.center))),
|
textAlign: TextAlign.center))),
|
||||||
wsLinkButton(context, title: trans(context, "CANCEL"),
|
wsLinkButton(context, title: trans(context, "CANCEL"),
|
||||||
action: () {
|
action: () {
|
||||||
|
|||||||
@ -60,25 +60,25 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
|||||||
Padding(
|
Padding(
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Order Status"),
|
trans(context, "Order Status"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.only(bottom: 15),
|
padding: EdgeInsets.only(bottom: 15),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
trans(context, "Thank You!"),
|
trans(context, "Thank You!"),
|
||||||
style: Theme.of(context).primaryTextTheme.title,
|
style: Theme.of(context).primaryTextTheme.headline6,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
trans(context, "Your transaction details"),
|
trans(context, "Your transaction details"),
|
||||||
style: Theme.of(context).primaryTextTheme.body1,
|
style: Theme.of(context).primaryTextTheme.bodyText2,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
trans(context, "Order Ref") +
|
trans(context, "Order Ref") +
|
||||||
". #" +
|
". #" +
|
||||||
_order.id.toString(),
|
_order.id.toString(),
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -96,7 +96,9 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
|||||||
child: Image(
|
child: Image(
|
||||||
image: new AssetImage("assets/images/camion.gif"),
|
image: new AssetImage("assets/images/camion.gif"),
|
||||||
height: 170),
|
height: 170),
|
||||||
color: Colors.white,
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
width: double.infinity),
|
width: double.infinity),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -104,7 +106,7 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
|||||||
child: Padding(
|
child: Padding(
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Items"),
|
trans(context, "Items"),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
@ -130,24 +132,28 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
|||||||
Text(lineItem.name,
|
Text(lineItem.name,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body2,
|
.bodyText1,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis),
|
overflow: TextOverflow.ellipsis),
|
||||||
Text("x" + lineItem.quantity.toString(),
|
Text("x" + lineItem.quantity.toString(),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body1),
|
.bodyText2),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatStringCurrency(
|
formatStringCurrency(
|
||||||
total: lineItem.total.toString()),
|
total: lineItem.total.toString()),
|
||||||
style: Theme.of(context).primaryTextTheme.body2)
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.bodyText1)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(color: Colors.white),
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
),
|
||||||
padding: EdgeInsets.all(16),
|
padding: EdgeInsets.all(16),
|
||||||
margin: EdgeInsets.all(8),
|
margin: EdgeInsets.all(8),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -46,7 +46,7 @@ class _ErrorPageState extends State<ErrorPage> {
|
|||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Sorry, something went wrong"),
|
trans(context, "Sorry, something went wrong"),
|
||||||
style: Theme.of(context).primaryTextTheme.body1,
|
style: Theme.of(context).primaryTextTheme.bodyText2,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import 'package:flutter/material.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/cart_icon.dart';
|
import 'package:label_storemax/widgets/cart_icon.dart';
|
||||||
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart' as WS;
|
import 'package:woosignal/models/response/product_category.dart' as WS;
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
@ -26,10 +27,11 @@ class HomePage extends StatefulWidget {
|
|||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
_HomePageState();
|
_HomePageState();
|
||||||
|
|
||||||
|
RefreshController _refreshController =
|
||||||
|
RefreshController(initialRefresh: false);
|
||||||
List<WS.Product> _products = [];
|
List<WS.Product> _products = [];
|
||||||
List<WS.ProductCategory> _categories = [];
|
List<WS.ProductCategory> _categories = [];
|
||||||
|
final GlobalKey _key = GlobalKey();
|
||||||
var _productsController = ScrollController();
|
|
||||||
|
|
||||||
int _page;
|
int _page;
|
||||||
bool _shouldStopRequests;
|
bool _shouldStopRequests;
|
||||||
@ -41,115 +43,68 @@ class _HomePageState extends State<HomePage> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
|
||||||
_page = 1;
|
_page = 1;
|
||||||
_home();
|
_home();
|
||||||
_addScrollListener();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_home() async {
|
_home() async {
|
||||||
await _fetchProducts();
|
|
||||||
await _fetchCategories();
|
|
||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
await _fetchMoreProducts();
|
||||||
|
await _fetchCategories();
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchProducts() async {
|
|
||||||
_products = await appWooSignal((api) {
|
|
||||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_fetchCategories() async {
|
_fetchCategories() async {
|
||||||
_categories = await appWooSignal((api) {
|
_categories = await appWooSignal((api) {
|
||||||
return api.getProductCategories();
|
return api.getProductCategories();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_addScrollListener() async {
|
|
||||||
_productsController.addListener(() {
|
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
|
||||||
double currentScroll = _productsController.position.pixels;
|
|
||||||
double delta = 50.0;
|
|
||||||
if (maxScroll - currentScroll <= delta) {
|
|
||||||
if (_shouldStopRequests) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (waitForNextRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_fetchMoreProducts();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_fetchMoreProducts() async {
|
_fetchMoreProducts() async {
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (waitForNextRequest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
waitForNextRequest = true;
|
waitForNextRequest = true;
|
||||||
List<WS.Product> products = await appWooSignal((api) {
|
List<WS.Product> products = await appWooSignal((api) => api.getProducts(
|
||||||
_page = _page + 1;
|
perPage: 50, page: _page, status: "publish", stockStatus: "instock"));
|
||||||
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
_page = _page + 1;
|
||||||
});
|
|
||||||
if (products.length == 0) {
|
if (products.length == 0) {
|
||||||
_shouldStopRequests = true;
|
_shouldStopRequests = true;
|
||||||
}
|
}
|
||||||
|
waitForNextRequest = false;
|
||||||
setState(() {
|
setState(() {
|
||||||
_products.addAll(products.toList());
|
_products.addAll(products.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _modalBottomSheetMenu() {
|
void _modalBottomSheetMenu() {
|
||||||
showModalBottomSheet(
|
_key.currentState.setState(() {});
|
||||||
context: context,
|
wsModalBottom(
|
||||||
backgroundColor: Colors.transparent,
|
context,
|
||||||
builder: (builder) {
|
title: trans(context, "Categories"),
|
||||||
return new Container(
|
bodyWidget: ListView.separated(
|
||||||
height: double.infinity,
|
itemCount: _categories.length,
|
||||||
width: double.infinity - 10,
|
separatorBuilder: (cxt, i) {
|
||||||
color: Colors.transparent,
|
return Divider();
|
||||||
child: new Container(
|
},
|
||||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
itemBuilder: (BuildContext context, int index) {
|
||||||
decoration: new BoxDecoration(
|
return ListTile(
|
||||||
color: Colors.white,
|
title: Text(parseHtmlString(_categories[index].name)),
|
||||||
borderRadius: new BorderRadius.only(
|
onTap: () {
|
||||||
topLeft: const Radius.circular(10.0),
|
Navigator.pop(context);
|
||||||
topRight: const Radius.circular(10.0),
|
Navigator.pushNamed(context, "/browse-category",
|
||||||
),
|
arguments: _categories[index])
|
||||||
),
|
.then((value) => setState(() {}));
|
||||||
child: Column(
|
},
|
||||||
children: <Widget>[
|
);
|
||||||
Text(trans(context, "Categories"),
|
},
|
||||||
style: Theme.of(context).primaryTextTheme.display1,
|
),
|
||||||
textAlign: TextAlign.left),
|
|
||||||
Expanded(
|
|
||||||
child: new ListView.builder(
|
|
||||||
itemCount: _categories.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return InkWell(
|
|
||||||
child: Container(
|
|
||||||
child: Text(_categories[index].name),
|
|
||||||
padding: EdgeInsets.all(15),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(
|
|
||||||
color: HexColor("#f2f2f2"), width: 2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pushNamed(context, "/browse-category",
|
|
||||||
arguments: _categories[index]);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,9 +116,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
leading: Container(
|
leading: Container(
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
icon: Icon(Icons.menu),
|
icon: Icon(Icons.menu),
|
||||||
onPressed: () {
|
onPressed: () => Navigator.pushNamed(context, "/home-menu"),
|
||||||
Navigator.pushNamed(context, "/home-menu");
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
margin: EdgeInsets.only(left: 0),
|
margin: EdgeInsets.only(left: 0),
|
||||||
),
|
),
|
||||||
@ -177,11 +130,10 @@ class _HomePageState extends State<HomePage> {
|
|||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
size: 35,
|
size: 35,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () => Navigator.pushNamed(context, "/home-search")
|
||||||
Navigator.pushNamed(context, "/home-search");
|
.then((value) => _key.currentState.setState(() {})),
|
||||||
},
|
|
||||||
),
|
),
|
||||||
wsCartIcon(context)
|
wsCartIcon(context, key: _key)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
@ -198,10 +150,10 @@ class _HomePageState extends State<HomePage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans(context, "Shop") + " / ",
|
Text(trans(context, "Shop") + " / ",
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
Text(
|
Text(
|
||||||
trans(context, "Newest"),
|
trans(context, "Newest"),
|
||||||
style: Theme.of(context).primaryTextTheme.body1,
|
style: Theme.of(context).primaryTextTheme.bodyText2,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -210,25 +162,21 @@ class _HomePageState extends State<HomePage> {
|
|||||||
height: 60,
|
height: 60,
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Browse categories"),
|
trans(context, "Browse categories"),
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: _modalBottomSheetMenu,
|
||||||
_modalBottomSheetMenu();
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
(_isLoading
|
(_isLoading
|
||||||
? Expanded(child: showAppLoader())
|
? Expanded(child: showAppLoader())
|
||||||
: Expanded(
|
: Expanded(
|
||||||
child: GridView.count(
|
child: refreshableScroll(context,
|
||||||
controller: _productsController,
|
refreshController: _refreshController,
|
||||||
crossAxisCount: 2,
|
onRefresh: _onRefresh,
|
||||||
children: List.generate(_products.length, (index) {
|
onLoading: _onLoading,
|
||||||
return wsCardProductItem(context,
|
products: _products,
|
||||||
index: index, product: _products[index]);
|
onTap: _showProduct),
|
||||||
}),
|
|
||||||
),
|
|
||||||
flex: 1,
|
flex: 1,
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
@ -236,4 +184,32 @@ class _HomePageState extends State<HomePage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onRefresh() async {
|
||||||
|
await _fetchMoreProducts();
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.resetNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.refreshCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onLoading() async {
|
||||||
|
await _fetchMoreProducts();
|
||||||
|
|
||||||
|
if (mounted) {
|
||||||
|
setState(() {});
|
||||||
|
if (_shouldStopRequests) {
|
||||||
|
_refreshController.loadNoData();
|
||||||
|
} else {
|
||||||
|
_refreshController.loadComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_showProduct(WS.Product product) {
|
||||||
|
Navigator.pushNamed(context, "/product-detail", arguments: product)
|
||||||
|
.then((value) => _key.currentState.setState(() {}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
import 'package:label_storemax/widgets/menu_item.dart';
|
import 'package:label_storemax/widgets/menu_item.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
@ -37,7 +38,7 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
|||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
elevation: 0.0,
|
elevation: 0.0,
|
||||||
title: Text(trans(context, "Menu"),
|
title: Text(trans(context, "Menu"),
|
||||||
style: Theme.of(context).primaryTextTheme.title),
|
style: Theme.of(context).primaryTextTheme.headline6),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(Icons.close),
|
icon: Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
@ -89,7 +90,12 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
|||||||
Navigator.pushNamed(context, "/about");
|
Navigator.pushNamed(context, "/about");
|
||||||
}
|
}
|
||||||
|
|
||||||
void _actionProfile() {
|
void _actionProfile() async {
|
||||||
|
if (use_wp_login == true && !(await authCheck())) {
|
||||||
|
UserAuth.instance.redirect = "/account-detail";
|
||||||
|
Navigator.pushNamed(context, "/account-landing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
Navigator.pushNamed(context, "/account-detail");
|
Navigator.pushNamed(context, "/account-detail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,7 +61,7 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
|||||||
),
|
),
|
||||||
TextField(
|
TextField(
|
||||||
controller: _txtSearchController,
|
controller: _txtSearchController,
|
||||||
style: Theme.of(context).primaryTextTheme.display2,
|
style: Theme.of(context).primaryTextTheme.headline3,
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
|
|||||||
@ -50,9 +50,23 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fetchProductVariations() async {
|
_fetchProductVariations() async {
|
||||||
_productVariations = await appWooSignal((api) {
|
List<WS.ProductVariation> tmpVariations = [];
|
||||||
return api.getProductVariations(_product.id);
|
int currentPage = 1;
|
||||||
});
|
|
||||||
|
bool isFetching = true;
|
||||||
|
while (isFetching) {
|
||||||
|
List<WS.ProductVariation> tmp = await appWooSignal((api) {
|
||||||
|
return api.getProductVariations(_product.id,
|
||||||
|
perPage: 100, page: currentPage);
|
||||||
|
});
|
||||||
|
if (tmp != null && tmp.length > 0) {
|
||||||
|
tmpVariations.addAll(tmp);
|
||||||
|
currentPage += 1;
|
||||||
|
} else {
|
||||||
|
isFetching = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_productVariations = tmpVariations;
|
||||||
setState(() {
|
setState(() {
|
||||||
_isLoading = false;
|
_isLoading = false;
|
||||||
});
|
});
|
||||||
@ -89,33 +103,30 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
title: trans(context, "Select a") +
|
title: trans(context, "Select a") +
|
||||||
" " +
|
" " +
|
||||||
_product.attributes[attributeIndex].name,
|
_product.attributes[attributeIndex].name,
|
||||||
bodyWidget: Expanded(
|
bodyWidget: ListView.separated(
|
||||||
child: ListView.separated(
|
itemCount: _product.attributes[attributeIndex].options.length,
|
||||||
itemCount: _product.attributes[attributeIndex].options.length,
|
separatorBuilder: (BuildContext context, int index) => Divider(),
|
||||||
separatorBuilder: (BuildContext context, int index) => Divider(),
|
itemBuilder: (BuildContext context, int index) {
|
||||||
itemBuilder: (BuildContext context, int index) {
|
return ListTile(
|
||||||
return ListTile(
|
title: Text(_product.attributes[attributeIndex].options[index],
|
||||||
title: Text(_product.attributes[attributeIndex].options[index],
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
_tmpAttributeObj.containsKey(attributeIndex) &&
|
||||||
_tmpAttributeObj.containsKey(attributeIndex) &&
|
_tmpAttributeObj[attributeIndex]["value"] ==
|
||||||
_tmpAttributeObj[attributeIndex]["value"] ==
|
_product.attributes[attributeIndex].options[index])
|
||||||
_product.attributes[attributeIndex].options[index])
|
? Icon(Icons.check, color: Colors.blueAccent)
|
||||||
? Icon(Icons.check, color: Colors.blueAccent)
|
: null,
|
||||||
: null,
|
onTap: () {
|
||||||
onTap: () {
|
_tmpAttributeObj[attributeIndex] = {
|
||||||
_tmpAttributeObj[attributeIndex] = {
|
"name": _product.attributes[attributeIndex].name,
|
||||||
"name": _product.attributes[attributeIndex].name,
|
"value": _product.attributes[attributeIndex].options[index]
|
||||||
"value": _product.attributes[attributeIndex].options[index]
|
};
|
||||||
};
|
Navigator.pop(context, () {});
|
||||||
Navigator.pop(context, () {});
|
Navigator.pop(context);
|
||||||
Navigator.pop(context);
|
_modalBottomSheetAttributes();
|
||||||
_modalBottomSheetAttributes();
|
},
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
|
||||||
),
|
|
||||||
flex: 1,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -134,8 +145,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
wsModalBottom(
|
wsModalBottom(
|
||||||
context,
|
context,
|
||||||
title: trans(context, "Options"),
|
title: trans(context, "Options"),
|
||||||
bodyWidget: Expanded(
|
bodyWidget: ListView.separated(
|
||||||
child: ListView.separated(
|
|
||||||
itemCount: _product.attributes.length,
|
itemCount: _product.attributes.length,
|
||||||
separatorBuilder: (BuildContext context, int index) => Divider(
|
separatorBuilder: (BuildContext context, int index) => Divider(
|
||||||
color: Colors.black12,
|
color: Colors.black12,
|
||||||
@ -144,11 +154,11 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(_product.attributes[index].name,
|
title: Text(_product.attributes[index].name,
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
||||||
_tmpAttributeObj.containsKey(index))
|
_tmpAttributeObj.containsKey(index))
|
||||||
? Text(_tmpAttributeObj[index]["value"],
|
? Text(_tmpAttributeObj[index]["value"],
|
||||||
style: Theme.of(context).primaryTextTheme.body2)
|
style: Theme.of(context).primaryTextTheme.bodyText1)
|
||||||
: Text(trans(context, "Select a") +
|
: Text(trans(context, "Select a") +
|
||||||
" " +
|
" " +
|
||||||
_product.attributes[index].name),
|
_product.attributes[index].name),
|
||||||
@ -161,7 +171,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)),
|
),
|
||||||
extraWidget: Container(
|
extraWidget: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
||||||
@ -179,14 +189,14 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
findProductVariation() == null)
|
findProductVariation() == null)
|
||||||
? trans(context, "This variation is unavailable")
|
? trans(context, "This variation is unavailable")
|
||||||
: trans(context, "Choose your options"))),
|
: trans(context, "Choose your options"))),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
style: Theme.of(context).primaryTextTheme.subtitle1),
|
||||||
Text(
|
Text(
|
||||||
(findProductVariation() != null
|
(findProductVariation() != null
|
||||||
? findProductVariation().stockStatus != "instock"
|
? findProductVariation().stockStatus != "instock"
|
||||||
? trans(context, "Out of stock")
|
? trans(context, "Out of stock")
|
||||||
: ""
|
: ""
|
||||||
: ""),
|
: ""),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
),
|
),
|
||||||
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
||||||
action: () {
|
action: () {
|
||||||
@ -255,11 +265,10 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
wsModalBottom(
|
wsModalBottom(
|
||||||
context,
|
context,
|
||||||
title: trans(context, "Description"),
|
title: trans(context, "Description"),
|
||||||
bodyWidget: Expanded(
|
bodyWidget: SingleChildScrollView(
|
||||||
child: SingleChildScrollView(
|
child: Text(
|
||||||
child: Text(parseHtmlString(_product.description)),
|
parseHtmlString(_product.description),
|
||||||
),
|
),
|
||||||
flex: 1,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -312,7 +321,9 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
Container(
|
Container(
|
||||||
height: 100,
|
height: 100,
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
vertical: 10, horizontal: 16),
|
vertical: 10,
|
||||||
|
horizontal: 16,
|
||||||
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
@ -320,8 +331,11 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
_product.name,
|
_product.name,
|
||||||
style:
|
style: Theme.of(context)
|
||||||
Theme.of(context).primaryTextTheme.body2,
|
.primaryTextTheme
|
||||||
|
.bodyText1
|
||||||
|
.copyWith(
|
||||||
|
color: Colors.black87, fontSize: 20),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
@ -338,13 +352,24 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
total: _product.price),
|
total: _product.price),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.display1
|
.headline4
|
||||||
.copyWith(
|
.copyWith(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
),
|
),
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
),
|
),
|
||||||
],
|
(_product.onSale == true
|
||||||
|
? Text(
|
||||||
|
formatStringCurrency(
|
||||||
|
total: _product.regularPrice),
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.grey,
|
||||||
|
decoration:
|
||||||
|
TextDecoration.lineThrough,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null)
|
||||||
|
].where((t) => t != null).toList(),
|
||||||
),
|
),
|
||||||
flex: 2,
|
flex: 2,
|
||||||
)
|
)
|
||||||
@ -352,7 +377,10 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
color: Colors.white,
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: wsBoxShadow(),
|
||||||
|
borderRadius: BorderRadius.circular(4)),
|
||||||
padding:
|
padding:
|
||||||
EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||||
height: 180,
|
height: 180,
|
||||||
@ -378,15 +406,13 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
trans(context, "Full description"),
|
trans(context, "Full description"),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body1
|
.bodyText2
|
||||||
.copyWith(fontSize: 14),
|
.copyWith(fontSize: 14),
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.right,
|
||||||
),
|
),
|
||||||
height: 50,
|
height: 50,
|
||||||
minWidth: 60,
|
minWidth: 60,
|
||||||
onPressed: () {
|
onPressed: _modalBottomSheetMenu,
|
||||||
_modalBottomSheetMenu();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -432,7 +458,8 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
"Quantity",
|
"Quantity",
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@ -451,8 +478,9 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
_quantityIndicator.toString(),
|
_quantityIndicator.toString(),
|
||||||
style:
|
style: Theme.of(context)
|
||||||
Theme.of(context).primaryTextTheme.body2,
|
.primaryTextTheme
|
||||||
|
.bodyText1,
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
@ -479,11 +507,12 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
child: Align(
|
child: Align(
|
||||||
child: Text(
|
child: Text(
|
||||||
formatStringCurrency(
|
formatStringCurrency(
|
||||||
total: (double.parse(_product.price) *
|
total: (parseWcPrice(_product.price) *
|
||||||
_quantityIndicator)
|
_quantityIndicator)
|
||||||
.toString()),
|
.toString()),
|
||||||
style:
|
style: Theme.of(context)
|
||||||
Theme.of(context).primaryTextTheme.display1,
|
.primaryTextTheme
|
||||||
|
.headline4,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
@ -492,9 +521,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
child: wsPrimaryButton(
|
child: wsPrimaryButton(
|
||||||
context,
|
context,
|
||||||
title: trans(context, "Add to cart"),
|
title: trans(context, "Add to cart"),
|
||||||
action: () {
|
action: () => _addItemToCart(),
|
||||||
_addItemToCart();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -50,13 +50,15 @@ class _ProductImageViewerPageState extends State<ProductImageViewerPage> {
|
|||||||
index: _initialIndex,
|
index: _initialIndex,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return CachedNetworkImage(
|
return CachedNetworkImage(
|
||||||
imageUrl: _arrImageSrc[index],
|
imageUrl: _arrImageSrc[index],
|
||||||
placeholder: (context, url) =>
|
placeholder: (context, url) =>
|
||||||
new CircularProgressIndicator(
|
new CircularProgressIndicator(
|
||||||
strokeWidth: 2, backgroundColor: Colors.black12),
|
strokeWidth: 2,
|
||||||
errorWidget: (context, url, error) =>
|
backgroundColor: Colors.black12,
|
||||||
new Icon(Icons.error),
|
),
|
||||||
fit: BoxFit.contain);
|
errorWidget: (context, url, error) => new Icon(Icons.error),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
itemCount: _arrImageSrc.length,
|
itemCount: _arrImageSrc.length,
|
||||||
viewportFraction: 0.9,
|
viewportFraction: 0.9,
|
||||||
|
|||||||
51
LabelStoreMax/lib/providers/cash_on_delivery.dart
Normal file
51
LabelStoreMax/lib/providers/cash_on_delivery.dart
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// LabelCore
|
||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// 2020, WooSignal Ltd. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:label_storemax/helpers/data/order_wc.dart';
|
||||||
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/pages/checkout_confirmation.dart';
|
||||||
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
|
import 'package:woosignal/models/response/order.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
|
cashOnDeliveryPay(context,
|
||||||
|
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||||
|
try {
|
||||||
|
OrderWC orderWC = await buildOrderWC(taxRate: taxRate, markPaid: false);
|
||||||
|
|
||||||
|
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||||
|
|
||||||
|
if (order != null) {
|
||||||
|
Cart.getInstance.clear();
|
||||||
|
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||||
|
} else {
|
||||||
|
showEdgeAlertWith(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
|
desc: trans(context,
|
||||||
|
trans(context, "Something went wrong, please contact our store")),
|
||||||
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
showEdgeAlertWith(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
|
desc: trans(context,
|
||||||
|
trans(context, "Something went wrong, please contact our store")),
|
||||||
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
LabelStoreMax/lib/providers/example_pay.dart
Normal file
62
LabelStoreMax/lib/providers/example_pay.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// LabelCore
|
||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// 2020, WooSignal Ltd. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
//
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:label_storemax/helpers/data/order_wc.dart';
|
||||||
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/pages/checkout_confirmation.dart';
|
||||||
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
|
import 'package:woosignal/models/response/order.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
|
// CALL THE BELOW METHOD TO SHOW AND HIDE LOADER
|
||||||
|
// state.reloadState(showLoader: false);
|
||||||
|
|
||||||
|
// CHECKOUT HELPER
|
||||||
|
// IT WILL RETURN THE ORDER TOTAL, BILLING DETAILS AND CART
|
||||||
|
// await checkout(taxRate, (total, billingDetails, cart) async {
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
|
||||||
|
// REMEMBER TO ADD THIS METHOD E.G. "examplePay" TO THE APP_PAYMENT_METHODS
|
||||||
|
// AS THE PAY METHOD
|
||||||
|
|
||||||
|
examplePay(context,
|
||||||
|
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||||
|
// HANDLE YOUR PAYMENT INTEGRATION HERE
|
||||||
|
// ...
|
||||||
|
// ...
|
||||||
|
// ...
|
||||||
|
// THEN ON SUCCESS OF A PAYMENT YOU CAN DO SOMETHING SIMILAR BELOW
|
||||||
|
|
||||||
|
// CREATES ORDER MODEL
|
||||||
|
OrderWC orderWC = await buildOrderWC(taxRate: taxRate, markPaid: true);
|
||||||
|
|
||||||
|
// CREATES ORDER IN WOOCOMMERCE
|
||||||
|
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||||
|
|
||||||
|
// CHECK IF ORDER IS NULL
|
||||||
|
if (order != null) {
|
||||||
|
Cart.getInstance.clear();
|
||||||
|
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||||
|
} else {
|
||||||
|
showEdgeAlertWith(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
|
desc: trans(context,
|
||||||
|
trans(context, "Something went wrong, please contact our store")),
|
||||||
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,87 +25,94 @@ import 'package:woosignal_stripe/woosignal_stripe.dart';
|
|||||||
|
|
||||||
stripePay(context,
|
stripePay(context,
|
||||||
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||||
// CONFIGURE STRIPE
|
try {
|
||||||
FlutterStripePayment.setStripeSettings(
|
// CONFIGURE STRIPE
|
||||||
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
FlutterStripePayment.setStripeSettings(
|
||||||
|
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
||||||
|
|
||||||
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
||||||
|
|
||||||
// CHECK STATUS FROM STRIPE
|
// CHECK STATUS FROM STRIPE
|
||||||
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
||||||
state.reloadState(showLoader: true);
|
state.reloadState(showLoader: true);
|
||||||
|
|
||||||
// CHECKOUT HELPER
|
// CHECKOUT HELPER
|
||||||
await checkout(taxRate, (total, billingDetails, cart) async {
|
await checkout(taxRate, (total, billingDetails, cart) async {
|
||||||
Map<String, dynamic> address = {
|
Map<String, dynamic> address = {
|
||||||
"name": billingDetails.billingAddress.nameFull(),
|
"name": billingDetails.billingAddress.nameFull(),
|
||||||
"line1": billingDetails.shippingAddress.addressLine,
|
"line1": billingDetails.shippingAddress.addressLine,
|
||||||
"city": billingDetails.shippingAddress.city,
|
"city": billingDetails.shippingAddress.city,
|
||||||
"postal_code": billingDetails.shippingAddress.postalCode,
|
"postal_code": billingDetails.shippingAddress.postalCode,
|
||||||
"country": billingDetails.shippingAddress.country
|
"country": billingDetails.shippingAddress.country
|
||||||
};
|
};
|
||||||
|
|
||||||
String cartShortDesc = await cart.cartShortDesc();
|
String cartShortDesc = await cart.cartShortDesc();
|
||||||
|
|
||||||
dynamic rsp = await appWooSignal((api) {
|
dynamic rsp = await appWooSignal((api) => api.stripePaymentIntent(
|
||||||
return api.stripePaymentIntent(
|
amount: total,
|
||||||
amount: total,
|
email: billingDetails.billingAddress.emailAddress,
|
||||||
email: billingDetails.billingAddress.emailAddress,
|
desc: cartShortDesc,
|
||||||
desc: cartShortDesc,
|
shipping: address,
|
||||||
shipping: address,
|
));
|
||||||
|
|
||||||
|
if (rsp == null) {
|
||||||
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Oops!"),
|
||||||
|
desc: trans(context, "Something went wrong, please try again."),
|
||||||
|
icon: Icons.payment,
|
||||||
|
style: EdgeAlertStyle.WARNING);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String clientSecret = rsp["client_secret"];
|
||||||
|
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
||||||
|
clientSecret,
|
||||||
|
paymentResponse.paymentMethodId,
|
||||||
|
(double.parse(total) * 100),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
|
|
||||||
if (rsp == null) {
|
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
||||||
showEdgeAlertWith(context,
|
OrderWC orderWC = await buildOrderWC(taxRate: taxRate);
|
||||||
title: trans(context, "Oops!"),
|
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||||
desc: trans(context, "Something went wrong, please try again."),
|
|
||||||
icon: Icons.payment,
|
|
||||||
style: EdgeAlertStyle.WARNING);
|
|
||||||
state.reloadState(showLoader: false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String clientSecret = rsp["client_secret"];
|
if (order != null) {
|
||||||
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
Cart.getInstance.clear();
|
||||||
clientSecret,
|
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||||
paymentResponse.paymentMethodId,
|
} else {
|
||||||
(double.parse(total) * 100),
|
showEdgeAlertWith(
|
||||||
);
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
desc: trans(
|
||||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate);
|
context,
|
||||||
Order order = await appWooSignal((api) {
|
trans(context,
|
||||||
return api.createOrder(orderWC);
|
"Something went wrong, please contact our store")),
|
||||||
});
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
if (order != null) {
|
}
|
||||||
Cart.getInstance.clear();
|
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
||||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
if (app_debug) {
|
||||||
} else {
|
print(intentResponse.errorMessage);
|
||||||
|
}
|
||||||
showEdgeAlertWith(
|
showEdgeAlertWith(
|
||||||
context,
|
context,
|
||||||
title: trans(context, "Error"),
|
title: trans(context, "Error"),
|
||||||
desc: trans(
|
desc: intentResponse.errorMessage,
|
||||||
context,
|
|
||||||
trans(
|
|
||||||
context, "Something went wrong, please contact our store")),
|
|
||||||
);
|
);
|
||||||
state.reloadState(showLoader: false);
|
state.reloadState(showLoader: false);
|
||||||
|
} else {
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
}
|
}
|
||||||
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
});
|
||||||
if (app_debug) {
|
} else {
|
||||||
print(intentResponse.errorMessage);
|
state.reloadState(showLoader: false);
|
||||||
}
|
}
|
||||||
showEdgeAlertWith(
|
} catch (ex) {
|
||||||
context,
|
showEdgeAlertWith(context,
|
||||||
title: trans(context, "Error"),
|
title: trans(context, "Oops!"),
|
||||||
desc: intentResponse.errorMessage,
|
desc: trans(context, "Something went wrong, please try again."),
|
||||||
);
|
icon: Icons.payment,
|
||||||
state.reloadState(showLoader: false);
|
style: EdgeAlertStyle.WARNING);
|
||||||
} else {
|
state.reloadState(showLoader: false);
|
||||||
state.reloadState(showLoader: false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,7 +38,7 @@ Widget wsSecondaryButton(BuildContext context,
|
|||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: Text(title,
|
child: Text(title,
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
textAlign: TextAlign.center),
|
textAlign: TextAlign.center),
|
||||||
onPressed: action,
|
onPressed: action,
|
||||||
color: HexColor("#f6f6f9"),
|
color: HexColor("#f6f6f9"),
|
||||||
@ -54,7 +54,7 @@ Widget wsLinkButton(BuildContext context,
|
|||||||
child: MaterialButton(
|
child: MaterialButton(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
child: Text(title,
|
child: Text(title,
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
textAlign: TextAlign.left),
|
textAlign: TextAlign.left),
|
||||||
onPressed: action,
|
onPressed: action,
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
|
|||||||
@ -12,44 +12,48 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:label_storemax/models/cart.dart';
|
import 'package:label_storemax/models/cart.dart';
|
||||||
import 'package:label_storemax/models/cart_line_item.dart';
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
|
||||||
Widget wsCartIcon(BuildContext context) {
|
Widget wsCartIcon(BuildContext context, {Key key}) {
|
||||||
return IconButton(
|
return StatefulBuilder(
|
||||||
icon: Stack(
|
key: key,
|
||||||
children: <Widget>[
|
builder: (BuildContext context, StateSetter setState) => IconButton(
|
||||||
Positioned.fill(
|
icon: Stack(
|
||||||
child: Align(
|
children: <Widget>[
|
||||||
child: Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
Positioned.fill(
|
||||||
alignment: Alignment.bottomCenter,
|
child: Align(
|
||||||
),
|
child:
|
||||||
bottom: 0),
|
Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
||||||
Positioned.fill(
|
alignment: Alignment.bottomCenter,
|
||||||
child: Align(
|
|
||||||
child: FutureBuilder<List<CartLineItem>>(
|
|
||||||
future: Cart.getInstance.getCart(),
|
|
||||||
builder: (BuildContext context,
|
|
||||||
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
|
||||||
switch (snapshot.connectionState) {
|
|
||||||
case ConnectionState.waiting:
|
|
||||||
return Text("");
|
|
||||||
default:
|
|
||||||
if (snapshot.hasError)
|
|
||||||
return Text("");
|
|
||||||
else
|
|
||||||
return new Text(
|
|
||||||
snapshot.data.length.toString(),
|
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.topCenter,
|
bottom: 0),
|
||||||
),
|
Positioned.fill(
|
||||||
top: 0)
|
child: Align(
|
||||||
],
|
child: FutureBuilder<List<CartLineItem>>(
|
||||||
|
future: Cart.getInstance.getCart(),
|
||||||
|
builder: (BuildContext context,
|
||||||
|
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
||||||
|
switch (snapshot.connectionState) {
|
||||||
|
case ConnectionState.waiting:
|
||||||
|
return Text("");
|
||||||
|
default:
|
||||||
|
if (snapshot.hasError)
|
||||||
|
return Text("");
|
||||||
|
else
|
||||||
|
return new Text(
|
||||||
|
snapshot.data.length.toString(),
|
||||||
|
style: Theme.of(context).primaryTextTheme.bodyText1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
),
|
||||||
|
top: 0)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, "/cart");
|
||||||
|
},
|
||||||
),
|
),
|
||||||
onPressed: () {
|
|
||||||
Navigator.pushNamed(context, "/cart");
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ Widget wsMenuItem(BuildContext context,
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
leading,
|
leading,
|
||||||
Text(" " + title,
|
Text(" " + title,
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
style: Theme.of(context).primaryTextTheme.bodyText2),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -28,7 +28,7 @@ Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(text1, style: Theme.of(context).textTheme.title),
|
child: Text(text1, style: Theme.of(context).textTheme.headline6),
|
||||||
),
|
),
|
||||||
flex: 3,
|
flex: 3,
|
||||||
),
|
),
|
||||||
@ -37,7 +37,7 @@ Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
|||||||
child: Text(text2,
|
child: Text(text2,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.body2
|
.bodyText1
|
||||||
.copyWith(fontSize: 16, color: Colors.black87)),
|
.copyWith(fontSize: 16, color: Colors.black87)),
|
||||||
),
|
),
|
||||||
flex: 3,
|
flex: 3,
|
||||||
@ -50,7 +50,7 @@ Widget wsNoResults(BuildContext context) {
|
|||||||
return Column(
|
return Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans(context, "No results"),
|
Text(trans(context, "No results"),
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
style: Theme.of(context).primaryTextTheme.bodyText2),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -70,7 +70,10 @@ Widget wsCheckoutRow(BuildContext context,
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
child: Text(heading,
|
child: Text(heading,
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.bodyText2
|
||||||
|
.copyWith(fontSize: 16)),
|
||||||
padding: EdgeInsets.only(bottom: 8),
|
padding: EdgeInsets.only(bottom: 8),
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
@ -87,8 +90,9 @@ Widget wsCheckoutRow(BuildContext context,
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(leadTitle,
|
child: Text(leadTitle,
|
||||||
style:
|
style: Theme.of(context)
|
||||||
Theme.of(context).primaryTextTheme.subhead,
|
.primaryTextTheme
|
||||||
|
.subtitle1,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
softWrap: false),
|
softWrap: false),
|
||||||
@ -131,15 +135,15 @@ Widget wsTextEditingRow(BuildContext context,
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
child:
|
child: Text(heading,
|
||||||
Text(heading, style: Theme.of(context).primaryTextTheme.body2),
|
style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||||
padding: EdgeInsets.only(bottom: 2),
|
padding: EdgeInsets.only(bottom: 2),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
keyboardType: keyboardType ?? TextInputType.text,
|
keyboardType: keyboardType ?? TextInputType.text,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
autofocus: shouldAutoFocus ?? false,
|
autofocus: shouldAutoFocus ?? false,
|
||||||
@ -160,13 +164,15 @@ Widget widgetCheckoutMeta(BuildContext context, {String title, String amount}) {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(title, style: Theme.of(context).primaryTextTheme.body1),
|
child:
|
||||||
|
Text(title, style: Theme.of(context).primaryTextTheme.bodyText2),
|
||||||
),
|
),
|
||||||
flex: 3,
|
flex: 3,
|
||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(amount, style: Theme.of(context).primaryTextTheme.body2),
|
child:
|
||||||
|
Text(amount, style: Theme.of(context).primaryTextTheme.bodyText1),
|
||||||
),
|
),
|
||||||
flex: 3,
|
flex: 3,
|
||||||
)
|
)
|
||||||
@ -188,51 +194,68 @@ List<BoxShadow> wsBoxShadow({double blurRadius}) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget wsCardProductItem(BuildContext context, {int index, Product product}) {
|
Widget wsCardProductItem(BuildContext context,
|
||||||
|
{int index, Product product, onTap}) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.all(10),
|
padding: EdgeInsets.all(10),
|
||||||
margin: EdgeInsets.all(5),
|
margin: EdgeInsets.all(5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(5),
|
borderRadius: BorderRadius.circular(5),
|
||||||
),
|
boxShadow: wsBoxShadow(blurRadius: 4),
|
||||||
child: Column(
|
),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
child: Column(
|
||||||
children: <Widget>[
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
Flexible(
|
children: <Widget>[
|
||||||
child: CachedNetworkImage(
|
Flexible(
|
||||||
imageUrl: (product.images.length > 0
|
child: CachedNetworkImage(
|
||||||
? product.images.first.src
|
imageUrl:
|
||||||
: ""),
|
(product.images.length > 0 ? product.images.first.src : ""),
|
||||||
placeholder: (context, url) =>
|
placeholder: (context, url) => new CircularProgressIndicator(),
|
||||||
new CircularProgressIndicator(),
|
errorWidget: (context, url, error) => new Icon(Icons.error),
|
||||||
errorWidget: (context, url, error) => new Icon(Icons.error),
|
fit: BoxFit.contain),
|
||||||
fit: BoxFit.fitWidth),
|
flex: 4,
|
||||||
flex: 4,
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
formatStringCurrency(total: product.price),
|
||||||
|
style: Theme.of(context).textTheme.bodyText1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
(product.onSale
|
||||||
|
? Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 8),
|
||||||
|
child: Text(
|
||||||
|
formatStringCurrency(total: product.regularPrice),
|
||||||
|
style: Theme.of(context).textTheme.bodyText1.copyWith(
|
||||||
|
decoration: TextDecoration.lineThrough,
|
||||||
|
color: Colors.grey),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null),
|
||||||
|
].where((t) => t != null).toList(),
|
||||||
),
|
),
|
||||||
Flexible(
|
flex: 1,
|
||||||
child: Text(
|
),
|
||||||
formatStringCurrency(total: product.price),
|
Expanded(
|
||||||
style: Theme.of(context).textTheme.body2,
|
child: Text(
|
||||||
textAlign: TextAlign.left,
|
product.name,
|
||||||
),
|
style: Theme.of(context).textTheme.bodyText2,
|
||||||
flex: 1,
|
overflow: TextOverflow.clip,
|
||||||
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
Expanded(
|
flex: 1,
|
||||||
child: Text(
|
)
|
||||||
product.name,
|
],
|
||||||
style: Theme.of(context).textTheme.body1,
|
),
|
||||||
overflow: TextOverflow.clip,
|
),
|
||||||
maxLines: 1,
|
onTap: () => onTap(product),
|
||||||
),
|
|
||||||
flex: 1,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pushNamed(context, "/product-detail", arguments: product);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,27 +268,41 @@ void wsModalBottom(BuildContext context,
|
|||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
width: double.infinity - 10,
|
width: double.infinity,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: new Container(
|
child: new Container(
|
||||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 4),
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: new BorderRadius.only(
|
borderRadius: new BorderRadius.only(
|
||||||
topLeft: const Radius.circular(10.0),
|
topLeft: const Radius.circular(10.0),
|
||||||
topRight: const Radius.circular(10.0)),
|
topRight: const Radius.circular(10.0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(title,
|
Padding(
|
||||||
style: Theme.of(context)
|
padding: EdgeInsets.symmetric(vertical: 16),
|
||||||
.primaryTextTheme
|
child: Text(title,
|
||||||
.display1
|
style: Theme.of(context)
|
||||||
.copyWith(fontSize: 20),
|
.primaryTextTheme
|
||||||
textAlign: TextAlign.left),
|
.headline4
|
||||||
bodyWidget,
|
.copyWith(fontSize: 20),
|
||||||
extraWidget ?? Container()
|
textAlign: TextAlign.left),
|
||||||
],
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Container(
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||||
|
width: double.infinity,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
boxShadow: wsBoxShadow(),
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8)),
|
||||||
|
child: bodyWidget),
|
||||||
|
),
|
||||||
|
extraWidget ?? null
|
||||||
|
].where((t) => t != null).toList(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -431,13 +468,14 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
cartLineItem.name,
|
cartLineItem.name,
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
),
|
),
|
||||||
(cartLineItem.variationOptions != null
|
(cartLineItem.variationOptions != null
|
||||||
? Text(cartLineItem.variationOptions,
|
? Text(cartLineItem.variationOptions,
|
||||||
style: Theme.of(context).primaryTextTheme.body2)
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.bodyText1)
|
||||||
: Container()),
|
: Container()),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
@ -449,11 +487,14 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
: trans(context, "In Stock")),
|
: trans(context, "In Stock")),
|
||||||
style: (cartLineItem.stockStatus == "outofstock"
|
style: (cartLineItem.stockStatus == "outofstock"
|
||||||
? Theme.of(context).textTheme.caption
|
? Theme.of(context).textTheme.caption
|
||||||
: Theme.of(context).primaryTextTheme.body1)),
|
: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.bodyText2)),
|
||||||
Text(
|
Text(
|
||||||
formatDoubleCurrency(
|
formatDoubleCurrency(
|
||||||
total: double.parse(cartLineItem.total)),
|
total: double.parse(cartLineItem.total)),
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.subtitle1,
|
||||||
textAlign: TextAlign.center)
|
textAlign: TextAlign.center)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -479,7 +520,7 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
highlightColor: Colors.transparent,
|
highlightColor: Colors.transparent,
|
||||||
),
|
),
|
||||||
Text(cartLineItem.quantity.toString(),
|
Text(cartLineItem.quantity.toString(),
|
||||||
style: Theme.of(context).primaryTextTheme.title),
|
style: Theme.of(context).primaryTextTheme.headline6),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.remove_circle_outline),
|
icon: Icon(Icons.remove_circle_outline),
|
||||||
onPressed: actionDecrementQuantity,
|
onPressed: actionDecrementQuantity,
|
||||||
|
|||||||
@ -7,35 +7,28 @@ packages:
|
|||||||
name: archive
|
name: archive
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.11"
|
version: "2.0.13"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.2"
|
version: "1.6.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.1"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.5"
|
version: "2.0.0"
|
||||||
braintree_payment:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: braintree_payment
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.4"
|
|
||||||
bubble_tab_indicator:
|
bubble_tab_indicator:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -56,7 +49,7 @@ packages:
|
|||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.2"
|
version: "1.1.3"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -70,7 +63,7 @@ packages:
|
|||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.14.11"
|
version: "1.14.12"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -84,7 +77,7 @@ packages:
|
|||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.4"
|
||||||
csslib:
|
csslib:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -237,7 +230,7 @@ packages:
|
|||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
version: "2.1.12"
|
||||||
intl:
|
intl:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -350,13 +343,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
pull_to_refresh:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pull_to_refresh
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.8"
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: quiver
|
name: quiver
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.5"
|
version: "2.1.3"
|
||||||
rxdart:
|
rxdart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -403,7 +403,7 @@ packages:
|
|||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.5"
|
version: "1.7.0"
|
||||||
sqflite:
|
sqflite:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -466,7 +466,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.11"
|
version: "0.2.15"
|
||||||
transformer_page_view:
|
transformer_page_view:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -529,7 +529,7 @@ packages:
|
|||||||
name: woosignal
|
name: woosignal
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.6"
|
version: "1.0.8"
|
||||||
woosignal_stripe:
|
woosignal_stripe:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -550,7 +550,7 @@ packages:
|
|||||||
name: xml
|
name: xml
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.5.0"
|
version: "3.6.1"
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
# Label StoreMax
|
# Label StoreMax
|
||||||
# Version 2.0.0
|
# Version 2.0.2
|
||||||
#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/
|
||||||
@ -23,7 +23,7 @@ environment:
|
|||||||
sdk: ">=2.1.0 <3.0.0"
|
sdk: ">=2.1.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
woosignal: ^1.0.6
|
woosignal: ^1.0.8
|
||||||
woosignal_stripe: ^0.0.4
|
woosignal_stripe: ^0.0.4
|
||||||
wp_json_api: ^0.1.2
|
wp_json_api: ^0.1.2
|
||||||
shared_preferences: ^0.5.6+3
|
shared_preferences: ^0.5.6+3
|
||||||
@ -34,6 +34,7 @@ dependencies:
|
|||||||
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
|
||||||
|
pull_to_refresh: ^1.5.8
|
||||||
dio: ^3.0.9
|
dio: ^3.0.9
|
||||||
intl: ^0.16.1
|
intl: ^0.16.1
|
||||||
flutter_swiper: ^1.1.6
|
flutter_swiper: ^1.1.6
|
||||||
@ -44,7 +45,6 @@ dependencies:
|
|||||||
flutter_spinkit: ^4.1.2+1
|
flutter_spinkit: ^4.1.2+1
|
||||||
flutter_launcher_icons: ^0.7.4
|
flutter_launcher_icons: ^0.7.4
|
||||||
html: ^0.14.0+3
|
html: ^0.14.0+3
|
||||||
braintree_payment: ^1.2.4
|
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ flutter:
|
|||||||
- assets/images/credit_cards.png
|
- assets/images/credit_cards.png
|
||||||
- assets/images/shipping_icon.png
|
- assets/images/shipping_icon.png
|
||||||
- assets/images/dark_powered_by_stripe.png
|
- assets/images/dark_powered_by_stripe.png
|
||||||
- assets/images/cart_empty.png
|
- assets/images/cash_on_delivery.jpeg
|
||||||
- lang/en.json
|
- lang/en.json
|
||||||
|
|
||||||
fonts:
|
fonts:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user