Login/register with WordPress, Updated product view, New account area, pubspec.yaml update, Bug fixes

This commit is contained in:
WooSignal 2020-04-30 22:00:19 +01:00
parent 1c41e57693
commit a47a90dde3
55 changed files with 2418 additions and 207 deletions

View File

@ -1 +1 @@
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_money_formatter","dependencies":[]},{"name":"flutter_web_browser","dependencies":[]},{"name":"package_info","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"woosignal_stripe","dependencies":[]}]}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"braintree_payment","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/braintree_payment-1.2.4/","dependencies":[]},{"name":"device_info","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-0.4.2+1/","dependencies":[]},{"name":"flutter_money_formatter","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_money_formatter-0.8.3/","dependencies":[]},{"name":"flutter_web_browser","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_web_browser-0.11.0/","dependencies":[]},{"name":"package_info","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/package_info-0.4.0+16/","dependencies":[]},{"name":"path_provider","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.3.0/","dependencies":[]},{"name":"shared_preferences","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.6+5/","dependencies":[]},{"name":"url_launcher","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.5/","dependencies":[]},{"name":"woosignal_stripe","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/woosignal_stripe-0.0.4/","dependencies":[]}],"android":[{"name":"braintree_payment","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/braintree_payment-1.2.4/","dependencies":[]},{"name":"device_info","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/device_info-0.4.2+1/","dependencies":[]},{"name":"flutter_money_formatter","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_money_formatter-0.8.3/","dependencies":[]},{"name":"flutter_web_browser","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_web_browser-0.11.0/","dependencies":[]},{"name":"package_info","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/package_info-0.4.0+16/","dependencies":[]},{"name":"path_provider","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.3.0/","dependencies":[]},{"name":"shared_preferences","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.6+3/","dependencies":[]},{"name":"sqflite","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.6+5/","dependencies":[]},{"name":"url_launcher","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.4.5/","dependencies":[]},{"name":"woosignal_stripe","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/woosignal_stripe-0.0.4/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+6/","dependencies":[]},{"name":"url_launcher_macos","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_macos-0.0.1+5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+4/","dependencies":[]},{"name":"url_launcher_web","path":"/Users/anthony/Documents/config/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"braintree_payment","dependencies":[]},{"name":"device_info","dependencies":[]},{"name":"flutter_money_formatter","dependencies":[]},{"name":"flutter_web_browser","dependencies":[]},{"name":"package_info","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"url_launcher","dependencies":["url_launcher_web","url_launcher_macos"]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"woosignal_stripe","dependencies":[]}],"date_created":"2020-04-30 21:50:05.674145","version":"1.15.17"}

View File

@ -1,3 +1,11 @@
## [2.0.1] - 2020-04-30
* Login/register with WordPress
* Updated product view
* New account area
* pubspec.yaml update
* Bug fixes
## [2.0.0] - 2020-04-10
* Flutter v1.12.13+hotfix.9 support

View File

@ -263,9 +263,40 @@
files = (
);
inputPaths = (
"${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",
"${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/Stripe/Stripe.framework",
"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
"${BUILT_PRODUCTS_DIR}/flutter_money_formatter/flutter_money_formatter.framework",
"${BUILT_PRODUCTS_DIR}/flutter_web_browser/flutter_web_browser.framework",
"${BUILT_PRODUCTS_DIR}/package_info/package_info.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework",
"${BUILT_PRODUCTS_DIR}/woosignal_stripe/woosignal_stripe.framework",
);
name = "[CP] Embed Pods Frameworks";
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}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Stripe.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_money_formatter.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}/path_provider.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/woosignal_stripe.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;

View File

@ -1,8 +1,10 @@
import UIKit
import Flutter
import Braintree
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
@ -10,4 +12,5 @@ import Flutter
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

View File

@ -1 +1 @@
#import "GeneratedPluginRegistrant.h"
#import "GeneratedPluginRegistrant.h"

View File

