From 683f67877e8b25186048906524fdaab01e843b56 Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 3 Nov 2022 15:43:16 +0800 Subject: [PATCH] v6.3.0 updates --- LabelStoreMax/CHANGELOG.md | 9 + LabelStoreMax/README.md | 2 +- LabelStoreMax/lang/de.json | 3 +- LabelStoreMax/lang/en.json | 3 +- LabelStoreMax/lang/es.json | 3 +- LabelStoreMax/lang/fr.json | 2 +- LabelStoreMax/lang/hi.json | 3 +- LabelStoreMax/lang/it.json | 3 +- LabelStoreMax/lang/nl.json | 3 +- LabelStoreMax/lang/pt.json | 3 +- LabelStoreMax/lang/tr.json | 3 +- LabelStoreMax/lang/zh.json | 3 +- .../lib/app/models/billing_details.dart | 33 ++ .../lib/app/models/customer_address.dart | 61 ++ .../lib/app/models/customer_country.dart | 9 + .../lib/app/providers/app_provider.dart | 22 +- .../{ => payments}/cash_on_delivery.dart | 2 +- .../providers/{ => payments}/example_pay.dart | 14 +- .../providers/{ => payments}/paypal_pay.dart | 2 +- .../{ => payments}/razorpay_pay.dart | 56 +- .../providers/{ => payments}/stripe_pay.dart | 14 +- LabelStoreMax/lib/bootstrap/helpers.dart | 77 ++- .../lib/config/payment_gateways.dart | 8 +- .../pages/account_billing_details.dart | 234 -------- .../resources/pages/account_delete_page.dart | 64 +-- ...t_detail.dart => account_detail_page.dart} | 3 +- ...landing.dart => account_landing_page.dart} | 24 +- ...il.dart => account_order_detail_page.dart} | 0 ....dart => account_profile_update_page.dart} | 0 ...gister.dart => account_register_page.dart} | 43 +- .../pages/account_shipping_details.dart | 258 --------- .../pages/account_shipping_details_page.dart | 377 +++++++++++++ ...ategory.dart => browse_category_page.dart} | 0 ...se_search.dart => browse_search_page.dart} | 0 .../pages/{cart.dart => cart_page.dart} | 0 ...n.dart => checkout_confirmation_page.dart} | 3 +- .../lib/resources/pages/checkout_details.dart | 437 --------------- .../pages/checkout_details_page.dart | 527 ++++++++++++++++++ ...e.dart => checkout_payment_type_page.dart} | 0 ....dart => checkout_shipping_type_page.dart} | 7 +- ..._status.dart => checkout_status_page.dart} | 0 ...ries.dart => customer_countries_page.dart} | 2 +- .../pages/{home.dart => home_page.dart} | 0 ...home_search.dart => home_search_page.dart} | 0 ...t_detail.dart => product_detail_page.dart} | 0 .../account_detail_settings_widget.dart | 13 +- .../checkout_select_coupon_widget.dart | 3 +- .../checkout_store_heading_widget.dart | 24 +- .../widgets/checkout_user_details_widget.dart | 4 +- .../resources/widgets/compo_theme_widget.dart | 8 +- .../widgets/customer_address_input.dart | 17 +- .../resources/widgets/home_drawer_widget.dart | 31 +- .../resources/widgets/notic_theme_widget.dart | 8 +- LabelStoreMax/lib/routes/router.dart | 40 +- LabelStoreMax/pubspec.lock | 123 ++-- LabelStoreMax/pubspec.yaml | 22 +- 56 files changed, 1412 insertions(+), 1198 deletions(-) rename LabelStoreMax/lib/app/providers/{ => payments}/cash_on_delivery.dart (99%) rename LabelStoreMax/lib/app/providers/{ => payments}/example_pay.dart (83%) rename LabelStoreMax/lib/app/providers/{ => payments}/paypal_pay.dart (99%) rename LabelStoreMax/lib/app/providers/{ => payments}/razorpay_pay.dart (60%) rename LabelStoreMax/lib/app/providers/{ => payments}/stripe_pay.dart (89%) delete mode 100644 LabelStoreMax/lib/resources/pages/account_billing_details.dart rename LabelStoreMax/lib/resources/pages/{account_detail.dart => account_detail_page.dart} (98%) rename LabelStoreMax/lib/resources/pages/{account_landing.dart => account_landing_page.dart} (94%) rename LabelStoreMax/lib/resources/pages/{account_order_detail.dart => account_order_detail_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{account_profile_update.dart => account_profile_update_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{account_register.dart => account_register_page.dart} (89%) delete mode 100644 LabelStoreMax/lib/resources/pages/account_shipping_details.dart create mode 100644 LabelStoreMax/lib/resources/pages/account_shipping_details_page.dart rename LabelStoreMax/lib/resources/pages/{browse_category.dart => browse_category_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{browse_search.dart => browse_search_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{cart.dart => cart_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{checkout_confirmation.dart => checkout_confirmation_page.dart} (99%) delete mode 100644 LabelStoreMax/lib/resources/pages/checkout_details.dart create mode 100644 LabelStoreMax/lib/resources/pages/checkout_details_page.dart rename LabelStoreMax/lib/resources/pages/{checkout_payment_type.dart => checkout_payment_type_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{checkout_shipping_type.dart => checkout_shipping_type_page.dart} (98%) rename LabelStoreMax/lib/resources/pages/{checkout_status.dart => checkout_status_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{customer_countries.dart => customer_countries_page.dart} (99%) rename LabelStoreMax/lib/resources/pages/{home.dart => home_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{home_search.dart => home_search_page.dart} (100%) rename LabelStoreMax/lib/resources/pages/{product_detail.dart => product_detail_page.dart} (100%) diff --git a/LabelStoreMax/CHANGELOG.md b/LabelStoreMax/CHANGELOG.md index b6c25bb..b5f9074 100644 --- a/LabelStoreMax/CHANGELOG.md +++ b/LabelStoreMax/CHANGELOG.md @@ -1,3 +1,12 @@ +## [6.3.0] - 2022-11-03 + +* Ability to add Menu Links to the drawer widget through the WooSignal dashboard +* Fix wording when a shipping zone cannot be found to "Shipping is not supported for your location, sorry" +* Update account shipping widget to be uniform with the checkout shipping widget +* When logged in, the `CheckoutDetailsPage` will now populate shipping info from the users account +* Small refactor to resources/pages +* Pubspec.yaml dependency updates + ## [6.2.0] - 2022-09-23 * Migration to use Nylo v3.4.0 diff --git a/LabelStoreMax/README.md b/LabelStoreMax/README.md index 03b71bf..0235c81 100644 --- a/LabelStoreMax/README.md +++ b/LabelStoreMax/README.md @@ -4,7 +4,7 @@ # WooCommerce App: Label StoreMax -### Label StoreMax - v6.2.0 +### Label StoreMax - v6.3.0 [Official WooSignal WooCommerce App](https://woosignal.com) diff --git a/LabelStoreMax/lang/de.json b/LabelStoreMax/lang/de.json index 33b13f8..4ac1812 100644 --- a/LabelStoreMax/lang/de.json +++ b/LabelStoreMax/lang/de.json @@ -226,5 +226,6 @@ "Delete your account": "Lösche deinen Account", "Are you sure?": "Bist du dir sicher?", "Yes, delete my account": "Ja, lösche mein Konto", - "Account deleted": "Konto gelöscht" + "Account deleted": "Konto gelöscht", + "Shipping is not supported for your location, sorry": "Der Versand wird für Ihren Standort nicht unterstützt, tut mir leid" } \ No newline at end of file diff --git a/LabelStoreMax/lang/en.json b/LabelStoreMax/lang/en.json index 05e9cd3..5fa9518 100644 --- a/LabelStoreMax/lang/en.json +++ b/LabelStoreMax/lang/en.json @@ -226,5 +226,6 @@ "Delete your account": "Delete your account", "Are you sure?": "Are you sure?", "Yes, delete my account": "Yes, delete my account", - "Account deleted": "Account deleted" + "Account deleted": "Account deleted", + "Shipping is not supported for your location, sorry": "Shipping is not supported for your location, sorry" } \ No newline at end of file diff --git a/LabelStoreMax/lang/es.json b/LabelStoreMax/lang/es.json index 8483a67..a682a53 100644 --- a/LabelStoreMax/lang/es.json +++ b/LabelStoreMax/lang/es.json @@ -226,5 +226,6 @@ "Delete your account": "eliminar su cuenta", "Are you sure?": "¿Está seguro?", "Yes, delete my account": "Sí, eliminar mi cuenta", - "Account deleted": "Cuenta borrada" + "Account deleted": "Cuenta borrada", + "Shipping is not supported for your location, sorry": "El envío no es compatible para su ubicación, lo siento" } \ No newline at end of file diff --git a/LabelStoreMax/lang/fr.json b/LabelStoreMax/lang/fr.json index 49d65f5..75696c0 100644 --- a/LabelStoreMax/lang/fr.json +++ b/LabelStoreMax/lang/fr.json @@ -227,5 +227,5 @@ "Are you sure?": "Êtes-vous sûr?", "Yes, delete my account": "Oui, supprimer mon compte", "Account deleted": "Compte supprimé", - "Phone Number": "Numéro de téléphone" + "Shipping is not supported for your location, sorry": "L'expédition n'est pas prise en charge pour votre emplacement, désolé" } \ No newline at end of file diff --git a/LabelStoreMax/lang/hi.json b/LabelStoreMax/lang/hi.json index e3b5a8b..39de5c5 100644 --- a/LabelStoreMax/lang/hi.json +++ b/LabelStoreMax/lang/hi.json @@ -226,5 +226,6 @@ "Delete your account": "apane khaate ko nasht karo", "Are you sure?": "kya aapako yakeen hai?", "Yes, delete my account": "haan, mera akaunt dileet kar do", - "Account deleted": "khaata hataaya gaya" + "Account deleted": "khaata hataaya gaya", + "Shipping is not supported for your location, sorry": "aapake sthaan ke lie shiping samarthit nahin hai, kshama karen" } \ No newline at end of file diff --git a/LabelStoreMax/lang/it.json b/LabelStoreMax/lang/it.json index 3f5a77b..1eac0eb 100644 --- a/LabelStoreMax/lang/it.json +++ b/LabelStoreMax/lang/it.json @@ -226,5 +226,6 @@ "Delete your account": "cancella il tuo account", "Are you sure?": "Sei sicuro?", "Yes, delete my account": "Sì, elimina il mio account", - "Account deleted": "Account cancellato" + "Account deleted": "Account cancellato", + "Shipping is not supported for your location, sorry": "La spedizione non è supportata per la tua posizione, mi dispiace" } \ No newline at end of file diff --git a/LabelStoreMax/lang/nl.json b/LabelStoreMax/lang/nl.json index f37d041..bb58665 100644 --- a/LabelStoreMax/lang/nl.json +++ b/LabelStoreMax/lang/nl.json @@ -226,5 +226,6 @@ "Delete your account": "Verwijder je account", "Are you sure?": "Weet je het zeker?", "Yes, delete my account": "Ja, verwijder mijn account", - "Account deleted": "Account verwijderd" + "Account deleted": "Account verwijderd", + "Shipping is not supported for your location, sorry": "Verzending wordt niet ondersteund voor uw locatie, sorry" } \ No newline at end of file diff --git a/LabelStoreMax/lang/pt.json b/LabelStoreMax/lang/pt.json index e29db87..577d4fd 100644 --- a/LabelStoreMax/lang/pt.json +++ b/LabelStoreMax/lang/pt.json @@ -226,5 +226,6 @@ "Delete your account": "Deletar sua conta", "Are you sure?": "Tem certeza?", "Yes, delete my account": "Sim, excluir minha conta", - "Account deleted": "Conta excluída" + "Account deleted": "Conta excluída", + "Shipping is not supported for your location, sorry": "O envio não é suportado para a sua localização, desculpe" } \ No newline at end of file diff --git a/LabelStoreMax/lang/tr.json b/LabelStoreMax/lang/tr.json index 3137620..c2f13fc 100644 --- a/LabelStoreMax/lang/tr.json +++ b/LabelStoreMax/lang/tr.json @@ -226,5 +226,6 @@ "Delete your account": "Hesabını sil", "Are you sure?": "Emin misin?", "Yes, delete my account": "Evet, hesabımı sil", - "Account deleted": "Hesap silindi" + "Account deleted": "Hesap silindi", + "Shipping is not supported for your location, sorry": "Bulunduğunuz yer için gönderim desteklenmiyor, üzgünüm" } \ No newline at end of file diff --git a/LabelStoreMax/lang/zh.json b/LabelStoreMax/lang/zh.json index 0037f33..40e5dc7 100644 --- a/LabelStoreMax/lang/zh.json +++ b/LabelStoreMax/lang/zh.json @@ -226,5 +226,6 @@ "Delete your account": "删除您的帐户", "Are you sure?": "你确定吗?", "Yes, delete my account": "是的,删除我的帐户", - "Account deleted": "帐号已删除" + "Account deleted": "帐号已删除", + "Shipping is not supported for your location, sorry": "您所在的位置不支持送货,抱歉" } \ No newline at end of file diff --git a/LabelStoreMax/lib/app/models/billing_details.dart b/LabelStoreMax/lib/app/models/billing_details.dart index 66f2d84..f21f781 100644 --- a/LabelStoreMax/lib/app/models/billing_details.dart +++ b/LabelStoreMax/lib/app/models/billing_details.dart @@ -15,8 +15,41 @@ class BillingDetails { CustomerAddress? shippingAddress; bool? rememberDetails; + BillingDetails(); + void initSession() { billingAddress = CustomerAddress(); shippingAddress = CustomerAddress(); } + + Map getShippingAddressStripe() => { + "name": shippingAddress?.nameFull(), + "line1": shippingAddress!.addressLine, + "city": shippingAddress!.city, + "postal_code": shippingAddress!.postalCode, + "country": (shippingAddress?.customerCountry?.name ?? "") + }; + + fromWpMeta(Map data) async { + final Map shippingDetailsWpMeta = {}, + billingDetailsWpMeta = {}; + + shippingDetailsWpMeta.addEntries(data.entries + .where((element) => element.key.startsWith("shipping_")) + .map((shippingMeta) => MapEntry( + shippingMeta.key.replaceAll("shipping_", ""), shippingMeta.value))); + billingDetailsWpMeta.addEntries(data.entries + .where((element) => element.key.startsWith("billing_")) + .map((billingMeta) => MapEntry( + billingMeta.key.replaceAll("billing_", ""), billingMeta.value))); + + CustomerAddress billingCustomerAddress = CustomerAddress(); + await billingCustomerAddress.fromWpMetaData(billingDetailsWpMeta); + + CustomerAddress shippingCustomerAddress = CustomerAddress(); + await shippingCustomerAddress.fromWpMetaData(shippingDetailsWpMeta); + + billingAddress = billingCustomerAddress; + shippingAddress = shippingCustomerAddress; + } } diff --git a/LabelStoreMax/lib/app/models/customer_address.dart b/LabelStoreMax/lib/app/models/customer_address.dart index c97ab94..4d1aca1 100644 --- a/LabelStoreMax/lib/app/models/customer_address.dart +++ b/LabelStoreMax/lib/app/models/customer_address.dart @@ -9,6 +9,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import 'package:flutter_app/app/models/customer_country.dart'; +import 'package:flutter_app/app/models/default_shipping.dart'; +import 'package:flutter_app/bootstrap/helpers.dart'; +import 'package:wp_json_api/models/wp_meta_meta.dart'; class CustomerAddress { String? firstName; @@ -114,4 +117,62 @@ class CustomerAddress { } return data; } + + fromWpMetaData(Map data) async { + if (data.containsKey('first_name')) { + firstName = data['first_name']; + } + + if (data.containsKey('last_name')) { + lastName = data['last_name']; + } + + if (data.containsKey('address_1')) { + addressLine = data['address_1']; + } + + if (data.containsKey('city')) { + city = data['city']; + } + + if (data.containsKey('postcode')) { + postalCode = data['postcode']; + } + + if (data.containsKey('email')) { + emailAddress = data['email']; + } + + if (data.containsKey('phone')) { + phoneNumber = data['phone']; + } + + if (data.containsKey('country')) { + DefaultShipping? defaultShipping = + await findCountryMetaForShipping(data['country']); + if (defaultShipping == null) { + return; + } + customerCountry = CustomerCountry.fromWpMeta(data, defaultShipping); + } + } + + List toUserMetaDataItem(String type) { + return [ + UserMetaDataItem(key: "${type}_first_name", value: firstName), + UserMetaDataItem(key: "${type}_last_name", value: lastName), + UserMetaDataItem(key: "${type}_address_1", value: addressLine), + UserMetaDataItem(key: "${type}_city", value: city), + UserMetaDataItem(key: "${type}_postcode", value: postalCode), + UserMetaDataItem(key: "${type}_phone", value: phoneNumber), + if (type != "shipping") + UserMetaDataItem(key: "${type}_email", value: emailAddress), + UserMetaDataItem( + key: "${type}_country", value: customerCountry?.countryCode), + UserMetaDataItem( + key: "${type}_state", + value: customerCountry?.state?.code + ?.replaceAll("${customerCountry?.countryCode}:", "")), + ]; + } } diff --git a/LabelStoreMax/lib/app/models/customer_country.dart b/LabelStoreMax/lib/app/models/customer_country.dart index c40557b..427897a 100644 --- a/LabelStoreMax/lib/app/models/customer_country.dart +++ b/LabelStoreMax/lib/app/models/customer_country.dart @@ -9,6 +9,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. import 'package:flutter_app/app/models/default_shipping.dart'; +import 'package:flutter_app/bootstrap/helpers.dart'; class CustomerCountry { String? countryCode; @@ -26,6 +27,14 @@ class CustomerCountry { } } + CustomerCountry.fromWpMeta( + Map json, DefaultShipping defaultShipping) { + countryCode = json['country']; + name = defaultShipping.country; + state = findDefaultShippingStateByCode( + defaultShipping, "${json['country']}:${json['state']}"); + } + CustomerCountry.fromJson(Map? json) { if (json == null) { return; diff --git a/LabelStoreMax/lib/app/providers/app_provider.dart b/LabelStoreMax/lib/app/providers/app_provider.dart index d7c9275..0ec02c9 100644 --- a/LabelStoreMax/lib/app/providers/app_provider.dart +++ b/LabelStoreMax/lib/app/providers/app_provider.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_app/bootstrap/app_helper.dart'; @@ -37,8 +39,10 @@ class AppProvider implements NyProvider { /// ); /// /// if (settings.authorizationStatus == AuthorizationStatus.authorized) { - /// String token = await messaging.getToken(); - /// WooSignal.instance.setFcmToken(token); + /// String? token = await messaging.getToken(); + /// if (token != null) { + /// WooSignal.instance.setFcmToken(token); + /// } /// } AppHelper.instance.appConfig = WooSignalApp(); @@ -70,10 +74,20 @@ class AppProvider implements NyProvider { AppHelper.instance.appConfig = wooSignalApp; if (wooSignalApp.wpLoginEnabled == 1) { + if (wooSignalApp.wpLoginBaseUrl == null) { + AppHelper.instance.appConfig?.wpLoginEnabled = 0; + log('Set your stores domain on WooSignal. Go to Features > WP Login and add your domain to "Store Base Url"'); + } + + if (wooSignalApp.wpLoginWpApiPath == null) { + AppHelper.instance.appConfig?.wpLoginEnabled = 0; + log('Set your stores Wp JSON path on WooSignal. Go to Features > WP Login and add your Wp JSON path to "WP API Path"'); + } + WPJsonAPI.instance.initWith( - baseUrl: wooSignalApp.wpLoginBaseUrl!, + baseUrl: wooSignalApp.wpLoginBaseUrl ?? "", shouldDebug: getEnv('APP_DEBUG'), - wpJsonPath: wooSignalApp.wpLoginWpApiPath!, + wpJsonPath: wooSignalApp.wpLoginWpApiPath ?? "", ); } diff --git a/LabelStoreMax/lib/app/providers/cash_on_delivery.dart b/LabelStoreMax/lib/app/providers/payments/cash_on_delivery.dart similarity index 99% rename from LabelStoreMax/lib/app/providers/cash_on_delivery.dart rename to LabelStoreMax/lib/app/providers/payments/cash_on_delivery.dart index 18f0a58..3314f91 100644 --- a/LabelStoreMax/lib/app/providers/cash_on_delivery.dart +++ b/LabelStoreMax/lib/app/providers/payments/cash_on_delivery.dart @@ -14,7 +14,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_app/bootstrap/data/order_wc.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; import 'package:nylo_framework/nylo_framework.dart'; import 'package:woosignal/models/payload/order_wc.dart'; import 'package:woosignal/models/response/order.dart'; diff --git a/LabelStoreMax/lib/app/providers/example_pay.dart b/LabelStoreMax/lib/app/providers/payments/example_pay.dart similarity index 83% rename from LabelStoreMax/lib/app/providers/example_pay.dart rename to LabelStoreMax/lib/app/providers/payments/example_pay.dart index 61c81a2..ba45722 100644 --- a/LabelStoreMax/lib/app/providers/example_pay.dart +++ b/LabelStoreMax/lib/app/providers/payments/example_pay.dart @@ -14,7 +14,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_app/bootstrap/data/order_wc.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; import 'package:nylo_framework/nylo_framework.dart'; import 'package:woosignal/models/payload/order_wc.dart'; import 'package:woosignal/models/response/order.dart'; @@ -29,8 +29,16 @@ import 'package:woosignal/models/response/tax_rate.dart'; // // }); -// REMEMBER TO ADD THIS METHOD E.G. "examplePay" TO THE APP_PAYMENT_METHODS -// AS THE PAY METHOD +// TO USE A PAYMENT GATEWAY, FIRST OPEN /config/payment_gateways.dart. +// THEN ADD A NEW PAYMENT LIKE IN THE BELOW EXAMPLE +// +// addPayment( +// id: 6, +// name: "My Payment", +// description: trans("Debit or Credit Card"), +// assetImage: "payment_logo.png", E.g. /public/assets/images/payment_logo.png +// pay: examplePay, +// ), examplePay(context, {required CheckoutConfirmationPageState state, TaxRate? taxRate}) async { diff --git a/LabelStoreMax/lib/app/providers/paypal_pay.dart b/LabelStoreMax/lib/app/providers/payments/paypal_pay.dart similarity index 99% rename from LabelStoreMax/lib/app/providers/paypal_pay.dart rename to LabelStoreMax/lib/app/providers/payments/paypal_pay.dart index 57664e8..bb62299 100644 --- a/LabelStoreMax/lib/app/providers/paypal_pay.dart +++ b/LabelStoreMax/lib/app/providers/payments/paypal_pay.dart @@ -15,7 +15,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/app/models/cart_line_item.dart'; import 'package:flutter_app/bootstrap/data/order_wc.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; import 'package:flutter_app/resources/widgets/checkout_paypal.dart'; import 'package:nylo_framework/nylo_framework.dart'; import 'package:woosignal/models/payload/order_wc.dart'; diff --git a/LabelStoreMax/lib/app/providers/razorpay_pay.dart b/LabelStoreMax/lib/app/providers/payments/razorpay_pay.dart similarity index 60% rename from LabelStoreMax/lib/app/providers/razorpay_pay.dart rename to LabelStoreMax/lib/app/providers/payments/razorpay_pay.dart index 6059810..00af414 100644 --- a/LabelStoreMax/lib/app/providers/razorpay_pay.dart +++ b/LabelStoreMax/lib/app/providers/payments/razorpay_pay.dart @@ -15,7 +15,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/bootstrap/data/order_wc.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; import 'package:nylo_framework/nylo_framework.dart'; import 'package:razorpay_flutter/razorpay_flutter.dart'; import 'package:woosignal/models/response/tax_rate.dart'; @@ -24,36 +24,36 @@ import 'package:woosignal/models/response/order.dart'; razorPay(context, {required CheckoutConfirmationPageState state, TaxRate? taxRate}) async { - Razorpay razorpay = Razorpay(); + Razorpay razorpay = Razorpay(); - razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, - (PaymentSuccessResponse response) async { - OrderWC orderWC = await buildOrderWC(taxRate: taxRate); + razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, + (PaymentSuccessResponse response) async { + OrderWC orderWC = await buildOrderWC(taxRate: taxRate); - Order? order = await appWooSignal((api) => api.createOrder(orderWC)); + Order? order = await appWooSignal((api) => api.createOrder(orderWC)); - if (order != null) { - Cart.getInstance.clear(); - Navigator.pushNamed(context, "/checkout-status", arguments: order); - } else { - showToastNotification( - context, - title: "Error".tr(), - description: trans("Something went wrong, please contact our store"), - ); - state.reloadState(showLoader: false); - } - }); + if (order != null) { + Cart.getInstance.clear(); + Navigator.pushNamed(context, "/checkout-status", arguments: order); + } else { + showToastNotification( + context, + title: "Error".tr(), + description: trans("Something went wrong, please contact our store"), + ); + state.reloadState(showLoader: false); + } + }); - razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) { - showToastNotification(context, - title: trans("Error"), - description: response.message ?? "", - style: ToastNotificationStyleType.WARNING); - state.reloadState(showLoader: false); - }); + razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) { + showToastNotification(context, + title: trans("Error"), + description: response.message ?? "", + style: ToastNotificationStyleType.WARNING); + state.reloadState(showLoader: false); + }); - razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); + razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); // CHECKOUT HELPER await checkout(taxRate, (total, billingDetails, cart) async { @@ -74,8 +74,8 @@ razorPay(context, state.reloadState(showLoader: true); - razorpay.open(options); + razorpay.open(options); }); } -void _handleExternalWallet(ExternalWalletResponse response) {} \ No newline at end of file +void _handleExternalWallet(ExternalWalletResponse response) {} diff --git a/LabelStoreMax/lib/app/providers/stripe_pay.dart b/LabelStoreMax/lib/app/providers/payments/stripe_pay.dart similarity index 89% rename from LabelStoreMax/lib/app/providers/stripe_pay.dart rename to LabelStoreMax/lib/app/providers/payments/stripe_pay.dart index 6abf3ac..6e2ff16 100644 --- a/LabelStoreMax/lib/app/providers/stripe_pay.dart +++ b/LabelStoreMax/lib/app/providers/payments/stripe_pay.dart @@ -15,7 +15,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/data/order_wc.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; import 'package:flutter_stripe/flutter_stripe.dart'; import 'package:nylo_framework/nylo_framework.dart'; import 'package:woosignal/models/payload/order_wc.dart'; @@ -50,21 +50,13 @@ stripePay(context, dynamic rsp = {}; // // CHECKOUT HELPER await checkout(taxRate, (total, billingDetails, cart) async { - Map address = { - "name": billingDetails!.billingAddress?.nameFull(), - "line1": billingDetails.shippingAddress!.addressLine, - "city": billingDetails.shippingAddress!.city, - "postal_code": billingDetails.shippingAddress!.postalCode, - "country": (billingDetails.shippingAddress?.customerCountry?.name ?? "") - }; - String cartShortDesc = await cart.cartShortDesc(); rsp = await appWooSignal((api) => api.stripePaymentIntent( amount: total, - email: billingDetails.billingAddress?.emailAddress, + email: billingDetails?.billingAddress?.emailAddress, desc: cartShortDesc, - shipping: address, + shipping: billingDetails?.getShippingAddressStripe(), )); }); diff --git a/LabelStoreMax/lib/bootstrap/helpers.dart b/LabelStoreMax/lib/bootstrap/helpers.dart index 716095e..6cea2ab 100644 --- a/LabelStoreMax/lib/bootstrap/helpers.dart +++ b/LabelStoreMax/lib/bootstrap/helpers.dart @@ -40,7 +40,9 @@ import 'package:status_alert/status_alert.dart'; import 'package:woosignal/models/response/products.dart'; import 'package:woosignal/models/response/tax_rate.dart'; import 'package:woosignal/woosignal.dart'; +import 'package:wp_json_api/models/responses/wp_user_info_response.dart'; import '../resources/themes/styles/color_styles.dart'; +import 'package:flutter/services.dart' show rootBundle; Future getUser() async => (await (NyStorage.read(SharedKey.authUser, model: User()))); @@ -498,9 +500,8 @@ class UserAuth { String redirect = "/home"; } -Future> getDefaultShipping(BuildContext context) async { - String data = await DefaultAssetBundle.of(context) - .loadString("public/assets/json/default_shipping.json"); +Future> getDefaultShipping() async { + String data = await rootBundle.loadString('public/assets/json/default_shipping.json'); dynamic dataJson = json.decode(data); List shipping = []; @@ -518,6 +519,37 @@ Future> getDefaultShipping(BuildContext context) async { return shipping; } +Future findCountryMetaForShipping(String countryCode) async { + List defaultShipping = await getDefaultShipping(); + List shippingByCountryCode = defaultShipping.where((element) => element.code == countryCode).toList(); + if (shippingByCountryCode.isNotEmpty) { + return shippingByCountryCode.first; + } + return null; +} + +DefaultShippingState? findDefaultShippingStateByCode(DefaultShipping defaultShipping, String code) { + List defaultShippingStates = defaultShipping.states.where((state) => state.code == code).toList(); + if (defaultShippingStates.isEmpty) { + return null; + } + DefaultShippingState defaultShippingState = defaultShippingStates.first; + return DefaultShippingState(code: defaultShippingState.code, name: defaultShippingState.name); +} + +bool hasKeyInMeta(WPUserInfoResponse wpUserInfoResponse, String key) { + return (wpUserInfoResponse.data!.metaData ?? []).where((meta) => meta.key == key).toList().isNotEmpty; +} + +String fetchValueInMeta(WPUserInfoResponse wpUserInfoResponse, String key) { + String value = ""; + List? metaDataValue = (wpUserInfoResponse.data!.metaData ?? []).where((meta) => meta.key == key).first.value; + if (metaDataValue != null && metaDataValue.isNotEmpty) { + return metaDataValue.first ?? ""; + } + return value; +} + String truncateString(String data, int length) { return (data.length >= length) ? '${data.substring(0, length)}...' : data; } @@ -560,6 +592,45 @@ removeWishlistProduct({required Product? product}) async { await NyStorage.store(SharedKey.wishlistProducts, json); } +Future billingDetailsFromWpUserInfoResponse(wpUserInfoResponse) async { + List metaDataAddress = [ + 'billing_first_name', + 'billing_last_name', + 'billing_company', + 'billing_address_1', + 'billing_address_2', + 'billing_city', + 'billing_postcode', + 'billing_country', + 'billing_state', + 'billing_phone', + 'billing_email', + 'shipping_first_name', + 'shipping_last_name', + 'shipping_company', + 'shipping_address_1', + 'shipping_address_2', + 'shipping_city', + 'shipping_postcode', + 'shipping_country', + 'shipping_state', + 'shipping_phone', + ]; + + Map metaData = {}; + + for (var dataKey in metaDataAddress) { + if (hasKeyInMeta(wpUserInfoResponse, dataKey)) { + String value = fetchValueInMeta(wpUserInfoResponse, dataKey); + metaData.addAll({dataKey: value}); + } + } + + BillingDetails billingDetails = BillingDetails(); + await billingDetails.fromWpMeta(metaData); + return billingDetails; +} + /// API helper api(dynamic Function(T) request, {BuildContext? context}) async => await nyApi( diff --git a/LabelStoreMax/lib/config/payment_gateways.dart b/LabelStoreMax/lib/config/payment_gateways.dart index a21d067..661ffde 100644 --- a/LabelStoreMax/lib/config/payment_gateways.dart +++ b/LabelStoreMax/lib/config/payment_gateways.dart @@ -1,8 +1,8 @@ import 'package:flutter_app/app/models/payment_type.dart'; -import 'package:flutter_app/app/providers/cash_on_delivery.dart'; -import 'package:flutter_app/app/providers/paypal_pay.dart'; -import 'package:flutter_app/app/providers/razorpay_pay.dart'; -import 'package:flutter_app/app/providers/stripe_pay.dart'; +import 'package:flutter_app/app/providers/payments/cash_on_delivery.dart'; +import 'package:flutter_app/app/providers/payments/paypal_pay.dart'; +import 'package:flutter_app/app/providers/payments/razorpay_pay.dart'; +import 'package:flutter_app/app/providers/payments/stripe_pay.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:nylo_framework/nylo_framework.dart'; diff --git a/LabelStoreMax/lib/resources/pages/account_billing_details.dart b/LabelStoreMax/lib/resources/pages/account_billing_details.dart deleted file mode 100644 index 2f1b2e8..0000000 --- a/LabelStoreMax/lib/resources/pages/account_billing_details.dart +++ /dev/null @@ -1,234 +0,0 @@ -// Label StoreMax -// -// Created by Anthony Gordon. -// 2022, 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:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; -import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; -import 'package:flutter_app/resources/widgets/buttons.dart'; -import 'package:flutter_app/resources/widgets/safearea_widget.dart'; -import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; -import 'package:nylo_framework/nylo_framework.dart'; -import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; -import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart'; -import 'package:wp_json_api/wp_json_api.dart'; - -class AccountBillingDetailsPage extends StatefulWidget { - AccountBillingDetailsPage(); - - @override - _AccountBillingDetailsPageState createState() => - _AccountBillingDetailsPageState(); -} - -class _AccountBillingDetailsPageState extends State { - _AccountBillingDetailsPageState(); - - // BILLING TEXT CONTROLLERS - final TextEditingController _txtShippingFirstName = TextEditingController(), - _txtShippingLastName = TextEditingController(), - _txtShippingAddressLine = TextEditingController(), - _txtShippingCity = TextEditingController(), - _txtShippingState = TextEditingController(), - _txtShippingPostalCode = TextEditingController(), - _txtShippingCountry = TextEditingController(); - - bool _isLoading = true, _isUpdating = false; - - @override - void initState() { - super.initState(); - _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( - resizeToAvoidBottomInset: false, - appBar: AppBar( - title: Text(trans("Billing Details")), - centerTitle: true, - ), - body: SafeAreaWidget( - child: GestureDetector( - onTap: () => FocusScope.of(context).requestFocus(FocusNode()), - child: _isLoading - ? AppLoaderWidget() - : LayoutBuilder( - builder: (context, constraints) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Row( - children: [ - Flexible( - child: TextEditingRow( - heading: trans("First Name"), - controller: _txtShippingFirstName, - shouldAutoFocus: true, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("Last Name"), - controller: _txtShippingLastName, - ), - ), - ], - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - ), - TextEditingRow( - heading: trans("Address Line"), - controller: _txtShippingAddressLine, - ), - Row(children: [ - Flexible( - child: TextEditingRow( - heading: trans("City"), - controller: _txtShippingCity, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("State"), - keyboardType: TextInputType.emailAddress, - controller: _txtShippingState), - ), - ]), - Row( - children: [ - Flexible( - child: TextEditingRow( - heading: trans("Postal code"), - controller: _txtShippingPostalCode, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("Country"), - keyboardType: TextInputType.emailAddress, - controller: _txtShippingCountry, - ), - ), - ], - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - ) - ], - ), - decoration: BoxDecoration( - color: ThemeColor.get(context).surfaceBackground, - borderRadius: BorderRadius.circular(10), - boxShadow: (Theme.of(context).brightness == - Brightness.light) - ? wsBoxShadow() - : null, - ), - padding: EdgeInsets.all(8), - ), - height: - (constraints.maxHeight - constraints.minHeight) * - 0.6, - ), - Column( - children: [ - PrimaryButton( - title: trans("UPDATE DETAILS"), - isLoading: _isUpdating, - action: _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; - try { - wcCustomerUpdatedResponse = await WPJsonAPI.instance.api((request) => - request.wcUpdateCustomerInfo(userToken, - billingFirstName: firstName, - billingLastName: lastName, - billingAddress1: addressLine, - billingCity: city, - billingState: state, - billingPostcode: postalCode, - billingCountry: country)); - } on Exception catch (_) { - showToastNotification(context, - title: trans("Oops!"), - description: trans("Something went wrong"), - style: ToastNotificationStyleType.DANGER); - } finally { - setState(() { - _isUpdating = false; - }); - } - - if (wcCustomerUpdatedResponse != null && - wcCustomerUpdatedResponse.status == 200) { - showToastNotification(context, - title: trans("Success"), - description: trans("Account updated"), - style: ToastNotificationStyleType.SUCCESS); - Navigator.pop(context); - } - } -} diff --git a/LabelStoreMax/lib/resources/pages/account_delete_page.dart b/LabelStoreMax/lib/resources/pages/account_delete_page.dart index c0e8414..e637279 100644 --- a/LabelStoreMax/lib/resources/pages/account_delete_page.dart +++ b/LabelStoreMax/lib/resources/pages/account_delete_page.dart @@ -8,17 +8,14 @@ import 'package:wp_json_api/wp_json_api.dart'; class AccountDeletePage extends StatefulWidget { AccountDeletePage({Key? key}) : super(key: key); - + @override _AccountDeletePageState createState() => _AccountDeletePageState(); } class _AccountDeletePageState extends NyState { - @override - init() async { - - } + init() async {} @override void dispose() { @@ -33,33 +30,39 @@ class _AccountDeletePageState extends NyState { ), body: SafeAreaWidget( child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.no_accounts_rounded, size: 50), + Text( + trans("Delete your account"), + style: textTheme.headline3, + ), + Padding( + padding: const EdgeInsets.only(top: 18), + child: Text(trans("Are you sure?")), + ), + ], + ), + ), + Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.no_accounts_rounded, size: 50), - Text(trans("Delete your account"), style: textTheme.headline3,), - Padding( - padding: const EdgeInsets.only(top: 18), - child: Text(trans("Are you sure?")), - ), - ],), - ), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - PrimaryButton(title: trans("Yes, delete my account"), isLoading: isLocked('delete_account'), action: _deleteAccount), - LinkButton(title: trans("Back"), action: pop) - ], - ) + PrimaryButton( + title: trans("Yes, delete my account"), + isLoading: isLocked('delete_account'), + action: _deleteAccount), + LinkButton(title: trans("Back"), action: pop) ], ) - ), + ], + )), ); } @@ -70,9 +73,7 @@ class _AccountDeletePageState extends NyState { WPUserDeleteResponse? wpUserDeleteResponse; try { wpUserDeleteResponse = await WPJsonAPI.instance - .api((request) => request.wpUserDelete( - userToken - )); + .api((request) => request.wpUserDelete(userToken)); } on Exception catch (e) { NyLogger.error(e.toString()); showToastNotification( @@ -84,7 +85,8 @@ class _AccountDeletePageState extends NyState { } if (wpUserDeleteResponse != null) { - showToast(title: trans("Success"), description: trans("Account deleted")); + showToast( + title: trans("Success"), description: trans("Account deleted")); await authLogout(context); } }); diff --git a/LabelStoreMax/lib/resources/pages/account_detail.dart b/LabelStoreMax/lib/resources/pages/account_detail_page.dart similarity index 98% rename from LabelStoreMax/lib/resources/pages/account_detail.dart rename to LabelStoreMax/lib/resources/pages/account_detail_page.dart index 36b00db..5c9f0ee 100644 --- a/LabelStoreMax/lib/resources/pages/account_detail.dart +++ b/LabelStoreMax/lib/resources/pages/account_detail_page.dart @@ -156,8 +156,7 @@ class _AccountDetailPageState extends State child: Padding( child: Text( [userFirstName, userLastName] - .where( - (t) => (t != null || t != "")) + .where((t) => (t != null || t != "")) .toList() .join(" "), style: TextStyle( diff --git a/LabelStoreMax/lib/resources/pages/account_landing.dart b/LabelStoreMax/lib/resources/pages/account_landing_page.dart similarity index 94% rename from LabelStoreMax/lib/resources/pages/account_landing.dart rename to LabelStoreMax/lib/resources/pages/account_landing_page.dart index bfe26c4..9794d5d 100644 --- a/LabelStoreMax/lib/resources/pages/account_landing.dart +++ b/LabelStoreMax/lib/resources/pages/account_landing_page.dart @@ -32,7 +32,6 @@ class AccountLandingPage extends StatefulWidget { } class _AccountLandingPageState extends NyState { - final TextEditingController _tfEmailController = TextEditingController(), _tfPasswordController = TextEditingController(); @@ -226,19 +225,18 @@ class _AccountLandingPageState extends NyState { if (wpUserLoginResponse.status != 200) { return; } - String? token = wpUserLoginResponse.data!.userToken; - String userId = wpUserLoginResponse.data!.userId.toString(); - User user = User.fromUserAuthResponse(token: token, userId: userId); - await user.save(SharedKey.authUser); - - showToastNotification(context, - title: trans("Hello"), - description: trans("Welcome back"), - style: ToastNotificationStyleType.SUCCESS, - icon: Icons.account_circle); - navigatorPush(context, - routeName: UserAuth.instance.redirect, forgetLast: 1); + String? token = wpUserLoginResponse.data!.userToken; + String userId = wpUserLoginResponse.data!.userId.toString(); + User user = User.fromUserAuthResponse(token: token, userId: userId); + await user.save(SharedKey.authUser); + showToastNotification(context, + title: trans("Hello"), + description: trans("Welcome back"), + style: ToastNotificationStyleType.SUCCESS, + icon: Icons.account_circle); + navigatorPush(context, + routeName: UserAuth.instance.redirect, forgetLast: 1); }); } } diff --git a/LabelStoreMax/lib/resources/pages/account_order_detail.dart b/LabelStoreMax/lib/resources/pages/account_order_detail_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/account_order_detail.dart rename to LabelStoreMax/lib/resources/pages/account_order_detail_page.dart diff --git a/LabelStoreMax/lib/resources/pages/account_profile_update.dart b/LabelStoreMax/lib/resources/pages/account_profile_update_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/account_profile_update.dart rename to LabelStoreMax/lib/resources/pages/account_profile_update_page.dart diff --git a/LabelStoreMax/lib/resources/pages/account_register.dart b/LabelStoreMax/lib/resources/pages/account_register_page.dart similarity index 89% rename from LabelStoreMax/lib/resources/pages/account_register.dart rename to LabelStoreMax/lib/resources/pages/account_register_page.dart index d39b14b..48d0c35 100644 --- a/LabelStoreMax/lib/resources/pages/account_register.dart +++ b/LabelStoreMax/lib/resources/pages/account_register_page.dart @@ -114,7 +114,8 @@ class _AccountRegistrationPageState extends NyState { child: InkWell( child: RichText( text: TextSpan( - text: '${trans("By tapping \"Register\" you agree to ")} ${AppHelper.instance.appConfig!.appName!}\'s ', + text: + '${trans("By tapping \"Register\" you agree to ")} ${AppHelper.instance.appConfig!.appName!}\'s ', children: [ TextSpan( text: trans("terms and conditions"), @@ -175,16 +176,20 @@ class _AccountRegistrationPageState extends NyState { WPUserRegisterResponse? wpUserRegisterResponse; try { wpUserRegisterResponse = await WPJsonAPI.instance.api( - (request) => request.wpRegister( + (request) => request.wpRegister( email: email.toLowerCase(), password: password, username: username, ), ); - + if (wpUserRegisterResponse?.data?.userToken != null) { - await WPJsonAPI.instance.api((request) => request.wpUserAddRole(wpUserRegisterResponse!.data!.userToken, role: "customer")); - await WPJsonAPI.instance.api((request) => request.wpUserRemoveRole(wpUserRegisterResponse!.data!.userToken, role: "subscriber")); + await WPJsonAPI.instance.api((request) => request.wpUserAddRole( + wpUserRegisterResponse!.data!.userToken, + role: "customer")); + await WPJsonAPI.instance.api((request) => request.wpUserRemoveRole( + wpUserRegisterResponse!.data!.userToken, + role: "subscriber")); } } on UsernameTakenException catch (e) { showToastNotification(context, @@ -195,7 +200,7 @@ class _AccountRegistrationPageState extends NyState { showToastNotification(context, title: trans("Invalid details"), description: - trans("Something went wrong, please contact our store"), + trans("Something went wrong, please contact our store"), style: ToastNotificationStyleType.DANGER); } on ExistingUserLoginException catch (_) { showToastNotification(context, @@ -233,21 +238,21 @@ class _AccountRegistrationPageState extends NyState { } // Save user to shared preferences - String? token = wpUserRegisterResponse.data!.userToken; - String userId = wpUserRegisterResponse.data!.userId.toString(); - User user = User.fromUserAuthResponse(token: token, userId: userId); - await user.save(SharedKey.authUser); + String? token = wpUserRegisterResponse.data!.userToken; + String userId = wpUserRegisterResponse.data!.userId.toString(); + User user = User.fromUserAuthResponse(token: token, userId: userId); + await user.save(SharedKey.authUser); - await WPJsonAPI.instance.api((request) => request - .wpUpdateUserInfo(token, firstName: firstName, lastName: lastName)); + await WPJsonAPI.instance.api((request) => request.wpUpdateUserInfo(token, + firstName: firstName, lastName: lastName)); - showToastNotification(context, - title: "${trans("Hello")} $firstName", - description: trans("you're now logged in"), - style: ToastNotificationStyleType.SUCCESS, - icon: Icons.account_circle); - navigatorPush(context, - routeName: UserAuth.instance.redirect, forgetLast: 2); + showToastNotification(context, + title: "${trans("Hello")} $firstName", + description: trans("you're now logged in"), + style: ToastNotificationStyleType.SUCCESS, + icon: Icons.account_circle); + navigatorPush(context, + routeName: UserAuth.instance.redirect, forgetLast: 2); }); } diff --git a/LabelStoreMax/lib/resources/pages/account_shipping_details.dart b/LabelStoreMax/lib/resources/pages/account_shipping_details.dart deleted file mode 100644 index 0fe5d97..0000000 --- a/LabelStoreMax/lib/resources/pages/account_shipping_details.dart +++ /dev/null @@ -1,258 +0,0 @@ -// Label StoreMax -// -// Created by Anthony Gordon. -// 2022, 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:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; -import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; -import 'package:flutter_app/resources/widgets/buttons.dart'; -import 'package:flutter_app/resources/widgets/safearea_widget.dart'; -import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; -import 'package:nylo_framework/nylo_framework.dart'; -import 'package:wp_json_api/models/responses/wc_customer_info_response.dart'; -import 'package:wp_json_api/models/responses/wc_customer_updated_response.dart'; -import 'package:wp_json_api/wp_json_api.dart'; - -class AccountShippingDetailsPage extends StatefulWidget { - AccountShippingDetailsPage(); - - @override - _AccountShippingDetailsPageState createState() => - _AccountShippingDetailsPageState(); -} - -class _AccountShippingDetailsPageState - extends State { - _AccountShippingDetailsPageState(); - - // BILLING TEXT CONTROLLERS - final TextEditingController _txtShippingFirstName = TextEditingController(), - _txtShippingLastName = TextEditingController(), - _txtShippingAddressLine = TextEditingController(), - _txtShippingCity = TextEditingController(), - _txtShippingPostalCode = TextEditingController(), - _txtShippingState = TextEditingController(), - _txtShippingCountry = TextEditingController(); - - bool _isLoading = true, _isUpdating = false; - - @override - void initState() { - super.initState(); - _fetchUserDetails(); - } - - _fetchUserDetails() async { - String? userToken = await readAuthToken(); - - WCCustomerInfoResponse? wcCustomerInfoResponse; - try { - wcCustomerInfoResponse = await WPJsonAPI.instance - .api((request) => request.wcCustomerInfo(userToken!)); - } on Exception catch (_) { - showToastNotification( - context, - title: trans("Oops!"), - description: trans("Something went wrong"), - style: ToastNotificationStyleType.DANGER, - ); - Navigator.pop(context); - return; - } finally { - setState(() { - _isLoading = false; - }); - } - - if (wcCustomerInfoResponse != null && - wcCustomerInfoResponse.status == 200) { - 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!; - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar( - title: Text(trans("Shipping Details")), - centerTitle: true, - ), - body: SafeAreaWidget( - child: GestureDetector( - onTap: () { - FocusScope.of(context).requestFocus(FocusNode()); - }, - child: _isLoading - ? AppLoaderWidget() - : LayoutBuilder( - builder: (context, constraints) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - child: Container( - margin: EdgeInsets.only(top: 10), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Row( - children: [ - Flexible( - child: TextEditingRow( - heading: trans("First Name"), - controller: _txtShippingFirstName, - shouldAutoFocus: true, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("Last Name"), - controller: _txtShippingLastName, - ), - ), - ], - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - ), - TextEditingRow( - heading: trans("Address Line"), - controller: _txtShippingAddressLine, - ), - Row(children: [ - Flexible( - child: TextEditingRow( - heading: trans("City"), - controller: _txtShippingCity, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("State"), - controller: _txtShippingState, - ), - ), - ]), - Row( - children: [ - Flexible( - child: TextEditingRow( - heading: trans("Postal code"), - controller: _txtShippingPostalCode, - ), - ), - Flexible( - child: TextEditingRow( - heading: trans("Country"), - controller: _txtShippingCountry, - ), - ), - ], - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - ) - ], - ), - decoration: BoxDecoration( - color: ThemeColor.get(context).surfaceBackground, - borderRadius: BorderRadius.circular(10), - boxShadow: (Theme.of(context).brightness == - Brightness.light) - ? wsBoxShadow() - : null, - ), - padding: EdgeInsets.all(8), - ), - height: - (constraints.maxHeight - constraints.minHeight) * - 0.6, - ), - Column( - children: [ - PrimaryButton( - title: trans("UPDATE DETAILS"), - isLoading: _isUpdating, - action: _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(); - - if (_isUpdating == true) { - return; - } - - setState(() { - _isUpdating = true; - }); - - WCCustomerUpdatedResponse? wcCustomerUpdatedResponse; - try { - wcCustomerUpdatedResponse = await WPJsonAPI.instance.api( - (request) => request.wcUpdateCustomerInfo( - userToken, - shippingFirstName: firstName, - shippingLastName: lastName, - shippingAddress1: addressLine, - shippingCity: city, - shippingState: state, - shippingPostcode: postalCode, - shippingCountry: country, - ), - ); - } on Exception catch (_) { - showToastNotification(context, - title: trans("Oops!"), - description: trans("Something went wrong"), - style: ToastNotificationStyleType.DANGER); - } finally { - setState(() { - _isUpdating = true; - }); - } - - if (wcCustomerUpdatedResponse != null && - wcCustomerUpdatedResponse.status == 200) { - showToastNotification(context, - title: trans("Success"), - description: trans("Account updated"), - style: ToastNotificationStyleType.SUCCESS); - Navigator.pop(context); - } - } -} diff --git a/LabelStoreMax/lib/resources/pages/account_shipping_details_page.dart b/LabelStoreMax/lib/resources/pages/account_shipping_details_page.dart new file mode 100644 index 0000000..01e6366 --- /dev/null +++ b/LabelStoreMax/lib/resources/pages/account_shipping_details_page.dart @@ -0,0 +1,377 @@ +// Label StoreMax +// +// Created by Anthony Gordon. +// 2022, 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:flutter_app/app/models/billing_details.dart'; +import 'package:flutter_app/app/models/customer_address.dart'; +import 'package:flutter_app/app/models/customer_country.dart'; +import 'package:flutter_app/app/models/default_shipping.dart'; +import 'package:flutter_app/bootstrap/helpers.dart'; +import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; +import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; +import 'package:flutter_app/resources/widgets/buttons.dart'; +import 'package:flutter_app/resources/widgets/customer_address_input.dart'; +import 'package:flutter_app/resources/widgets/safearea_widget.dart'; +import 'package:flutter_app/resources/widgets/switch_address_tab.dart'; +import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; +import 'package:nylo_framework/nylo_framework.dart'; +import 'package:wp_json_api/models/responses/wp_user_info_response.dart'; +import 'package:wp_json_api/models/responses/wp_user_info_updated_response.dart'; +import 'package:wp_json_api/wp_json_api.dart'; +import 'package:validated/validated.dart' as validate; + +class AccountShippingDetailsPage extends StatefulWidget { + AccountShippingDetailsPage(); + + @override + _AccountShippingDetailsPageState createState() => + _AccountShippingDetailsPageState(); +} + +class _AccountShippingDetailsPageState + extends NyState { + _AccountShippingDetailsPageState(); + + int activeTabIndex = 0; + + // TEXT CONTROLLERS + final TextEditingController + // billing + _txtBillingFirstName = TextEditingController(), + _txtBillingLastName = TextEditingController(), + _txtBillingAddressLine = TextEditingController(), + _txtBillingCity = TextEditingController(), + _txtBillingPostalCode = TextEditingController(), + _txtBillingEmailAddress = TextEditingController(), + _txtBillingPhoneNumber = TextEditingController(), + // shipping + _txtShippingFirstName = TextEditingController(), + _txtShippingLastName = TextEditingController(), + _txtShippingAddressLine = TextEditingController(), + _txtShippingCity = TextEditingController(), + _txtShippingPostalCode = TextEditingController(); + + CustomerCountry? _billingCountry, _shippingCountry; + + Widget? activeTab; + + Widget tabShippingDetails() => CustomerAddressInput( + txtControllerFirstName: _txtShippingFirstName, + txtControllerLastName: _txtShippingLastName, + txtControllerAddressLine: _txtShippingAddressLine, + txtControllerCity: _txtShippingCity, + txtControllerPostalCode: _txtShippingPostalCode, + customerCountry: _shippingCountry, + onTapCountry: () => _navigateToSelectCountry(type: "shipping")); + + Widget tabBillingDetails() => CustomerAddressInput( + txtControllerFirstName: _txtBillingFirstName, + txtControllerLastName: _txtBillingLastName, + txtControllerAddressLine: _txtBillingAddressLine, + txtControllerCity: _txtBillingCity, + txtControllerPostalCode: _txtBillingPostalCode, + txtControllerEmailAddress: _txtBillingEmailAddress, + txtControllerPhoneNumber: _txtBillingPhoneNumber, + customerCountry: _billingCountry, + onTapCountry: () => _navigateToSelectCountry(type: "billing"), + ); + + @override + init() async { + super.init(); + + await awaitData(perform: () async { + await _fetchUserDetails(); + }); + } + + _setFieldsFromCustomerAddress(CustomerAddress? customerAddress, + {required String type}) { + assert(type != ""); + if (customerAddress == null) { + return; + } + _setFields( + firstName: customerAddress.firstName, + lastName: customerAddress.lastName, + addressLine: customerAddress.addressLine, + city: customerAddress.city, + postalCode: customerAddress.postalCode, + emailAddress: customerAddress.emailAddress, + phoneNumber: customerAddress.phoneNumber, + customerCountry: customerAddress.customerCountry, + type: type, + ); + } + + _setFields( + {required String? firstName, + required String? lastName, + required String? addressLine, + required String? city, + required String? postalCode, + required String? emailAddress, + required String? phoneNumber, + required CustomerCountry? customerCountry, + String? type}) { + if (type == "billing") { + _txtBillingFirstName.text = firstName ?? ""; + _txtBillingLastName.text = lastName ?? ""; + _txtBillingAddressLine.text = addressLine ?? ""; + _txtBillingCity.text = city ?? ""; + _txtBillingPostalCode.text = postalCode ?? ""; + _txtBillingPhoneNumber.text = phoneNumber ?? ""; + _txtBillingEmailAddress.text = emailAddress ?? ""; + _billingCountry = customerCountry; + } else if (type == "shipping") { + _txtShippingFirstName.text = firstName ?? ""; + _txtShippingLastName.text = lastName ?? ""; + _txtShippingAddressLine.text = addressLine ?? ""; + _txtShippingCity.text = city ?? ""; + _txtShippingPostalCode.text = postalCode ?? ""; + _shippingCountry = customerCountry; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + title: Text( + trans("Billing & Shipping Details"), + ), + centerTitle: true, + ), + body: SafeAreaWidget( + child: isLoading() + ? AppLoaderWidget() + : GestureDetector( + onTap: () => FocusScope.of(context).requestFocus(FocusNode()), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.symmetric(vertical: 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Padding( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + SwitchAddressTab( + title: trans("Billing Details"), + currentTabIndex: activeTabIndex, + type: "billing", + onTapAction: () => setState(() { + activeTabIndex = 0; + activeTab = tabBillingDetails(); + })), + SwitchAddressTab( + title: trans("Shipping Address"), + currentTabIndex: activeTabIndex, + type: "shipping", + onTapAction: () => setState(() { + activeTabIndex = 1; + activeTab = + tabShippingDetails(); + })), + ], + ), + padding: EdgeInsets.symmetric(vertical: 4), + ), + ], + ), + height: 60, + ), + Expanded( + child: Container( + decoration: BoxDecoration( + color: ThemeColor.get(context) + .backgroundContainer, + borderRadius: BorderRadius.circular(10), + boxShadow: (Theme.of(context).brightness == + Brightness.light) + ? wsBoxShadow() + : null, + ), + padding: + EdgeInsets.only(left: 8, right: 8, top: 8), + margin: EdgeInsets.only(top: 8), + child: (activeTab ?? tabBillingDetails())), + ), + ], + ), + ), + Container( + margin: EdgeInsets.only(top: 16), + height: 160, + child: Column( + children: [ + PrimaryButton( + title: trans("USE DETAILS"), + action: _useDetailsTapped, + isLoading: isLocked('update_details'), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + _useDetailsTapped() async { + lockRelease('update_details', perform: () async { + // Billing email is required for Stripe + String billingEmail = _txtBillingEmailAddress.text; + if (billingEmail.isNotEmpty && !validate.isEmail(billingEmail)) { + showToastNotification( + context, + title: trans("Oops"), + description: trans("Please enter a valid shipping email"), + style: ToastNotificationStyleType.WARNING, + ); + return; + } + + CustomerAddress userBillingAddress = _setCustomerAddress( + firstName: _txtBillingFirstName.text, + lastName: _txtBillingLastName.text, + addressLine: _txtBillingAddressLine.text, + city: _txtBillingCity.text, + postalCode: _txtBillingPostalCode.text, + phoneNumber: _txtBillingPhoneNumber.text, + emailAddress: _txtBillingEmailAddress.text.trim(), + customerCountry: _billingCountry, + ), + userShippingAddress = _setCustomerAddress( + firstName: _txtShippingFirstName.text, + lastName: _txtShippingLastName.text, + addressLine: _txtShippingAddressLine.text, + city: _txtShippingCity.text, + postalCode: _txtShippingPostalCode.text, + customerCountry: _shippingCountry, + ); + + String? userToken = await readAuthToken(); + + WPUserInfoUpdatedResponse? wpUserInfoUpdatedResponse; + try { + wpUserInfoUpdatedResponse = await WPJsonAPI.instance.api( + (request) => request.wpUpdateUserInfo(userToken, wpUserMetaData: [ + ...userBillingAddress.toUserMetaDataItem('billing'), + ...userShippingAddress.toUserMetaDataItem('shipping'), + ]), + ); + } on Exception catch (_) { + showToastNotification(context, + title: trans("Oops!"), + description: trans("Something went wrong"), + style: ToastNotificationStyleType.DANGER); + } + + if (wpUserInfoUpdatedResponse != null && + wpUserInfoUpdatedResponse.status == 200) { + showToastNotification(context, + title: trans("Success"), + description: trans("Account updated"), + style: ToastNotificationStyleType.SUCCESS); + Navigator.pop(context); + } + }); + } + + CustomerAddress _setCustomerAddress( + {required String firstName, + required String lastName, + required String addressLine, + required String city, + required String postalCode, + String? emailAddress, + String? phoneNumber, + required CustomerCountry? customerCountry}) { + CustomerAddress customerShippingAddress = CustomerAddress(); + customerShippingAddress.firstName = firstName; + customerShippingAddress.lastName = lastName; + customerShippingAddress.addressLine = addressLine; + customerShippingAddress.city = city; + customerShippingAddress.postalCode = postalCode; + if (phoneNumber != null && phoneNumber != "") { + customerShippingAddress.phoneNumber = phoneNumber; + } + customerShippingAddress.customerCountry = customerCountry; + customerShippingAddress.emailAddress = emailAddress; + return customerShippingAddress; + } + + _navigateToSelectCountry({required String type}) { + Navigator.pushNamed(context, "/customer-countries").then((value) { + if (value == null) { + return; + } + + if (type == "billing") { + _billingCountry = CustomerCountry.fromDefaultShipping( + defaultShipping: value as DefaultShipping); + activeTab = tabBillingDetails(); + } else if (type == "shipping") { + _shippingCountry = CustomerCountry.fromDefaultShipping( + defaultShipping: value as DefaultShipping); + activeTab = tabShippingDetails(); + } + setState(() {}); + }); + } + + _fetchUserDetails() async { + String? userToken = await readAuthToken(); + + WPUserInfoResponse? wpUserInfoResponse; + try { + wpUserInfoResponse = await WPJsonAPI.instance + .api((request) => request.wpGetUserInfo(userToken!)); + } on Exception catch (e) { + print(e.toString()); + showToastNotification( + context, + title: trans("Oops!"), + description: trans("Something went wrong"), + style: ToastNotificationStyleType.DANGER, + ); + Navigator.pop(context); + } + + if (wpUserInfoResponse != null && wpUserInfoResponse.status == 200) { + BillingDetails billingDetails = + await billingDetailsFromWpUserInfoResponse(wpUserInfoResponse); + + _setFieldsFromCustomerAddress(billingDetails.shippingAddress, + type: "shipping"); + _setFieldsFromCustomerAddress(billingDetails.billingAddress, + type: "billing"); + + setState(() {}); + } + } +} diff --git a/LabelStoreMax/lib/resources/pages/browse_category.dart b/LabelStoreMax/lib/resources/pages/browse_category_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/browse_category.dart rename to LabelStoreMax/lib/resources/pages/browse_category_page.dart diff --git a/LabelStoreMax/lib/resources/pages/browse_search.dart b/LabelStoreMax/lib/resources/pages/browse_search_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/browse_search.dart rename to LabelStoreMax/lib/resources/pages/browse_search_page.dart diff --git a/LabelStoreMax/lib/resources/pages/cart.dart b/LabelStoreMax/lib/resources/pages/cart_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/cart.dart rename to LabelStoreMax/lib/resources/pages/cart_page.dart diff --git a/LabelStoreMax/lib/resources/pages/checkout_confirmation.dart b/LabelStoreMax/lib/resources/pages/checkout_confirmation_page.dart similarity index 99% rename from LabelStoreMax/lib/resources/pages/checkout_confirmation.dart rename to LabelStoreMax/lib/resources/pages/checkout_confirmation_page.dart index e064ef2..c799756 100644 --- a/LabelStoreMax/lib/resources/pages/checkout_confirmation.dart +++ b/LabelStoreMax/lib/resources/pages/checkout_confirmation_page.dart @@ -294,7 +294,8 @@ class CheckoutConfirmationPageState extends State { return; } - if (checkoutSession.billingDetails?.billingAddress?.hasMissingFields() ?? true) { + if (checkoutSession.billingDetails?.billingAddress?.hasMissingFields() ?? + true) { showToastNotification( context, title: trans("Oops"), diff --git a/LabelStoreMax/lib/resources/pages/checkout_details.dart b/LabelStoreMax/lib/resources/pages/checkout_details.dart deleted file mode 100644 index bcf7776..0000000 --- a/LabelStoreMax/lib/resources/pages/checkout_details.dart +++ /dev/null @@ -1,437 +0,0 @@ -// Label StoreMax -// -// Created by Anthony Gordon. -// 2022, 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:flutter_app/app/models/billing_details.dart'; -import 'package:flutter_app/app/models/checkout_session.dart'; -import 'package:flutter_app/app/models/customer_address.dart'; -import 'package:flutter_app/app/models/customer_country.dart'; -import 'package:flutter_app/bootstrap/helpers.dart'; -import 'package:flutter_app/resources/widgets/buttons.dart'; -import 'package:flutter_app/resources/widgets/customer_address_input.dart'; -import 'package:flutter_app/resources/widgets/safearea_widget.dart'; -import 'package:flutter_app/resources/widgets/switch_address_tab.dart'; -import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; -import 'package:nylo_framework/nylo_framework.dart'; -import 'package:validated/validated.dart' as validate; - -import '../../app/models/default_shipping.dart'; - -class CheckoutDetailsPage extends StatefulWidget { - CheckoutDetailsPage(); - - @override - _CheckoutDetailsPageState createState() => _CheckoutDetailsPageState(); -} - -class _CheckoutDetailsPageState extends State { - _CheckoutDetailsPageState(); - - bool? _hasDifferentShippingAddress = false, valRememberDetails = true; - int activeTabIndex = 0; - - // TEXT CONTROLLERS - final TextEditingController - // billing - _txtBillingFirstName = TextEditingController(), - _txtBillingLastName = TextEditingController(), - _txtBillingAddressLine = TextEditingController(), - _txtBillingCity = TextEditingController(), - _txtBillingPostalCode = TextEditingController(), - _txtBillingEmailAddress = TextEditingController(), - _txtBillingPhoneNumber = TextEditingController(), - // shipping - _txtShippingFirstName = TextEditingController(), - _txtShippingLastName = TextEditingController(), - _txtShippingAddressLine = TextEditingController(), - _txtShippingCity = TextEditingController(), - _txtShippingPostalCode = TextEditingController(), - _txtShippingEmailAddress = TextEditingController(); - - CustomerCountry? _billingCountry, _shippingCountry; - - Widget? activeTab; - - Widget tabShippingDetails() => CustomerAddressInput( - txtControllerFirstName: _txtShippingFirstName, - txtControllerLastName: _txtShippingLastName, - txtControllerAddressLine: _txtShippingAddressLine, - txtControllerCity: _txtShippingCity, - txtControllerPostalCode: _txtShippingPostalCode, - txtControllerEmailAddress: _txtShippingEmailAddress, - customerCountry: _shippingCountry, - onTapCountry: () => _navigateToSelectCountry(type: "shipping"), - ); - - Widget tabBillingDetails() => CustomerAddressInput( - txtControllerFirstName: _txtBillingFirstName, - txtControllerLastName: _txtBillingLastName, - txtControllerAddressLine: _txtBillingAddressLine, - txtControllerCity: _txtBillingCity, - txtControllerPostalCode: _txtBillingPostalCode, - txtControllerEmailAddress: _txtBillingEmailAddress, - txtControllerPhoneNumber: _txtBillingPhoneNumber, - customerCountry: _billingCountry, - onTapCountry: () => _navigateToSelectCountry(type: "billing"), - ); - - @override - void initState() { - super.initState(); - - if (CheckoutSession.getInstance.billingDetails!.billingAddress == null) { - CheckoutSession.getInstance.billingDetails!.initSession(); - CheckoutSession.getInstance.billingDetails!.shippingAddress! - .initAddress(); - CheckoutSession.getInstance.billingDetails!.billingAddress?.initAddress(); - } - BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails!; - _setFieldsFromCustomerAddress(billingDetails.billingAddress, - type: "billing"); - _setFieldsFromCustomerAddress(billingDetails.shippingAddress, - type: "shipping"); - - _hasDifferentShippingAddress = - CheckoutSession.getInstance.shipToDifferentAddress; - valRememberDetails = billingDetails.rememberDetails ?? true; - _setCustomersDetails(); - } - - _setCustomersDetails() async { - CustomerAddress? sfCustomerBillingAddress = - await CheckoutSession.getInstance.getBillingAddress(); - _setFieldsFromCustomerAddress(sfCustomerBillingAddress, type: "billing"); - - CustomerAddress? sfCustomerShippingAddress = - await CheckoutSession.getInstance.getShippingAddress(); - _setFieldsFromCustomerAddress(sfCustomerShippingAddress, type: "shipping"); - setState(() {}); - } - - _setFieldsFromCustomerAddress(CustomerAddress? customerAddress, - {required String type}) { - assert(type != ""); - if (customerAddress == null) { - return; - } - _setFields( - firstName: customerAddress.firstName, - lastName: customerAddress.lastName, - addressLine: customerAddress.addressLine, - city: customerAddress.city, - postalCode: customerAddress.postalCode, - emailAddress: customerAddress.emailAddress, - phoneNumber: customerAddress.phoneNumber, - customerCountry: customerAddress.customerCountry, - type: type, - ); - } - - _setFields( - {required String? firstName, - required String? lastName, - required String? addressLine, - required String? city, - required String? postalCode, - required String? emailAddress, - required String? phoneNumber, - required CustomerCountry? customerCountry, - String? type}) { - if (type == "billing") { - _txtBillingFirstName.text = firstName!; - _txtBillingLastName.text = lastName!; - _txtBillingAddressLine.text = addressLine!; - _txtBillingCity.text = city!; - _txtBillingPostalCode.text = postalCode!; - _txtBillingPhoneNumber.text = phoneNumber ?? ""; - _txtBillingEmailAddress.text = emailAddress!; - _billingCountry = customerCountry; - } else if (type == "shipping") { - _txtShippingFirstName.text = firstName!; - _txtShippingLastName.text = lastName!; - _txtShippingAddressLine.text = addressLine!; - _txtShippingCity.text = city!; - _txtShippingPostalCode.text = postalCode!; - _txtShippingEmailAddress.text = emailAddress!; - _shippingCountry = customerCountry; - } - } - - @override - Widget build(BuildContext context) { - return Scaffold( - resizeToAvoidBottomInset: false, - appBar: AppBar( - title: Text( - trans("Billing & Shipping Details"), - ), - centerTitle: true, - ), - body: SafeAreaWidget( - child: GestureDetector( - onTap: () => FocusScope.of(context).requestFocus(FocusNode()), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (_hasDifferentShippingAddress!) - Container( - margin: EdgeInsets.symmetric(vertical: 0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Padding( - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: - MainAxisAlignment.spaceAround, - children: [ - SwitchAddressTab( - title: trans("Billing Details"), - currentTabIndex: activeTabIndex, - type: "billing", - onTapAction: () => setState(() { - activeTabIndex = 0; - activeTab = tabBillingDetails(); - })), - SwitchAddressTab( - title: trans("Shipping Address"), - currentTabIndex: activeTabIndex, - type: "shipping", - onTapAction: () => setState(() { - activeTabIndex = 1; - activeTab = tabShippingDetails(); - })), - ], - ), - padding: EdgeInsets.symmetric(vertical: 4), - ), - ], - ), - height: 60, - ), - Expanded( - child: Container( - decoration: BoxDecoration( - color: ThemeColor.get(context).backgroundContainer, - borderRadius: BorderRadius.circular(10), - boxShadow: (Theme.of(context).brightness == - Brightness.light) - ? wsBoxShadow() - : null, - ), - padding: EdgeInsets.only(left: 8, right: 8, top: 8), - margin: EdgeInsets.only(top: 8), - child: (activeTab ?? tabBillingDetails())), - ), - ], - ), - ), - Container( - height: 160, - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - trans("Ship to a different address?"), - style: Theme.of(context).textTheme.bodyText2, - ), - Checkbox( - value: _hasDifferentShippingAddress, - onChanged: _onChangeShipping, - ) - ], - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - trans("Remember my details"), - style: Theme.of(context).textTheme.bodyText2, - ), - Checkbox( - value: valRememberDetails, - onChanged: (bool? value) { - setState(() { - valRememberDetails = value; - }); - }, - ) - ], - ), - PrimaryButton( - title: trans("USE DETAILS"), - action: _useDetailsTapped, - ), - ], - ), - ), - ], - ), - ), - ), - ); - } - - _useDetailsTapped() async { - CustomerAddress customerBillingAddress = _setCustomerAddress( - firstName: _txtBillingFirstName.text, - lastName: _txtBillingLastName.text, - addressLine: _txtBillingAddressLine.text, - city: _txtBillingCity.text, - postalCode: _txtBillingPostalCode.text, - phoneNumber: _txtBillingPhoneNumber.text, - emailAddress: _txtBillingEmailAddress.text.trim(), - customerCountry: _billingCountry, - ); - - CheckoutSession.getInstance.billingDetails!.shippingAddress = - customerBillingAddress; - CheckoutSession.getInstance.billingDetails!.billingAddress = - customerBillingAddress; - - if (_hasDifferentShippingAddress == true) { - CustomerAddress customerShippingAddress = _setCustomerAddress( - firstName: _txtShippingFirstName.text, - lastName: _txtShippingLastName.text, - addressLine: _txtShippingAddressLine.text, - city: _txtShippingCity.text, - postalCode: _txtShippingPostalCode.text, - emailAddress: _txtShippingEmailAddress.text.trim(), - customerCountry: _shippingCountry); - - if (customerShippingAddress.hasMissingFields()) { - showToastNotification( - context, - title: trans("Oops"), - description: trans( - "Invalid shipping address, please check your shipping details"), - style: ToastNotificationStyleType.WARNING, - ); - return; - } - - CheckoutSession.getInstance.billingDetails!.shippingAddress = - customerShippingAddress; - } - - // Email validation - String billingEmail = CheckoutSession.getInstance.billingDetails!.billingAddress!.emailAddress!; - String shippingEmail = CheckoutSession.getInstance.billingDetails!.shippingAddress!.emailAddress!; - // Billing email is required for Stripe - if (billingEmail.isEmpty || !validate.isEmail(billingEmail)) { - showToastNotification( - context, - title: trans("Oops"), - description: trans("Please enter a valid billing email"), - style: ToastNotificationStyleType.WARNING, - ); - return; - } - - if (shippingEmail.isNotEmpty && !validate.isEmail(shippingEmail)) { - showToastNotification( - context, - title: trans("Oops"), - description: trans("Please enter a valid shipping email"), - style: ToastNotificationStyleType.WARNING, - ); - return; - } - - if (valRememberDetails == true) { - await CheckoutSession.getInstance.saveBillingAddress(); - await CheckoutSession.getInstance.saveShippingAddress(); - } else { - await CheckoutSession.getInstance.clearBillingAddress(); - await CheckoutSession.getInstance.clearShippingAddress(); - } - - CheckoutSession.getInstance.billingDetails!.rememberDetails = - valRememberDetails; - CheckoutSession.getInstance.shipToDifferentAddress = - _hasDifferentShippingAddress; - - CheckoutSession.getInstance.shippingType = null; - Navigator.pop(context); - } - - _onChangeShipping(bool? value) async { - _hasDifferentShippingAddress = value; - activeTabIndex = 1; - activeTab = value == true ? tabShippingDetails() : tabBillingDetails(); - - CustomerAddress? sfCustomerShippingAddress = - await CheckoutSession.getInstance.getShippingAddress(); - if (sfCustomerShippingAddress == null) { - _setFields( - firstName: "", - lastName: "", - addressLine: "", - city: "", - postalCode: "", - phoneNumber: "", - emailAddress: "", - customerCountry: CustomerCountry()); - } - setState(() {}); - } - - CustomerAddress _setCustomerAddress( - {required String firstName, - required String lastName, - required String addressLine, - required String city, - required String postalCode, - required String emailAddress, - String? phoneNumber, - required CustomerCountry? customerCountry}) { - CustomerAddress customerShippingAddress = CustomerAddress(); - customerShippingAddress.firstName = firstName; - customerShippingAddress.lastName = lastName; - customerShippingAddress.addressLine = addressLine; - customerShippingAddress.city = city; - customerShippingAddress.postalCode = postalCode; - if (phoneNumber != null && phoneNumber != "") { - customerShippingAddress.phoneNumber = phoneNumber; - } - customerShippingAddress.customerCountry = customerCountry; - customerShippingAddress.emailAddress = emailAddress; - return customerShippingAddress; - } - - _navigateToSelectCountry({required String type}) { - Navigator.pushNamed(context, "/customer-countries").then((value) { - if (value == null) { - return; - } - if (type == "billing") { - _billingCountry = CustomerCountry.fromDefaultShipping( - defaultShipping: value as DefaultShipping); - activeTab = tabBillingDetails(); - } else if (type == "shipping") { - _shippingCountry = CustomerCountry.fromDefaultShipping( - defaultShipping: value as DefaultShipping); - activeTab = tabShippingDetails(); - } - setState(() {}); - }); - } -} diff --git a/LabelStoreMax/lib/resources/pages/checkout_details_page.dart b/LabelStoreMax/lib/resources/pages/checkout_details_page.dart new file mode 100644 index 0000000..b144e98 --- /dev/null +++ b/LabelStoreMax/lib/resources/pages/checkout_details_page.dart @@ -0,0 +1,527 @@ +// Label StoreMax +// +// Created by Anthony Gordon. +// 2022, 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:flutter_app/app/models/billing_details.dart'; +import 'package:flutter_app/app/models/checkout_session.dart'; +import 'package:flutter_app/app/models/customer_address.dart'; +import 'package:flutter_app/app/models/customer_country.dart'; +import 'package:flutter_app/bootstrap/app_helper.dart'; +import 'package:flutter_app/bootstrap/helpers.dart'; +import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; +import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; +import 'package:flutter_app/resources/widgets/buttons.dart'; +import 'package:flutter_app/resources/widgets/customer_address_input.dart'; +import 'package:flutter_app/resources/widgets/safearea_widget.dart'; +import 'package:flutter_app/resources/widgets/switch_address_tab.dart'; +import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; +import 'package:nylo_framework/nylo_framework.dart'; +import 'package:validated/validated.dart' as validate; +import 'package:wp_json_api/models/responses/wp_user_info_response.dart'; +import 'package:wp_json_api/wp_json_api.dart'; +import '../../app/models/default_shipping.dart'; + +class CheckoutDetailsPage extends StatefulWidget { + CheckoutDetailsPage(); + + @override + _CheckoutDetailsPageState createState() => _CheckoutDetailsPageState(); +} + +class _CheckoutDetailsPageState extends NyState { + _CheckoutDetailsPageState(); + + bool? _hasDifferentShippingAddress = false, + valRememberDetails = true, + _wpLoginEnabled; + int activeTabIndex = 0; + + // TEXT CONTROLLERS + final TextEditingController + // billing + _txtBillingFirstName = TextEditingController(), + _txtBillingLastName = TextEditingController(), + _txtBillingAddressLine = TextEditingController(), + _txtBillingCity = TextEditingController(), + _txtBillingPostalCode = TextEditingController(), + _txtBillingEmailAddress = TextEditingController(), + _txtBillingPhoneNumber = TextEditingController(), + // shipping + _txtShippingFirstName = TextEditingController(), + _txtShippingLastName = TextEditingController(), + _txtShippingAddressLine = TextEditingController(), + _txtShippingCity = TextEditingController(), + _txtShippingPostalCode = TextEditingController(), + _txtShippingEmailAddress = TextEditingController(); + + CustomerCountry? _billingCountry, _shippingCountry; + + Widget? activeTab; + + Widget tabShippingDetails() => CustomerAddressInput( + txtControllerFirstName: _txtShippingFirstName, + txtControllerLastName: _txtShippingLastName, + txtControllerAddressLine: _txtShippingAddressLine, + txtControllerCity: _txtShippingCity, + txtControllerPostalCode: _txtShippingPostalCode, + txtControllerEmailAddress: _txtShippingEmailAddress, + customerCountry: _shippingCountry, + onTapCountry: () => _navigateToSelectCountry(type: "shipping"), + ); + + Widget tabBillingDetails() => CustomerAddressInput( + txtControllerFirstName: _txtBillingFirstName, + txtControllerLastName: _txtBillingLastName, + txtControllerAddressLine: _txtBillingAddressLine, + txtControllerCity: _txtBillingCity, + txtControllerPostalCode: _txtBillingPostalCode, + txtControllerEmailAddress: _txtBillingEmailAddress, + txtControllerPhoneNumber: _txtBillingPhoneNumber, + customerCountry: _billingCountry, + onTapCountry: () => _navigateToSelectCountry(type: "billing"), + ); + + @override + void init() async { + super.init(); + + _wpLoginEnabled = AppHelper.instance.appConfig?.wpLoginEnabled == 1; + + if (_wpLoginEnabled == true) { + await awaitData(perform: () async { + await _fetchUserDetails(); + }); + return; + } + + if (CheckoutSession.getInstance.billingDetails!.billingAddress == null) { + CheckoutSession.getInstance.billingDetails!.initSession(); + CheckoutSession.getInstance.billingDetails!.shippingAddress! + .initAddress(); + CheckoutSession.getInstance.billingDetails!.billingAddress?.initAddress(); + } + BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails!; + _setFieldsFromCustomerAddress(billingDetails.billingAddress, + type: "billing"); + _setFieldsFromCustomerAddress(billingDetails.shippingAddress, + type: "shipping"); + + _hasDifferentShippingAddress = + CheckoutSession.getInstance.shipToDifferentAddress; + valRememberDetails = billingDetails.rememberDetails ?? true; + if (valRememberDetails == true) { + await _setCustomersDetailsFromRemember(); + return; + } + setState(() {}); + } + + _setCustomersDetailsFromRemember() async { + CustomerAddress? sfCustomerBillingAddress = + await CheckoutSession.getInstance.getBillingAddress(); + _setFieldsFromCustomerAddress(sfCustomerBillingAddress, type: "billing"); + + CustomerAddress? sfCustomerShippingAddress = + await CheckoutSession.getInstance.getShippingAddress(); + _setFieldsFromCustomerAddress(sfCustomerShippingAddress, type: "shipping"); + setState(() {}); + } + + _setFieldsFromCustomerAddress(CustomerAddress? customerAddress, + {required String type}) { + assert(type != ""); + if (customerAddress == null) { + return; + } + _setFields( + firstName: customerAddress.firstName, + lastName: customerAddress.lastName, + addressLine: customerAddress.addressLine, + city: customerAddress.city, + postalCode: customerAddress.postalCode, + emailAddress: customerAddress.emailAddress, + phoneNumber: customerAddress.phoneNumber, + customerCountry: customerAddress.customerCountry, + type: type, + ); + } + + _setFields( + {required String? firstName, + required String? lastName, + required String? addressLine, + required String? city, + required String? postalCode, + required String? emailAddress, + required String? phoneNumber, + required CustomerCountry? customerCountry, + String? type}) { + if (type == "billing") { + _txtBillingFirstName.text = firstName ?? ""; + _txtBillingLastName.text = lastName ?? ""; + _txtBillingAddressLine.text = addressLine ?? ""; + _txtBillingCity.text = city ?? ""; + _txtBillingPostalCode.text = postalCode ?? ""; + _txtBillingPhoneNumber.text = phoneNumber ?? ""; + _txtBillingEmailAddress.text = emailAddress ?? ""; + _billingCountry = customerCountry; + } else if (type == "shipping") { + _txtShippingFirstName.text = firstName ?? ""; + _txtShippingLastName.text = lastName ?? ""; + _txtShippingAddressLine.text = addressLine ?? ""; + _txtShippingCity.text = city ?? ""; + _txtShippingPostalCode.text = postalCode ?? ""; + _txtShippingEmailAddress.text = emailAddress ?? ""; + _shippingCountry = customerCountry; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + title: Text( + trans("Billing & Shipping Details"), + ), + centerTitle: true, + ), + body: SafeAreaWidget( + child: (isLoading() || isLocked('load_shipping_info')) + ? AppLoaderWidget() + : GestureDetector( + onTap: () => FocusScope.of(context).requestFocus(FocusNode()), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (_hasDifferentShippingAddress!) + Container( + margin: EdgeInsets.symmetric(vertical: 0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + Padding( + child: Row( + crossAxisAlignment: + CrossAxisAlignment.center, + mainAxisAlignment: + MainAxisAlignment.spaceAround, + children: [ + SwitchAddressTab( + title: trans("Billing Details"), + currentTabIndex: activeTabIndex, + type: "billing", + onTapAction: () => setState(() { + activeTabIndex = 0; + activeTab = + tabBillingDetails(); + })), + SwitchAddressTab( + title: trans("Shipping Address"), + currentTabIndex: activeTabIndex, + type: "shipping", + onTapAction: () => setState(() { + activeTabIndex = 1; + activeTab = + tabShippingDetails(); + })), + ], + ), + padding: EdgeInsets.symmetric(vertical: 4), + ), + ], + ), + height: 60, + ), + Expanded( + child: Container( + decoration: BoxDecoration( + color: ThemeColor.get(context) + .backgroundContainer, + borderRadius: BorderRadius.circular(10), + boxShadow: (Theme.of(context).brightness == + Brightness.light) + ? wsBoxShadow() + : null, + ), + padding: + EdgeInsets.only(left: 8, right: 8, top: 8), + margin: EdgeInsets.only(top: 8), + child: (activeTab ?? tabBillingDetails())), + ), + ], + ), + ), + Container( + height: 160, + child: Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + trans("Ship to a different address?"), + style: Theme.of(context).textTheme.bodyText2, + ), + Checkbox( + value: _hasDifferentShippingAddress, + onChanged: _onChangeShipping, + ) + ], + ), + if (_wpLoginEnabled == true) + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + trans("Remember my details"), + style: Theme.of(context).textTheme.bodyText2, + ), + Checkbox( + value: valRememberDetails, + onChanged: (bool? value) { + setState(() { + valRememberDetails = value; + }); + }, + ) + ], + ), + PrimaryButton( + title: trans("USE DETAILS"), + action: _useDetailsTapped, + isLoading: isLocked('update_shipping'), + ), + ], + ), + ), + ], + ), + ), + ), + ); + } + + _useDetailsTapped() async { + await lockRelease('update_shipping', perform: () async { + CustomerAddress customerBillingAddress = _setCustomerAddress( + firstName: _txtBillingFirstName.text, + lastName: _txtBillingLastName.text, + addressLine: _txtBillingAddressLine.text, + city: _txtBillingCity.text, + postalCode: _txtBillingPostalCode.text, + phoneNumber: _txtBillingPhoneNumber.text, + emailAddress: _txtBillingEmailAddress.text.trim(), + customerCountry: _billingCountry, + ); + + CheckoutSession.getInstance.billingDetails!.shippingAddress = + customerBillingAddress; + CheckoutSession.getInstance.billingDetails!.billingAddress = + customerBillingAddress; + + if (_hasDifferentShippingAddress == true) { + CustomerAddress customerShippingAddress = _setCustomerAddress( + firstName: _txtShippingFirstName.text, + lastName: _txtShippingLastName.text, + addressLine: _txtShippingAddressLine.text, + city: _txtShippingCity.text, + postalCode: _txtShippingPostalCode.text, + emailAddress: _txtShippingEmailAddress.text.trim(), + customerCountry: _shippingCountry); + + if (customerShippingAddress.hasMissingFields()) { + showToastNotification( + context, + title: trans("Oops"), + description: trans( + "Invalid shipping address, please check your shipping details"), + style: ToastNotificationStyleType.WARNING, + ); + return; + } + + CheckoutSession.getInstance.billingDetails!.shippingAddress = + customerShippingAddress; + } + + BillingDetails billingDetails = + CheckoutSession.getInstance.billingDetails!; + + // Email validation + String billingEmail = billingDetails.billingAddress!.emailAddress!; + String shippingEmail = billingDetails.shippingAddress!.emailAddress!; + // Billing email is required for Stripe + if (billingEmail.isEmpty || !validate.isEmail(billingEmail)) { + showToastNotification( + context, + title: trans("Oops"), + description: trans("Please enter a valid billing email"), + style: ToastNotificationStyleType.WARNING, + ); + return; + } + + if (shippingEmail.isNotEmpty && !validate.isEmail(shippingEmail)) { + showToastNotification( + context, + title: trans("Oops"), + description: trans("Please enter a valid shipping email"), + style: ToastNotificationStyleType.WARNING, + ); + return; + } + + // Update WP shipping info for user + if (_wpLoginEnabled == true) { + String? userToken = await readAuthToken(); + + try { + await WPJsonAPI.instance.api( + (request) => request.wpUpdateUserInfo(userToken, wpUserMetaData: [ + ...?billingDetails.billingAddress?.toUserMetaDataItem('billing'), + ...?billingDetails.shippingAddress + ?.toUserMetaDataItem('shipping'), + ]), + ); + } on Exception catch (e) { + showToastNotification(context, + title: trans("Oops!"), + description: trans("Something went wrong"), + style: ToastNotificationStyleType.DANGER); + if (getEnv('APP_DEBUG', defaultValue: true) == true) { + NyLogger.error(e.toString()); + } + } + } + + if (valRememberDetails == true) { + await CheckoutSession.getInstance.saveBillingAddress(); + await CheckoutSession.getInstance.saveShippingAddress(); + } else { + await CheckoutSession.getInstance.clearBillingAddress(); + await CheckoutSession.getInstance.clearShippingAddress(); + } + + CheckoutSession.getInstance.billingDetails!.rememberDetails = + valRememberDetails; + CheckoutSession.getInstance.shipToDifferentAddress = + _hasDifferentShippingAddress; + + CheckoutSession.getInstance.shippingType = null; + Navigator.pop(context); + }); + } + + _onChangeShipping(bool? value) async { + _hasDifferentShippingAddress = value; + activeTabIndex = 1; + activeTab = value == true ? tabShippingDetails() : tabBillingDetails(); + + CustomerAddress? sfCustomerShippingAddress = + await CheckoutSession.getInstance.getShippingAddress(); + if (sfCustomerShippingAddress == null) { + _setFields( + firstName: "", + lastName: "", + addressLine: "", + city: "", + postalCode: "", + phoneNumber: "", + emailAddress: "", + customerCountry: CustomerCountry()); + } + setState(() {}); + } + + CustomerAddress _setCustomerAddress( + {required String firstName, + required String lastName, + required String addressLine, + required String city, + required String postalCode, + required String emailAddress, + String? phoneNumber, + required CustomerCountry? customerCountry}) { + CustomerAddress customerShippingAddress = CustomerAddress(); + customerShippingAddress.firstName = firstName; + customerShippingAddress.lastName = lastName; + customerShippingAddress.addressLine = addressLine; + customerShippingAddress.city = city; + customerShippingAddress.postalCode = postalCode; + if (phoneNumber != null && phoneNumber != "") { + customerShippingAddress.phoneNumber = phoneNumber; + } + customerShippingAddress.customerCountry = customerCountry; + customerShippingAddress.emailAddress = emailAddress; + return customerShippingAddress; + } + + _navigateToSelectCountry({required String type}) { + Navigator.pushNamed(context, "/customer-countries").then((value) { + if (value == null) { + return; + } + if (type == "billing") { + _billingCountry = CustomerCountry.fromDefaultShipping( + defaultShipping: value as DefaultShipping); + activeTab = tabBillingDetails(); + } else if (type == "shipping") { + _shippingCountry = CustomerCountry.fromDefaultShipping( + defaultShipping: value as DefaultShipping); + activeTab = tabShippingDetails(); + } + setState(() {}); + }); + } + + _fetchUserDetails() async { + await lockRelease('load_shipping_info', perform: () async { + String? userToken = await readAuthToken(); + + WPUserInfoResponse? wpUserInfoResponse; + try { + wpUserInfoResponse = await WPJsonAPI.instance + .api((request) => request.wpGetUserInfo(userToken!)); + } on Exception catch (e) { + print(e.toString()); + showToastNotification( + context, + title: trans("Oops!"), + description: trans("Something went wrong"), + style: ToastNotificationStyleType.DANGER, + ); + Navigator.pop(context); + } + + if (wpUserInfoResponse != null && wpUserInfoResponse.status == 200) { + BillingDetails billingDetails = + await billingDetailsFromWpUserInfoResponse(wpUserInfoResponse); + + _setFieldsFromCustomerAddress(billingDetails.shippingAddress, + type: "shipping"); + _setFieldsFromCustomerAddress(billingDetails.billingAddress, + type: "billing"); + + setState(() {}); + } + }); + } +} diff --git a/LabelStoreMax/lib/resources/pages/checkout_payment_type.dart b/LabelStoreMax/lib/resources/pages/checkout_payment_type_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/checkout_payment_type.dart rename to LabelStoreMax/lib/resources/pages/checkout_payment_type_page.dart diff --git a/LabelStoreMax/lib/resources/pages/checkout_shipping_type.dart b/LabelStoreMax/lib/resources/pages/checkout_shipping_type_page.dart similarity index 98% rename from LabelStoreMax/lib/resources/pages/checkout_shipping_type.dart rename to LabelStoreMax/lib/resources/pages/checkout_shipping_type_page.dart index f8f419d..4b179a2 100644 --- a/LabelStoreMax/lib/resources/pages/checkout_shipping_type.dart +++ b/LabelStoreMax/lib/resources/pages/checkout_shipping_type_page.dart @@ -330,9 +330,8 @@ class _CheckoutShippingTypePageState extends State { "min_amount"] != null) TextSpan( - text: "\n${trans("Spend a minimum of")} ${formatStringCurrency( - total: shippingOption[ - "min_amount"])}", + text: + "\n${trans("Spend a minimum of")} ${formatStringCurrency(total: shippingOption["min_amount"])}", style: Theme.of( context) .textTheme @@ -366,7 +365,7 @@ class _CheckoutShippingTypePageState extends State { ) : Text( trans( - "Shipping is not supported for your country, sorry"), + "Shipping is not supported for your location, sorry"), style: Theme.of(context).textTheme.headline6, textAlign: TextAlign.center, diff --git a/LabelStoreMax/lib/resources/pages/checkout_status.dart b/LabelStoreMax/lib/resources/pages/checkout_status_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/checkout_status.dart rename to LabelStoreMax/lib/resources/pages/checkout_status_page.dart diff --git a/LabelStoreMax/lib/resources/pages/customer_countries.dart b/LabelStoreMax/lib/resources/pages/customer_countries_page.dart similarity index 99% rename from LabelStoreMax/lib/resources/pages/customer_countries.dart rename to LabelStoreMax/lib/resources/pages/customer_countries_page.dart index 9a3036d..a98d320 100644 --- a/LabelStoreMax/lib/resources/pages/customer_countries.dart +++ b/LabelStoreMax/lib/resources/pages/customer_countries_page.dart @@ -35,7 +35,7 @@ class _CustomerCountriesPageState extends State { } _getDefaultShipping() async { - _defaultShipping = await getDefaultShipping(context); + _defaultShipping = await getDefaultShipping(); _activeShippingResults = _defaultShipping; setState(() {}); } diff --git a/LabelStoreMax/lib/resources/pages/home.dart b/LabelStoreMax/lib/resources/pages/home_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/home.dart rename to LabelStoreMax/lib/resources/pages/home_page.dart diff --git a/LabelStoreMax/lib/resources/pages/home_search.dart b/LabelStoreMax/lib/resources/pages/home_search_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/home_search.dart rename to LabelStoreMax/lib/resources/pages/home_search_page.dart diff --git a/LabelStoreMax/lib/resources/pages/product_detail.dart b/LabelStoreMax/lib/resources/pages/product_detail_page.dart similarity index 100% rename from LabelStoreMax/lib/resources/pages/product_detail.dart rename to LabelStoreMax/lib/resources/pages/product_detail_page.dart diff --git a/LabelStoreMax/lib/resources/widgets/account_detail_settings_widget.dart b/LabelStoreMax/lib/resources/widgets/account_detail_settings_widget.dart index e33fe21..3b69649 100644 --- a/LabelStoreMax/lib/resources/widgets/account_detail_settings_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/account_detail_settings_widget.dart @@ -33,25 +33,16 @@ class AccountDetailSettingsWidget extends StatelessWidget { Card( child: ListTile( leading: Icon(Icons.local_shipping), - title: Text(trans("Shipping Details")), + title: Text(trans("Billing/shipping details")), onTap: () => Navigator.pushNamed(context, "/account-shipping-details"), ), ), - Card( - child: ListTile( - leading: Icon(Icons.credit_card), - title: Text(trans("Billing Details")), - onTap: () => - Navigator.pushNamed(context, "/account-billing-details"), - ), - ), Card( child: ListTile( leading: Icon(Icons.no_accounts_rounded), title: Text(trans("Delete Account")), - onTap: () => - Navigator.pushNamed(context, "/account-delete"), + onTap: () => Navigator.pushNamed(context, "/account-delete"), ), ), Card( diff --git a/LabelStoreMax/lib/resources/widgets/checkout_select_coupon_widget.dart b/LabelStoreMax/lib/resources/widgets/checkout_select_coupon_widget.dart index 69fcc85..89c0e61 100644 --- a/LabelStoreMax/lib/resources/widgets/checkout_select_coupon_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/checkout_select_coupon_widget.dart @@ -63,7 +63,8 @@ class CheckoutSelectCouponWidget extends StatelessWidget { return; } - if (checkoutSession.billingDetails?.billingAddress?.hasMissingFields() ?? true) { + if (checkoutSession.billingDetails?.billingAddress?.hasMissingFields() ?? + true) { showToastNotification( context, title: trans("Oops"), diff --git a/LabelStoreMax/lib/resources/widgets/checkout_store_heading_widget.dart b/LabelStoreMax/lib/resources/widgets/checkout_store_heading_widget.dart index da24343..ad013f4 100644 --- a/LabelStoreMax/lib/resources/widgets/checkout_store_heading_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/checkout_store_heading_widget.dart @@ -7,18 +7,18 @@ class CheckoutStoreHeadingWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Container( - decoration: BoxDecoration( - boxShadow: (Theme.of(context).brightness == Brightness.light) - ? wsBoxShadow(blurRadius: 10) - : null, - color: Colors.transparent, - ), - padding: EdgeInsets.all(2), - margin: EdgeInsets.only(top: 16), - child: ClipRRect( - child: StoreLogo(height: 65), - borderRadius: BorderRadius.circular(8), - ), + decoration: BoxDecoration( + boxShadow: (Theme.of(context).brightness == Brightness.light) + ? wsBoxShadow(blurRadius: 10) + : null, + color: Colors.transparent, + ), + padding: EdgeInsets.all(2), + margin: EdgeInsets.only(top: 16), + child: ClipRRect( + child: StoreLogo(height: 65), + borderRadius: BorderRadius.circular(8), + ), ); } } diff --git a/LabelStoreMax/lib/resources/widgets/checkout_user_details_widget.dart b/LabelStoreMax/lib/resources/widgets/checkout_user_details_widget.dart index e6faa95..0e31fb8 100644 --- a/LabelStoreMax/lib/resources/widgets/checkout_user_details_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/checkout_user_details_widget.dart @@ -23,7 +23,9 @@ class CheckoutUserDetailsWidget extends StatelessWidget { leadImage: Icon(Icons.home), leadTitle: hasUserCheckoutInfo ? (checkoutSession.billingDetails == null || - (checkoutSession.billingDetails?.billingAddress?.hasMissingFields() ?? true) + (checkoutSession.billingDetails?.billingAddress + ?.hasMissingFields() ?? + true) ? trans("Billing address is incomplete") : checkoutSession.billingDetails!.billingAddress?.addressFull()) : trans("Add billing & shipping details"), diff --git a/LabelStoreMax/lib/resources/widgets/compo_theme_widget.dart b/LabelStoreMax/lib/resources/widgets/compo_theme_widget.dart index f60638f..1278ac8 100644 --- a/LabelStoreMax/lib/resources/widgets/compo_theme_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/compo_theme_widget.dart @@ -15,11 +15,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/app/models/bottom_nav_item.dart'; import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; -import 'package:flutter_app/resources/pages/account_detail.dart'; -import 'package:flutter_app/resources/pages/account_landing.dart'; -import 'package:flutter_app/resources/pages/cart.dart'; +import 'package:flutter_app/resources/pages/account_detail_page.dart'; +import 'package:flutter_app/resources/pages/account_landing_page.dart'; +import 'package:flutter_app/resources/pages/cart_page.dart'; import 'package:flutter_app/resources/pages/wishlist_page_widget.dart'; -import 'package:flutter_app/resources/pages/home_search.dart'; +import 'package:flutter_app/resources/pages/home_search_page.dart'; import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; import 'package:flutter_app/resources/widgets/compo_home_widget.dart'; import 'package:woosignal/models/response/woosignal_app.dart'; diff --git a/LabelStoreMax/lib/resources/widgets/customer_address_input.dart b/LabelStoreMax/lib/resources/widgets/customer_address_input.dart index f607c16..855ff73 100644 --- a/LabelStoreMax/lib/resources/widgets/customer_address_input.dart +++ b/LabelStoreMax/lib/resources/widgets/customer_address_input.dart @@ -22,7 +22,7 @@ class CustomerAddressInput extends StatelessWidget { required this.txtControllerAddressLine, required this.txtControllerCity, required this.txtControllerPostalCode, - required this.txtControllerEmailAddress, + this.txtControllerEmailAddress, this.txtControllerPhoneNumber, required this.customerCountry, required this.onTapCountry}) @@ -87,12 +87,13 @@ class CustomerAddressInput extends StatelessWidget { controller: txtControllerPostalCode, ), ), - Flexible( - child: TextEditingRow( - heading: trans("Email address"), - keyboardType: TextInputType.emailAddress, - controller: txtControllerEmailAddress), - ), + if (txtControllerEmailAddress == null) + Flexible( + child: TextEditingRow( + heading: trans("Email address"), + keyboardType: TextInputType.emailAddress, + controller: txtControllerEmailAddress), + ), ], ), if (txtControllerPhoneNumber != null) @@ -111,7 +112,7 @@ class CustomerAddressInput extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 4), child: Row( children: [ - if (customerCountry!.hasState()) + if (customerCountry?.hasState() ?? false) Flexible( child: Column( children: [ diff --git a/LabelStoreMax/lib/resources/widgets/home_drawer_widget.dart b/LabelStoreMax/lib/resources/widgets/home_drawer_widget.dart index 553dd12..73c79cd 100644 --- a/LabelStoreMax/lib/resources/widgets/home_drawer_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/home_drawer_widget.dart @@ -13,9 +13,11 @@ import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/helpers.dart'; import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; import 'package:flutter_app/resources/widgets/app_version_widget.dart'; +import 'package:flutter_app/resources/widgets/cached_image_widget.dart'; import 'package:flutter_app/resources/widgets/woosignal_ui.dart'; import 'package:nylo_framework/theme/helper/ny_theme.dart'; import 'package:nylo_framework/nylo_framework.dart'; +import 'package:woosignal/models/menu_link.dart'; import 'package:woosignal/models/response/woosignal_app.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -30,13 +32,13 @@ class HomeDrawerWidget extends StatefulWidget { } class _HomeDrawerWidgetState extends State { - Map _socialLinks = {}; + List _menuLinks = []; String? _themeType; @override void initState() { super.initState(); - _socialLinks = AppHelper.instance.appConfig!.socialLinks ?? {}; + _menuLinks = AppHelper.instance.appConfig?.menuLinks ?? []; _themeType = AppHelper.instance.appConfig!.theme; } @@ -157,7 +159,7 @@ class _HomeDrawerWidgetState extends State { }); }, ), - if (_socialLinks.isNotEmpty) + if (_menuLinks.isNotEmpty) Padding( child: Text( trans("Social"), @@ -165,20 +167,23 @@ class _HomeDrawerWidgetState extends State { ), padding: EdgeInsets.only(left: 16, top: 8, bottom: 8), ), - ..._socialLinks.entries - .where((element) => element.value != "") - .map((socialLink) => ListTile( - title: Text(capitalize(socialLink.key), + ..._menuLinks + .where((element) => element.label != "") + .map((menuLink) => ListTile( + title: Text(menuLink.label, style: Theme.of(context) .textTheme .bodyText2! .copyWith(fontSize: 16)), - leading: Image.asset( - '${getImageAsset(socialLink.key)}.png', - height: 25, - width: 25), + leading: Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: CachedImageWidget( + image: menuLink.iconUrl, + width: 40, + ), + ), onTap: () async => - await launchUrl(Uri.parse(socialLink.value)), + await launchUrl(Uri.parse(menuLink.linkUrl)), )) .toList(), ListTile( @@ -213,6 +218,4 @@ class _HomeDrawerWidgetState extends State { Navigator.pop(context); Navigator.pushNamed(context, "/cart"); } - - String capitalize(String s) => s[0].toUpperCase() + s.substring(1); } diff --git a/LabelStoreMax/lib/resources/widgets/notic_theme_widget.dart b/LabelStoreMax/lib/resources/widgets/notic_theme_widget.dart index 3cf74ea..e42e32d 100644 --- a/LabelStoreMax/lib/resources/widgets/notic_theme_widget.dart +++ b/LabelStoreMax/lib/resources/widgets/notic_theme_widget.dart @@ -15,11 +15,11 @@ import 'package:flutter/material.dart'; import 'package:flutter_app/app/models/bottom_nav_item.dart'; import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart'; -import 'package:flutter_app/resources/pages/account_detail.dart'; -import 'package:flutter_app/resources/pages/account_landing.dart'; -import 'package:flutter_app/resources/pages/cart.dart'; +import 'package:flutter_app/resources/pages/account_detail_page.dart'; +import 'package:flutter_app/resources/pages/account_landing_page.dart'; +import 'package:flutter_app/resources/pages/cart_page.dart'; import 'package:flutter_app/resources/pages/wishlist_page_widget.dart'; -import 'package:flutter_app/resources/pages/home_search.dart'; +import 'package:flutter_app/resources/pages/home_search_page.dart'; import 'package:flutter_app/resources/widgets/app_loader_widget.dart'; import 'package:flutter_app/resources/widgets/notic_home_widget.dart'; import 'package:woosignal/models/response/woosignal_app.dart'; diff --git a/LabelStoreMax/lib/routes/router.dart b/LabelStoreMax/lib/routes/router.dart index 2146341..e70cabf 100644 --- a/LabelStoreMax/lib/routes/router.dart +++ b/LabelStoreMax/lib/routes/router.dart @@ -1,26 +1,25 @@ -import 'package:flutter_app/resources/pages/account_billing_details.dart'; import 'package:flutter_app/resources/pages/account_delete_page.dart'; -import 'package:flutter_app/resources/pages/account_detail.dart'; -import 'package:flutter_app/resources/pages/account_landing.dart'; -import 'package:flutter_app/resources/pages/account_order_detail.dart'; -import 'package:flutter_app/resources/pages/account_profile_update.dart'; -import 'package:flutter_app/resources/pages/account_register.dart'; -import 'package:flutter_app/resources/pages/account_shipping_details.dart'; -import 'package:flutter_app/resources/pages/browse_category.dart'; -import 'package:flutter_app/resources/pages/browse_search.dart'; -import 'package:flutter_app/resources/pages/cart.dart'; -import 'package:flutter_app/resources/pages/checkout_confirmation.dart'; -import 'package:flutter_app/resources/pages/checkout_details.dart'; -import 'package:flutter_app/resources/pages/checkout_payment_type.dart'; -import 'package:flutter_app/resources/pages/checkout_shipping_type.dart'; -import 'package:flutter_app/resources/pages/checkout_status.dart'; +import 'package:flutter_app/resources/pages/account_detail_page.dart'; +import 'package:flutter_app/resources/pages/account_landing_page.dart'; +import 'package:flutter_app/resources/pages/account_order_detail_page.dart'; +import 'package:flutter_app/resources/pages/account_profile_update_page.dart'; +import 'package:flutter_app/resources/pages/account_register_page.dart'; +import 'package:flutter_app/resources/pages/account_shipping_details_page.dart'; +import 'package:flutter_app/resources/pages/browse_category_page.dart'; +import 'package:flutter_app/resources/pages/browse_search_page.dart'; +import 'package:flutter_app/resources/pages/cart_page.dart'; +import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart'; +import 'package:flutter_app/resources/pages/checkout_details_page.dart'; +import 'package:flutter_app/resources/pages/checkout_payment_type_page.dart'; +import 'package:flutter_app/resources/pages/checkout_shipping_type_page.dart'; +import 'package:flutter_app/resources/pages/checkout_status_page.dart'; import 'package:flutter_app/resources/pages/coupon_page.dart'; -import 'package:flutter_app/resources/pages/customer_countries.dart'; -import 'package:flutter_app/resources/pages/home.dart'; -import 'package:flutter_app/resources/pages/home_search.dart'; +import 'package:flutter_app/resources/pages/customer_countries_page.dart'; +import 'package:flutter_app/resources/pages/home_page.dart'; +import 'package:flutter_app/resources/pages/home_search_page.dart'; import 'package:flutter_app/resources/pages/leave_review_page.dart'; import 'package:flutter_app/resources/pages/no_connection_page.dart'; -import 'package:flutter_app/resources/pages/product_detail.dart'; +import 'package:flutter_app/resources/pages/product_detail_page.dart'; import 'package:flutter_app/resources/pages/product_image_viewer_page.dart'; import 'package:flutter_app/resources/pages/product_reviews_page.dart'; import 'package:flutter_app/resources/pages/wishlist_page_widget.dart'; @@ -105,9 +104,6 @@ appRouter() => nyRoutes((router) { router.route("/account-delete", (context) => AccountDeletePage()); - router.route( - "/account-billing-details", (context) => AccountBillingDetailsPage()); - router.route("/account-shipping-details", (context) => AccountShippingDetailsPage()); }); diff --git a/LabelStoreMax/pubspec.lock b/LabelStoreMax/pubspec.lock index 3ee0771..5514475 100644 --- a/LabelStoreMax/pubspec.lock +++ b/LabelStoreMax/pubspec.lock @@ -8,6 +8,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "41.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.6" analyzer: dependency: "direct main" description: @@ -120,6 +127,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "5.8.3" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.3" collection: dependency: "direct main" description: @@ -161,42 +182,14 @@ packages: name: device_info_plus url: "https://pub.dartlang.org" source: hosted - version: "4.1.2" - device_info_plus_linux: - dependency: transitive - description: - name: device_info_plus_linux - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - device_info_plus_macos: - dependency: transitive - description: - name: device_info_plus_macos - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" + version: "8.0.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" - device_info_plus_web: - dependency: transitive - description: - name: device_info_plus_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0" - device_info_plus_windows: - dependency: transitive - description: - name: device_info_plus_windows - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.0" + version: "7.0.0" dio: dependency: transitive description: @@ -232,6 +225,48 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.2" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.2" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + url: "https://pub.dartlang.org" + source: hosted + version: "14.0.3" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.4" flare_flutter: dependency: transitive description: @@ -346,7 +381,7 @@ packages: name: flutter_stripe url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "6.0.0" flutter_styled_toast: dependency: "direct main" description: @@ -384,7 +419,7 @@ packages: name: flutter_widget_from_html_core url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+3" + version: "0.9.0" fluttertoast: dependency: transitive description: @@ -426,7 +461,7 @@ packages: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.15.0" + version: "0.15.1" http: dependency: transitive description: @@ -685,7 +720,7 @@ packages: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.1.3" process: dependency: transitive description: @@ -713,7 +748,7 @@ packages: name: razorpay_flutter url: "https://pub.dartlang.org" source: hosted - version: "1.3.2" + version: "1.3.4" recase: dependency: transitive description: @@ -823,7 +858,7 @@ packages: name: status_alert url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" stream_channel: dependency: transitive description: @@ -844,21 +879,21 @@ packages: name: stripe_android url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "6.0.0" stripe_ios: dependency: transitive description: name: stripe_ios url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "6.0.0" stripe_platform_interface: dependency: transitive description: name: stripe_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "5.0.0" + version: "6.0.0" synchronized: dependency: transitive description: @@ -900,7 +935,7 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.1.5" + version: "6.1.6" url_launcher_android: dependency: transitive description: @@ -1016,10 +1051,10 @@ packages: woosignal: dependency: "direct main" description: - name: woosignal - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" + path: "/Users/anthony/AndroidStudioProjects/woosignal-woocommerce-api" + relative: false + source: path + version: "3.2.0" wp_json_api: dependency: "direct main" description: diff --git a/LabelStoreMax/pubspec.yaml b/LabelStoreMax/pubspec.yaml index e0432a2..107f765 100644 --- a/LabelStoreMax/pubspec.yaml +++ b/LabelStoreMax/pubspec.yaml @@ -1,7 +1,7 @@ # Official WooSignal App Template for WooCommerce # Label StoreMax -# Version: 6.2.0 +# Version: 6.3.0 # Author: Anthony Gordon # Homepage: https://woosignal.com # Documentation: https://woosignal.com/docs/app/label-storemax @@ -29,8 +29,8 @@ dependencies: analyzer: ^4.2.0 intl: ^0.17.0 nylo_framework: ^3.4.0 - woosignal: ^3.1.1 - flutter_stripe: ^5.0.0 + woosignal: ^3.2.0 + flutter_stripe: ^6.0.0 wp_json_api: ^3.2.0 cached_network_image: ^3.2.2 package_info: ^2.0.2 @@ -38,23 +38,23 @@ dependencies: flutter_web_browser: ^0.17.1 webview_flutter: ^3.0.4 pull_to_refresh_flutter3: 2.0.1 - url_launcher: ^6.1.5 + url_launcher: ^6.1.6 flutter_styled_toast: ^2.1.3 animate_do: ^2.1.0 bubble_tab_indicator: ^0.1.5 - razorpay_flutter: ^1.3.2 - status_alert: ^1.0.0 + razorpay_flutter: ^1.3.4 + status_alert: ^1.0.1 math_expressions: ^2.3.1 validated: ^2.0.0 flutter_spinkit: ^5.1.0 auto_size_text: ^3.0.0 - html: ^0.15.0 - flutter_widget_from_html_core: ^0.8.5+3 + html: ^0.15.1 + flutter_widget_from_html_core: ^0.9.0 flutter_rating_bar: ^4.0.1 flutter_staggered_grid_view: ^0.6.2 flutter_swiper_view: ^1.1.8 -# firebase_messaging: ^11.2.3 -# firebase_core: ^1.10.5 + firebase_messaging: ^14.0.3 + firebase_core: ^2.1.1 flutter: sdk: flutter flutter_localizations: @@ -63,7 +63,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.5 - collection: ^1.15.0-nullsafety.4 + collection: ^1.15.0 dev_dependencies: flutter_launcher_icons: ^0.10.0