@ -92,5 +92,42 @@
"Product variation does not exist": "Product variation does not exist",
"This variation is unavailable": "This variation is unavailable",
"Sorry, something went wrong": "Sorry, something went wrong",
"Back": "Back"
"Back": "Back",
"Profile": "Profile",
"Forgot Password": "Forgot Password",
"Create an account": "Create an account",
"Login": "Login",
"Password": "Password",
"Oops!": "Oops!",
"Invalid login credentials": "Invalid login credentials",
"That email address is not valid": "That email address is not valid",
"Password must be a min 6 characters": "Password must be a min 6 characters",
"Please check your details": "Please check your details",
"Invalid": "Invalid",
"Actions": "Actions",
"View Terms and Conditions or Privacy policy": "View Terms and Conditions or Privacy policy",
"Terms and Conditions": "Terms and Conditions",
"Privacy Policy": "Privacy Policy",
"terms and conditions": "terms and conditions",
"and": "and",
"By tapping \"Register\" you agree to ": "By tapping \"Register\" you agree to ",
"privacy policy": "privacy policy",
"Sign up": "Sign up",
"Email": "Email",
"Update details": "Update details",
"Settings": "Settings",
"Account": "Account",
"Logout": "Logout",
"No orders found": "No orders found",
"items": "items",
"Update Details": "Update Details",
"Invalid details": "Invalid details",
"Please check your email and password": "Please check your email and password",
"Something went wrong, please try again.": "Something went wrong, please try again.",
"Done": "Done",
"Billing Details": "Billing Details",
"Shipping Details": "Shipping Details",
"State": "State",
"Country": "Country",
"UPDATE DETAILS": "UPDATE DETAILS"
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,9 +1,18 @@
// 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:label_storemax/helpers/tools.dart';
import 'package:label_storemax/models/payment_type.dart';
import 'package:label_storemax/providers/stripe_pay.dart';
// Payment methods available for uses in the app
// To use use a payment method, include the PaymentType "name" in the app_payment_methods variable in #labelconfig.dart
List<PaymentType> arrPaymentMethods = [
addPayment(

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -151,17 +151,18 @@ TextTheme textThemeAppBar() {
ColorScheme colorSchemeButton() {
return ColorScheme.light(
primary: const Color(0xff6200ee),
primaryVariant: const Color(0xff3700b3),
secondary: const Color(0xff03dac6),
secondaryVariant: const Color(0xff018786),
surface: Colors.white,
background: Colors.white,
error: const Color(0xffb00020),
onPrimary: Colors.white,
onSecondary: Colors.black,
onSurface: Colors.black,
onBackground: Colors.black,
onError: Colors.white,
brightness: Brightness.light);
primary: const Color(0xff6200ee),
primaryVariant: const Color(0xff3700b3),
secondary: const Color(0xff03dac6),
secondaryVariant: const Color(0xff018786),
surface: Colors.white,
background: Colors.white,
error: const Color(0xffb00020),
onPrimary: Colors.white,
onSecondary: Colors.black,
onSurface: Colors.black,
onBackground: Colors.black,
onError: Colors.white,
brightness: Brightness.light,
);
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -10,6 +10,7 @@
import 'dart:io';
import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart';
import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/models/billing_details.dart';
import 'package:label_storemax/models/cart.dart';
@ -32,6 +33,8 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
orderWC.setPaid = true;
orderWC.status = "pending";
orderWC.currency = app_currency_iso.toUpperCase();
orderWC.customerId =
(use_wp_login == true) ? int.parse(await readUserId()) : 0;
List<LineItems> lineItems = [];
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
@ -44,7 +47,8 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
tmpLineItem.variationId = cartItem.variationId;
}
tmpLineItem.total = cartItem.total;
tmpLineItem.total =
(cartItem.quantity > 1 ? cartItem.getCartTotal() : cartItem.subtotal);
tmpLineItem.subtotal = cartItem.subtotal;
lineItems.add(tmpLineItem);

View File

@ -1,40 +0,0 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. 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/cupertino.dart';
import 'package:flutter/foundation.dart';
class LifecycleEventHandler extends WidgetsBindingObserver {
final AsyncCallback resumeCallBack;
final AsyncCallback suspendingCallBack;
LifecycleEventHandler({
this.resumeCallBack,
this.suspendingCallBack,
});
@override
Future<Null> didChangeAppLifecycleState(AppLifecycleState state) async {
switch (state) {
case AppLifecycleState.resumed:
if (resumeCallBack != null) {
await resumeCallBack();
}
break;
case AppLifecycleState.inactive:
case AppLifecycleState.paused:
case AppLifecycleState.detached:
if (suspendingCallBack != null) {
await suspendingCallBack();
}
break;
}
}
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -0,0 +1,42 @@
// 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/cupertino.dart';
import 'package:label_storemax/helpers/shared_pref.dart';
import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/models/cart.dart';
const keyAuthCheck = "DEFAULT_SP_AUTHCHECK";
Future<bool> authCheck() async {
SharedPref sharedPref = SharedPref();
String val = await sharedPref.read(keyAuthCheck);
return val != null ? true : false;
}
authUser(String v) async {
SharedPref sharedPref = SharedPref();
await sharedPref.save(keyAuthCheck, v);
}
Future<String> readAuthToken() async {
SharedPref sharedPref = SharedPref();
dynamic val = await sharedPref.read(keyAuthCheck);
return val.toString();
}
authLogout(BuildContext context) async {
SharedPref sharedPref = SharedPref();
await sharedPref.save(keyAuthCheck, null);
destroyUserId(context);
Cart.getInstance.clear();
navigatorPush(context, routeName: "/account-landing", forgetAll: true);
}

View File

@ -0,0 +1,30 @@
// 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/cupertino.dart';
import 'package:label_storemax/helpers/shared_pref.dart';
const keyUserId = "DEFAULT_SP_USERID";
storeUserId(String v) async {
SharedPref sharedPref = SharedPref();
await sharedPref.save(keyUserId, v);
}
Future<String> readUserId() async {
SharedPref sharedPref = SharedPref();
String val = await sharedPref.read(keyUserId);
return val;
}
destroyUserId(BuildContext context) async {
SharedPref sharedPref = SharedPref();
await sharedPref.save(keyUserId, null);
}

View File

@ -1,13 +1,14 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 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:intl/intl.dart';
import 'package:label_storemax/app_payment_methods.dart';
import 'package:label_storemax/helpers/app_localizations.dart';
import 'package:flutter/material.dart';
@ -22,6 +23,7 @@ import 'package:html/parser.dart';
import 'package:flutter_web_browser/flutter_web_browser.dart';
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
import 'package:math_expressions/math_expressions.dart';
import 'package:platform_alert_dialog/platform_alert_dialog.dart';
import 'package:status_alert/status_alert.dart';
import 'package:woosignal/models/response/tax_rate.dart';
import 'package:woosignal/woosignal.dart';
@ -52,12 +54,6 @@ class HexColor extends Color {
HexColor(final String hexColor) : super(_getColorFromHex(hexColor));
}
String truncateWithEllipsis(int cutoff, String myString) {
return (myString.length <= cutoff)
? myString
: '${myString.substring(0, cutoff)}...';
}
showStatusAlert(context,
{@required String title, String subtitle, IconData icon, int duration}) {
StatusAlert.show(
@ -141,7 +137,7 @@ String formatDoubleCurrency({double total}) {
return fmf.output.symbolOnLeft;
}
String formatStringCurrency({String total}) {
String formatStringCurrency({@required String total}) {
double tmpVal;
if (total == null || total == "") {
tmpVal = 0;
@ -345,3 +341,112 @@ RegExp defaultRegex(
multiLine: false,
);
}
bool isEmail(String em) {
String p =
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regExp = new RegExp(p);
return regExp.hasMatch(em);
}
// 6 LENGTH, 1 DIGIT
bool validPassword(String pw) {
String p = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$';
RegExp regExp = new RegExp(p);
return regExp.hasMatch(pw);
}
navigatorPush(BuildContext context,
{@required String routeName, Object arguments, bool forgetAll = false}) {
if (forgetAll) {
Navigator.of(context).pushNamedAndRemoveUntil(
routeName, (Route<dynamic> route) => false,
arguments: arguments ?? null);
} else {
Navigator.of(context).pushNamed(routeName, arguments: arguments ?? null);
}
}
PlatformDialogAction dialogAction(BuildContext context,
{@required title, ActionType actionType, Function() action}) {
return PlatformDialogAction(
actionType: actionType ?? ActionType.Default,
child: Text(title ?? ""),
onPressed: action ??
() {
Navigator.of(context).pop();
},
);
}
showPlatformAlertDialog(BuildContext context,
{String title,
String subtitle,
List<PlatformDialogAction> actions,
bool showDoneAction = true}) {
if (showDoneAction) {
actions
.add(dialogAction(context, title: trans(context, "Done"), action: () {
Navigator.of(context).pop();
}));
}
showDialog<void>(
context: context,
builder: (BuildContext context) {
return PlatformAlertDialog(
title: Text(title ?? ""),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text(subtitle ?? ""),
],
),
),
actions: actions,
);
},
);
}
DateTime parseDateTime(String strDate) {
return DateTime.parse(strDate);
}
DateFormat formatDateTime(String format) {
return DateFormat(format);
}
String dateFormatted({@required String date, @required String formatType}) {
return formatDateTime(formatType).format(parseDateTime(date));
}
enum FormatType {
DateTime,
Date,
Time,
}
String formatForDateTime(FormatType formatType) {
switch (formatType) {
case FormatType.Date:
{
return "yyyy-MM-dd";
}
case FormatType.DateTime:
{
return "dd-MM-yyyy hh:mm a";
}
case FormatType.Time:
{
return "hh:mm a";
}
default:
{
return "";
}
}
}
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);

View File

@ -3,7 +3,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -14,7 +14,7 @@
Developer Notes
SUPPORT EMAIL - support@woosignal.com
VERSION - 2.0.0
VERSION - 2.0.1
https://woosignal.com
*/
@ -22,21 +22,34 @@
const app_name = "MyApp";
const app_key = "Your App Key";
const app_key = "your app key";
// Your App key from WooSignal
// link: https://woosignal.com/dashboard/apps
const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
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_terms_url = "https://yourdomain.com/terms";
const app_privacy_url = "https://yourdomain.com/privacy";
/*<! ------ WP LOGIN (OPTIONAL) ------!>*/
// Allows customers to login/register, view account, purchase items as a user.
// #1 Install the "WP JSON API" plugin on WordPress via https://woosignal.com/plugins/wordpress/wpapp-json-api
// #2 Next activate the plugin on your WordPress and enable "use_wp_login = true"
// link: https://woosignal.com/dashboard/plugins
const use_wp_login = false;
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_wp_api_path = "/wp-json"; // By default "/wp-json" should work
/*<! ------ STRIPE (OPTIONAL) ------!>*/
const app_stripe_account = "Your Stripe Key";
// 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

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -10,10 +10,20 @@
import 'package:flutter/material.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_detail.dart';
import 'package:label_storemax/pages/account_landing.dart';
import 'package:label_storemax/pages/account_order_detail.dart';
import 'package:label_storemax/pages/account_profile_update.dart';
import 'package:label_storemax/pages/account_register.dart';
import 'package:label_storemax/pages/account_shipping_details.dart';
import 'package:label_storemax/pages/error_page.dart';
import 'package:label_storemax/pages/product_image_viewer_page.dart';
import 'package:woosignal/models/response/order.dart';
import 'package:woosignal/models/response/product_category.dart';
import 'package:woosignal/models/response/products.dart';
import 'package:wp_json_api/wp_json_api.dart';
import 'labelconfig.dart';
import 'package:label_storemax/pages/checkout_details.dart';
import 'package:label_storemax/pages/home.dart';
@ -41,17 +51,36 @@ void main() async {
DeviceOrientation.portraitUp,
]);
String initialRoute = (use_wp_login) ? "/account-landing" : "/home";
WPJsonAPI.instance.initWith(
baseUrl: app_base_url,
shouldDebug: app_debug,
wpJsonPath: app_wp_api_path);
if (await authCheck() == true) {
initialRoute = "/home";
}
runApp(
new MaterialApp(
title: app_name,
color: Colors.white,
debugShowCheckedModeBanner: false,
initialRoute: "/home",
initialRoute: initialRoute,
routes: <String, WidgetBuilder>{
'/home': (BuildContext context) => new HomePage(),
'/cart': (BuildContext context) => new CartPage(),
'/error': (BuildContext context) => new ErrorPage(),
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
'/account-landing': (BuildContext context) => new AccountLandingPage(),
'/account-register': (BuildContext context) =>
new AccountRegistrationPage(),
'/account-detail': (BuildContext context) => new AccountDetailPage(),
'/account-update': (BuildContext context) =>
new AccountProfileUpdatePage(),
'/account-billing-details': (BuildContext context) =>
new AccountBillingDetailsPage(),
'/account-shipping-details': (BuildContext context) =>
new AccountShippingDetailsPage(),
},
onGenerateRoute: (settings) {
switch (settings.name) {
@ -95,6 +124,30 @@ void main() async {
type: PageTransitionType.fade,
);
case '/product-images':
if (settings.arguments != null) {
final Map<String, dynamic> args = settings.arguments;
return PageTransition(
child: ProductImageViewerPage(
initialIndex: args["index"], arrImageSrc: args["images"]),
type: PageTransitionType.fade);
}
return PageTransition(
child: ErrorPage(), type: PageTransitionType.rightToLeft);
case '/account-order-detail':
if (settings.arguments != null) {
final int orderId = settings.arguments as int;
return PageTransition(
child: AccountOrderDetailPage(orderId: orderId),
type: PageTransitionType.rightToLeftWithFade,
);
}
return PageTransition(
child: ErrorPage(),
type: PageTransitionType.fade,
);
case '/checkout-status':
if (settings.arguments != null) {
final Order order = settings.arguments as Order;

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -66,7 +66,7 @@ class Cart {
if (withFormat != null && withFormat == true) {
return formatDoubleCurrency(total: total);
}
return total.toString();
return total.toStringAsFixed(2);
}
Future<String> getSubtotal({bool withFormat}) async {
@ -78,7 +78,7 @@ class Cart {
if (withFormat != null && withFormat == true) {
return formatDoubleCurrency(total: subtotal);
}
return subtotal.toString();
return subtotal.toStringAsFixed(2);
}
void updateQuantity(
@ -176,6 +176,6 @@ class Cart {
if (shippingTotal != 0) {
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
}
return (total).toString();
return (total).toStringAsFixed(2);
}
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -44,6 +44,10 @@ class CartLineItem {
this.total,
this.metaData});
String getCartTotal() {
return (quantity * double.parse(subtotal)).toString();
}
CartLineItem.fromJson(Map<String, dynamic> json)
: name = json['name'],
productId = json['product_id'],

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -0,0 +1,257 @@
// 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/cupertino.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/widgets/app_loader.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart';
import 'package:wp_json_api/models/responses/WCCustomerUpdatedResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountBillingDetailsPage extends StatefulWidget {
AccountBillingDetailsPage();
@override
_AccountBillingDetailsPageState createState() =>
_AccountBillingDetailsPageState();
}
class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
_AccountBillingDetailsPageState();
// BILLING TEXT CONTROLLERS
TextEditingController _txtShippingFirstName;
TextEditingController _txtShippingLastName;
TextEditingController _txtShippingAddressLine;
TextEditingController _txtShippingCity;
TextEditingController _txtShippingState;
TextEditingController _txtShippingPostalCode;
TextEditingController _txtShippingCountry;
bool _isLoading;
bool _isUpdating;
@override
void initState() {
super.initState();
_txtShippingFirstName = TextEditingController();
_txtShippingLastName = TextEditingController();
_txtShippingAddressLine = TextEditingController();
_txtShippingCity = TextEditingController();
_txtShippingState = TextEditingController();
_txtShippingPostalCode = TextEditingController();
_txtShippingCountry = TextEditingController();
_isLoading = true;
_isUpdating = false;
_fetchUserDetails();
}
_fetchUserDetails() async {
WCCustomerInfoResponse wcCustomerInfoResponse =
await WPJsonAPI.instance.api((request) async {
return request.wcCustomerInfo(await readAuthToken());
});
Billing billing = wcCustomerInfoResponse.data.billing;
_txtShippingFirstName.text = billing.firstName;
_txtShippingLastName.text = billing.lastName;
_txtShippingAddressLine.text = billing.address1;
_txtShippingCity.text = billing.city;
_txtShippingState.text = billing.state;
_txtShippingPostalCode.text = billing.postcode;
_txtShippingCountry.text = billing.country;
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Text(
trans(context, "Billing Details"),
style: Theme.of(context).primaryTextTheme.subhead,
),
centerTitle: true,
),
body: SafeArea(
minimum: safeAreaDefault(),
child: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: _isLoading
? showAppLoader()
: LayoutBuilder(
builder: (context, constraints) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "First Name"),
controller: _txtShippingFirstName,
shouldAutoFocus: true,
),
),
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Last Name"),
controller: _txtShippingLastName,
),
),
],
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
),
wsTextEditingRow(
context,
heading: trans(context, "Address Line"),
controller: _txtShippingAddressLine,
),
Row(children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "City"),
controller: _txtShippingCity,
),
),
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "State"),
keyboardType: TextInputType.emailAddress,
controller: _txtShippingState),
),
]),
Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Postal code"),
controller: _txtShippingPostalCode,
),
),
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "Country"),
keyboardType:
TextInputType.emailAddress,
controller: _txtShippingCountry),
),
],
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
)
],
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: HexColor("#e8e8e8"),
blurRadius: 15.0,
// has the effect of softening the shadow
spreadRadius: 0,
offset: Offset(
0,
0,
),
)
],
),
padding: EdgeInsets.all(8),
),
height:
(constraints.maxHeight - constraints.minHeight) *
0.6,
),
Column(
children: <Widget>[
wsPrimaryButton(context,
title: trans(context, "UPDATE DETAILS"),
action:
_isUpdating ? null : _updateBillingDetails),
],
),
],
),
),
),
),
);
}
_updateBillingDetails() async {
String firstName = _txtShippingFirstName.text;
String lastName = _txtShippingLastName.text;
String addressLine = _txtShippingAddressLine.text;
String city = _txtShippingCity.text;
String state = _txtShippingState.text;
String postalCode = _txtShippingPostalCode.text;
String country = _txtShippingCountry.text;
String userToken = await readAuthToken();
setState(() {
_isUpdating = true;
});
WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI
.instance
.api((request) => request.wcUpdateCustomerInfo(userToken,
billingFirstName: firstName,
billingLastName: lastName,
billingAddress1: addressLine,
billingCity: city,
billingState: state,
billingPostcode: postalCode,
billingCountry: country));
setState(() {
_isUpdating = false;
});
if (wcCustomerUpdatedResponse.status != 200) {
showEdgeAlertWith(context,
title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"),
style: EdgeAlertStyle.WARNING);
return;
}
Navigator.pop(context);
}
}

View File

@ -0,0 +1,392 @@
// 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:bubble_tab_indicator/bubble_tab_indicator.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/widgets/app_loader.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:woosignal/models/response/order.dart';
import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountDetailPage extends StatefulWidget {
@override
_AccountDetailPageState createState() => _AccountDetailPageState();
}
class _AccountDetailPageState extends State<AccountDetailPage>
with SingleTickerProviderStateMixin {
int _page;
List<Order> _orders;
WCCustomerInfoResponse _wcCustomerInfoResponse;
bool _isLoading;
bool _isLoadingOrders;
int _currentTabIndex = 0;
Widget _activeBody;
TabController _tabController;
List<Tab> _tabs = [];
@override
void initState() {
super.initState();
_isLoading = true;
_isLoadingOrders = true;
_page = 1;
_orders = [];
_tabs = [
new Tab(text: "Orders"),
new Tab(text: "Settings"),
];
_tabController = TabController(vsync: this, length: _tabs.length);
_activeBody = showAppLoader();
_fetchWpUserData();
_fetchOrders();
}
_fetchWpUserData() async {
WCCustomerInfoResponse wcCustomerInfoResponse =
await WPJsonAPI.instance.api((request) async {
return request.wcCustomerInfo(await readAuthToken());
});
if (wcCustomerInfoResponse != null) {
_wcCustomerInfoResponse = wcCustomerInfoResponse;
}
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: Container(
child: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
margin: EdgeInsets.only(left: 0),
),
title: Text(
trans(context, "Account"),
style: Theme.of(context).primaryTextTheme.title,
),
centerTitle: true,
),
resizeToAvoidBottomPadding: false,
body: SafeArea(
minimum: safeAreaDefault(),
child: _isLoading
? showAppLoader()
: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 10, bottom: 10),
padding: EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 10),
child: CircleAvatar(
backgroundImage: NetworkImage(
_wcCustomerInfoResponse.data.avatar,
),
),
height: 90,
width: 90,
),
Expanded(
child: Padding(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
(_wcCustomerInfoResponse == null
? ""
: [
_wcCustomerInfoResponse
.data.firstName,
_wcCustomerInfoResponse
.data.lastName
]
.where((t) =>
(t != null || t != ""))
.toList()
.join(" ")),
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
),
),
],
)
],
),
padding: EdgeInsets.only(left: 16),
),
),
],
),
Padding(
child: TabBar(
tabs: _tabs,
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
labelColor: Colors.white,
unselectedLabelColor: Colors.black87,
indicator: new BubbleTabIndicator(
indicatorHeight: 25.0,
indicatorColor: Colors.black87,
tabBarIndicatorSize: TabBarIndicatorSize.tab,
),
onTap: _tabsTapped,
),
padding: EdgeInsets.symmetric(vertical: 8),
),
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
boxShadow: wsBoxShadow(),
color: Colors.white,
),
),
Expanded(child: _activeBody),
],
),
),
);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
_tabsTapped(int i) {
_currentTabIndex = i;
setState(() {
if (_currentTabIndex == 0) {
_activeBody = _widgetOrders();
} else {
_activeBody = _widgetSettings();
}
});
}
ListView _widgetSettings() {
return ListView(
children: <Widget>[
Card(
child: ListTile(
leading: Icon(Icons.account_circle),
title: Text(trans(context, "Update details")),
onTap: () {
Navigator.pushNamed(context, "/account-update");
},
),
),
Card(
child: ListTile(
leading: Icon(Icons.local_shipping),
title: Text(trans(context, "Shipping Details")),
onTap: () {
Navigator.pushNamed(context, "/account-shipping-details");
},
),
),
Card(
child: ListTile(
leading: Icon(Icons.credit_card),
title: Text(trans(context, "Billing Details")),
onTap: () {
Navigator.pushNamed(context, "/account-billing-details");
},
),
),
Card(
child: ListTile(
leading: Icon(Icons.exit_to_app),
title: Text(trans(context, "Logout")),
onTap: () {
authLogout(context);
},
),
),
],
);
}
_fetchOrders() async {
String userId = await readUserId();
if (userId == null) {
setState(() {
_isLoadingOrders = false;
_activeBody = _widgetOrders();
});
return;
}
_orders = await appWooSignal((api) {
return api.getOrders(
customer: int.parse(userId), page: _page, perPage: 100);
});
setState(() {
_isLoadingOrders = false;
_activeBody = _widgetOrders();
});
}
Widget _widgetOrders() {
return _isLoadingOrders
? showAppLoader()
: _orders.length <= 0
? Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.shopping_cart,
color: Colors.black54,
size: 40,
),
Text(
trans(context, "No orders found"),
),
],
),
)
: ListView.builder(
itemBuilder: (cxt, i) {
return Card(
child: ListTile(
contentPadding:
EdgeInsets.only(top: 5, bottom: 5, left: 8, right: 6),
title: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: HexColor("#fcfcfc"), width: 1),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"#" + _orders[i].id.toString(),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
capitalize(_orders[i].status),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
formatStringCurrency(total: _orders[i].total),
style: Theme.of(context)
.primaryTextTheme
.body1
.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black),
textAlign: TextAlign.left,
),
Text(
_orders[i].lineItems.length.toString() +
" " +
trans(context, "items"),
style: Theme.of(context)
.primaryTextTheme
.body2
.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black),
textAlign: TextAlign.left,
),
],
),
Text(
dateFormatted(
date: _orders[i].dateCreated,
formatType:
formatForDateTime(FormatType.Date)) +
"\n" +
dateFormatted(
date: _orders[i].dateCreated,
formatType:
formatForDateTime(FormatType.Time)),
textAlign: TextAlign.right,
style: Theme.of(context)
.primaryTextTheme
.bodyText1
.copyWith(
fontWeight: FontWeight.w400,
color: Colors.black),
),
],
),
),
trailing: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.chevron_right),
],
),
onTap: () {
int orderId = _orders[i].id;
Navigator.pushNamed(context, "/account-order-detail",
arguments: orderId);
},
),
);
},
itemCount: _orders.length,
);
}
}

View File

@ -0,0 +1,173 @@
// 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/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:wp_json_api/models/responses/WPUserLoginResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountLandingPage extends StatefulWidget {
AccountLandingPage();
@override
_AccountLandingPageState createState() => _AccountLandingPageState();
}
class _AccountLandingPageState extends State<AccountLandingPage> {
bool _hasTappedLogin;
TextEditingController _tfEmailController;
TextEditingController _tfPasswordController;
@override
void initState() {
super.initState();
_hasTappedLogin = false;
_tfEmailController = TextEditingController();
_tfPasswordController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomPadding: false,
body: SafeArea(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
storeLogo(height: 100),
Flexible(
child: Container(
height: 70,
padding: EdgeInsets.only(bottom: 20),
margin: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.bottomLeft,
child: Text(
trans(context, "Login"),
textAlign: TextAlign.left,
style: Theme.of(context)
.primaryTextTheme
.display1
.copyWith(
fontSize: 24,
fontWeight: FontWeight.w700,
),
),
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
boxShadow: wsBoxShadow(),
color: Colors.white),
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 8),
margin: EdgeInsets.symmetric(horizontal: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
wsTextEditingRow(context,
heading: trans(context, "Email"),
controller: _tfEmailController,
keyboardType: TextInputType.emailAddress),
wsTextEditingRow(context,
heading: trans(context, "Password"),
controller: _tfPasswordController,
keyboardType: TextInputType.visiblePassword,
obscureText: true),
wsPrimaryButton(
context,
title: trans(context, "Login"),
action: _hasTappedLogin == true ? null : _loginUser,
),
],
),
),
],
),
),
FlatButton(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.account_circle,
color: Colors.black38,
),
Padding(
child: Text(
trans(context, "Create an account"),
style: Theme.of(context).primaryTextTheme.body2,
),
padding: EdgeInsets.only(left: 8),
)
],
),
onPressed: () {
Navigator.pushNamed(context, "/account-register");
},
),
wsLinkButton(context, title: trans(context, "Forgot Password"),
action: () {
launch(app_forgot_password_url);
}),
],
),
),
);
}
_loginUser() async {
String email = _tfEmailController.text;
String password = _tfPasswordController.text;
if (_hasTappedLogin == false) {
setState(() {
_hasTappedLogin = true;
});
WPUserLoginResponse wpUserLoginResponse = await WPJsonAPI.instance
.api((request) => request.wpLogin(email: email, password: password));
_hasTappedLogin = false;
if (wpUserLoginResponse != null) {
String token = wpUserLoginResponse.data.userToken;
authUser(token);
storeUserId(wpUserLoginResponse.data.userId.toString());
navigatorPush(context, routeName: "/home", forgetAll: true);
} else {
showEdgeAlertWith(context,
title: trans(context, "Oops!"),
desc: trans(context, "Invalid login credentials"),
style: EdgeAlertStyle.WARNING,
icon: Icons.account_circle);
setState(() {
_hasTappedLogin = false;
});
}
}
}
}

View File

@ -0,0 +1,209 @@
// 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/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/widgets/app_loader.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:woosignal/models/response/order.dart';
class AccountOrderDetailPage extends StatefulWidget {
final int orderId;
AccountOrderDetailPage({Key key, this.orderId}) : super(key: key);
@override
_AccountOrderDetailPageState createState() =>
_AccountOrderDetailPageState(this.orderId);
}
class _AccountOrderDetailPageState extends State<AccountOrderDetailPage> {
_AccountOrderDetailPageState(this._orderId);
int _orderId;
Order _order;
bool _isLoading;
@override
void initState() {
super.initState();
_isLoading = true;
_fetchOrder();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: Container(
child: IconButton(
icon: Icon(Icons.arrow_back_ios),
onPressed: () {
Navigator.pop(context);
},
),
margin: EdgeInsets.only(left: 0),
),
title: Text(
"Order #" + _orderId.toString(),
style: Theme.of(context).primaryTextTheme.title,
),
centerTitle: true,
),
resizeToAvoidBottomPadding: false,
body: SafeArea(
minimum: safeAreaDefault(),
child: _isLoading
? showAppLoader()
: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Ordered date: " +
dateFormatted(
date: _order.dateCreated,
formatType: formatForDateTime(FormatType.Date))),
Container(
margin: EdgeInsets.only(top: 10, bottom: 10),
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(child: Text("Ships to:")),
Flexible(
child: Text(
[
[
_order.shipping.firstName,
_order.shipping.lastName
].where((t) => t != null).toList().join(" "),
_order.shipping.address1,
_order.shipping.address2,
_order.shipping.city,
_order.shipping.state,
_order.shipping.postcode,
_order.shipping.country,
]
.where((t) => (t != "" && t != null))
.toList()
.join("\n"),
textAlign: TextAlign.right,
),
),
],
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
boxShadow: wsBoxShadow(),
color: Colors.white,
),
),
Expanded(
child: ListView.builder(
itemBuilder: (cxt, i) {
return Card(
child: ListTile(
contentPadding: EdgeInsets.only(
top: 5, bottom: 5, left: 8, right: 6),
title: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
color: HexColor("#fcfcfc"), width: 1),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: Text(
_order.lineItems[i].name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
Text(
capitalize(formatStringCurrency(
total: _order.lineItems[i].price)),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
formatStringCurrency(
total: _order.lineItems[i].total),
style: Theme.of(context)
.primaryTextTheme
.body1
.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black),
textAlign: TextAlign.left,
),
Text(
"x" +
_order.lineItems[i].quantity
.toString(),
style: Theme.of(context)
.primaryTextTheme
.body2
.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black),
textAlign: TextAlign.left,
),
],
),
],
),
),
),
);
},
itemCount: _order.lineItems.length,
)),
],
),
),
);
}
@override
void dispose() {
super.dispose();
}
_fetchOrder() async {
_order = await appWooSignal((api) {
return api.retrieveOrder(_orderId);
});
if (_order != null) {
setState(() {
_isLoading = false;
});
}
}
}

View File

@ -0,0 +1,166 @@
// 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/cupertino.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/widgets/app_loader.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:wp_json_api/models/responses/WPUserInfoResponse.dart';
import 'package:wp_json_api/models/responses/WPUserInfoUpdatedResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountProfileUpdatePage extends StatefulWidget {
AccountProfileUpdatePage();
@override
_AccountProfileUpdatePageState createState() =>
_AccountProfileUpdatePageState();
}
class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
_AccountProfileUpdatePageState();
bool isLoading;
TextEditingController _tfFirstName;
TextEditingController _tfLastName;
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
isLoading = true;
_tfFirstName = TextEditingController();
_tfLastName = TextEditingController();
_fetchUserDetails();
}
_fetchUserDetails() async {
WPUserInfoResponse wpUserInfoResponse =
await WPJsonAPI.instance.api((request) async {
return request.wpGetUserInfo(await readAuthToken());
});
_tfFirstName.text = wpUserInfoResponse.data.firstName;
_tfLastName.text = wpUserInfoResponse.data.lastName;
setState(() {
isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
trans(context, "Update Details"),
style: TextStyle(
fontSize: 20,
),
),
centerTitle: true,
elevation: 1,
),
body: isLoading
? showAppLoader()
: SafeArea(
// minimum: safeAreaDefault(),
child: Column(
children: <Widget>[
Expanded(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Flexible(
child: Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "First Name"),
controller: _tfFirstName,
keyboardType: TextInputType.text)),
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "Last Name"),
controller: _tfLastName,
keyboardType: TextInputType.text),
),
],
),
),
Padding(
padding: EdgeInsets.only(top: 5),
),
Padding(
padding: EdgeInsets.only(top: 10),
),
wsPrimaryButton(context,
title: trans(context, "Update details"),
action: _updateDetails)
],
),
margin: EdgeInsets.all(8),
padding: EdgeInsets.all(8),
color: Colors.white,
),
),
],
),
),
);
}
bool _isNetworking = false;
_updateDetails() async {
String firstName = _tfFirstName.text;
String lastName = _tfLastName.text;
if (_isNetworking == false) {
setState(() {
_isNetworking = true;
isLoading = true;
});
WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse =
await WPJsonAPI.instance.api((request) async {
return request.wpUpdateUserInfo(await readAuthToken(),
firstName: firstName, lastName: lastName);
});
if (wpUserInfoUpdatedResponse != null &&
wpUserInfoUpdatedResponse.status == 200) {
showEdgeAlertWith(context,
title: trans(context, "Success"),
desc: trans(context, "Account updated"),
style: EdgeAlertStyle.SUCCESS);
} else {
showEdgeAlertWith(context,
title: trans(context, "Invalid details"),
desc: trans(context, "Please check your email and password"),
style: EdgeAlertStyle.WARNING);
}
setState(() {
_isNetworking = false;
isLoading = false;
});
}
}
}

View File

@ -0,0 +1,224 @@
// 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/material.dart';
import 'package:label_storemax/helpers/shared_pref/sp_auth.dart';
import 'package:label_storemax/helpers/shared_pref/sp_user_id.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:woosignal/helpers/shared_pref.dart';
import 'package:wp_json_api/models/responses/WPUserInfoUpdatedResponse.dart';
import 'package:wp_json_api/models/responses/WPUserRegisterResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountRegistrationPage extends StatefulWidget {
AccountRegistrationPage();
@override
_AccountRegistrationPageState createState() =>
_AccountRegistrationPageState();
}
class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
_AccountRegistrationPageState();
bool _hasTappedRegister;
TextEditingController _tfEmailAddressController;
TextEditingController _tfPasswordController;
TextEditingController _tfFirstNameController;
TextEditingController _tfLastNameController;
@override
void initState() {
super.initState();
_hasTappedRegister = false;
_tfEmailAddressController = TextEditingController();
_tfPasswordController = TextEditingController();
_tfFirstNameController = TextEditingController();
_tfLastNameController = TextEditingController();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.pop(context);
},
),
title: Text(
"Register",
style: Theme.of(context).primaryTextTheme.title,
),
centerTitle: true,
),
resizeToAvoidBottomPadding: false,
body: SafeArea(
minimum: safeAreaDefault(),
child: Column(
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 10),
child: Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "First Name"),
controller: _tfFirstNameController,
shouldAutoFocus: true,
keyboardType: TextInputType.text),
),
Flexible(
child: wsTextEditingRow(context,
heading: trans(context, "Last Name"),
controller: _tfLastNameController,
shouldAutoFocus: false,
keyboardType: TextInputType.text),
),
],
)),
wsTextEditingRow(
context,
heading: trans(context, "Email address"),
controller: _tfEmailAddressController,
shouldAutoFocus: false,
keyboardType: TextInputType.emailAddress,
),
wsTextEditingRow(
context,
heading: trans(context, "Password"),
controller: _tfPasswordController,
shouldAutoFocus: true,
obscureText: true,
),
Padding(
child: wsPrimaryButton(context,
title: trans(context, "Sign up"),
action: _hasTappedRegister ? null : _signUpTapped),
padding: EdgeInsets.only(top: 10),
),
Padding(
child: InkWell(
child: RichText(
text: TextSpan(
text: trans(
context, "By tapping \"Register\" you agree to ") +
app_name +
'\'s ',
children: <TextSpan>[
TextSpan(
text: trans(context, "terms and conditions"),
style: TextStyle(fontWeight: FontWeight.bold)),
TextSpan(text: ' ' + trans(context, "and") + ' '),
TextSpan(
text: trans(context, "privacy policy"),
style: TextStyle(fontWeight: FontWeight.bold)),
],
style: TextStyle(color: Colors.black45),
),
textAlign: TextAlign.center,
),
onTap: _viewTOSModal,
),
padding: EdgeInsets.symmetric(vertical: 16),
),
],
),
),
);
}
_signUpTapped() async {
String email = _tfEmailAddressController.text;
String password = _tfPasswordController.text;
String firstName = _tfFirstNameController.text;
String lastName = _tfLastNameController.text;
if (!isEmail(email)) {
showEdgeAlertWith(context,
title: trans(context, "Oops"),
desc: trans(context, "That email address is not valid"),
style: EdgeAlertStyle.DANGER);
return;
}
if (password.length <= 5) {
showEdgeAlertWith(context,
title: trans(context, "Oops"),
desc: trans(context, "Password must be a min 6 characters"),
style: EdgeAlertStyle.DANGER);
return;
}
if (_hasTappedRegister == false) {
setState(() {
_hasTappedRegister = true;
});
String username =
(email.replaceAll(new RegExp(r'(@|\.)'), "")) + randomStr(4);
WPUserRegisterResponse wpUserRegisterResponse = await WPJsonAPI.instance
.api((request) => request.wpRegister(
email: email, password: password, username: username));
if (wpUserRegisterResponse != null) {
String token = wpUserRegisterResponse.data.userToken;
authUser(token);
storeUserId(wpUserRegisterResponse.data.userId.toString());
WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse = await WPJsonAPI
.instance
.api((request) => request.wpUpdateUserInfo(token,
firstName: firstName, lastName: lastName));
navigatorPush(context, routeName: "/home", forgetAll: true);
} else {
setState(() {
showEdgeAlertWith(context,
title: trans(context, "Invalid"),
desc: trans(context, "Please check your details"),
style: EdgeAlertStyle.WARNING);
_hasTappedRegister = false;
});
}
}
}
_viewTOSModal() {
showPlatformAlertDialog(context,
title: trans(context, "Actions"),
subtitle: trans(context, "View Terms and Conditions or Privacy policy"),
actions: [
dialogAction(context,
title: trans(context, "Terms and Conditions"),
action: _viewTermsConditions),
dialogAction(context,
title: trans(context, "Privacy Policy"),
action: _viewPrivacyPolicy),
]);
}
void _viewTermsConditions() {
Navigator.pop(context);
openBrowserTab(url: app_terms_url);
}
void _viewPrivacyPolicy() {
Navigator.pop(context);
openBrowserTab(url: app_privacy_url);
}
}

View File

@ -0,0 +1,255 @@
// 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/cupertino.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/widgets/app_loader.dart';
import 'package:label_storemax/widgets/buttons.dart';
import 'package:label_storemax/widgets/woosignal_ui.dart';
import 'package:wp_json_api/models/responses/WCCustomerInfoResponse.dart';
import 'package:wp_json_api/models/responses/WCCustomerUpdatedResponse.dart';
import 'package:wp_json_api/wp_json_api.dart';
class AccountShippingDetailsPage extends StatefulWidget {
AccountShippingDetailsPage();
@override
_AccountShippingDetailsPageState createState() =>
_AccountShippingDetailsPageState();
}
class _AccountShippingDetailsPageState
extends State<AccountShippingDetailsPage> {
_AccountShippingDetailsPageState();
// BILLING TEXT CONTROLLERS
TextEditingController _txtShippingFirstName;
TextEditingController _txtShippingLastName;
TextEditingController _txtShippingAddressLine;
TextEditingController _txtShippingCity;
TextEditingController _txtShippingPostalCode;
TextEditingController _txtShippingState;
TextEditingController _txtShippingCountry;
bool _isLoading;
bool _isUpdating;
@override
void initState() {
super.initState();
_txtShippingFirstName = TextEditingController();
_txtShippingLastName = TextEditingController();
_txtShippingAddressLine = TextEditingController();
_txtShippingCity = TextEditingController();
_txtShippingPostalCode = TextEditingController();
_txtShippingState = TextEditingController();
_txtShippingCountry = TextEditingController();
_isLoading = true;
_isUpdating = false;
_fetchUserDetails();
}
_fetchUserDetails() async {
WCCustomerInfoResponse wcCustomerInfoResponse =
await WPJsonAPI.instance.api((request) async {
return request.wcCustomerInfo(await readAuthToken());
});
Shipping shipping = wcCustomerInfoResponse.data.shipping;
_txtShippingFirstName.text = shipping.firstName;
_txtShippingLastName.text = shipping.lastName;
_txtShippingAddressLine.text = shipping.address1;
_txtShippingCity.text = shipping.city;
_txtShippingState.text = shipping.state;
_txtShippingPostalCode.text = shipping.postcode;
_txtShippingCountry.text = shipping.country;
setState(() {
_isLoading = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
appBar: AppBar(
backgroundColor: Colors.transparent,
title: Text(
trans(context, "Shipping Details"),
style: Theme.of(context).primaryTextTheme.subhead,
),
centerTitle: true,
),
body: SafeArea(
minimum: safeAreaDefault(),
child: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: _isLoading
? showAppLoader()
: LayoutBuilder(
builder: (context, constraints) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
SizedBox(
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "First Name"),
controller: _txtShippingFirstName,
shouldAutoFocus: true,
),
),
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Last Name"),
controller: _txtShippingLastName,
),
),
],
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
),
wsTextEditingRow(
context,
heading: trans(context, "Address Line"),
controller: _txtShippingAddressLine,
),
Row(children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "City"),
controller: _txtShippingCity,
),
),
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "State"),
controller: _txtShippingState,
),
),
]),
Row(
children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Postal code"),
controller: _txtShippingPostalCode,
),
),
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Country"),
controller: _txtShippingCountry,
),
),
],
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
)
],
),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: HexColor("#e8e8e8"),
blurRadius: 15.0,
// has the effect of softening the shadow
spreadRadius: 0,
offset: Offset(
0,
0,
),
)
],
),
padding: EdgeInsets.all(8),
),
height:
(constraints.maxHeight - constraints.minHeight) *
0.6,
),
Column(
children: <Widget>[
wsPrimaryButton(context,
title: trans(context, "UPDATE DETAILS"),
action:
_isUpdating ? null : _updateShippingDetails),
],
),
],
),
),
),
),
);
}
_updateShippingDetails() async {
String firstName = _txtShippingFirstName.text;
String lastName = _txtShippingLastName.text;
String addressLine = _txtShippingAddressLine.text;
String city = _txtShippingCity.text;
String state = _txtShippingState.text;
String postalCode = _txtShippingPostalCode.text;
String country = _txtShippingCountry.text;
String userToken = await readAuthToken();
setState(() {
_isUpdating = true;
});
WCCustomerUpdatedResponse wcCustomerUpdatedResponse = await WPJsonAPI
.instance
.api((request) => request.wcUpdateCustomerInfo(userToken,
shippingFirstName: firstName,
shippingLastName: lastName,
shippingAddress1: addressLine,
shippingCity: city,
shippingState: state,
shippingPostcode: postalCode,
shippingCountry: country));
if (wcCustomerUpdatedResponse.status != 200) {
showEdgeAlertWith(context,
title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong"),
style: EdgeAlertStyle.WARNING);
return;
}
Navigator.pop(context);
}
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -184,10 +184,11 @@ class _CartPageState extends State<CartPage> {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Image(
image: AssetImage("assets/images/cart_empty.png"),
height: 150,
alignment: Alignment.center),
Icon(
Icons.shopping_cart,
size: 100,
color: Colors.black45,
),
Padding(
child: Text(trans(context, "Empty Basket"),
style: Theme.of(context).primaryTextTheme.body1),

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -50,6 +50,8 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
_getTaxes();
}
_fetchUserId() {}
void reloadState({bool showLoader}) {
setState(() {
_showFullLoader = showLoader ?? false;
@ -110,7 +112,9 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
icon: Icons.local_shipping);
return;
}
Navigator.pushNamed(context, "/checkout-shipping-type");
Navigator.pushNamed(context, "/checkout-shipping-type").then((value) {
setState(() {});
});
}
@override
@ -156,12 +160,9 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
.billingDetails.billingAddress
.hasMissingFields()
? "Billing address is incomplete"
: truncateWithEllipsis(
30,
CheckoutSession.getInstance
.billingDetails.billingAddress
.addressFull(),
)),
: CheckoutSession.getInstance
.billingDetails.billingAddress
.addressFull()),
action: _actionCheckoutDetails,
showBorderBottom: true)
: wsCheckoutRow(context,

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -28,12 +28,12 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
_CheckoutDetailsPageState();
// BILLING TEXT CONTROLLERS
TextEditingController _txtBillingFirstName;
TextEditingController _txtBillingLastName;
TextEditingController _txtBillingAddressLine;
TextEditingController _txtBillingCity;
TextEditingController _txtBillingPostalCode;
TextEditingController _txtBillingEmailAddress;
TextEditingController _txtShippingFirstName;
TextEditingController _txtShippingLastName;
TextEditingController _txtShippingAddressLine;
TextEditingController _txtShippingCity;
TextEditingController _txtShippingPostalCode;
TextEditingController _txtShippingEmailAddress;
String _strBillingCountry;
var valRememberDetails = true;
@ -42,12 +42,12 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
void initState() {
super.initState();
_txtBillingFirstName = TextEditingController();
_txtBillingLastName = TextEditingController();
_txtBillingAddressLine = TextEditingController();
_txtBillingCity = TextEditingController();
_txtBillingPostalCode = TextEditingController();
_txtBillingEmailAddress = TextEditingController();
_txtShippingFirstName = TextEditingController();
_txtShippingLastName = TextEditingController();
_txtShippingAddressLine = TextEditingController();
_txtShippingCity = TextEditingController();
_txtShippingPostalCode = TextEditingController();
_txtShippingEmailAddress = TextEditingController();
if (CheckoutSession.getInstance.billingDetails.billingAddress == null) {
CheckoutSession.getInstance.billingDetails.initSession();
@ -55,12 +55,12 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
CheckoutSession.getInstance.billingDetails.billingAddress.initAddress();
}
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
_txtBillingFirstName.text = billingDetails.billingAddress.firstName;
_txtBillingLastName.text = billingDetails.billingAddress.lastName;
_txtBillingAddressLine.text = billingDetails.billingAddress.addressLine;
_txtBillingCity.text = billingDetails.billingAddress.city;
_txtBillingPostalCode.text = billingDetails.billingAddress.postalCode;
_txtBillingEmailAddress.text = billingDetails.billingAddress.emailAddress;
_txtShippingFirstName.text = billingDetails.billingAddress.firstName;
_txtShippingLastName.text = billingDetails.billingAddress.lastName;
_txtShippingAddressLine.text = billingDetails.billingAddress.addressLine;
_txtShippingCity.text = billingDetails.billingAddress.city;
_txtShippingPostalCode.text = billingDetails.billingAddress.postalCode;
_txtShippingEmailAddress.text = billingDetails.billingAddress.emailAddress;
_strBillingCountry = billingDetails.billingAddress.country;
valRememberDetails = billingDetails.rememberDetails ?? true;
@ -72,12 +72,12 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
await CheckoutSession.getInstance.getBillingAddress();
if (sfCustomerAddress != null) {
CustomerAddress customerAddress = sfCustomerAddress;
_txtBillingFirstName.text = customerAddress.firstName;
_txtBillingLastName.text = customerAddress.lastName;
_txtBillingAddressLine.text = customerAddress.addressLine;
_txtBillingCity.text = customerAddress.city;
_txtBillingPostalCode.text = customerAddress.postalCode;
_txtBillingEmailAddress.text = customerAddress.emailAddress;
_txtShippingFirstName.text = customerAddress.firstName;
_txtShippingLastName.text = customerAddress.lastName;
_txtShippingAddressLine.text = customerAddress.addressLine;
_txtShippingCity.text = customerAddress.city;
_txtShippingPostalCode.text = customerAddress.postalCode;
_txtShippingEmailAddress.text = customerAddress.emailAddress;
_strBillingCountry = customerAddress.country;
}
}
@ -152,7 +152,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
child: wsTextEditingRow(
context,
heading: trans(context, "First Name"),
controller: _txtBillingFirstName,
controller: _txtShippingFirstName,
shouldAutoFocus: true,
),
),
@ -160,7 +160,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
child: wsTextEditingRow(
context,
heading: trans(context, "Last Name"),
controller: _txtBillingLastName,
controller: _txtShippingLastName,
),
),
],
@ -170,21 +170,21 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
wsTextEditingRow(
context,
heading: trans(context, "Address Line"),
controller: _txtBillingAddressLine,
controller: _txtShippingAddressLine,
),
Row(children: <Widget>[
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "City"),
controller: _txtBillingCity,
controller: _txtShippingCity,
),
),
Flexible(
child: wsTextEditingRow(
context,
heading: trans(context, "Postal code"),
controller: _txtBillingPostalCode,
controller: _txtShippingPostalCode,
),
),
]),
@ -194,7 +194,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
child: wsTextEditingRow(context,
heading: trans(context, "Email address"),
keyboardType: TextInputType.emailAddress,
controller: _txtBillingEmailAddress),
controller: _txtShippingEmailAddress),
),
Flexible(
child: Padding(
@ -256,14 +256,15 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
title: trans(context, "USE SHIPPING ADDRESS"),
action: () {
CustomerAddress customerAddress = new CustomerAddress();
customerAddress.firstName = _txtBillingFirstName.text;
customerAddress.lastName = _txtBillingLastName.text;
customerAddress.addressLine = _txtBillingAddressLine.text;
customerAddress.city = _txtBillingCity.text;
customerAddress.postalCode = _txtBillingPostalCode.text;
customerAddress.firstName = _txtShippingFirstName.text;
customerAddress.lastName = _txtShippingLastName.text;
customerAddress.addressLine =
_txtShippingAddressLine.text;
customerAddress.city = _txtShippingCity.text;
customerAddress.postalCode = _txtShippingPostalCode.text;
customerAddress.country = _strBillingCountry;
customerAddress.emailAddress =
_txtBillingEmailAddress.text;
_txtShippingEmailAddress.text;
CheckoutSession.getInstance.billingDetails
.shippingAddress = customerAddress;

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -9,6 +9,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import 'package:flutter/material.dart';
import 'package:label_storemax/labelconfig.dart';
import 'package:label_storemax/widgets/menu_item.dart';
import 'package:label_storemax/helpers/tools.dart';
@ -36,7 +37,7 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
backgroundColor: Colors.transparent,
elevation: 0.0,
title: Text(trans(context, "Menu"),
style: Theme.of(context).primaryTextTheme.subhead),
style: Theme.of(context).primaryTextTheme.title),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () {
@ -57,6 +58,12 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
(use_wp_login
? wsMenuItem(context,
title: trans(context, "Profile"),
leading: Icon(Icons.account_circle),
action: _actionProfile)
: Container()),
wsMenuItem(context,
title: trans(context, "Cart"),
leading: Icon(Icons.shopping_cart),
@ -81,4 +88,8 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
void _actionAboutUs() {
Navigator.pushNamed(context, "/about");
}
void _actionProfile() {
Navigator.pushNamed(context, "/account-detail");
}
}

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -305,9 +305,7 @@ class _ProductDetailState extends State<ProductDetailPage> {
itemCount: _product.images.length,
viewportFraction: 0.85,
scale: 0.9,
onTap: (i) {
setState(() {});
},
onTap: _productImageTapped,
),
),
),
@ -541,4 +539,12 @@ class _ProductDetailState extends State<ProductDetailPage> {
icon: Icons.local_shipping);
}
}
_productImageTapped(int i) {
Map<String, dynamic> obj = {
"index": i,
"images": _product.images.map((f) => f.src).toList()
};
Navigator.pushNamed(context, "/product-images", arguments: obj);
}
}

View File

@ -0,0 +1,79 @@
// PRODUCT DETAIL NEW
// 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/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/tools.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:cached_network_image/cached_network_image.dart';
class ProductImageViewerPage extends StatefulWidget {
final int initialIndex;
final List<String> arrImageSrc;
const ProductImageViewerPage({Key key, this.initialIndex, this.arrImageSrc})
: super(key: key);
@override
_ProductImageViewerPageState createState() =>
_ProductImageViewerPageState(this.initialIndex, this.arrImageSrc);
}
class _ProductImageViewerPageState extends State<ProductImageViewerPage> {
_ProductImageViewerPageState(this._initialIndex, this._arrImageSrc);
int _initialIndex;
List<String> _arrImageSrc;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
minimum: safeAreaDefault(),
child: Column(
children: <Widget>[
Expanded(
child: Swiper(
index: _initialIndex,
itemBuilder: (BuildContext context, int index) {
return CachedNetworkImage(
imageUrl: _arrImageSrc[index],
placeholder: (context, url) =>
new CircularProgressIndicator(
strokeWidth: 2, backgroundColor: Colors.black12),
errorWidget: (context, url, error) =>
new Icon(Icons.error),
fit: BoxFit.contain);
},
itemCount: _arrImageSrc.length,
viewportFraction: 0.9,
scale: 0.95,
),
),
Container(
child: IconButton(
icon: Icon(Icons.close),
onPressed: () {
Navigator.pop(context);
},
),
)
],
),
),
);
}
}

View File

@ -3,13 +3,14 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 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/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:label_storemax/helpers/data/order_wc.dart';
@ -57,8 +58,8 @@ stripePay(context,
if (rsp == null) {
showEdgeAlertWith(context,
title: "Oops!",
desc: "Something went wrong, please try again.",
title: trans(context, "Oops!"),
desc: trans(context, "Something went wrong, please try again."),
icon: Icons.payment,
style: EdgeAlertStyle.WARNING);
state.reloadState(showLoader: false);
@ -86,7 +87,9 @@ stripePay(context,
context,
title: trans(context, "Error"),
desc: trans(
context, "Something went wrong, please contact our store"),
context,
trans(
context, "Something went wrong, please contact our store")),
);
state.reloadState(showLoader: false);
}

View File

@ -1,3 +1,13 @@
// 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:flutter_spinkit/flutter_spinkit.dart';
import '../helpers/tools.dart';

View File

@ -1,3 +1,13 @@
// 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/cupertino.dart';
import 'package:flutter/material.dart';
@ -42,11 +52,12 @@ Widget wsLinkButton(BuildContext context,
height: 60,
margin: EdgeInsets.only(top: 10),
child: MaterialButton(
padding: EdgeInsets.all(10),
child: Text(title,
style: Theme.of(context).primaryTextTheme.body2,
textAlign: TextAlign.left),
onPressed: action,
elevation: 0),
padding: EdgeInsets.all(10),
child: Text(title,
style: Theme.of(context).primaryTextTheme.body2,
textAlign: TextAlign.left),
onPressed: action,
elevation: 0,
),
);
}

View File

@ -1,3 +1,13 @@
// 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/material.dart';
import 'package:label_storemax/models/cart.dart';
import 'package:label_storemax/models/cart_line_item.dart';

View File

@ -1,3 +1,13 @@
// 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/material.dart';
Widget wsMenuItem(BuildContext context,

View File

@ -1,7 +1,7 @@
// Label StoreMAX
//
// Created by Anthony Gordon.
// Copyright © 2020 WooSignal. All rights reserved.
// 2020, WooSignal Ltd. All rights reserved.
//
// Unless required by applicable law or agreed to in writing, software
@ -73,27 +73,34 @@ Widget wsCheckoutRow(BuildContext context,
style: Theme.of(context).primaryTextTheme.body1),
padding: EdgeInsets.only(bottom: 8),
),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
leadImage,
Container(
child: Text(leadTitle,
style: Theme.of(context).primaryTextTheme.subhead,
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: false),
padding: EdgeInsets.only(left: 15),
)
],
),
Icon(Icons.arrow_forward_ios)
],
Flexible(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
leadImage,
Flexible(
child: Container(
child: Text(leadTitle,
style:
Theme.of(context).primaryTextTheme.subhead,
maxLines: 2,
overflow: TextOverflow.ellipsis,
softWrap: false),
padding: EdgeInsets.only(left: 15),
),
)
],
),
),
Icon(Icons.arrow_forward_ios)
],
),
)
],
),
@ -115,23 +122,30 @@ Widget wsTextEditingRow(BuildContext context,
{heading: String,
TextEditingController controller,
bool shouldAutoFocus,
TextInputType keyboardType}) {
TextInputType keyboardType,
bool obscureText}) {
return Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
child: Text(heading, style: Theme.of(context).primaryTextTheme.body2),
padding: EdgeInsets.only(bottom: 2),
Flexible(
child: Padding(
child:
Text(heading, style: Theme.of(context).primaryTextTheme.body2),
padding: EdgeInsets.only(bottom: 2),
),
),
TextField(
controller: controller,
style: Theme.of(context).primaryTextTheme.subhead,
keyboardType: keyboardType ?? TextInputType.text,
autocorrect: false,
autofocus: shouldAutoFocus ?? false,
textCapitalization: TextCapitalization.sentences)
Flexible(
child: TextField(
controller: controller,
style: Theme.of(context).primaryTextTheme.subhead,
keyboardType: keyboardType ?? TextInputType.text,
autocorrect: false,
autofocus: shouldAutoFocus ?? false,
obscureText: obscureText ?? false,
textCapitalization: TextCapitalization.sentences),
)
],
),
padding: EdgeInsets.all(2),
@ -385,6 +399,7 @@ Widget wsCardCartItem(BuildContext context,
void Function() actionDecrementQuantity,
void Function() actionRemoveItem}) {
return Container(
margin: EdgeInsets.only(bottom: 7),
decoration: BoxDecoration(
color: Colors.white,
border: Border(
@ -493,12 +508,13 @@ Widget storeLogo({double height, double width}) {
Widget cachedImage(image, {double height, Widget placeholder, BoxFit fit}) {
return CachedNetworkImage(
imageUrl: image,
placeholder: (context, url) =>
placeholder ?? new CircularProgressIndicator(),
errorWidget: (context, url, error) => new Icon(Icons.error),
height: height ?? null,
width: null,
alignment: Alignment.center,
fit: fit);
imageUrl: image,
placeholder: (context, url) =>
placeholder ?? new CircularProgressIndicator(),
errorWidget: (context, url, error) => new Icon(Icons.error),
height: height ?? null,
width: null,
alignment: Alignment.center,
fit: fit,
);
}

View File

@ -29,6 +29,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.5"
braintree_payment:
dependency: "direct main"
description:
name: braintree_payment
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.4"
bubble_tab_indicator:
dependency: "direct main"
description:
name: bubble_tab_indicator
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
cached_network_image:
dependency: "direct main"
description:
@ -195,7 +209,7 @@ packages:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.0+2"
version: "0.12.0+4"
http_parser:
dependency: transitive
description:
@ -217,6 +231,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.0"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1+1"
matcher:
dependency: transitive
description:
@ -287,6 +308,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
platform_alert_dialog:
dependency: "direct main"
description:
name: platform_alert_dialog
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+2"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
quiver:
dependency: transitive
description:
@ -389,7 +424,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.11"
version: "0.2.15"
transformer_page_view:
dependency: transitive
description:
@ -404,6 +439,34 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.6"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
url: "https://pub.dartlang.org"
source: hosted
version: "5.4.5"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+5"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.6"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+2"
uuid:
dependency: transitive
description:
@ -432,6 +495,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
wp_json_api:
dependency: "direct main"
description:
path: "../../wp_json_mobile_api"
relative: true
source: path
version: "0.0.2"
xml:
dependency: transitive
description:

View File

@ -25,21 +25,27 @@ environment:
dependencies:
woosignal: ^1.0.6
woosignal_stripe: ^0.0.4
wp_json_api:
path: ../../wp_json_mobile_api
shared_preferences: ^0.5.6+3
cached_network_image: ^2.0.0
page_transition: ^1.1.5
package_info: ^0.4.0+16
url_launcher: ^5.4.5
flutter_money_formatter: ^0.8.3
platform_alert_dialog: ^1.0.0+2
flutter_web_browser: ^0.11.0
dio: ^3.0.9
intl: ^0.15.8
intl: ^0.16.1
flutter_swiper: ^1.1.6
edge_alert: ^0.0.1
bubble_tab_indicator: ^0.1.4
status_alert: ^0.1.1
math_expressions: ^2.0.0
flutter_spinkit: ^4.1.2+1
flutter_launcher_icons: ^0.7.4
html: ^0.14.0+3
braintree_payment: ^1.2.4
flutter:
sdk: flutter