v5.9.0 updates
This commit is contained in:
parent
c72cc3250c
commit
9b187684b5
@ -1,3 +1,11 @@
|
||||
## [5.9.0] - 2022-05-19
|
||||
|
||||
* Migrate to Nylo 3.x
|
||||
* Null safety
|
||||
* Min dart version 2.17
|
||||
* Refactor product detail screen
|
||||
* Pubspec.yaml dependency updates
|
||||
|
||||
## [5.8.0] - 2022-03-29
|
||||
|
||||
* Add phone number to customer input form
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
# WooCommerce App: Label StoreMax
|
||||
|
||||
### Label StoreMax - v5.8.0
|
||||
### Label StoreMax - v5.9.0
|
||||
|
||||
|
||||
[Official WooSignal WooCommerce App](https://woosignal.com)
|
||||
|
||||
@ -61,5 +61,7 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:nylo_support/controllers/controller.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
/// Base Controller for the Nylo
|
||||
/// See more on controllers here - https://nylo.dev/docs/2.x/controllers
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||
import 'package:woosignal/models/response/order.dart';
|
||||
|
||||
@ -17,9 +15,9 @@ class CustomerOrdersLoaderController
|
||||
CustomerOrdersLoaderController();
|
||||
|
||||
Future<void> loadOrders(
|
||||
{@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
@required String userId}) async {
|
||||
{required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
required String userId}) async {
|
||||
await load(
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
|
||||
@ -12,10 +12,8 @@ import 'controller.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class LeaveReviewController extends Controller {
|
||||
|
||||
@override
|
||||
construct(BuildContext context) {
|
||||
super.construct(context);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
@ -18,19 +17,19 @@ class ProductCategorySearchLoaderController
|
||||
ProductCategorySearchLoaderController();
|
||||
|
||||
Future<void> loadProducts(
|
||||
{@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
@required ProductCategory productCategory}) async {
|
||||
{required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
required ProductCategory? productCategory}) async {
|
||||
await load(
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
apiQuery: (api) => api.getProducts(
|
||||
perPage: 50,
|
||||
category: productCategory.id.toString(),
|
||||
page: page,
|
||||
status: "publish",
|
||||
stockStatus: "instock",
|
||||
),
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
apiQuery: (api) => api.getProducts(
|
||||
perPage: 50,
|
||||
category: productCategory!.id.toString(),
|
||||
page: page,
|
||||
status: "publish",
|
||||
stockStatus: "instock",
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,44 +16,46 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
import 'package:woosignal/models/response/product_variation.dart'
|
||||
as ws_product_variation;
|
||||
as ws_product_variation;
|
||||
|
||||
import 'controller.dart';
|
||||
|
||||
class ProductDetailController extends Controller {
|
||||
int quantity = 1;
|
||||
Product product;
|
||||
Product? product;
|
||||
|
||||
@override
|
||||
construct(BuildContext context) {
|
||||
super.construct(context);
|
||||
product = data() as Product;
|
||||
product = data() as Product?;
|
||||
}
|
||||
|
||||
viewExternalProduct() {
|
||||
if (product.externalUrl != null && product.externalUrl.isNotEmpty) {
|
||||
openBrowserTab(url: product.externalUrl);
|
||||
if (product!.externalUrl != null && product!.externalUrl!.isNotEmpty) {
|
||||
openBrowserTab(url: product!.externalUrl!);
|
||||
}
|
||||
}
|
||||
|
||||
itemAddToCart({@required CartLineItem cartLineItem, @required Function onSuccess}) async {
|
||||
itemAddToCart(
|
||||
{required CartLineItem cartLineItem, required Function onSuccess}) async {
|
||||
await Cart.getInstance.addToCart(cartLineItem: cartLineItem);
|
||||
showStatusAlert(context,
|
||||
title: trans("Success"),
|
||||
subtitle: trans("Added to cart"),
|
||||
duration: 1,
|
||||
icon: Icons.add_shopping_cart,
|
||||
showStatusAlert(
|
||||
context,
|
||||
title: trans("Success"),
|
||||
subtitle: trans("Added to cart"),
|
||||
duration: 1,
|
||||
icon: Icons.add_shopping_cart,
|
||||
);
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
addQuantityTapped({@required Function onSuccess}) {
|
||||
if (product.manageStock != null && product.manageStock == true) {
|
||||
if (quantity >= product.stockQuantity) {
|
||||
showToastNotification(context,
|
||||
addQuantityTapped({required Function onSuccess}) {
|
||||
if (product!.manageStock != null && product!.manageStock == true) {
|
||||
if (quantity >= product!.stockQuantity!) {
|
||||
showToastNotification(context!,
|
||||
title: trans("Maximum quantity reached"),
|
||||
description:
|
||||
"${trans("Sorry, only")} ${product.stockQuantity} ${trans("left")}",
|
||||
"${trans("Sorry, only")} ${product!.stockQuantity} ${trans("left")}",
|
||||
style: ToastNotificationStyleType.INFO);
|
||||
return;
|
||||
}
|
||||
@ -64,14 +66,16 @@ class ProductDetailController extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
removeQuantityTapped({@required Function onSuccess}) {
|
||||
removeQuantityTapped({required Function onSuccess}) {
|
||||
if ((quantity - 1) >= 1) {
|
||||
quantity--;
|
||||
onSuccess();
|
||||
}
|
||||
}
|
||||
|
||||
toggleWishList({@required Function onSuccess, @required WishlistAction wishlistAction}) async {
|
||||
toggleWishList(
|
||||
{required Function onSuccess,
|
||||
required WishlistAction wishlistAction}) async {
|
||||
String subtitleMsg;
|
||||
if (wishlistAction == WishlistAction.remove) {
|
||||
await removeWishlistProduct(product: product);
|
||||
@ -80,7 +84,8 @@ class ProductDetailController extends Controller {
|
||||
await saveWishlistProduct(product: product);
|
||||
subtitleMsg = trans("This product has been added to your wishlist");
|
||||
}
|
||||
showStatusAlert(context,
|
||||
showStatusAlert(
|
||||
context,
|
||||
title: trans("Success"),
|
||||
subtitle: subtitleMsg,
|
||||
icon: Icons.favorite,
|
||||
@ -90,18 +95,18 @@ class ProductDetailController extends Controller {
|
||||
onSuccess();
|
||||
}
|
||||
|
||||
ws_product_variation.ProductVariation findProductVariation(
|
||||
{@required Map<int, dynamic> tmpAttributeObj,
|
||||
@required List<ws_product_variation.ProductVariation> productVariations}) {
|
||||
ws_product_variation.ProductVariation tmpProductVariation;
|
||||
ws_product_variation.ProductVariation? findProductVariation(
|
||||
{required Map<int, dynamic> tmpAttributeObj,
|
||||
required List<ws_product_variation.ProductVariation> productVariations}) {
|
||||
ws_product_variation.ProductVariation? tmpProductVariation;
|
||||
|
||||
Map<String, dynamic> tmpSelectedObj = {};
|
||||
Map<String?, dynamic> tmpSelectedObj = {};
|
||||
for (var attributeObj in tmpAttributeObj.values) {
|
||||
tmpSelectedObj[attributeObj["name"]] = attributeObj["value"];
|
||||
}
|
||||
|
||||
for (var productVariation in productVariations) {
|
||||
Map<String, dynamic> tmpVariations = {};
|
||||
Map<String?, dynamic> tmpVariations = {};
|
||||
|
||||
for (var attr in productVariation.attributes) {
|
||||
tmpVariations[attr.name] = attr.option;
|
||||
@ -114,4 +119,4 @@ class ProductDetailController extends Controller {
|
||||
|
||||
return tmpProductVariation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,18 +8,16 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
|
||||
class ProductLoaderController extends WooSignalApiLoaderController<Product> {
|
||||
ProductLoaderController();
|
||||
|
||||
Future<void> loadProducts({
|
||||
@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
List<int> productIds = const []
|
||||
}) async {
|
||||
Future<void> loadProducts(
|
||||
{required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
List<int>? productIds = const []}) async {
|
||||
await load(
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
|
||||
@ -12,11 +12,8 @@ import 'controller.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class ProductReviewsController extends Controller {
|
||||
|
||||
@override
|
||||
construct(BuildContext context) {
|
||||
super.construct(context);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,27 +8,27 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||
import 'package:woosignal/models/response/product_review.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
|
||||
class ProductReviewsLoaderController extends WooSignalApiLoaderController<ProductReview> {
|
||||
class ProductReviewsLoaderController
|
||||
extends WooSignalApiLoaderController<ProductReview> {
|
||||
ProductReviewsLoaderController();
|
||||
|
||||
Future<void> loadProductReviews({
|
||||
@required Product product,
|
||||
@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
required Product? product,
|
||||
required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
}) async {
|
||||
await load(
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
apiQuery: (api) => api.getProductReviews(
|
||||
product: [product.id],
|
||||
perPage: 50,
|
||||
page: page,
|
||||
status: "approved",
|
||||
));
|
||||
product: [product!.id!],
|
||||
perPage: 50,
|
||||
page: page,
|
||||
status: "approved",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
|
||||
@ -17,9 +16,9 @@ class ProductSearchLoaderController
|
||||
ProductSearchLoaderController();
|
||||
|
||||
Future<void> loadProducts(
|
||||
{@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
@required String search}) async {
|
||||
{required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
required String? search}) async {
|
||||
await load(
|
||||
hasResults: hasResults,
|
||||
didFinish: didFinish,
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
|
||||
@ -20,15 +19,15 @@ class WooSignalApiLoaderController<T> {
|
||||
WooSignalApiLoaderController();
|
||||
|
||||
Future<void> load(
|
||||
{@required bool Function(bool hasProducts) hasResults,
|
||||
@required void Function() didFinish,
|
||||
@required Future<List<T>> Function(WooSignal query) apiQuery}) async {
|
||||
{required bool Function(bool hasProducts) hasResults,
|
||||
required void Function() didFinish,
|
||||
required Future<List<T>> Function(WooSignal query) apiQuery}) async {
|
||||
if (_waitForNextRequest) {
|
||||
return;
|
||||
}
|
||||
_waitForNextRequest = true;
|
||||
|
||||
List<T> apiResults = await appWooSignal((api) => apiQuery(api));
|
||||
List<T> apiResults = await (appWooSignal((api) => apiQuery(api)));
|
||||
|
||||
if (!hasResults(apiResults.isNotEmpty)) {
|
||||
return;
|
||||
@ -41,9 +40,7 @@ class WooSignalApiLoaderController<T> {
|
||||
didFinish();
|
||||
}
|
||||
|
||||
List<T> getResults() {
|
||||
return _results;
|
||||
}
|
||||
List<T> getResults() => _results;
|
||||
|
||||
void clear() {
|
||||
_results = [];
|
||||
|
||||
15
LabelStoreMax/lib/app/events/login_event.dart
Normal file
15
LabelStoreMax/lib/app/events/login_event.dart
Normal file
@ -0,0 +1,15 @@
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class LoginEvent implements NyEvent {
|
||||
@override
|
||||
final listeners = {
|
||||
DefaultListener: DefaultListener(),
|
||||
};
|
||||
}
|
||||
|
||||
class DefaultListener extends NyListener {
|
||||
@override
|
||||
handle(dynamic event) async {
|
||||
// handle the payload from event
|
||||
}
|
||||
}
|
||||
13
LabelStoreMax/lib/app/events/logout_event.dart
Normal file
13
LabelStoreMax/lib/app/events/logout_event.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class LogoutEvent implements NyEvent {
|
||||
@override
|
||||
final listeners = {DefaultListener: DefaultListener()};
|
||||
}
|
||||
|
||||
class DefaultListener extends NyListener {
|
||||
@override
|
||||
handle(dynamic event) async {
|
||||
// handle the payload from event
|
||||
}
|
||||
}
|
||||
@ -11,9 +11,9 @@
|
||||
import 'package:flutter_app/app/models/customer_address.dart';
|
||||
|
||||
class BillingDetails {
|
||||
CustomerAddress billingAddress;
|
||||
CustomerAddress shippingAddress;
|
||||
bool rememberDetails;
|
||||
CustomerAddress? billingAddress;
|
||||
CustomerAddress? shippingAddress;
|
||||
bool? rememberDetails;
|
||||
|
||||
void initSession() {
|
||||
billingAddress = CustomerAddress();
|
||||
|
||||
@ -15,5 +15,8 @@ class BottomNavItem {
|
||||
BottomNavigationBarItem bottomNavigationBarItem;
|
||||
Widget tabWidget;
|
||||
|
||||
BottomNavItem({this.id, this.bottomNavigationBarItem, this.tabWidget});
|
||||
BottomNavItem(
|
||||
{required this.id,
|
||||
required this.bottomNavigationBarItem,
|
||||
required this.tabWidget});
|
||||
}
|
||||
|
||||
@ -10,14 +10,14 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:flutter_app/app/models/cart_line_item.dart';
|
||||
import 'package:flutter_app/app/models/checkout_session.dart';
|
||||
import 'package:flutter_app/app/models/shipping_type.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
@ -27,7 +27,7 @@ class Cart {
|
||||
|
||||
Future<List<CartLineItem>> getCart() async {
|
||||
List<CartLineItem> cartLineItems = [];
|
||||
String currentCartArrJSON = await NyStorage.read(SharedKey.cart);
|
||||
String? currentCartArrJSON = await (NyStorage.read(SharedKey.cart));
|
||||
|
||||
if (currentCartArrJSON != null) {
|
||||
cartLineItems = (jsonDecode(currentCartArrJSON) as List<dynamic>)
|
||||
@ -38,15 +38,14 @@ class Cart {
|
||||
return cartLineItems;
|
||||
}
|
||||
|
||||
Future addToCart({@required CartLineItem cartLineItem}) async {
|
||||
Future addToCart({required CartLineItem cartLineItem}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
|
||||
if (cartLineItem.variationId != null &&
|
||||
cartLineItems.firstWhere(
|
||||
(i) => (i.productId == cartLineItem.productId &&
|
||||
cartLineItems.firstWhereOrNull((i) =>
|
||||
(i.productId == cartLineItem.productId &&
|
||||
i.variationId == cartLineItem.variationId &&
|
||||
i.variationOptions == cartLineItem.variationOptions),
|
||||
orElse: () => null) !=
|
||||
i.variationOptions == cartLineItem.variationOptions)) !=
|
||||
null) {
|
||||
cartLineItems.removeWhere((item) =>
|
||||
item.productId == cartLineItem.productId &&
|
||||
@ -55,8 +54,8 @@ class Cart {
|
||||
}
|
||||
|
||||
if (cartLineItem.variationId == null &&
|
||||
cartLineItems.firstWhere((i) => i.productId == cartLineItem.productId,
|
||||
orElse: () => null) !=
|
||||
cartLineItems.firstWhereOrNull(
|
||||
(i) => i.productId == cartLineItem.productId) !=
|
||||
null) {
|
||||
cartLineItems
|
||||
.removeWhere((item) => item.productId == cartLineItem.productId);
|
||||
@ -80,7 +79,7 @@ class Cart {
|
||||
total = total - double.parse(discountAmount);
|
||||
}
|
||||
|
||||
if (withFormat != null && withFormat == true) {
|
||||
if (withFormat == true) {
|
||||
return formatDoubleCurrency(total: total);
|
||||
}
|
||||
return total.toStringAsFixed(2);
|
||||
@ -92,15 +91,15 @@ class Cart {
|
||||
for (var cartItem in cartLineItems) {
|
||||
subtotal += (parseWcPrice(cartItem.subtotal) * cartItem.quantity);
|
||||
}
|
||||
if (withFormat != null && withFormat == true) {
|
||||
if (withFormat == true) {
|
||||
return formatDoubleCurrency(total: subtotal);
|
||||
}
|
||||
return subtotal.toStringAsFixed(2);
|
||||
}
|
||||
|
||||
updateQuantity(
|
||||
{@required CartLineItem cartLineItem,
|
||||
@required int incrementQuantity}) async {
|
||||
{required CartLineItem cartLineItem,
|
||||
required int incrementQuantity}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
List<CartLineItem> tmpCartItem = [];
|
||||
for (var cartItem in cartLineItems) {
|
||||
@ -124,7 +123,7 @@ class Cart {
|
||||
.join(",");
|
||||
}
|
||||
|
||||
removeCartItemForIndex({@required int index}) async {
|
||||
removeCartItemForIndex({required int index}) async {
|
||||
List<CartLineItem> cartLineItems = await getCart();
|
||||
cartLineItems.removeAt(index);
|
||||
await saveCartToPref(cartLineItems: cartLineItems);
|
||||
@ -132,12 +131,12 @@ class Cart {
|
||||
|
||||
clear() async => NyStorage.delete(SharedKey.cart);
|
||||
|
||||
saveCartToPref({@required List<CartLineItem> cartLineItems}) async {
|
||||
saveCartToPref({required List<CartLineItem> cartLineItems}) async {
|
||||
String json = jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||
await NyStorage.store(SharedKey.cart, json);
|
||||
}
|
||||
|
||||
Future<String> taxAmount(TaxRate taxRate) async {
|
||||
Future<String> taxAmount(TaxRate? taxRate) async {
|
||||
double subtotal = 0;
|
||||
double shippingTotal = 0;
|
||||
|
||||
@ -150,7 +149,7 @@ class Cart {
|
||||
cartItems.where((c) => c.taxStatus == 'taxable').toList();
|
||||
double cartSubtotal = 0;
|
||||
|
||||
if (AppHelper.instance.appConfig.productPricesIncludeTax == 1 &&
|
||||
if (AppHelper.instance.appConfig!.productPricesIncludeTax == 1 &&
|
||||
taxableCartLines.isNotEmpty) {
|
||||
cartSubtotal = taxableCartLines
|
||||
.map<double>((m) => parseWcPrice(m.subtotal) * m.quantity)
|
||||
@ -163,22 +162,20 @@ class Cart {
|
||||
|
||||
subtotal = cartSubtotal;
|
||||
|
||||
ShippingType shippingType = CheckoutSession.getInstance.shippingType;
|
||||
ShippingType? shippingType = CheckoutSession.getInstance.shippingType;
|
||||
|
||||
if (shippingType != null) {
|
||||
switch (shippingType.methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (shippingType.object as FlatRate);
|
||||
if (flatRate.taxable != null && flatRate.taxable) {
|
||||
shippingTotal += parseWcPrice(
|
||||
shippingType.cost == null || shippingType.cost == ""
|
||||
? "0"
|
||||
: shippingType.cost);
|
||||
if (flatRate.taxable != null && flatRate.taxable!) {
|
||||
shippingTotal +=
|
||||
parseWcPrice(shippingType.cost == "" ? "0" : shippingType.cost);
|
||||
}
|
||||
break;
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
||||
if (localPickup.taxable != null && localPickup.taxable) {
|
||||
if (localPickup.taxable != null && localPickup.taxable!) {
|
||||
shippingTotal += parseWcPrice(
|
||||
(localPickup.cost == null || localPickup.cost == ""
|
||||
? "0"
|
||||
@ -192,10 +189,10 @@ class Cart {
|
||||
|
||||
double total = 0;
|
||||
if (subtotal != 0) {
|
||||
total += ((parseWcPrice(taxRate.rate) * subtotal) / 100);
|
||||
total += ((parseWcPrice(taxRate!.rate) * subtotal) / 100);
|
||||
}
|
||||
if (shippingTotal != 0) {
|
||||
total += ((parseWcPrice(taxRate.rate) * shippingTotal) / 100);
|
||||
total += ((parseWcPrice(taxRate!.rate) * shippingTotal) / 100);
|
||||
}
|
||||
return (total).toStringAsFixed(2);
|
||||
}
|
||||
@ -213,10 +210,10 @@ class Cart {
|
||||
for (var cartItem in cartLineItems) {
|
||||
bool canContinue = true;
|
||||
|
||||
if (checkoutSession.coupon.excludedProductCategories.isNotEmpty) {
|
||||
if (checkoutSession.coupon!.excludedProductCategories!.isNotEmpty) {
|
||||
for (var excludedProductCategory
|
||||
in checkoutSession.coupon.excludedProductCategories) {
|
||||
if (cartItem.categories
|
||||
in checkoutSession.coupon!.excludedProductCategories!) {
|
||||
if (cartItem.categories!
|
||||
.map((category) => category.id)
|
||||
.contains(excludedProductCategory)) {
|
||||
canContinue = false;
|
||||
@ -225,10 +222,10 @@ class Cart {
|
||||
}
|
||||
}
|
||||
|
||||
if (checkoutSession.coupon.productCategories.isNotEmpty) {
|
||||
if (checkoutSession.coupon!.productCategories!.isNotEmpty) {
|
||||
for (var productCategories
|
||||
in checkoutSession.coupon.productCategories) {
|
||||
if (cartItem.categories
|
||||
in checkoutSession.coupon!.productCategories!) {
|
||||
if (cartItem.categories!
|
||||
.map((category) => category.id)
|
||||
.contains(productCategories) ==
|
||||
false) {
|
||||
@ -242,41 +239,41 @@ class Cart {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkoutSession.coupon.excludeSaleItems == true &&
|
||||
if (checkoutSession.coupon!.excludeSaleItems == true &&
|
||||
cartItem.onSale == true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkoutSession.coupon.excludedProductIds.isNotEmpty &&
|
||||
checkoutSession.coupon.excludedProductIds
|
||||
if (checkoutSession.coupon!.excludedProductIds!.isNotEmpty &&
|
||||
checkoutSession.coupon!.excludedProductIds!
|
||||
.contains(cartItem.productId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (checkoutSession.coupon.productIds.isNotEmpty &&
|
||||
!checkoutSession.coupon.productIds.contains(cartItem.productId)) {
|
||||
if (checkoutSession.coupon!.productIds!.isNotEmpty &&
|
||||
!checkoutSession.coupon!.productIds!.contains(cartItem.productId)) {
|
||||
continue;
|
||||
}
|
||||
subtotal += (parseWcPrice(cartItem.subtotal) * cartItem.quantity);
|
||||
eligibleCartLineItems.add(cartItem);
|
||||
}
|
||||
|
||||
String discountType = checkoutSession.coupon.discountType;
|
||||
String amount = checkoutSession.coupon.amount;
|
||||
String? discountType = checkoutSession.coupon!.discountType;
|
||||
String? amount = checkoutSession.coupon!.amount;
|
||||
|
||||
// Percentage
|
||||
if (discountType == 'percent') {
|
||||
return ((subtotal * double.parse(amount)) / 100).toStringAsFixed(2);
|
||||
return ((subtotal * double.parse(amount!)) / 100).toStringAsFixed(2);
|
||||
}
|
||||
|
||||
// Fixed cart
|
||||
if (discountType == 'fixed_cart') {
|
||||
return (double.parse(amount)).toStringAsFixed(2);
|
||||
return (double.parse(amount!)).toStringAsFixed(2);
|
||||
}
|
||||
|
||||
// Fixed product
|
||||
if (discountType == 'fixed_product') {
|
||||
return (eligibleCartLineItems.length * double.parse(amount))
|
||||
return (eligibleCartLineItems.length * double.parse(amount!))
|
||||
.toStringAsFixed(2);
|
||||
}
|
||||
return "0";
|
||||
|
||||
@ -14,24 +14,24 @@ import 'package:woosignal/models/response/product_variation.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
||||
|
||||
class CartLineItem {
|
||||
String name;
|
||||
int productId;
|
||||
int variationId;
|
||||
int quantity;
|
||||
bool isManagedStock;
|
||||
int stockQuantity;
|
||||
String shippingClassId;
|
||||
String taxStatus;
|
||||
String taxClass;
|
||||
bool shippingIsTaxable;
|
||||
String subtotal;
|
||||
String total;
|
||||
String imageSrc;
|
||||
String variationOptions;
|
||||
List<ws_product.Category> categories;
|
||||
bool onSale;
|
||||
String stockStatus;
|
||||
Object metaData = {};
|
||||
String? name;
|
||||
int? productId;
|
||||
int? variationId;
|
||||
int quantity = 0;
|
||||
bool? isManagedStock;
|
||||
int? stockQuantity;
|
||||
String? shippingClassId;
|
||||
String? taxStatus;
|
||||
String? taxClass;
|
||||
bool? shippingIsTaxable;
|
||||
String? subtotal;
|
||||
String? total;
|
||||
String? imageSrc;
|
||||
String? variationOptions;
|
||||
List<ws_product.Category>? categories;
|
||||
bool? onSale;
|
||||
String? stockStatus;
|
||||
Object? metaData = {};
|
||||
|
||||
CartLineItem(
|
||||
{this.name,
|
||||
@ -39,7 +39,7 @@ class CartLineItem {
|
||||
this.variationId,
|
||||
this.isManagedStock,
|
||||
this.stockQuantity,
|
||||
this.quantity,
|
||||
this.quantity = 1,
|
||||
this.stockStatus,
|
||||
this.shippingClassId,
|
||||
this.taxStatus,
|
||||
@ -57,10 +57,11 @@ class CartLineItem {
|
||||
return (quantity * parseWcPrice(subtotal)).toStringAsFixed(2);
|
||||
}
|
||||
|
||||
CartLineItem.fromProduct({int quantityAmount, ws_product.Product product}) {
|
||||
CartLineItem.fromProduct(
|
||||
{int? quantityAmount, required ws_product.Product product}) {
|
||||
name = product.name;
|
||||
productId = product.id;
|
||||
quantity = quantityAmount;
|
||||
quantity = quantityAmount ?? 1;
|
||||
taxStatus = product.taxStatus;
|
||||
shippingClassId = product.shippingClassId.toString();
|
||||
subtotal = product.price;
|
||||
@ -76,21 +77,21 @@ class CartLineItem {
|
||||
}
|
||||
|
||||
CartLineItem.fromProductVariation(
|
||||
{int quantityAmount,
|
||||
List<String> options,
|
||||
ws_product.Product product,
|
||||
ProductVariation productVariation}) {
|
||||
String imageSrc = getEnv("PRODUCT_PLACEHOLDER_IMAGE");
|
||||
{int? quantityAmount,
|
||||
required List<String> options,
|
||||
required ws_product.Product product,
|
||||
required ProductVariation productVariation}) {
|
||||
String? imageSrc = getEnv("PRODUCT_PLACEHOLDER_IMAGE");
|
||||
if (product.images.isNotEmpty) {
|
||||
imageSrc = product.images.first.src;
|
||||
}
|
||||
if (productVariation.image != null) {
|
||||
imageSrc = productVariation.image.src;
|
||||
imageSrc = productVariation.image!.src;
|
||||
}
|
||||
name = product.name;
|
||||
productId = product.id;
|
||||
variationId = productVariation.id;
|
||||
quantity = quantityAmount;
|
||||
quantity = quantityAmount ?? 1;
|
||||
taxStatus = productVariation.taxStatus;
|
||||
shippingClassId = productVariation.shippingClassId.toString();
|
||||
subtotal = productVariation.price;
|
||||
@ -145,7 +146,7 @@ class CartLineItem {
|
||||
'shipping_is_taxable': shippingIsTaxable,
|
||||
'image_src': imageSrc,
|
||||
'categories': categories != null
|
||||
? categories.map((e) => e.toJson()).toList()
|
||||
? categories!.map((e) => e.toJson()).toList()
|
||||
: [],
|
||||
'variation_options': variationOptions,
|
||||
'subtotal': subtotal,
|
||||
|
||||
@ -16,21 +16,21 @@ import 'package:flutter_app/app/models/payment_type.dart';
|
||||
import 'package:flutter_app/app/models/shipping_type.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/coupon.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
class CheckoutSession {
|
||||
bool shipToDifferentAddress = false;
|
||||
bool? shipToDifferentAddress = false;
|
||||
|
||||
CheckoutSession._privateConstructor();
|
||||
static final CheckoutSession getInstance =
|
||||
CheckoutSession._privateConstructor();
|
||||
|
||||
BillingDetails billingDetails;
|
||||
ShippingType shippingType;
|
||||
PaymentType paymentType;
|
||||
Coupon coupon;
|
||||
BillingDetails? billingDetails;
|
||||
ShippingType? shippingType;
|
||||
PaymentType? paymentType;
|
||||
Coupon? coupon;
|
||||
|
||||
void initSession() {
|
||||
billingDetails = BillingDetails();
|
||||
@ -45,8 +45,8 @@ class CheckoutSession {
|
||||
}
|
||||
|
||||
saveBillingAddress() async {
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress;
|
||||
CustomerAddress? customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.billingAddress;
|
||||
|
||||
if (customerAddress == null) {
|
||||
return;
|
||||
@ -56,9 +56,9 @@ class CheckoutSession {
|
||||
await NyStorage.store(SharedKey.customerBillingDetails, billingAddress);
|
||||
}
|
||||
|
||||
Future<CustomerAddress> getBillingAddress() async {
|
||||
String strCheckoutDetails =
|
||||
await NyStorage.read(SharedKey.customerBillingDetails);
|
||||
Future<CustomerAddress?> getBillingAddress() async {
|
||||
String? strCheckoutDetails =
|
||||
await (NyStorage.read(SharedKey.customerBillingDetails));
|
||||
|
||||
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
||||
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
||||
@ -70,8 +70,8 @@ class CheckoutSession {
|
||||
await NyStorage.delete(SharedKey.customerBillingDetails);
|
||||
|
||||
saveShippingAddress() async {
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||
CustomerAddress? customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress;
|
||||
if (customerAddress == null) {
|
||||
return;
|
||||
}
|
||||
@ -79,9 +79,9 @@ class CheckoutSession {
|
||||
await NyStorage.store(SharedKey.customerShippingDetails, shippingAddress);
|
||||
}
|
||||
|
||||
Future<CustomerAddress> getShippingAddress() async {
|
||||
String strCheckoutDetails =
|
||||
await NyStorage.read(SharedKey.customerShippingDetails);
|
||||
Future<CustomerAddress?> getShippingAddress() async {
|
||||
String? strCheckoutDetails =
|
||||
await (NyStorage.read(SharedKey.customerShippingDetails));
|
||||
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
||||
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
||||
}
|
||||
@ -91,19 +91,19 @@ class CheckoutSession {
|
||||
clearShippingAddress() async =>
|
||||
await NyStorage.delete(SharedKey.customerShippingDetails);
|
||||
|
||||
Future<String> total({bool withFormat = false, TaxRate taxRate}) async {
|
||||
Future<String> total({bool withFormat = false, TaxRate? taxRate}) async {
|
||||
double totalCart = parseWcPrice(await Cart.getInstance.getTotal());
|
||||
double totalShipping = 0;
|
||||
if (shippingType != null && shippingType.object != null) {
|
||||
switch (shippingType.methodId) {
|
||||
if (shippingType != null && shippingType!.object != null) {
|
||||
switch (shippingType!.methodId) {
|
||||
case "flat_rate":
|
||||
totalShipping = parseWcPrice(shippingType.cost);
|
||||
totalShipping = parseWcPrice(shippingType!.cost);
|
||||
break;
|
||||
case "free_shipping":
|
||||
totalShipping = parseWcPrice(shippingType.cost);
|
||||
totalShipping = parseWcPrice(shippingType!.cost);
|
||||
break;
|
||||
case "local_pickup":
|
||||
totalShipping = parseWcPrice(shippingType.cost);
|
||||
totalShipping = parseWcPrice(shippingType!.cost);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -11,14 +11,14 @@
|
||||
import 'package:flutter_app/app/models/customer_country.dart';
|
||||
|
||||
class CustomerAddress {
|
||||
String firstName;
|
||||
String lastName;
|
||||
String addressLine;
|
||||
String city;
|
||||
String postalCode;
|
||||
String emailAddress;
|
||||
String phoneNumber;
|
||||
CustomerCountry customerCountry;
|
||||
String? firstName;
|
||||
String? lastName;
|
||||
String? addressLine;
|
||||
String? city;
|
||||
String? postalCode;
|
||||
String? emailAddress;
|
||||
String? phoneNumber;
|
||||
CustomerCountry? customerCountry;
|
||||
|
||||
CustomerAddress(
|
||||
{this.firstName,
|
||||
@ -27,7 +27,7 @@ class CustomerAddress {
|
||||
this.city,
|
||||
this.postalCode,
|
||||
this.emailAddress,
|
||||
this.phoneNumber,
|
||||
this.phoneNumber,
|
||||
this.customerCountry});
|
||||
|
||||
void initAddress() {
|
||||
@ -42,17 +42,17 @@ class CustomerAddress {
|
||||
}
|
||||
|
||||
bool hasMissingFields() =>
|
||||
(firstName.isEmpty ||
|
||||
lastName.isEmpty ||
|
||||
addressLine.isEmpty ||
|
||||
city.isEmpty ||
|
||||
postalCode.isEmpty) ||
|
||||
(customerCountry.hasState() == true
|
||||
(firstName!.isEmpty ||
|
||||
lastName!.isEmpty ||
|
||||
addressLine!.isEmpty ||
|
||||
city!.isEmpty ||
|
||||
postalCode!.isEmpty) ||
|
||||
(customerCountry!.hasState() == true
|
||||
? (customerCountry?.state?.name ?? "").isEmpty
|
||||
: false);
|
||||
|
||||
String addressFull() {
|
||||
List<String> tmpArrAddress = [];
|
||||
List<String?> tmpArrAddress = [];
|
||||
if (addressLine != null && addressLine != "") {
|
||||
tmpArrAddress.add(addressLine);
|
||||
}
|
||||
@ -66,13 +66,13 @@ class CustomerAddress {
|
||||
tmpArrAddress.add(customerCountry?.state?.name);
|
||||
}
|
||||
if (customerCountry != null && customerCountry?.name != null) {
|
||||
tmpArrAddress.add(customerCountry.name);
|
||||
tmpArrAddress.add(customerCountry!.name);
|
||||
}
|
||||
return tmpArrAddress.join(", ");
|
||||
}
|
||||
|
||||
String nameFull() {
|
||||
List<String> tmpArrName = [];
|
||||
List<String?> tmpArrName = [];
|
||||
if (firstName != "") {
|
||||
tmpArrName.add(firstName);
|
||||
}
|
||||
@ -102,15 +102,15 @@ class CustomerAddress {
|
||||
data['address_line'] = addressLine;
|
||||
data['city'] = city;
|
||||
data['postal_code'] = postalCode;
|
||||
data['state'] = customerCountry.state;
|
||||
data['country'] = customerCountry.name;
|
||||
data['state'] = customerCountry!.state;
|
||||
data['country'] = customerCountry!.name;
|
||||
if (phoneNumber != null && phoneNumber != "") {
|
||||
data['phone_number'] = phoneNumber;
|
||||
}
|
||||
data['email_address'] = emailAddress;
|
||||
data['customer_country'] = null;
|
||||
if (customerCountry != null) {
|
||||
data['customer_country'] = customerCountry.toJson();
|
||||
data['customer_country'] = customerCountry!.toJson();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -11,21 +11,22 @@
|
||||
import 'package:flutter_app/app/models/default_shipping.dart';
|
||||
|
||||
class CustomerCountry {
|
||||
String countryCode;
|
||||
String name;
|
||||
DefaultShippingState state;
|
||||
String? countryCode;
|
||||
String? name;
|
||||
DefaultShippingState? state;
|
||||
|
||||
CustomerCountry({this.countryCode, this.name, this.state});
|
||||
|
||||
CustomerCountry.fromDefaultShipping({DefaultShipping defaultShipping}) {
|
||||
CustomerCountry.fromDefaultShipping(
|
||||
{required DefaultShipping defaultShipping}) {
|
||||
countryCode = defaultShipping.code;
|
||||
name = defaultShipping.country;
|
||||
if ((defaultShipping.states?.length ?? 0) == 1) {
|
||||
if ((defaultShipping.states.length) == 1) {
|
||||
state = defaultShipping.states.first;
|
||||
}
|
||||
}
|
||||
|
||||
CustomerCountry.fromJson(Map<String, dynamic> json) {
|
||||
CustomerCountry.fromJson(Map<String, dynamic>? json) {
|
||||
if (json == null) {
|
||||
return;
|
||||
}
|
||||
@ -40,7 +41,7 @@ class CustomerCountry {
|
||||
}
|
||||
}
|
||||
|
||||
bool hasState() => (state != null && state.name != null ? true : false);
|
||||
bool hasState() => (state != null && state!.name != null ? true : false);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
@ -48,7 +49,7 @@ class CustomerCountry {
|
||||
data['name'] = name;
|
||||
data['state'] = null;
|
||||
if (state != null) {
|
||||
data['state'] = state.toJson();
|
||||
data['state'] = state!.toJson();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -7,22 +7,19 @@
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class DefaultShipping {
|
||||
String code;
|
||||
String country;
|
||||
String? country;
|
||||
List<DefaultShippingState> states;
|
||||
DefaultShipping(
|
||||
{@required this.code, @required this.country, @required this.states});
|
||||
{required this.code, required this.country, required this.states});
|
||||
}
|
||||
|
||||
class DefaultShippingState {
|
||||
String code;
|
||||
String name;
|
||||
String? code;
|
||||
String? name;
|
||||
|
||||
DefaultShippingState({@required this.code, @required this.name});
|
||||
DefaultShippingState({required this.code, required this.name});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
class PaymentType {
|
||||
int id;
|
||||
String name;
|
||||
@ -18,9 +16,9 @@ class PaymentType {
|
||||
Function pay;
|
||||
|
||||
PaymentType(
|
||||
{@required this.id,
|
||||
@required this.name,
|
||||
@required this.desc,
|
||||
@required this.assetImage,
|
||||
@required this.pay});
|
||||
{required this.id,
|
||||
required this.name,
|
||||
required this.desc,
|
||||
required this.assetImage,
|
||||
required this.pay});
|
||||
}
|
||||
|
||||
@ -7,22 +7,20 @@
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
|
||||
class ShippingType {
|
||||
String methodId;
|
||||
String? methodId;
|
||||
String cost;
|
||||
String minimumValue;
|
||||
String? minimumValue;
|
||||
dynamic object;
|
||||
|
||||
ShippingType(
|
||||
{@required this.methodId,
|
||||
{required this.methodId,
|
||||
this.object,
|
||||
@required this.cost,
|
||||
@required this.minimumValue});
|
||||
required this.cost,
|
||||
required this.minimumValue});
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'methodId': methodId,
|
||||
@ -31,24 +29,24 @@ class ShippingType {
|
||||
'minimumValue': minimumValue
|
||||
};
|
||||
|
||||
String getTotal({bool withFormatting = false}) {
|
||||
String? getTotal({bool withFormatting = false}) {
|
||||
if (object != null) {
|
||||
switch (methodId) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (object as FlatRate);
|
||||
FlatRate? flatRate = (object as FlatRate?);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: flatRate.cost);
|
||||
: flatRate!.cost);
|
||||
case "free_shipping":
|
||||
FreeShipping freeShipping = (object as FreeShipping);
|
||||
FreeShipping? freeShipping = (object as FreeShipping?);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: freeShipping.cost);
|
||||
: freeShipping!.cost);
|
||||
case "local_pickup":
|
||||
LocalPickup localPickup = (object as LocalPickup);
|
||||
LocalPickup? localPickup = (object as LocalPickup?);
|
||||
return (withFormatting == true
|
||||
? formatStringCurrency(total: cost)
|
||||
: localPickup.cost);
|
||||
: localPickup!.cost);
|
||||
default:
|
||||
return "0";
|
||||
}
|
||||
@ -56,7 +54,7 @@ class ShippingType {
|
||||
return "0";
|
||||
}
|
||||
|
||||
String getTitle() {
|
||||
String? getTitle() {
|
||||
if (object != null) {
|
||||
switch (methodId) {
|
||||
case "flat_rate":
|
||||
@ -75,7 +73,7 @@ class ShippingType {
|
||||
return "";
|
||||
}
|
||||
|
||||
Map<String, dynamic> toShippingLineFee() {
|
||||
Map<String, dynamic>? toShippingLineFee() {
|
||||
if (object != null) {
|
||||
Map<String, dynamic> tmpShippingLinesObj = {};
|
||||
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class User extends Storable {
|
||||
String userId;
|
||||
String token;
|
||||
String? userId;
|
||||
String? token;
|
||||
|
||||
User();
|
||||
User.fromUserAuthResponse({this.userId, this.token});
|
||||
|
||||
@ -1,11 +1,29 @@
|
||||
// Label StoreMax
|
||||
//
|
||||
// Created by Anthony Gordon.
|
||||
// 2022, WooSignal Ltd. All rights reserved.
|
||||
//
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/networking/dio/base_api_service.dart';
|
||||
import 'package:flutter_app/app/networking/dio/interceptors/logging_interceptor.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
// 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.
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| ApiService
|
||||
| -------------------------------------------------------------------------
|
||||
| Define your API endpoints
|
||||
| Learn more https://nylo.dev/docs/3.x/networking
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
class ApiService {}
|
||||
class ApiService extends BaseApiService {
|
||||
ApiService({BuildContext? buildContext}) : super(buildContext);
|
||||
|
||||
@override
|
||||
String get baseUrl => getEnv('API_BASE_URL');
|
||||
|
||||
@override
|
||||
final interceptors = {LoggingInterceptor: LoggingInterceptor()};
|
||||
|
||||
Future<dynamic> fetchTestData() async {
|
||||
return await network(
|
||||
request: (request) => request.get("/endpoint-path"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
16
LabelStoreMax/lib/app/networking/dio/base_api_service.dart
Normal file
16
LabelStoreMax/lib/app/networking/dio/base_api_service.dart
Normal file
@ -0,0 +1,16 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/networking/dio/interceptors/logging_interceptor.dart';
|
||||
import 'package:flutter_app/config/decoders.dart';
|
||||
import 'package:nylo_framework/networking/ny_base_networking.dart';
|
||||
|
||||
class BaseApiService extends NyBaseApiService {
|
||||
BaseApiService(BuildContext? context) : super(context);
|
||||
|
||||
/// Map decoders to modelDecoders
|
||||
@override
|
||||
final Map<Type, dynamic> decoders = modelDecoders;
|
||||
|
||||
/// Default interceptors
|
||||
@override
|
||||
final interceptors = {LoggingInterceptor: LoggingInterceptor()};
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class BearerAuthInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
String? userToken = Backpack.instance.read('user_token');
|
||||
if (userToken != null) {
|
||||
options.headers.addAll({"Authorization": "Bearer $userToken"});
|
||||
}
|
||||
return super.onRequest(options, handler);
|
||||
}
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
handler.next(response);
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(DioError err, ErrorInterceptorHandler handler) {
|
||||
handler.next(err);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
import 'dart:developer';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class LoggingInterceptor extends Interceptor {
|
||||
@override
|
||||
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
|
||||
if (getEnv('APP_DEBUG') == true) {
|
||||
print('REQUEST[${options.method}] => PATH: ${options.path}');
|
||||
}
|
||||
return super.onRequest(options, handler);
|
||||
}
|
||||
|
||||
@override
|
||||
void onResponse(Response response, ResponseInterceptorHandler handler) {
|
||||
if (getEnv('APP_DEBUG') == true) {
|
||||
print(
|
||||
'RESPONSE[${response.statusCode}] => PATH: ${response.requestOptions.path}');
|
||||
print('DATA: ${response.requestOptions.path}');
|
||||
log(response.data.toString());
|
||||
}
|
||||
handler.next(response);
|
||||
}
|
||||
|
||||
@override
|
||||
void onError(DioError err, ErrorInterceptorHandler handler) {
|
||||
if (getEnv('APP_DEBUG') == true) {
|
||||
print(
|
||||
'ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
|
||||
}
|
||||
handler.next(err);
|
||||
}
|
||||
}
|
||||
96
LabelStoreMax/lib/app/providers/app_provider.dart
Normal file
96
LabelStoreMax/lib/app/providers/app_provider.dart
Normal file
@ -0,0 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:flutter_app/config/localization.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:wp_json_api/wp_json_api.dart';
|
||||
|
||||
class AppProvider implements NyProvider {
|
||||
boot(Nylo nylo) async {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
]);
|
||||
|
||||
await WooSignal.instance
|
||||
.init(appKey: getEnv('APP_KEY'), debugMode: getEnv('APP_DEBUG'));
|
||||
|
||||
// Notifications
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
///
|
||||
/// FirebaseMessaging messaging = FirebaseMessaging.instance;
|
||||
///
|
||||
/// NotificationSettings settings = await messaging.requestPermission(
|
||||
/// alert: true,
|
||||
/// announcement: false,
|
||||
/// badge: true,
|
||||
/// carPlay: false,
|
||||
/// criticalAlert: false,
|
||||
/// provisional: false,
|
||||
/// sound: true,
|
||||
/// );
|
||||
///
|
||||
/// if (settings.authorizationStatus == AuthorizationStatus.authorized) {
|
||||
/// String token = await messaging.getToken();
|
||||
/// WooSignal.instance.setFcmToken(token);
|
||||
/// }
|
||||
|
||||
AppHelper.instance.appConfig = WooSignalApp();
|
||||
AppHelper.instance.appConfig!.themeFont = "Poppins";
|
||||
AppHelper.instance.appConfig!.themeColors = {
|
||||
'light': {
|
||||
'background': '0xFFFFFFFF',
|
||||
'primary_text': '0xFF000000',
|
||||
'button_background': '0xFF529cda',
|
||||
'button_text': '0xFFFFFFFF',
|
||||
'app_bar_background': '0xFFFFFFFF',
|
||||
'app_bar_text': '0xFF3a3d40',
|
||||
},
|
||||
'dark': {
|
||||
'background': '0xFF212121',
|
||||
'primary_text': '0xFFE1E1E1',
|
||||
'button_background': '0xFFFFFFFF',
|
||||
'button_text': '0xFF232c33',
|
||||
'app_bar_background': '0xFF2C2C2C',
|
||||
'app_bar_text': '0xFFFFFFFF',
|
||||
}
|
||||
};
|
||||
|
||||
// WooSignal Setup
|
||||
WooSignalApp? wooSignalApp = await (appWooSignal((api) => api.getApp()));
|
||||
Locale locale = Locale('en');
|
||||
|
||||
if (wooSignalApp != null) {
|
||||
AppHelper.instance.appConfig = wooSignalApp;
|
||||
|
||||
if (wooSignalApp.wpLoginEnabled == 1) {
|
||||
WPJsonAPI.instance.initWith(
|
||||
baseUrl: wooSignalApp.wpLoginBaseUrl!,
|
||||
shouldDebug: getEnv('APP_DEBUG'),
|
||||
wpJsonPath: wooSignalApp.wpLoginWpApiPath!,
|
||||
);
|
||||
}
|
||||
|
||||
if (getEnv('DEFAULT_LOCALE', defaultValue: null) == null &&
|
||||
wooSignalApp.locale != null) {
|
||||
locale = Locale(wooSignalApp.locale!);
|
||||
} else {
|
||||
locale = Locale(envVal('DEFAULT_LOCALE', defaultValue: 'en'));
|
||||
}
|
||||
}
|
||||
|
||||
/// NyLocalization
|
||||
await NyLocalization.instance.init(
|
||||
localeType: localeType,
|
||||
languageCode: locale.languageCode,
|
||||
languagesList: languagesList,
|
||||
assetsDirectory: assetsDirectory,
|
||||
valuesAsMap: valuesAsMap);
|
||||
|
||||
return nylo;
|
||||
}
|
||||
}
|
||||
@ -21,11 +21,11 @@ import 'package:woosignal/models/response/order.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
cashOnDeliveryPay(context,
|
||||
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||
{required CheckoutConfirmationPageState state, TaxRate? taxRate}) async {
|
||||
try {
|
||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate, markPaid: false);
|
||||
|
||||
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||
Order? order = await (appWooSignal((api) => api.createOrder(orderWC)));
|
||||
|
||||
if (order != null) {
|
||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||
|
||||
11
LabelStoreMax/lib/app/providers/event_provider.dart
Normal file
11
LabelStoreMax/lib/app/providers/event_provider.dart
Normal file
@ -0,0 +1,11 @@
|
||||
import 'package:flutter_app/config/events.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class EventProvider implements NyProvider {
|
||||
@override
|
||||
boot(Nylo nylo) async {
|
||||
nylo.addEvents(events);
|
||||
|
||||
return nylo;
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ import 'package:woosignal/models/response/tax_rate.dart';
|
||||
// AS THE PAY METHOD
|
||||
|
||||
examplePay(context,
|
||||
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||
{required CheckoutConfirmationPageState state, TaxRate? taxRate}) async {
|
||||
// HANDLE YOUR PAYMENT INTEGRATION HERE
|
||||
// ...
|
||||
// ...
|
||||
@ -44,7 +44,7 @@ examplePay(context,
|
||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate, markPaid: true);
|
||||
|
||||
// CREATES ORDER IN WOOCOMMERCE
|
||||
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||
Order? order = await (appWooSignal((api) => api.createOrder(orderWC)));
|
||||
|
||||
// CHECK IF ORDER IS NULL
|
||||
if (order != null) {
|
||||
|
||||
@ -23,7 +23,7 @@ import 'package:woosignal/models/response/order.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
|
||||
payPalPay(context,
|
||||
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||
{required CheckoutConfirmationPageState state, TaxRate? taxRate}) async {
|
||||
await checkout(taxRate, (total, billingDetails, cart) async {
|
||||
List<CartLineItem> cartLineItems = await cart.getCart();
|
||||
String description = await cart.cartShortDesc();
|
||||
@ -35,7 +35,7 @@ payPalPay(context,
|
||||
description: description,
|
||||
amount: total,
|
||||
cartLineItems: cartLineItems))).then((value) async {
|
||||
if (!(value is Map<String, dynamic>)) {
|
||||
if (value is! Map<String, dynamic>) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Payment Cancelled"),
|
||||
@ -48,7 +48,7 @@ payPalPay(context,
|
||||
state.reloadState(showLoader: true);
|
||||
if (value.containsKey("status") && value["status"] == "success") {
|
||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate, markPaid: true);
|
||||
Order order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||
Order? order = await (appWooSignal((api) => api.createOrder(orderWC)));
|
||||
|
||||
if (order == null) {
|
||||
showToastNotification(
|
||||
|
||||
10
LabelStoreMax/lib/app/providers/route_provider.dart
Normal file
10
LabelStoreMax/lib/app/providers/route_provider.dart
Normal file
@ -0,0 +1,10 @@
|
||||
import 'package:flutter_app/routes/router.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class RouteProvider implements NyProvider {
|
||||
boot(Nylo nylo) async {
|
||||
nylo.addRouter(appRouter());
|
||||
|
||||
return nylo;
|
||||
}
|
||||
}
|
||||
@ -24,16 +24,16 @@ import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
stripePay(context,
|
||||
{@required CheckoutConfirmationPageState state, TaxRate taxRate}) async {
|
||||
WooSignalApp wooSignalApp = AppHelper.instance.appConfig;
|
||||
{required CheckoutConfirmationPageState state, TaxRate? taxRate}) async {
|
||||
WooSignalApp? wooSignalApp = AppHelper.instance.appConfig;
|
||||
|
||||
bool liveMode = getEnv('STRIPE_LIVE_MODE') == null
|
||||
? !wooSignalApp.stripeLiveMode
|
||||
? !wooSignalApp!.stripeLiveMode!
|
||||
: getEnv('STRIPE_LIVE_MODE', defaultValue: false);
|
||||
|
||||
// CONFIGURE STRIPE
|
||||
Stripe.stripeAccountId =
|
||||
getEnv('STRIPE_ACCOUNT') ?? wooSignalApp.stripeAccount;
|
||||
getEnv('STRIPE_ACCOUNT') ?? wooSignalApp!.stripeAccount;
|
||||
|
||||
Stripe.publishableKey = liveMode
|
||||
? "pk_live_IyS4Vt86L49jITSfaUShumzi"
|
||||
@ -51,10 +51,10 @@ stripePay(context,
|
||||
// // CHECKOUT HELPER
|
||||
await checkout(taxRate, (total, billingDetails, cart) async {
|
||||
Map<String, dynamic> address = {
|
||||
"name": billingDetails.billingAddress.nameFull(),
|
||||
"line1": billingDetails.shippingAddress.addressLine,
|
||||
"city": billingDetails.shippingAddress.city,
|
||||
"postal_code": billingDetails.shippingAddress.postalCode,
|
||||
"name": billingDetails!.billingAddress!.nameFull(),
|
||||
"line1": billingDetails.shippingAddress!.addressLine,
|
||||
"city": billingDetails.shippingAddress!.city,
|
||||
"postal_code": billingDetails.shippingAddress!.postalCode,
|
||||
"country": (billingDetails.shippingAddress?.customerCountry?.name ?? "")
|
||||
};
|
||||
|
||||
@ -62,7 +62,7 @@ stripePay(context,
|
||||
|
||||
rsp = await appWooSignal((api) => api.stripePaymentIntent(
|
||||
amount: total,
|
||||
email: billingDetails.billingAddress.emailAddress,
|
||||
email: billingDetails.billingAddress!.emailAddress,
|
||||
desc: cartShortDesc,
|
||||
shipping: address,
|
||||
));
|
||||
@ -87,7 +87,7 @@ stripePay(context,
|
||||
: ThemeMode.dark,
|
||||
testEnv: liveMode,
|
||||
merchantCountryCode: envVal('STRIPE_COUNTRY_CODE',
|
||||
defaultValue: wooSignalApp.stripeCountryCode),
|
||||
defaultValue: wooSignalApp!.stripeCountryCode),
|
||||
merchantDisplayName:
|
||||
envVal('APP_NAME', defaultValue: wooSignalApp.appName),
|
||||
paymentIntentClientSecret: rsp['client_secret'],
|
||||
@ -98,7 +98,7 @@ stripePay(context,
|
||||
state.reloadState(showLoader: true);
|
||||
|
||||
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) {
|
||||
showToastNotification(
|
||||
@ -113,12 +113,12 @@ stripePay(context,
|
||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||
} on StripeException catch (e) {
|
||||
if (getEnv('APP_DEBUG', defaultValue: true)) {
|
||||
NyLogger.error(e.error.message);
|
||||
NyLogger.error(e.error.message!);
|
||||
}
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Oops!"),
|
||||
description: e.error.localizedMessage,
|
||||
description: e.error.localizedMessage!,
|
||||
icon: Icons.payment,
|
||||
style: ToastNotificationStyleType.WARNING,
|
||||
);
|
||||
|
||||
@ -1,42 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/config/app_theme.dart';
|
||||
import 'package:flutter_app/config/theme.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
// ignore: must_be_immutable
|
||||
class AppBuild extends StatelessWidget {
|
||||
String initialRoute;
|
||||
ThemeData themeData;
|
||||
ThemeData darkTheme;
|
||||
ThemeData lightTheme;
|
||||
Locale locale;
|
||||
String title;
|
||||
String? initialRoute;
|
||||
ThemeData? themeData;
|
||||
ThemeData? darkTheme;
|
||||
ThemeData? lightTheme;
|
||||
Locale? locale;
|
||||
String? title;
|
||||
bool debugShowCheckedModeBanner;
|
||||
bool debugShowMaterialGrid;
|
||||
bool showPerformanceOverlay;
|
||||
bool checkerboardRasterCacheImages;
|
||||
bool checkerboardOffscreenLayers;
|
||||
bool showSemanticsDebugger;
|
||||
Map<LogicalKeySet, Intent> shortcuts;
|
||||
Map<Type, Action<Intent>> actions;
|
||||
Map<LogicalKeySet, Intent>? shortcuts;
|
||||
Map<Type, Action<Intent>>? actions;
|
||||
List<Locale> supportedLocales;
|
||||
ThemeMode themeMode;
|
||||
Color color;
|
||||
GenerateAppTitle onGenerateTitle;
|
||||
TransitionBuilder builder;
|
||||
Color? color;
|
||||
GenerateAppTitle? onGenerateTitle;
|
||||
TransitionBuilder? builder;
|
||||
List<NavigatorObserver> navigatorObservers;
|
||||
RouteFactory onUnknownRoute;
|
||||
InitialRouteListFactory onGenerateInitialRoutes;
|
||||
GlobalKey<NavigatorState> navigatorKey;
|
||||
RouteFactory? onUnknownRoute;
|
||||
InitialRouteListFactory? onGenerateInitialRoutes;
|
||||
GlobalKey<NavigatorState>? navigatorKey;
|
||||
|
||||
Route<dynamic> Function(RouteSettings settings) onGenerateRoute;
|
||||
Route<dynamic>? Function(RouteSettings settings) onGenerateRoute;
|
||||
|
||||
AppBuild({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.initialRoute,
|
||||
this.title,
|
||||
this.locale,
|
||||
this.themeData,
|
||||
@required this.onGenerateRoute,
|
||||
required this.onGenerateRoute,
|
||||
this.navigatorKey,
|
||||
this.onGenerateInitialRoutes,
|
||||
this.onUnknownRoute,
|
||||
@ -64,7 +64,7 @@ class AppBuild extends StatelessWidget {
|
||||
child: ThemeProvider(
|
||||
themes: appThemes
|
||||
.map((appTheme) => appTheme.toAppTheme(
|
||||
defaultTheme: appTheme.theme.brightness == Brightness.light
|
||||
defaultTheme: appTheme.theme!.brightness == Brightness.light
|
||||
? lightTheme
|
||||
: darkTheme))
|
||||
.toList(),
|
||||
@ -96,13 +96,12 @@ class AppBuild extends StatelessWidget {
|
||||
darkTheme: darkTheme ?? ThemeConfig.dark().theme,
|
||||
theme: themeData ?? ThemeProvider.themeOf(context).data,
|
||||
localeResolutionCallback:
|
||||
(Locale locale, Iterable<Locale> supportedLocales) {
|
||||
(Locale? locale, Iterable<Locale> supportedLocales) {
|
||||
return locale;
|
||||
},
|
||||
localizationsDelegates: NyLocalization.instance.delegates,
|
||||
locale: NyLocalization.instance.locale,
|
||||
supportedLocales:
|
||||
supportedLocales ?? NyLocalization.instance.locals(),
|
||||
supportedLocales: supportedLocales,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -15,5 +15,5 @@ class AppHelper {
|
||||
|
||||
static final AppHelper instance = AppHelper._privateConstructor();
|
||||
|
||||
WooSignalApp appConfig;
|
||||
WooSignalApp? appConfig;
|
||||
}
|
||||
|
||||
@ -3,10 +3,10 @@ import 'package:flutter_app/resources/themes/styles/base_styles.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class BaseThemeConfig {
|
||||
final String id;
|
||||
final String description;
|
||||
final ThemeData theme;
|
||||
final BaseColorStyles colors;
|
||||
final String? id;
|
||||
final String? description;
|
||||
final ThemeData? theme;
|
||||
final BaseColorStyles? colors;
|
||||
final dynamic meta;
|
||||
|
||||
BaseThemeConfig(
|
||||
@ -16,9 +16,9 @@ class BaseThemeConfig {
|
||||
this.colors,
|
||||
this.meta = const {}});
|
||||
|
||||
AppTheme toAppTheme({ThemeData defaultTheme}) => AppTheme(
|
||||
id: id,
|
||||
data: defaultTheme ?? theme,
|
||||
description: description,
|
||||
AppTheme toAppTheme({ThemeData? defaultTheme}) => AppTheme(
|
||||
id: id!,
|
||||
data: defaultTheme ?? theme!,
|
||||
description: description!,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,96 +1,12 @@
|
||||
// import 'package:firebase_core/firebase_core.dart';
|
||||
// import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
// import 'package:flutter_app/firebase_options.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/config/app_localization.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
import 'package:wp_json_api/wp_json_api.dart';
|
||||
|
||||
/// boot application
|
||||
Future<void> boot() async {
|
||||
await SystemChrome.setPreferredOrientations([
|
||||
DeviceOrientation.portraitUp,
|
||||
]);
|
||||
import 'package:flutter_app/config/providers.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
await WooSignal.instance
|
||||
.init(appKey: getEnv('APP_KEY'), debugMode: getEnv('APP_DEBUG'));
|
||||
|
||||
// Notifications
|
||||
/// await Firebase.initializeApp(
|
||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
||||
/// );
|
||||
///
|
||||
/// FirebaseMessaging messaging = FirebaseMessaging.instance;
|
||||
///
|
||||
/// NotificationSettings settings = await messaging.requestPermission(
|
||||
/// alert: true,
|
||||
/// announcement: false,
|
||||
/// badge: true,
|
||||
/// carPlay: false,
|
||||
/// criticalAlert: false,
|
||||
/// provisional: false,
|
||||
/// sound: true,
|
||||
/// );
|
||||
///
|
||||
/// if (settings.authorizationStatus == AuthorizationStatus.authorized) {
|
||||
/// String token = await messaging.getToken();
|
||||
/// WooSignal.instance.setFcmToken(token);
|
||||
/// }
|
||||
|
||||
AppHelper?.instance?.appConfig = WooSignalApp();
|
||||
AppHelper.instance.appConfig.themeFont = "Poppins";
|
||||
AppHelper.instance.appConfig.themeColors = {
|
||||
'light': {
|
||||
'background': '0xFFFFFFFF',
|
||||
'primary_text': '0xFF000000',
|
||||
'button_background': '0xFF529cda',
|
||||
'button_text': '0xFFFFFFFF',
|
||||
'app_bar_background': '0xFFFFFFFF',
|
||||
'app_bar_text': '0xFF3a3d40',
|
||||
},
|
||||
'dark': {
|
||||
'background': '0xFF212121',
|
||||
'primary_text': '0xFFE1E1E1',
|
||||
'button_background': '0xFFFFFFFF',
|
||||
'button_text': '0xFF232c33',
|
||||
'app_bar_background': '0xFF2C2C2C',
|
||||
'app_bar_text': '0xFFFFFFFF',
|
||||
}
|
||||
};
|
||||
|
||||
// WooSignal Setup
|
||||
WooSignalApp wooSignalApp = await appWooSignal((api) => api.getApp());
|
||||
Locale locale = Locale('en');
|
||||
|
||||
if (wooSignalApp != null) {
|
||||
AppHelper.instance.appConfig = wooSignalApp;
|
||||
|
||||
if (wooSignalApp.wpLoginEnabled == 1) {
|
||||
WPJsonAPI.instance.initWith(
|
||||
baseUrl: wooSignalApp.wpLoginBaseUrl,
|
||||
shouldDebug: getEnv('APP_DEBUG'),
|
||||
wpJsonPath: wooSignalApp.wpLoginWpApiPath,
|
||||
);
|
||||
}
|
||||
|
||||
if (getEnv('DEFAULT_LOCALE', defaultValue: null) == null &&
|
||||
wooSignalApp.locale != null) {
|
||||
locale = Locale(wooSignalApp.locale);
|
||||
} else {
|
||||
locale = Locale(envVal('DEFAULT_LOCALE', defaultValue: 'en'));
|
||||
}
|
||||
}
|
||||
|
||||
/// NyLocalization
|
||||
await NyLocalization.instance.init(
|
||||
localeType: localeType,
|
||||
languageCode: locale.languageCode,
|
||||
languagesList: languagesList,
|
||||
assetsDirectory: assetsDirectory,
|
||||
valuesAsMap: valuesAsMap);
|
||||
class Boot {
|
||||
static Future<Nylo> nylo() async => await bootApplication(providers);
|
||||
static Future<void> finished(Nylo nylo) async => await bootFinished(nylo);
|
||||
}
|
||||
|
||||
@ -20,12 +20,12 @@ import 'package:woosignal/models/payload/order_wc.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
|
||||
Future<OrderWC> buildOrderWC({TaxRate? taxRate, bool markPaid = true}) async {
|
||||
CheckoutSession checkoutSession = CheckoutSession.getInstance;
|
||||
OrderWC orderWC = OrderWC();
|
||||
WooSignalApp wooSignalApp = AppHelper.instance.appConfig;
|
||||
WooSignalApp wooSignalApp = AppHelper.instance.appConfig!;
|
||||
|
||||
String paymentMethodName = checkoutSession.paymentType.name ?? "";
|
||||
String paymentMethodName = checkoutSession.paymentType!.name;
|
||||
|
||||
orderWC.paymentMethod = Platform.isAndroid
|
||||
? "$paymentMethodName - Android App"
|
||||
@ -35,9 +35,10 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
|
||||
|
||||
orderWC.setPaid = markPaid;
|
||||
orderWC.status = "pending";
|
||||
orderWC.currency = wooSignalApp.currencyMeta.code.toUpperCase();
|
||||
orderWC.customerId =
|
||||
(wooSignalApp.wpLoginEnabled == 1) ? int.parse(await readUserId()) : 0;
|
||||
orderWC.currency = wooSignalApp.currencyMeta!.code!.toUpperCase();
|
||||
orderWC.customerId = (wooSignalApp.wpLoginEnabled == 1)
|
||||
? int.parse(await (readUserId()) ?? "0")
|
||||
: 0;
|
||||
|
||||
List<LineItems> lineItems = [];
|
||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||
@ -56,49 +57,50 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
|
||||
|
||||
orderWC.lineItems = lineItems;
|
||||
|
||||
BillingDetails billingDetails = checkoutSession.billingDetails;
|
||||
BillingDetails billingDetails = checkoutSession.billingDetails!;
|
||||
|
||||
Billing billing = Billing();
|
||||
billing.firstName = billingDetails.billingAddress.firstName;
|
||||
billing.lastName = billingDetails.billingAddress.lastName;
|
||||
billing.address1 = billingDetails.billingAddress.addressLine;
|
||||
billing.city = billingDetails.billingAddress.city;
|
||||
billing.postcode = billingDetails.billingAddress.postalCode;
|
||||
billing.email = billingDetails.billingAddress.emailAddress;
|
||||
if (billingDetails.billingAddress.phoneNumber != "") {
|
||||
billing.phone = billingDetails.billingAddress.phoneNumber;
|
||||
billing.firstName = billingDetails.billingAddress!.firstName;
|
||||
billing.lastName = billingDetails.billingAddress!.lastName;
|
||||
billing.address1 = billingDetails.billingAddress!.addressLine;
|
||||
billing.city = billingDetails.billingAddress!.city;
|
||||
billing.postcode = billingDetails.billingAddress!.postalCode;
|
||||
billing.email = billingDetails.billingAddress!.emailAddress;
|
||||
if (billingDetails.billingAddress!.phoneNumber != "") {
|
||||
billing.phone = billingDetails.billingAddress!.phoneNumber;
|
||||
}
|
||||
if (billingDetails.billingAddress.customerCountry.hasState()) {
|
||||
billing.state = billingDetails.billingAddress.customerCountry.state.name;
|
||||
if (billingDetails.billingAddress!.customerCountry!.hasState()) {
|
||||
billing.state = billingDetails.billingAddress!.customerCountry!.state!.name;
|
||||
}
|
||||
billing.country = billingDetails.billingAddress.customerCountry.name;
|
||||
billing.country = billingDetails.billingAddress!.customerCountry!.name;
|
||||
|
||||
orderWC.billing = billing;
|
||||
|
||||
Shipping shipping = Shipping();
|
||||
|
||||
shipping.firstName = billingDetails.shippingAddress.firstName;
|
||||
shipping.lastName = billingDetails.shippingAddress.lastName;
|
||||
shipping.address1 = billingDetails.shippingAddress.addressLine;
|
||||
shipping.city = billingDetails.shippingAddress.city;
|
||||
shipping.postcode = billingDetails.shippingAddress.postalCode;
|
||||
if (billingDetails.shippingAddress.customerCountry.hasState()) {
|
||||
billing.state = billingDetails.shippingAddress.customerCountry.state.name;
|
||||
shipping.firstName = billingDetails.shippingAddress!.firstName;
|
||||
shipping.lastName = billingDetails.shippingAddress!.lastName;
|
||||
shipping.address1 = billingDetails.shippingAddress!.addressLine;
|
||||
shipping.city = billingDetails.shippingAddress!.city;
|
||||
shipping.postcode = billingDetails.shippingAddress!.postalCode;
|
||||
if (billingDetails.shippingAddress!.customerCountry!.hasState()) {
|
||||
billing.state =
|
||||
billingDetails.shippingAddress!.customerCountry!.state!.name;
|
||||
}
|
||||
billing.country = billingDetails.shippingAddress.customerCountry.name;
|
||||
billing.country = billingDetails.shippingAddress!.customerCountry!.name;
|
||||
|
||||
orderWC.shipping = shipping;
|
||||
|
||||
orderWC.shippingLines = [];
|
||||
if (wooSignalApp.disableShipping != 1) {
|
||||
Map<String, dynamic> shippingLineFeeObj =
|
||||
checkoutSession.shippingType.toShippingLineFee();
|
||||
Map<String, dynamic>? shippingLineFeeObj =
|
||||
checkoutSession.shippingType!.toShippingLineFee();
|
||||
if (shippingLineFeeObj != null) {
|
||||
ShippingLines shippingLine = ShippingLines();
|
||||
shippingLine.methodId = shippingLineFeeObj['method_id'];
|
||||
shippingLine.methodTitle = shippingLineFeeObj['method_title'];
|
||||
shippingLine.total = shippingLineFeeObj['total'];
|
||||
orderWC.shippingLines.add(shippingLine);
|
||||
orderWC.shippingLines!.add(shippingLine);
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,13 +111,13 @@ Future<OrderWC> buildOrderWC({TaxRate taxRate, bool markPaid = true}) async {
|
||||
feeLines.total = await Cart.getInstance.taxAmount(taxRate);
|
||||
feeLines.taxClass = "";
|
||||
feeLines.taxStatus = "taxable";
|
||||
orderWC.feeLines.add(feeLines);
|
||||
orderWC.feeLines!.add(feeLines);
|
||||
}
|
||||
|
||||
if (checkoutSession.coupon != null) {
|
||||
orderWC.couponLines = [];
|
||||
CouponLines couponLine = CouponLines(code: checkoutSession.coupon.code);
|
||||
orderWC.couponLines.add(couponLine);
|
||||
CouponLines couponLine = CouponLines(code: checkoutSession.coupon!.code);
|
||||
orderWC.couponLines!.add(couponLine);
|
||||
}
|
||||
|
||||
return orderWC;
|
||||
|
||||
@ -8,8 +8,4 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
|
||||
enum WishlistAction {
|
||||
add,
|
||||
remove
|
||||
}
|
||||
enum WishlistAction { add, remove }
|
||||
|
||||
@ -9,6 +9,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'dart:convert';
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/models/billing_details.dart';
|
||||
import 'package:flutter_app/app/models/cart.dart';
|
||||
@ -20,9 +21,11 @@ import 'package:flutter_app/app/models/user.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
|
||||
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
||||
import 'package:flutter_app/config/app_currency.dart';
|
||||
import 'package:flutter_app/config/app_payment_gateways.dart';
|
||||
import 'package:flutter_app/config/app_theme.dart';
|
||||
import 'package:flutter_app/config/currency.dart';
|
||||
import 'package:flutter_app/config/decoders.dart';
|
||||
import 'package:flutter_app/config/events.dart';
|
||||
import 'package:flutter_app/config/payment_gateways.dart';
|
||||
import 'package:flutter_app/config/theme.dart';
|
||||
import 'package:flutter_app/resources/themes/styles/base_styles.dart';
|
||||
import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
@ -34,15 +37,14 @@ import 'package:flutter_web_browser/flutter_web_browser.dart';
|
||||
import 'package:math_expressions/math_expressions.dart';
|
||||
import 'package:money_formatter/money_formatter.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:platform_alert_dialog/platform_alert_dialog.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:status_alert/status_alert.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal/woosignal.dart';
|
||||
|
||||
Future<User> getUser() async =>
|
||||
(await NyStorage.read<User>(SharedKey.authUser, model: User()));
|
||||
Future<User?> getUser() async =>
|
||||
(await (NyStorage.read<User>(SharedKey.authUser, model: User())));
|
||||
|
||||
Future appWooSignal(Function(WooSignal) api) async {
|
||||
return await api(WooSignal.instance);
|
||||
@ -50,7 +52,7 @@ Future appWooSignal(Function(WooSignal) api) async {
|
||||
|
||||
/// helper to find correct color from the [context].
|
||||
class ThemeColor {
|
||||
static BaseColorStyles get(BuildContext context) {
|
||||
static BaseColorStyles? get(BuildContext context) {
|
||||
return ((Theme.of(context).brightness == Brightness.light)
|
||||
? ThemeConfig.light().colors
|
||||
: ThemeConfig.dark().colors);
|
||||
@ -60,39 +62,37 @@ class ThemeColor {
|
||||
/// helper to set colors on TextStyle
|
||||
extension ColorsHelper on TextStyle {
|
||||
TextStyle setColor(
|
||||
BuildContext context, Color Function(BaseColorStyles color) newColor) {
|
||||
BuildContext context, Color Function(BaseColorStyles? color) newColor) {
|
||||
return copyWith(color: newColor(ThemeColor.get(context)));
|
||||
}
|
||||
}
|
||||
|
||||
List<PaymentType> getPaymentTypes() {
|
||||
List<PaymentType> paymentTypes = [];
|
||||
for (var appPaymentGateway in app_payment_gateways) {
|
||||
List<PaymentType?> getPaymentTypes() {
|
||||
List<PaymentType?> paymentTypes = [];
|
||||
for (var appPaymentGateway in appPaymentGateways) {
|
||||
if (paymentTypes.firstWhere(
|
||||
(paymentType) => paymentType.name != appPaymentGateway,
|
||||
(paymentType) => paymentType!.name != appPaymentGateway,
|
||||
orElse: () => null) ==
|
||||
null) {
|
||||
paymentTypes.add(paymentTypeList.firstWhere(
|
||||
(paymentTypeList) => paymentTypeList.name == appPaymentGateway,
|
||||
orElse: () => null));
|
||||
paymentTypes.add(paymentTypeList.firstWhereOrNull(
|
||||
(paymentTypeList) => paymentTypeList.name == appPaymentGateway));
|
||||
}
|
||||
}
|
||||
|
||||
if (!app_payment_gateways.contains('Stripe') &&
|
||||
AppHelper.instance.appConfig.stripeEnabled == true) {
|
||||
if (!appPaymentGateways.contains('Stripe') &&
|
||||
AppHelper.instance.appConfig!.stripeEnabled == true) {
|
||||
paymentTypes.add(paymentTypeList
|
||||
.firstWhere((element) => element.name == "Stripe", orElse: () => null));
|
||||
.firstWhereOrNull((element) => element.name == "Stripe"));
|
||||
}
|
||||
if (!app_payment_gateways.contains('PayPal') &&
|
||||
AppHelper.instance.appConfig.paypalEnabled == true) {
|
||||
if (!appPaymentGateways.contains('PayPal') &&
|
||||
AppHelper.instance.appConfig!.paypalEnabled == true) {
|
||||
paymentTypes.add(paymentTypeList
|
||||
.firstWhere((element) => element.name == "PayPal", orElse: () => null));
|
||||
.firstWhereOrNull((element) => element.name == "PayPal"));
|
||||
}
|
||||
if (!app_payment_gateways.contains('CashOnDelivery') &&
|
||||
AppHelper.instance.appConfig.codEnabled == true) {
|
||||
paymentTypes.add(paymentTypeList.firstWhere(
|
||||
(element) => element.name == "CashOnDelivery",
|
||||
orElse: () => null));
|
||||
if (!appPaymentGateways.contains('CashOnDelivery') &&
|
||||
AppHelper.instance.appConfig!.codEnabled == true) {
|
||||
paymentTypes.add(paymentTypeList
|
||||
.firstWhereOrNull((element) => element.name == "CashOnDelivery"));
|
||||
}
|
||||
|
||||
return paymentTypes.where((v) => v != null).toList();
|
||||
@ -102,11 +102,11 @@ dynamic envVal(String envVal, {dynamic defaultValue}) =>
|
||||
(getEnv(envVal) ?? defaultValue);
|
||||
|
||||
PaymentType addPayment(
|
||||
{@required int id,
|
||||
@required String name,
|
||||
@required String desc,
|
||||
@required String assetImage,
|
||||
@required Function pay}) =>
|
||||
{required int id,
|
||||
required String name,
|
||||
required String desc,
|
||||
required String assetImage,
|
||||
required Function pay}) =>
|
||||
PaymentType(
|
||||
id: id,
|
||||
name: name,
|
||||
@ -116,7 +116,10 @@ PaymentType addPayment(
|
||||
);
|
||||
|
||||
showStatusAlert(context,
|
||||
{@required String title, String subtitle, IconData icon, int duration}) {
|
||||
{required String title,
|
||||
required String subtitle,
|
||||
IconData? icon,
|
||||
int? duration}) {
|
||||
StatusAlert.show(
|
||||
context,
|
||||
duration: Duration(seconds: duration ?? 2),
|
||||
@ -126,31 +129,31 @@ showStatusAlert(context,
|
||||
);
|
||||
}
|
||||
|
||||
String parseHtmlString(String htmlString) {
|
||||
String parseHtmlString(String? htmlString) {
|
||||
var document = parse(htmlString);
|
||||
return parse(document.body.text).documentElement.text;
|
||||
return parse(document.body!.text).documentElement!.text;
|
||||
}
|
||||
|
||||
String moneyFormatter(double amount) {
|
||||
MoneyFormatter fmf = MoneyFormatter(
|
||||
amount: amount,
|
||||
settings: MoneyFormatterSettings(
|
||||
symbol: AppHelper.instance.appConfig.currencyMeta.symbolNative,
|
||||
symbol: AppHelper.instance.appConfig!.currencyMeta!.symbolNative,
|
||||
),
|
||||
);
|
||||
if (app_currency_symbol_position == SymbolPositionType.left) {
|
||||
if (appCurrencySymbolPosition == SymbolPositionType.left) {
|
||||
return fmf.output.symbolOnLeft;
|
||||
} else if (app_currency_symbol_position == SymbolPositionType.right) {
|
||||
} else if (appCurrencySymbolPosition == SymbolPositionType.right) {
|
||||
return fmf.output.symbolOnRight;
|
||||
}
|
||||
return fmf.output.symbolOnLeft;
|
||||
}
|
||||
|
||||
String formatDoubleCurrency({@required double total}) {
|
||||
String formatDoubleCurrency({required double total}) {
|
||||
return moneyFormatter(total);
|
||||
}
|
||||
|
||||
String formatStringCurrency({@required String total}) {
|
||||
String formatStringCurrency({required String? total}) {
|
||||
double tmpVal = 0;
|
||||
if (total != null && total != "") {
|
||||
tmpVal = parseWcPrice(total);
|
||||
@ -159,20 +162,24 @@ String formatStringCurrency({@required String total}) {
|
||||
}
|
||||
|
||||
String workoutSaleDiscount(
|
||||
{@required String salePrice, @required String priceBefore}) {
|
||||
{required String? salePrice, required String? priceBefore}) {
|
||||
double dSalePrice = parseWcPrice(salePrice);
|
||||
double dPriceBefore = parseWcPrice(priceBefore);
|
||||
return ((dPriceBefore - dSalePrice) * (100 / dPriceBefore))
|
||||
.toStringAsFixed(0);
|
||||
}
|
||||
|
||||
openBrowserTab({@required String url}) async {
|
||||
openBrowserTab({required String url}) async {
|
||||
await FlutterWebBrowser.openWebPage(
|
||||
url: url,
|
||||
customTabsOptions: CustomTabsOptions(toolbarColor: Colors.white70));
|
||||
url: url,
|
||||
customTabsOptions: CustomTabsOptions(
|
||||
defaultColorSchemeParams:
|
||||
CustomTabsColorSchemeParams(toolbarColor: Colors.white70),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool isNumeric(String str) {
|
||||
bool isNumeric(String? str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
@ -180,18 +187,18 @@ bool isNumeric(String str) {
|
||||
}
|
||||
|
||||
checkout(
|
||||
TaxRate taxRate,
|
||||
Function(String total, BillingDetails billingDetails, Cart cart)
|
||||
TaxRate? taxRate,
|
||||
Function(String total, BillingDetails? billingDetails, Cart cart)
|
||||
completeCheckout) async {
|
||||
String cartTotal = await CheckoutSession.getInstance
|
||||
.total(withFormat: false, taxRate: taxRate);
|
||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||
BillingDetails? billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||
Cart cart = Cart.getInstance;
|
||||
return await completeCheckout(cartTotal, billingDetails, cart);
|
||||
}
|
||||
|
||||
double strCal({@required String sum}) {
|
||||
if (sum == null || sum == "") {
|
||||
double? strCal({required String sum}) {
|
||||
if (sum == "") {
|
||||
return 0;
|
||||
}
|
||||
Parser p = Parser();
|
||||
@ -200,7 +207,7 @@ double strCal({@required String sum}) {
|
||||
return exp.evaluate(EvaluationType.REAL, cm);
|
||||
}
|
||||
|
||||
Future<double> workoutShippingCostWC({@required String sum}) async {
|
||||
Future<double?> workoutShippingCostWC({required String? sum}) async {
|
||||
if (sum == null || sum == "") {
|
||||
return 0;
|
||||
}
|
||||
@ -219,27 +226,27 @@ Future<double> workoutShippingCostWC({@required String sum}) async {
|
||||
if (replace.groupCount < 1) {
|
||||
return "()";
|
||||
}
|
||||
String newSum = replace.group(1);
|
||||
String newSum = replace.group(1)!;
|
||||
|
||||
// PERCENT
|
||||
String percentVal = newSum.replaceAllMapped(
|
||||
defaultRegex(r'percent="([0-9\.]+)"'), (replacePercent) {
|
||||
if (replacePercent != null && replacePercent.groupCount >= 1) {
|
||||
if (replacePercent.groupCount >= 1) {
|
||||
String strPercentage = "( (" +
|
||||
orderTotal.toString() +
|
||||
" * " +
|
||||
replacePercent.group(1).toString() +
|
||||
") / 100 )";
|
||||
double calPercentage = strCal(sum: strPercentage);
|
||||
double? calPercentage = strCal(sum: strPercentage);
|
||||
|
||||
// MIN
|
||||
String strRegexMinFee = r'min_fee="([0-9\.]+)"';
|
||||
if (defaultRegex(strRegexMinFee).hasMatch(newSum)) {
|
||||
String strMinFee =
|
||||
defaultRegex(strRegexMinFee).firstMatch(newSum).group(1) ?? "0";
|
||||
defaultRegex(strRegexMinFee).firstMatch(newSum)!.group(1) ?? "0";
|
||||
double doubleMinFee = double.parse(strMinFee);
|
||||
|
||||
if (calPercentage < doubleMinFee) {
|
||||
if (calPercentage! < doubleMinFee) {
|
||||
return "(" + doubleMinFee.toString() + ")";
|
||||
}
|
||||
newSum = newSum.replaceAll(defaultRegex(strRegexMinFee), "");
|
||||
@ -249,10 +256,10 @@ Future<double> workoutShippingCostWC({@required String sum}) async {
|
||||
String strRegexMaxFee = r'max_fee="([0-9\.]+)"';
|
||||
if (defaultRegex(strRegexMaxFee).hasMatch(newSum)) {
|
||||
String strMaxFee =
|
||||
defaultRegex(strRegexMaxFee).firstMatch(newSum).group(1) ?? "0";
|
||||
defaultRegex(strRegexMaxFee).firstMatch(newSum)!.group(1) ?? "0";
|
||||
double doubleMaxFee = double.parse(strMaxFee);
|
||||
|
||||
if (calPercentage > doubleMaxFee) {
|
||||
if (calPercentage! > doubleMaxFee) {
|
||||
return "(" + doubleMaxFee.toString() + ")";
|
||||
}
|
||||
newSum = newSum.replaceAll(defaultRegex(strRegexMaxFee), "");
|
||||
@ -273,13 +280,13 @@ Future<double> workoutShippingCostWC({@required String sum}) async {
|
||||
return strCal(sum: sum);
|
||||
}
|
||||
|
||||
Future<double> workoutShippingClassCostWC(
|
||||
{@required String sum, List<CartLineItem> cartLineItem}) async {
|
||||
Future<double?> workoutShippingClassCostWC(
|
||||
{required String? sum, List<CartLineItem>? cartLineItem}) async {
|
||||
if (sum == null || sum == "") {
|
||||
return 0;
|
||||
}
|
||||
sum = sum.replaceAllMapped(defaultRegex(r'\[qty\]', strict: true), (replace) {
|
||||
return cartLineItem
|
||||
return cartLineItem!
|
||||
.map((f) => f.quantity)
|
||||
.toList()
|
||||
.reduce((i, d) => i + d)
|
||||
@ -292,27 +299,27 @@ Future<double> workoutShippingClassCostWC(
|
||||
if (replace.groupCount < 1) {
|
||||
return "()";
|
||||
}
|
||||
String newSum = replace.group(1);
|
||||
String newSum = replace.group(1)!;
|
||||
|
||||
// PERCENT
|
||||
String percentVal = newSum.replaceAllMapped(
|
||||
defaultRegex(r'percent="([0-9\.]+)"'), (replacePercent) {
|
||||
if (replacePercent != null && replacePercent.groupCount >= 1) {
|
||||
if (replacePercent.groupCount >= 1) {
|
||||
String strPercentage = "( (" +
|
||||
orderTotal.toString() +
|
||||
" * " +
|
||||
replacePercent.group(1).toString() +
|
||||
") / 100 )";
|
||||
double calPercentage = strCal(sum: strPercentage);
|
||||
double? calPercentage = strCal(sum: strPercentage);
|
||||
|
||||
// MIN
|
||||
String strRegexMinFee = r'min_fee="([0-9\.]+)"';
|
||||
if (defaultRegex(strRegexMinFee).hasMatch(newSum)) {
|
||||
String strMinFee =
|
||||
defaultRegex(strRegexMinFee).firstMatch(newSum).group(1) ?? "0";
|
||||
defaultRegex(strRegexMinFee).firstMatch(newSum)!.group(1) ?? "0";
|
||||
double doubleMinFee = double.parse(strMinFee);
|
||||
|
||||
if (calPercentage < doubleMinFee) {
|
||||
if (calPercentage! < doubleMinFee) {
|
||||
return "(" + doubleMinFee.toString() + ")";
|
||||
}
|
||||
newSum = newSum.replaceAll(defaultRegex(strRegexMinFee), "");
|
||||
@ -322,10 +329,10 @@ Future<double> workoutShippingClassCostWC(
|
||||
String strRegexMaxFee = r'max_fee="([0-9\.]+)"';
|
||||
if (defaultRegex(strRegexMaxFee).hasMatch(newSum)) {
|
||||
String strMaxFee =
|
||||
defaultRegex(strRegexMaxFee).firstMatch(newSum).group(1) ?? "0";
|
||||
defaultRegex(strRegexMaxFee).firstMatch(newSum)!.group(1) ?? "0";
|
||||
double doubleMaxFee = double.parse(strMaxFee);
|
||||
|
||||
if (calPercentage > doubleMaxFee) {
|
||||
if (calPercentage! > doubleMaxFee) {
|
||||
return "(" + doubleMaxFee.toString() + ")";
|
||||
}
|
||||
newSum = newSum.replaceAll(defaultRegex(strRegexMaxFee), "");
|
||||
@ -348,7 +355,7 @@ Future<double> workoutShippingClassCostWC(
|
||||
|
||||
RegExp defaultRegex(
|
||||
String pattern, {
|
||||
bool strict,
|
||||
bool? strict,
|
||||
}) {
|
||||
return RegExp(
|
||||
pattern,
|
||||
@ -365,10 +372,10 @@ bool isEmail(String em) {
|
||||
}
|
||||
|
||||
navigatorPush(BuildContext context,
|
||||
{@required String routeName,
|
||||
Object arguments,
|
||||
{required String routeName,
|
||||
Object? arguments,
|
||||
bool forgetAll = false,
|
||||
int forgetLast}) {
|
||||
int? forgetLast}) {
|
||||
if (forgetAll) {
|
||||
Navigator.of(context).pushNamedAndRemoveUntil(
|
||||
routeName, (Route<dynamic> route) => false,
|
||||
@ -383,51 +390,11 @@ navigatorPush(BuildContext context,
|
||||
Navigator.of(context).pushNamed(routeName, arguments: arguments);
|
||||
}
|
||||
|
||||
PlatformDialogAction dialogAction(BuildContext context,
|
||||
{@required title, ActionType actionType, Function() action}) {
|
||||
return PlatformDialogAction(
|
||||
actionType: actionType ?? ActionType.Default,
|
||||
child: Text(title ?? ""),
|
||||
onPressed: action ??
|
||||
() {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
showPlatformAlertDialog(BuildContext context,
|
||||
{String title,
|
||||
String subtitle,
|
||||
List<PlatformDialogAction> actions,
|
||||
bool showDoneAction = true}) {
|
||||
if (showDoneAction) {
|
||||
actions.add(dialogAction(context, title: trans("Done"), action: () {
|
||||
Navigator.of(context).pop();
|
||||
}));
|
||||
}
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return PlatformAlertDialog(
|
||||
title: Text(title ?? ""),
|
||||
content: SingleChildScrollView(
|
||||
child: ListBody(
|
||||
children: <Widget>[
|
||||
Text(subtitle ?? ""),
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: actions,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
DateTime parseDateTime(String strDate) => DateTime.parse(strDate);
|
||||
|
||||
DateFormat formatDateTime(String format) => DateFormat(format);
|
||||
|
||||
String dateFormatted({@required String date, @required String formatType}) =>
|
||||
String dateFormatted({required String date, required String formatType}) =>
|
||||
formatDateTime(formatType).format(parseDateTime(date));
|
||||
|
||||
enum FormatType {
|
||||
@ -457,20 +424,20 @@ String formatForDateTime(FormatType formatType) {
|
||||
}
|
||||
}
|
||||
|
||||
double parseWcPrice(String price) => (double.tryParse(price ?? "0") ?? 0);
|
||||
double parseWcPrice(String? price) => (double.tryParse(price ?? "0") ?? 0);
|
||||
|
||||
Widget refreshableScroll(context,
|
||||
{@required refreshController,
|
||||
@required VoidCallback onRefresh,
|
||||
@required VoidCallback onLoading,
|
||||
@required List<Product> products,
|
||||
@required onTap,
|
||||
{required refreshController,
|
||||
required VoidCallback onRefresh,
|
||||
required VoidCallback onLoading,
|
||||
required List<Product> products,
|
||||
required onTap,
|
||||
key}) {
|
||||
return SmartRefresher(
|
||||
enablePullDown: true,
|
||||
enablePullUp: true,
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode) {
|
||||
builder: (BuildContext context, LoadStatus? mode) {
|
||||
Widget body;
|
||||
if (mode == LoadStatus.idle) {
|
||||
body = Text(trans("pull up load"));
|
||||
@ -492,24 +459,24 @@ Widget refreshableScroll(context,
|
||||
controller: refreshController,
|
||||
onRefresh: onRefresh,
|
||||
onLoading: onLoading,
|
||||
child: (products.length != null && products.isNotEmpty
|
||||
? StaggeredGridView.countBuilder(
|
||||
child: products.isEmpty
|
||||
? NoResultsForProductsWidget()
|
||||
: StaggeredGrid.count(
|
||||
crossAxisCount: 2,
|
||||
itemCount: products.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
height: 200,
|
||||
child: ProductItemContainer(
|
||||
product: products[index],
|
||||
onTap: onTap,
|
||||
),
|
||||
);
|
||||
},
|
||||
staggeredTileBuilder: (int index) => StaggeredTile.fit(1),
|
||||
mainAxisSpacing: 4.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
)
|
||||
: NoResultsForProductsWidget()),
|
||||
children: products.map((product) {
|
||||
return StaggeredGridTile.fit(
|
||||
crossAxisCellCount: 1,
|
||||
child: Container(
|
||||
height: 200,
|
||||
child: ProductItemContainer(
|
||||
product: product,
|
||||
onTap: onTap,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
);
|
||||
}
|
||||
|
||||
@ -546,38 +513,47 @@ String truncateString(String data, int length) {
|
||||
|
||||
Future<List<dynamic>> getWishlistProducts() async {
|
||||
List<dynamic> favouriteProducts = [];
|
||||
String currentProductsJSON = await NyStorage.read(SharedKey.wishlistProducts);
|
||||
String? currentProductsJSON =
|
||||
await (NyStorage.read(SharedKey.wishlistProducts));
|
||||
if (currentProductsJSON != null) {
|
||||
favouriteProducts =
|
||||
(jsonDecode(currentProductsJSON) as List<dynamic>).toList();
|
||||
(jsonDecode(currentProductsJSON)).toList();
|
||||
}
|
||||
return favouriteProducts;
|
||||
}
|
||||
|
||||
hasAddedWishlistProduct(int productId) async {
|
||||
hasAddedWishlistProduct(int? productId) async {
|
||||
List<dynamic> favouriteProducts = await getWishlistProducts();
|
||||
List<int> productIds =
|
||||
favouriteProducts.map((e) => e['id']).cast<int>().toList();
|
||||
favouriteProducts.map((e) => e['id']).cast<int>().toList();
|
||||
if (productIds.isEmpty) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
return productIds.contains(productId);
|
||||
}
|
||||
|
||||
saveWishlistProduct({@required Product product}) async {
|
||||
saveWishlistProduct({required Product? product}) async {
|
||||
List<dynamic> products = await getWishlistProducts();
|
||||
if (products.any((wishListProduct) => wishListProduct['id'] == product.id) ==
|
||||
if (products.any((wishListProduct) => wishListProduct['id'] == product!.id) ==
|
||||
false) {
|
||||
products.add({"id": product.id});
|
||||
products.add({"id": product!.id});
|
||||
}
|
||||
String json = jsonEncode(products.map((i) => {"id": i['id']}).toList());
|
||||
await NyStorage.store(SharedKey.wishlistProducts, json);
|
||||
}
|
||||
|
||||
removeWishlistProduct({@required Product product}) async {
|
||||
removeWishlistProduct({required Product? product}) async {
|
||||
List<dynamic> products = await getWishlistProducts();
|
||||
products.removeWhere((element) => element['id'] == product.id);
|
||||
products.removeWhere((element) => element['id'] == product!.id);
|
||||
|
||||
String json = jsonEncode(products.map((i) => {"id": i['id']}).toList());
|
||||
await NyStorage.store(SharedKey.wishlistProducts, json);
|
||||
}
|
||||
|
||||
/// API helper
|
||||
api<T>(dynamic Function(T) request, {BuildContext? context}) async =>
|
||||
await nyApi<T>(
|
||||
request: request, apiDecoders: apiDecoders, context: context);
|
||||
|
||||
/// Event helper
|
||||
event<T>({Map? data}) async => nyEvent<T>(params: data, events: events);
|
||||
|
||||
@ -12,13 +12,13 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_app/app/models/cart.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
Future<bool> authCheck() async => ((await getUser()) != null);
|
||||
|
||||
Future<String> readAuthToken() async => (await getUser()).token;
|
||||
Future<String?> readAuthToken() async => (await getUser())!.token;
|
||||
|
||||
Future<String> readUserId() async => (await getUser()).userId;
|
||||
Future<String?> readUserId() async => (await getUser())!.userId;
|
||||
|
||||
authLogout(BuildContext context) async {
|
||||
await NyStorage.delete(SharedKey.authUser);
|
||||
|
||||
@ -18,7 +18,7 @@ import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const SymbolPositionType app_currency_symbol_position = SymbolPositionType.left;
|
||||
const SymbolPositionType appCurrencySymbolPosition = SymbolPositionType.left;
|
||||
// currency_symbol_position example.
|
||||
// left: $15
|
||||
// right: 15€
|
||||
30
LabelStoreMax/lib/config/decoders.dart
Normal file
30
LabelStoreMax/lib/config/decoders.dart
Normal file
@ -0,0 +1,30 @@
|
||||
import 'package:flutter_app/app/networking/api_service.dart';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Model Decoders
|
||||
| -------------------------------------------------------------------------
|
||||
| Model decoders are used in 'app/networking/' for morphing json payloads
|
||||
| into Models. Learn more https://nylo.dev/docs/3.x/decoders#model-decoders
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
final Map<Type, dynamic> modelDecoders = {
|
||||
// ...
|
||||
};
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Decoders
|
||||
| -------------------------------------------------------------------------
|
||||
| API decoders are used when you need to access an API service using the
|
||||
| 'api' helper. E.g. api<MyApiService>((request) => request.fetchData());
|
||||
| Learn more https://nylo.dev/docs/3.x/decoders#api-decoders
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
final Map<Type, dynamic> apiDecoders = {
|
||||
ApiService: ApiService(),
|
||||
|
||||
// ...
|
||||
};
|
||||
18
LabelStoreMax/lib/config/events.dart
Normal file
18
LabelStoreMax/lib/config/events.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'package:flutter_app/app/events/login_event.dart';
|
||||
import 'package:flutter_app/app/events/logout_event.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Events
|
||||
| Add your "app/events" here.
|
||||
| Events can be fired using: event<MyEvent>();
|
||||
|
|
||||
| Learn more: https://nylo.dev/docs/3.x/events
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
final Map<Type, NyEvent> events = {
|
||||
LoginEvent: LoginEvent(),
|
||||
LogoutEvent: LogoutEvent(),
|
||||
};
|
||||
@ -18,7 +18,7 @@ final LocaleType localeType = LocaleType.asDefined; // device, asDefined
|
||||
| The language code should match the name of the file i.e /lang/es.json
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
final String languageCode = getEnv('DEFAULT_LOCALE', defaultValue: "en");
|
||||
final String? languageCode = getEnv('DEFAULT_LOCALE', defaultValue: "en");
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -13,7 +13,7 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
const app_payment_gateways = [];
|
||||
const appPaymentGateways = [];
|
||||
// Available: "Stripe", "CashOnDelivery", "PayPal"
|
||||
// e.g. app_payment_gateways = ["Stripe", "CashOnDelivery"]; will only use Stripe and Cash on Delivery.
|
||||
|
||||
19
LabelStoreMax/lib/config/providers.dart
Normal file
19
LabelStoreMax/lib/config/providers.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter_app/app/providers/app_provider.dart';
|
||||
import 'package:flutter_app/app/providers/event_provider.dart';
|
||||
import 'package:flutter_app/app/providers/route_provider.dart';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Providers
|
||||
| Add your "app/providers" here.
|
||||
| Providers are booted when your application start.
|
||||
|
|
||||
| Learn more: https://nylo.dev/docs/3.x/providers
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
final providers = {
|
||||
AppProvider: AppProvider(),
|
||||
RouteProvider: RouteProvider(),
|
||||
EventProvider: EventProvider(),
|
||||
};
|
||||
@ -2,21 +2,20 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/bootstrap/app.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/bootstrap/boot.dart';
|
||||
import 'package:flutter_app/routes/router.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
Nylo nylo = await Nylo.init(router: appRouter(), setup: boot);
|
||||
Nylo nylo = await Nylo.init(setup: Boot.nylo, setupFinished: Boot.finished);
|
||||
|
||||
String initialRoute = AppHelper.instance.appConfig.appStatus != null
|
||||
String initialRoute = AppHelper.instance.appConfig!.appStatus != null
|
||||
? '/home'
|
||||
: '/no-connection';
|
||||
|
||||
runApp(
|
||||
AppBuild(
|
||||
navigatorKey: nylo.router.navigatorKey,
|
||||
onGenerateRoute: nylo.router.generator(),
|
||||
navigatorKey: NyNavigator.instance.router.navigatorKey,
|
||||
onGenerateRoute: nylo.router!.generator(),
|
||||
initialRoute: initialRoute,
|
||||
debugShowCheckedModeBanner: false,
|
||||
),
|
||||
|
||||
@ -51,18 +51,18 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
||||
_fetchUserDetails() async {
|
||||
WCCustomerInfoResponse wcCustomerInfoResponse =
|
||||
await WPJsonAPI.instance.api((request) async {
|
||||
return request.wcCustomerInfo(await readAuthToken());
|
||||
return request.wcCustomerInfo((await readAuthToken())!);
|
||||
});
|
||||
|
||||
Billing billing = wcCustomerInfoResponse.data.billing;
|
||||
_txtShippingFirstName.text = billing.firstName;
|
||||
_txtShippingLastName.text = billing.lastName;
|
||||
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;
|
||||
_txtShippingAddressLine.text = billing.address1!;
|
||||
_txtShippingCity.text = billing.city!;
|
||||
_txtShippingState.text = billing.state!;
|
||||
_txtShippingPostalCode.text = billing.postcode!;
|
||||
_txtShippingCountry.text = billing.country!;
|
||||
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
@ -155,7 +155,7 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: ThemeColor.get(context).surfaceBackground,
|
||||
color: ThemeColor.get(context)!.surfaceBackground,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: (Theme.of(context).brightness ==
|
||||
Brightness.light)
|
||||
@ -171,9 +171,9 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
||||
Column(
|
||||
children: <Widget>[
|
||||
PrimaryButton(
|
||||
title: trans("UPDATE DETAILS"),
|
||||
isLoading: _isUpdating,
|
||||
action: _updateBillingDetails,
|
||||
title: trans("UPDATE DETAILS"),
|
||||
isLoading: _isUpdating,
|
||||
action: _updateBillingDetails,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -194,13 +194,13 @@ class _AccountBillingDetailsPageState extends State<AccountBillingDetailsPage> {
|
||||
String postalCode = _txtShippingPostalCode.text;
|
||||
String country = _txtShippingCountry.text;
|
||||
|
||||
String userToken = await readAuthToken();
|
||||
String? userToken = await readAuthToken();
|
||||
|
||||
setState(() {
|
||||
_isUpdating = true;
|
||||
});
|
||||
|
||||
WCCustomerUpdatedResponse wcCustomerUpdatedResponse;
|
||||
WCCustomerUpdatedResponse? wcCustomerUpdatedResponse;
|
||||
try {
|
||||
wcCustomerUpdatedResponse = await WPJsonAPI.instance.api((request) =>
|
||||
request.wcUpdateCustomerInfo(userToken,
|
||||
|
||||
@ -31,10 +31,10 @@ class AccountDetailPage extends StatefulWidget {
|
||||
|
||||
class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
with SingleTickerProviderStateMixin {
|
||||
TabController _tabController;
|
||||
TabController? _tabController;
|
||||
bool _isLoading = true;
|
||||
int _currentTabIndex = 0;
|
||||
WCCustomerInfoResponse _wcCustomerInfoResponse;
|
||||
WCCustomerInfoResponse? _wcCustomerInfoResponse;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -44,12 +44,12 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
}
|
||||
|
||||
_fetchWpUserData() async {
|
||||
String userToken = await readAuthToken();
|
||||
String? userToken = await readAuthToken();
|
||||
|
||||
WCCustomerInfoResponse wcCustomerInfoResponse;
|
||||
WCCustomerInfoResponse? wcCustomerInfoResponse;
|
||||
try {
|
||||
wcCustomerInfoResponse = await WPJsonAPI.instance
|
||||
.api((request) => request.wcCustomerInfo(userToken));
|
||||
.api((request) => request.wcCustomerInfo(userToken!));
|
||||
} on InvalidUserTokenException catch (_) {
|
||||
showToastNotification(
|
||||
context,
|
||||
@ -81,7 +81,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget activeBody;
|
||||
Widget? activeBody;
|
||||
if (_currentTabIndex == 0) {
|
||||
activeBody = AccountDetailOrdersWidget();
|
||||
} else if (_currentTabIndex == 1) {
|
||||
@ -98,16 +98,15 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
if (activeBody == null) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
String userAvatar;
|
||||
String userFirstName = "";
|
||||
String userLastName = "";
|
||||
if (_wcCustomerInfoResponse != null && _wcCustomerInfoResponse.data != null) {
|
||||
userAvatar = _wcCustomerInfoResponse.data.avatar;
|
||||
String? userAvatar;
|
||||
String? userFirstName = "";
|
||||
String? userLastName = "";
|
||||
if (_wcCustomerInfoResponse != null &&
|
||||
_wcCustomerInfoResponse!.data != null) {
|
||||
userAvatar = _wcCustomerInfoResponse!.data!.avatar;
|
||||
|
||||
userFirstName = _wcCustomerInfoResponse
|
||||
.data.firstName;
|
||||
userLastName = _wcCustomerInfoResponse
|
||||
.data.lastName;
|
||||
userFirstName = _wcCustomerInfoResponse!.data!.firstName;
|
||||
userLastName = _wcCustomerInfoResponse!.data!.lastName;
|
||||
}
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
@ -142,9 +141,14 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
children: <Widget>[
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: userAvatar != null ? CircleAvatar(
|
||||
backgroundImage: NetworkImage(userAvatar),
|
||||
) : Icon(Icons.account_circle_rounded, size: 65,),
|
||||
child: userAvatar != null
|
||||
? CircleAvatar(
|
||||
backgroundImage: NetworkImage(userAvatar),
|
||||
)
|
||||
: Icon(
|
||||
Icons.account_circle_rounded,
|
||||
size: 65,
|
||||
),
|
||||
height: 90,
|
||||
width: 90,
|
||||
),
|
||||
@ -161,11 +165,9 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
[
|
||||
userFirstName,
|
||||
userLastName
|
||||
].where((t) =>
|
||||
(t != null || t != ""))
|
||||
[userFirstName, userLastName]
|
||||
.where(
|
||||
(t) => (t != null || t != ""))
|
||||
.toList()
|
||||
.join(" "),
|
||||
style: TextStyle(
|
||||
@ -210,7 +212,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
(Theme.of(context).brightness == Brightness.light)
|
||||
? wsBoxShadow()
|
||||
: null,
|
||||
color: ThemeColor.get(context).backgroundContainer,
|
||||
color: ThemeColor.get(context)!.backgroundContainer,
|
||||
),
|
||||
),
|
||||
Expanded(child: activeBody),
|
||||
@ -222,7 +224,7 @@ class _AccountDetailPageState extends State<AccountDetailPage>
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_tabController.dispose();
|
||||
_tabController!.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -65,7 +65,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
child: Text(
|
||||
trans("Login"),
|
||||
textAlign: TextAlign.left,
|
||||
style: Theme.of(context).textTheme.headline4.copyWith(
|
||||
style: Theme.of(context).textTheme.headline4!.copyWith(
|
||||
fontSize: 24,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
@ -79,7 +79,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
(Theme.of(context).brightness == Brightness.light)
|
||||
? wsBoxShadow()
|
||||
: null,
|
||||
color: ThemeColor.get(context).backgroundContainer,
|
||||
color: ThemeColor.get(context)!.backgroundContainer,
|
||||
),
|
||||
padding: EdgeInsets.symmetric(vertical: 18, horizontal: 8),
|
||||
margin: EdgeInsets.symmetric(horizontal: 16),
|
||||
@ -133,8 +133,8 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
LinkButton(
|
||||
title: trans("Forgot Password"),
|
||||
action: () {
|
||||
String forgotPasswordUrl =
|
||||
AppHelper.instance.appConfig.wpLoginForgotPasswordUrl;
|
||||
String? forgotPasswordUrl =
|
||||
AppHelper.instance.appConfig!.wpLoginForgotPasswordUrl;
|
||||
if (forgotPasswordUrl != null) {
|
||||
openBrowserTab(url: forgotPasswordUrl);
|
||||
} else {
|
||||
@ -155,7 +155,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
: Padding(
|
||||
padding: EdgeInsets.only(bottom: 20),
|
||||
)
|
||||
].where((element) => element != null).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -190,7 +190,7 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
_hasTappedLogin = true;
|
||||
});
|
||||
|
||||
WPUserLoginResponse wpUserLoginResponse;
|
||||
WPUserLoginResponse? wpUserLoginResponse;
|
||||
try {
|
||||
wpUserLoginResponse = await WPJsonAPI.instance.api(
|
||||
(request) => request.wpLogin(email: email, password: password));
|
||||
@ -228,8 +228,8 @@ class _AccountLandingPageState extends State<AccountLandingPage> {
|
||||
}
|
||||
|
||||
if (wpUserLoginResponse != null && wpUserLoginResponse.status == 200) {
|
||||
String token = wpUserLoginResponse.data.userToken;
|
||||
String userId = wpUserLoginResponse.data.userId.toString();
|
||||
String? token = wpUserLoginResponse.data!.userToken;
|
||||
String userId = wpUserLoginResponse.data!.userId.toString();
|
||||
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
||||
user.save(SharedKey.authUser);
|
||||
|
||||
|
||||
@ -14,28 +14,27 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_support/widgets/ny_state.dart';
|
||||
import 'package:nylo_support/widgets/ny_stateful_widget.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
|
||||
import 'package:woosignal/models/response/order.dart';
|
||||
|
||||
class AccountOrderDetailPage extends NyStatefulWidget {
|
||||
final AccountOrderDetailController controller =
|
||||
AccountOrderDetailController();
|
||||
AccountOrderDetailPage({Key key}) : super(key: key);
|
||||
AccountOrderDetailPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_AccountOrderDetailPageState createState() => _AccountOrderDetailPageState();
|
||||
}
|
||||
|
||||
class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
int _orderId;
|
||||
Order _order;
|
||||
int? _orderId;
|
||||
Order? _order;
|
||||
bool _isLoading = true;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
super.widgetDidLoad();
|
||||
init() async {
|
||||
_orderId = widget.controller.data();
|
||||
await _fetchOrder();
|
||||
}
|
||||
@ -67,7 +66,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
child: Text(
|
||||
"${trans("Date Ordered").capitalize()}: " +
|
||||
dateFormatted(
|
||||
date: _order.dateCreated,
|
||||
date: _order!.dateCreated!,
|
||||
formatType: formatForDateTime(FormatType.date),
|
||||
),
|
||||
),
|
||||
@ -86,15 +85,15 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
child: Text(
|
||||
[
|
||||
[
|
||||
_order.shipping.firstName,
|
||||
_order.shipping.lastName
|
||||
_order!.shipping!.firstName,
|
||||
_order!.shipping!.lastName
|
||||
].where((t) => t != null).toList().join(" "),
|
||||
_order.shipping.address1,
|
||||
_order.shipping.address2,
|
||||
_order.shipping.city,
|
||||
_order.shipping.state,
|
||||
_order.shipping.postcode,
|
||||
_order.shipping.country,
|
||||
_order!.shipping!.address1,
|
||||
_order!.shipping!.address2,
|
||||
_order!.shipping!.city,
|
||||
_order!.shipping!.state,
|
||||
_order!.shipping!.postcode,
|
||||
_order!.shipping!.country,
|
||||
]
|
||||
.where((t) => (t != "" && t != null))
|
||||
.toList()
|
||||
@ -118,7 +117,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemBuilder: (cxt, i) {
|
||||
LineItems lineItem = _order.lineItems[i];
|
||||
LineItems lineItem = _order!.lineItems![i];
|
||||
return Card(
|
||||
child: ListTile(
|
||||
contentPadding: EdgeInsets.only(
|
||||
@ -137,7 +136,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Text(
|
||||
lineItem.name,
|
||||
lineItem.name!,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@ -169,7 +168,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText2
|
||||
.bodyText2!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
@ -190,7 +189,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: _order.lineItems.length,
|
||||
itemCount: _order!.lineItems!.length,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -205,9 +204,9 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||
}
|
||||
|
||||
_fetchOrder() async {
|
||||
_order = await appWooSignal((api) {
|
||||
return api.retrieveOrder(_orderId);
|
||||
});
|
||||
_order = await (appWooSignal((api) {
|
||||
return api.retrieveOrder(_orderId!);
|
||||
}));
|
||||
if (_order != null) {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
|
||||
@ -47,11 +47,11 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
|
||||
_fetchUserDetails() async {
|
||||
WPUserInfoResponse wpUserInfoResponse =
|
||||
await WPJsonAPI.instance.api((request) async {
|
||||
return request.wpGetUserInfo(await readAuthToken());
|
||||
return request.wpGetUserInfo((await readAuthToken()) ?? "0");
|
||||
});
|
||||
|
||||
_tfFirstName.text = wpUserInfoResponse.data.firstName;
|
||||
_tfLastName.text = wpUserInfoResponse.data.lastName;
|
||||
_tfFirstName.text = wpUserInfoResponse.data!.firstName!;
|
||||
_tfLastName.text = wpUserInfoResponse.data!.lastName!;
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
@ -108,9 +108,9 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
),
|
||||
PrimaryButton(
|
||||
title: trans("Update details"),
|
||||
isLoading: isLoading,
|
||||
action: _updateDetails,
|
||||
title: trans("Update details"),
|
||||
isLoading: isLoading,
|
||||
action: _updateDetails,
|
||||
)
|
||||
],
|
||||
),
|
||||
@ -133,8 +133,8 @@ class _AccountProfileUpdatePageState extends State<AccountProfileUpdatePage> {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
String userToken = await readAuthToken();
|
||||
WPUserInfoUpdatedResponse wpUserInfoUpdatedResponse;
|
||||
String? userToken = await readAuthToken();
|
||||
WPUserInfoUpdatedResponse? wpUserInfoUpdatedResponse;
|
||||
try {
|
||||
wpUserInfoUpdatedResponse = await WPJsonAPI.instance.api((request) =>
|
||||
request.wpUpdateUserInfo(userToken,
|
||||
|
||||
@ -47,7 +47,7 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
_tfFirstNameController = TextEditingController(),
|
||||
_tfLastNameController = TextEditingController();
|
||||
|
||||
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
|
||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -105,9 +105,9 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
),
|
||||
Padding(
|
||||
child: PrimaryButton(
|
||||
title: trans("Sign up"),
|
||||
isLoading: _hasTappedRegister,
|
||||
action: _signUpTapped,
|
||||
title: trans("Sign up"),
|
||||
isLoading: _hasTappedRegister,
|
||||
action: _signUpTapped,
|
||||
),
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
),
|
||||
@ -116,7 +116,7 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
text: trans("By tapping \"Register\" you agree to ") +
|
||||
AppHelper.instance.appConfig.appName +
|
||||
AppHelper.instance.appConfig!.appName! +
|
||||
'\'s ',
|
||||
children: <TextSpan>[
|
||||
TextSpan(
|
||||
@ -179,7 +179,7 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
String username =
|
||||
(email.replaceAll(RegExp(r'([@.])'), "")) + _randomStr(4);
|
||||
|
||||
WPUserRegisterResponse wpUserRegisterResponse;
|
||||
WPUserRegisterResponse? wpUserRegisterResponse;
|
||||
try {
|
||||
wpUserRegisterResponse = await WPJsonAPI.instance.api(
|
||||
(request) => request.wpRegister(
|
||||
@ -232,8 +232,8 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
|
||||
if (wpUserRegisterResponse != null &&
|
||||
wpUserRegisterResponse.status == 200) {
|
||||
String token = wpUserRegisterResponse.data.userToken;
|
||||
String userId = wpUserRegisterResponse.data.userId.toString();
|
||||
String? token = wpUserRegisterResponse.data!.userToken;
|
||||
String userId = wpUserRegisterResponse.data!.userId.toString();
|
||||
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
||||
user.save(SharedKey.authUser);
|
||||
|
||||
@ -251,17 +251,30 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
}
|
||||
}
|
||||
|
||||
_viewTOSModal() {
|
||||
showPlatformAlertDialog(
|
||||
context,
|
||||
title: trans("Actions"),
|
||||
subtitle: trans("View Terms and Conditions or Privacy policy"),
|
||||
actions: [
|
||||
dialogAction(context,
|
||||
title: trans("Terms and Conditions"), action: _viewTermsConditions),
|
||||
dialogAction(context,
|
||||
title: trans("Privacy Policy"), action: _viewPrivacyPolicy),
|
||||
],
|
||||
_viewTOSModal() async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(trans("Actions")),
|
||||
content: Text(trans("View Terms and Conditions or Privacy policy")),
|
||||
actions: <Widget>[
|
||||
MaterialButton(
|
||||
onPressed: _viewTermsConditions,
|
||||
child: Text(trans("Terms and Conditions")),
|
||||
),
|
||||
MaterialButton(
|
||||
onPressed: _viewPrivacyPolicy,
|
||||
child: Text(trans("Privacy Policy")),
|
||||
),
|
||||
Divider(),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text('Close'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -277,11 +290,11 @@ class _AccountRegistrationPageState extends State<AccountRegistrationPage> {
|
||||
|
||||
void _viewTermsConditions() {
|
||||
Navigator.pop(context);
|
||||
openBrowserTab(url: _wooSignalApp.appTermsLink);
|
||||
openBrowserTab(url: _wooSignalApp!.appTermsLink!);
|
||||
}
|
||||
|
||||
void _viewPrivacyPolicy() {
|
||||
Navigator.pop(context);
|
||||
openBrowserTab(url: _wooSignalApp.appPrivacyLink);
|
||||
openBrowserTab(url: _wooSignalApp!.appPrivacyLink!);
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,12 +50,12 @@ class _AccountShippingDetailsPageState
|
||||
}
|
||||
|
||||
_fetchUserDetails() async {
|
||||
String userToken = await readAuthToken();
|
||||
String? userToken = await readAuthToken();
|
||||
|
||||
WCCustomerInfoResponse wcCustomerInfoResponse;
|
||||
WCCustomerInfoResponse? wcCustomerInfoResponse;
|
||||
try {
|
||||
wcCustomerInfoResponse = await WPJsonAPI.instance
|
||||
.api((request) => request.wcCustomerInfo(userToken));
|
||||
.api((request) => request.wcCustomerInfo(userToken!));
|
||||
} on Exception catch (_) {
|
||||
showToastNotification(
|
||||
context,
|
||||
@ -73,15 +73,15 @@ class _AccountShippingDetailsPageState
|
||||
|
||||
if (wcCustomerInfoResponse != null &&
|
||||
wcCustomerInfoResponse.status == 200) {
|
||||
Shipping shipping = wcCustomerInfoResponse.data.shipping;
|
||||
_txtShippingFirstName.text = shipping.firstName;
|
||||
_txtShippingLastName.text = shipping.lastName;
|
||||
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;
|
||||
_txtShippingAddressLine.text = shipping.address1!;
|
||||
_txtShippingCity.text = shipping.city!;
|
||||
_txtShippingState.text = shipping.state!;
|
||||
_txtShippingPostalCode.text = shipping.postcode!;
|
||||
_txtShippingCountry.text = shipping.country!;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ class _AccountShippingDetailsPageState
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: ThemeColor.get(context).surfaceBackground,
|
||||
color: ThemeColor.get(context)!.surfaceBackground,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: (Theme.of(context).brightness ==
|
||||
Brightness.light)
|
||||
@ -188,9 +188,9 @@ class _AccountShippingDetailsPageState
|
||||
Column(
|
||||
children: <Widget>[
|
||||
PrimaryButton(
|
||||
title: trans("UPDATE DETAILS"),
|
||||
isLoading: _isUpdating,
|
||||
action: _updateShippingDetails,
|
||||
title: trans("UPDATE DETAILS"),
|
||||
isLoading: _isUpdating,
|
||||
action: _updateShippingDetails,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -211,7 +211,7 @@ class _AccountShippingDetailsPageState
|
||||
String postalCode = _txtShippingPostalCode.text;
|
||||
String country = _txtShippingCountry.text;
|
||||
|
||||
String userToken = await readAuthToken();
|
||||
String? userToken = await readAuthToken();
|
||||
|
||||
if (_isUpdating == true) {
|
||||
return;
|
||||
@ -221,7 +221,7 @@ class _AccountShippingDetailsPageState
|
||||
_isUpdating = true;
|
||||
});
|
||||
|
||||
WCCustomerUpdatedResponse wcCustomerUpdatedResponse;
|
||||
WCCustomerUpdatedResponse? wcCustomerUpdatedResponse;
|
||||
try {
|
||||
wcCustomerUpdatedResponse = await WPJsonAPI.instance.api(
|
||||
(request) => request.wcUpdateCustomerInfo(
|
||||
|
||||
@ -17,23 +17,23 @@ 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_support/helpers/helper.dart';
|
||||
import 'package:nylo_support/widgets/ny_state.dart';
|
||||
import 'package:nylo_support/widgets/ny_stateful_widget.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
||||
|
||||
class BrowseCategoryPage extends NyStatefulWidget {
|
||||
final BrowseCategoryController controller = BrowseCategoryController();
|
||||
BrowseCategoryPage({Key key}) : super(key: key);
|
||||
BrowseCategoryPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_BrowseCategoryPageState createState() => _BrowseCategoryPageState();
|
||||
}
|
||||
|
||||
class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
||||
ProductCategory productCategory;
|
||||
ProductCategory? productCategory;
|
||||
_BrowseCategoryPageState();
|
||||
|
||||
final RefreshController _refreshController =
|
||||
@ -46,8 +46,7 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
||||
bool _isLoading = true;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
super.widgetDidLoad();
|
||||
init() async {
|
||||
productCategory = widget.controller.data();
|
||||
await fetchProducts();
|
||||
}
|
||||
@ -66,7 +65,7 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(trans("Browse"), style: Theme.of(context).textTheme.subtitle1),
|
||||
Text(parseHtmlString(productCategory.name))
|
||||
Text(parseHtmlString(productCategory!.name))
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
@ -115,7 +114,7 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
||||
}
|
||||
}
|
||||
|
||||
_sortProducts({@required SortByType by}) {
|
||||
_sortProducts({required SortByType by}) {
|
||||
List<ws_product.Product> products =
|
||||
_productCategorySearchLoaderController.getResults();
|
||||
switch (by) {
|
||||
@ -133,12 +132,12 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
||||
break;
|
||||
case SortByType.nameAZ:
|
||||
products.sort(
|
||||
(product1, product2) => product1.name.compareTo(product2.name),
|
||||
(product1, product2) => product1.name!.compareTo(product2.name!),
|
||||
);
|
||||
break;
|
||||
case SortByType.nameZA:
|
||||
products.sort(
|
||||
(product1, product2) => product2.name.compareTo(product1.name),
|
||||
(product1, product2) => product2.name!.compareTo(product1.name!),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -14,15 +14,15 @@ import 'package:flutter_app/app/controllers/product_search_loader_controller.dar
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_support/widgets/ny_state.dart';
|
||||
import 'package:nylo_support/widgets/ny_stateful_widget.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
||||
|
||||
class BrowseSearchPage extends NyStatefulWidget {
|
||||
final BrowseSearchController controller = BrowseSearchController();
|
||||
BrowseSearchPage({Key key}) : super(key: key);
|
||||
BrowseSearchPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_BrowseSearchState createState() => _BrowseSearchState();
|
||||
@ -34,12 +34,11 @@ class _BrowseSearchState extends NyState<BrowseSearchPage> {
|
||||
final ProductSearchLoaderController _productSearchLoaderController =
|
||||
ProductSearchLoaderController();
|
||||
|
||||
String _search;
|
||||
String? _search;
|
||||
bool _shouldStopRequests = false, _isLoading = true;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
super.widgetDidLoad();
|
||||
init() async {
|
||||
_search = widget.controller.data();
|
||||
await fetchProducts();
|
||||
}
|
||||
@ -59,7 +58,7 @@ class _BrowseSearchState extends NyState<BrowseSearchPage> {
|
||||
children: <Widget>[
|
||||
Text(trans("Search results for"),
|
||||
style: Theme.of(context).textTheme.subtitle1),
|
||||
Text("\"" + _search + "\"")
|
||||
Text("\"" + _search! + "\"")
|
||||
],
|
||||
),
|
||||
centerTitle: true,
|
||||
|
||||
@ -56,7 +56,7 @@ class _CartPageState extends State<CartPage> {
|
||||
List<Map<String, dynamic>> cartJSON = cart.map((c) => c.toJson()).toList();
|
||||
|
||||
List<dynamic> cartRes =
|
||||
await appWooSignal((api) => api.cartCheck(cartJSON));
|
||||
await (appWooSignal((api) => api.cartCheck(cartJSON)));
|
||||
if (cartRes.isEmpty) {
|
||||
Cart.getInstance.saveCartToPref(cartLineItems: []);
|
||||
setState(() {
|
||||
@ -105,17 +105,17 @@ class _CartPageState extends State<CartPage> {
|
||||
}
|
||||
|
||||
CheckoutSession.getInstance.initSession();
|
||||
CustomerAddress sfCustomerAddress =
|
||||
CustomerAddress? sfCustomerAddress =
|
||||
await CheckoutSession.getInstance.getBillingAddress();
|
||||
|
||||
if (sfCustomerAddress != null) {
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.billingAddress =
|
||||
sfCustomerAddress;
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress =
|
||||
sfCustomerAddress;
|
||||
}
|
||||
|
||||
if (AppHelper.instance.appConfig.wpLoginEnabled == 1 &&
|
||||
if (AppHelper.instance.appConfig!.wpLoginEnabled == 1 &&
|
||||
!(await authCheck())) {
|
||||
UserAuth.instance.redirect = "/checkout";
|
||||
Navigator.pushNamed(context, "/account-landing");
|
||||
@ -125,9 +125,9 @@ class _CartPageState extends State<CartPage> {
|
||||
Navigator.pushNamed(context, "/checkout");
|
||||
}
|
||||
|
||||
actionIncrementQuantity({CartLineItem cartLineItem}) {
|
||||
if (cartLineItem.isManagedStock &&
|
||||
cartLineItem.quantity + 1 > cartLineItem.stockQuantity) {
|
||||
actionIncrementQuantity({required CartLineItem cartLineItem}) {
|
||||
if (cartLineItem.isManagedStock! &&
|
||||
cartLineItem.quantity + 1 > cartLineItem.stockQuantity!) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Cart"),
|
||||
@ -143,7 +143,7 @@ class _CartPageState extends State<CartPage> {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
actionDecrementQuantity({CartLineItem cartLineItem}) {
|
||||
actionDecrementQuantity({required CartLineItem cartLineItem}) {
|
||||
if (cartLineItem.quantity - 1 <= 0) {
|
||||
return;
|
||||
}
|
||||
@ -153,7 +153,7 @@ class _CartPageState extends State<CartPage> {
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
actionRemoveItem({int index}) {
|
||||
actionRemoveItem({required int index}) {
|
||||
Cart.getInstance.removeCartItemForIndex(index: index);
|
||||
_cartLines.removeAt(index);
|
||||
showToastNotification(
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/models/cart.dart';
|
||||
import 'package:flutter_app/app/models/checkout_session.dart';
|
||||
@ -30,7 +31,7 @@ import 'package:woosignal/models/response/tax_rate.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
class CheckoutConfirmationPage extends StatefulWidget {
|
||||
CheckoutConfirmationPage({Key key}) : super(key: key);
|
||||
CheckoutConfirmationPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
CheckoutConfirmationPageState createState() =>
|
||||
@ -43,14 +44,14 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
bool _showFullLoader = true, _isProcessingPayment = false;
|
||||
|
||||
final List<TaxRate> _taxRates = [];
|
||||
TaxRate _taxRate;
|
||||
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
|
||||
TaxRate? _taxRate;
|
||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
CheckoutSession.getInstance.coupon = null;
|
||||
List<PaymentType> paymentTypes = getPaymentTypes();
|
||||
List<PaymentType?> paymentTypes = getPaymentTypes();
|
||||
if (CheckoutSession.getInstance.paymentType == null &&
|
||||
paymentTypes.isNotEmpty) {
|
||||
CheckoutSession.getInstance.paymentType = paymentTypes.first;
|
||||
@ -58,9 +59,9 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
_getTaxes();
|
||||
}
|
||||
|
||||
reloadState({@required bool showLoader}) {
|
||||
reloadState({required bool showLoader}) {
|
||||
setState(() {
|
||||
_showFullLoader = showLoader ?? false;
|
||||
_showFullLoader = showLoader;
|
||||
});
|
||||
}
|
||||
|
||||
@ -68,10 +69,10 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
int pageIndex = 1;
|
||||
bool fetchMore = true;
|
||||
while (fetchMore == true) {
|
||||
List<TaxRate> tmpTaxRates = await appWooSignal(
|
||||
(api) => api.getTaxRates(page: pageIndex, perPage: 100));
|
||||
List<TaxRate> tmpTaxRates = await (appWooSignal(
|
||||
(api) => api.getTaxRates(page: pageIndex, perPage: 100)));
|
||||
|
||||
if (tmpTaxRates != null && tmpTaxRates.isNotEmpty) {
|
||||
if (tmpTaxRates.isNotEmpty) {
|
||||
_taxRates.addAll(tmpTaxRates);
|
||||
}
|
||||
if (tmpTaxRates.length >= 100) {
|
||||
@ -81,7 +82,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
}
|
||||
}
|
||||
|
||||
if (_taxRates == null || _taxRates.isEmpty) {
|
||||
if (_taxRates.isEmpty) {
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
@ -89,16 +90,16 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
}
|
||||
|
||||
if (CheckoutSession.getInstance.billingDetails == null ||
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress == null) {
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress == null) {
|
||||
setState(() {
|
||||
_showFullLoader = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
CustomerCountry shippingCountry = CheckoutSession
|
||||
.getInstance.billingDetails.shippingAddress.customerCountry;
|
||||
String postalCode =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress.postalCode;
|
||||
CustomerCountry? shippingCountry = CheckoutSession
|
||||
.getInstance.billingDetails!.shippingAddress!.customerCountry;
|
||||
String? postalCode =
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress!.postalCode;
|
||||
|
||||
if (shippingCountry == null) {
|
||||
_showFullLoader = false;
|
||||
@ -106,15 +107,14 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
TaxRate taxRate;
|
||||
TaxRate? taxRate;
|
||||
if (shippingCountry.hasState()) {
|
||||
taxRate = _taxRates.firstWhere((t) {
|
||||
if (shippingCountry == null ||
|
||||
(shippingCountry?.state?.code ?? "") == "") {
|
||||
taxRate = _taxRates.firstWhereOrNull((t) {
|
||||
if ((shippingCountry.state?.code ?? "") == "") {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<String> stateElements = shippingCountry.state.code.split(":");
|
||||
List<String> stateElements = shippingCountry.state!.code!.split(":");
|
||||
String state = stateElements.last;
|
||||
|
||||
if (t.country == shippingCountry.countryCode &&
|
||||
@ -127,20 +127,18 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, orElse: () => null);
|
||||
});
|
||||
}
|
||||
|
||||
if (taxRate == null) {
|
||||
taxRate = _taxRates.firstWhere(
|
||||
taxRate = _taxRates.firstWhereOrNull(
|
||||
(t) =>
|
||||
t.country == shippingCountry.countryCode &&
|
||||
t.postcode == postalCode,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
taxRate ??= _taxRates.firstWhere(
|
||||
taxRate ??= _taxRates.firstWhereOrNull(
|
||||
(t) => t.country == shippingCountry.countryCode,
|
||||
orElse: () => null,
|
||||
);
|
||||
}
|
||||
|
||||
@ -157,19 +155,21 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
CheckoutSession checkoutSession = CheckoutSession.getInstance;
|
||||
|
||||
if (_showFullLoader == true) {
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
AppLoaderWidget(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15),
|
||||
child: Text(
|
||||
"${trans("One moment")}...",
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
),
|
||||
)
|
||||
],
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
AppLoaderWidget(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 15),
|
||||
child: Text(
|
||||
"${trans("One moment")}...",
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -199,7 +199,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: ThemeColor.get(context).backgroundContainer,
|
||||
color: ThemeColor.get(context)!.backgroundContainer,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow: (Theme.of(context).brightness == Brightness.light)
|
||||
? wsBoxShadow()
|
||||
@ -232,10 +232,10 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
resetState: () => setState(() {}),
|
||||
wooSignalApp: _wooSignalApp,
|
||||
),
|
||||
].where((e) => e != null).toList()),
|
||||
]),
|
||||
),
|
||||
),
|
||||
if (_wooSignalApp.couponEnabled == true)
|
||||
if (_wooSignalApp!.couponEnabled == true)
|
||||
CheckoutSelectCouponWidget(
|
||||
context: context,
|
||||
checkoutSession: checkoutSession,
|
||||
@ -244,7 +244,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
children: [
|
||||
Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
@ -253,21 +253,20 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
title: trans("Subtotal"),
|
||||
),
|
||||
CheckoutCouponAmountWidget(checkoutSession: checkoutSession),
|
||||
_wooSignalApp.disableShipping == 1
|
||||
? null
|
||||
: CheckoutMetaLine(
|
||||
title: trans("Shipping fee"),
|
||||
amount: CheckoutSession.getInstance.shippingType == null
|
||||
? trans("Select shipping")
|
||||
: CheckoutSession.getInstance.shippingType
|
||||
.getTotal(withFormatting: true)),
|
||||
(_taxRate != null ? CheckoutTaxTotal(taxRate: _taxRate) : null),
|
||||
if (_wooSignalApp!.disableShipping != 1)
|
||||
CheckoutMetaLine(
|
||||
title: trans("Shipping fee"),
|
||||
amount: CheckoutSession.getInstance.shippingType == null
|
||||
? trans("Select shipping")
|
||||
: CheckoutSession.getInstance.shippingType!
|
||||
.getTotal(withFormatting: true)),
|
||||
if (_taxRate != null) CheckoutTaxTotal(taxRate: _taxRate),
|
||||
CheckoutTotal(title: trans("Total"), taxRate: _taxRate),
|
||||
Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
),
|
||||
].where((e) => e != null).toList(),
|
||||
],
|
||||
),
|
||||
PrimaryButton(
|
||||
title: _isProcessingPayment
|
||||
@ -283,7 +282,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
|
||||
_handleCheckout() async {
|
||||
CheckoutSession checkoutSession = CheckoutSession.getInstance;
|
||||
if (checkoutSession.billingDetails.billingAddress == null) {
|
||||
if (checkoutSession.billingDetails!.billingAddress == null) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Oops"),
|
||||
@ -295,7 +294,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkoutSession.billingDetails.billingAddress.hasMissingFields()) {
|
||||
if (checkoutSession.billingDetails!.billingAddress!.hasMissingFields()) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Oops"),
|
||||
@ -306,7 +305,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_wooSignalApp.disableShipping == 0 &&
|
||||
if (_wooSignalApp!.disableShipping == 0 &&
|
||||
checkoutSession.shippingType == null) {
|
||||
showToastNotification(
|
||||
context,
|
||||
@ -329,28 +328,27 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_wooSignalApp.disableShipping == 0 &&
|
||||
if (_wooSignalApp!.disableShipping == 0 &&
|
||||
checkoutSession.shippingType?.minimumValue != null) {
|
||||
String total = await Cart.getInstance.getTotal();
|
||||
if (total == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
double doubleTotal = double.parse(total);
|
||||
|
||||
double doubleMinimumValue =
|
||||
double.parse(checkoutSession.shippingType?.minimumValue);
|
||||
double.parse(checkoutSession.shippingType!.minimumValue!);
|
||||
|
||||
if (doubleTotal < doubleMinimumValue) {
|
||||
showToastNotification(context,
|
||||
title: trans("Sorry"),
|
||||
description:
|
||||
"${trans("Spend a minimum of")} ${formatDoubleCurrency(total: doubleMinimumValue)} ${trans("for")} ${checkoutSession.shippingType.getTitle()}",
|
||||
"${trans("Spend a minimum of")} ${formatDoubleCurrency(total: doubleMinimumValue)} ${trans("for")} ${checkoutSession.shippingType!.getTitle()}",
|
||||
style: ToastNotificationStyleType.INFO,
|
||||
duration: Duration(seconds: 3));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool appStatus = await appWooSignal((api) => api.checkAppStatus());
|
||||
bool appStatus = await (appWooSignal((api) => api.checkAppStatus()));
|
||||
|
||||
if (!appStatus) {
|
||||
showToastNotification(context,
|
||||
@ -369,7 +367,7 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||
_isProcessingPayment = true;
|
||||
});
|
||||
|
||||
await checkoutSession.paymentType
|
||||
await checkoutSession.paymentType!
|
||||
.pay(context, state: this, taxRate: _taxRate);
|
||||
|
||||
setState(() {
|
||||
|
||||
@ -22,6 +22,8 @@ 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();
|
||||
|
||||
@ -32,7 +34,7 @@ class CheckoutDetailsPage extends StatefulWidget {
|
||||
class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
_CheckoutDetailsPageState();
|
||||
|
||||
bool _hasDifferentShippingAddress = false, valRememberDetails = true;
|
||||
bool? _hasDifferentShippingAddress = false, valRememberDetails = true;
|
||||
int activeTabIndex = 0;
|
||||
|
||||
// TEXT CONTROLLERS
|
||||
@ -53,9 +55,9 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
_txtShippingPostalCode = TextEditingController(),
|
||||
_txtShippingEmailAddress = TextEditingController();
|
||||
|
||||
CustomerCountry _billingCountry, _shippingCountry;
|
||||
CustomerCountry? _billingCountry, _shippingCountry;
|
||||
|
||||
Widget activeTab;
|
||||
Widget? activeTab;
|
||||
|
||||
Widget tabShippingDetails() => CustomerAddressInput(
|
||||
txtControllerFirstName: _txtShippingFirstName,
|
||||
@ -84,12 +86,13 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (CheckoutSession.getInstance.billingDetails.billingAddress == null) {
|
||||
CheckoutSession.getInstance.billingDetails.initSession();
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress.initAddress();
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress.initAddress();
|
||||
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;
|
||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails!;
|
||||
_setFieldsFromCustomerAddress(billingDetails.billingAddress,
|
||||
type: "billing");
|
||||
_setFieldsFromCustomerAddress(billingDetails.shippingAddress,
|
||||
@ -102,20 +105,18 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
}
|
||||
|
||||
_setCustomersDetails() async {
|
||||
CustomerAddress sfCustomerBillingAddress =
|
||||
CustomerAddress? sfCustomerBillingAddress =
|
||||
await CheckoutSession.getInstance.getBillingAddress();
|
||||
_setFieldsFromCustomerAddress(sfCustomerBillingAddress, type: "billing");
|
||||
|
||||
CustomerAddress sfCustomerShippingAddress =
|
||||
CustomerAddress? sfCustomerShippingAddress =
|
||||
await CheckoutSession.getInstance.getShippingAddress();
|
||||
_setFieldsFromCustomerAddress(sfCustomerShippingAddress, type: "shipping");
|
||||
setState(() {
|
||||
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
_setFieldsFromCustomerAddress(CustomerAddress customerAddress,
|
||||
{@required String type}) {
|
||||
_setFieldsFromCustomerAddress(CustomerAddress? customerAddress,
|
||||
{required String type}) {
|
||||
assert(type != "");
|
||||
if (customerAddress == null) {
|
||||
return;
|
||||
@ -134,31 +135,31 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
}
|
||||
|
||||
_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}) {
|
||||
{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;
|
||||
_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;
|
||||
_txtShippingFirstName.text = firstName!;
|
||||
_txtShippingLastName.text = lastName!;
|
||||
_txtShippingAddressLine.text = addressLine!;
|
||||
_txtShippingCity.text = city!;
|
||||
_txtShippingPostalCode.text = postalCode!;
|
||||
_txtShippingEmailAddress.text = emailAddress!;
|
||||
_shippingCountry = customerCountry;
|
||||
}
|
||||
}
|
||||
@ -185,59 +186,56 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
if (_hasDifferentShippingAddress)
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
child: Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
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();
|
||||
})),
|
||||
].where((e) => e != null).toList(),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(vertical: 4),
|
||||
),
|
||||
].where((e) => e != null).toList(),
|
||||
if (_hasDifferentShippingAddress!)
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
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,
|
||||
),
|
||||
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())
|
||||
),
|
||||
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())),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -270,7 +268,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
),
|
||||
Checkbox(
|
||||
value: valRememberDetails,
|
||||
onChanged: (bool value) {
|
||||
onChanged: (bool? value) {
|
||||
setState(() {
|
||||
valRememberDetails = value;
|
||||
});
|
||||
@ -294,19 +292,19 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
|
||||
_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,
|
||||
customerCountry: _billingCountry,
|
||||
firstName: _txtBillingFirstName.text,
|
||||
lastName: _txtBillingLastName.text,
|
||||
addressLine: _txtBillingAddressLine.text,
|
||||
city: _txtBillingCity.text,
|
||||
postalCode: _txtBillingPostalCode.text,
|
||||
phoneNumber: _txtBillingPhoneNumber.text,
|
||||
emailAddress: _txtBillingEmailAddress.text,
|
||||
customerCountry: _billingCountry,
|
||||
);
|
||||
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress =
|
||||
customerBillingAddress;
|
||||
CheckoutSession.getInstance.billingDetails.billingAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.billingAddress =
|
||||
customerBillingAddress;
|
||||
|
||||
if (_hasDifferentShippingAddress == true) {
|
||||
@ -353,7 +351,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress =
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress =
|
||||
customerShippingAddress;
|
||||
}
|
||||
|
||||
@ -365,7 +363,7 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
await CheckoutSession.getInstance.clearShippingAddress();
|
||||
}
|
||||
|
||||
CheckoutSession.getInstance.billingDetails.rememberDetails =
|
||||
CheckoutSession.getInstance.billingDetails!.rememberDetails =
|
||||
valRememberDetails;
|
||||
CheckoutSession.getInstance.shipToDifferentAddress =
|
||||
_hasDifferentShippingAddress;
|
||||
@ -374,12 +372,12 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
_onChangeShipping(bool value) async {
|
||||
_onChangeShipping(bool? value) async {
|
||||
_hasDifferentShippingAddress = value;
|
||||
activeTabIndex = 1;
|
||||
activeTab = value == true ? tabShippingDetails() : tabBillingDetails();
|
||||
|
||||
CustomerAddress sfCustomerShippingAddress =
|
||||
CustomerAddress? sfCustomerShippingAddress =
|
||||
await CheckoutSession.getInstance.getShippingAddress();
|
||||
if (sfCustomerShippingAddress == null) {
|
||||
_setFields(
|
||||
@ -396,14 +394,14 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
}
|
||||
|
||||
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}) {
|
||||
{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;
|
||||
@ -418,18 +416,18 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
||||
return customerShippingAddress;
|
||||
}
|
||||
|
||||
_navigateToSelectCountry({@required String type}) {
|
||||
_navigateToSelectCountry({required String type}) {
|
||||
Navigator.pushNamed(context, "/customer-countries").then((value) {
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
if (type == "billing") {
|
||||
_billingCountry =
|
||||
CustomerCountry.fromDefaultShipping(defaultShipping: value);
|
||||
_billingCountry = CustomerCountry.fromDefaultShipping(
|
||||
defaultShipping: value as DefaultShipping);
|
||||
activeTab = tabBillingDetails();
|
||||
} else if (type == "shipping") {
|
||||
_shippingCountry =
|
||||
CustomerCountry.fromDefaultShipping(defaultShipping: value);
|
||||
_shippingCountry = CustomerCountry.fromDefaultShipping(
|
||||
defaultShipping: value as DefaultShipping);
|
||||
activeTab = tabShippingDetails();
|
||||
}
|
||||
setState(() {});
|
||||
|
||||
@ -16,7 +16,7 @@ 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:nylo_support/helpers/helper.dart';
|
||||
|
||||
|
||||
class CheckoutPaymentTypePage extends StatefulWidget {
|
||||
CheckoutPaymentTypePage();
|
||||
@ -34,7 +34,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
super.initState();
|
||||
|
||||
if (CheckoutSession.getInstance.paymentType == null) {
|
||||
if (getPaymentTypes() != null && getPaymentTypes().isNotEmpty) {
|
||||
if (getPaymentTypes().isNotEmpty) {
|
||||
CheckoutSession.getInstance.paymentType = getPaymentTypes().first;
|
||||
}
|
||||
}
|
||||
@ -42,7 +42,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
List<PaymentType> paymentTypes = getPaymentTypes();
|
||||
List<PaymentType?> paymentTypes = getPaymentTypes();
|
||||
if (paymentTypes.isEmpty &&
|
||||
getEnv('APP_DEBUG', defaultValue: false) == true) {
|
||||
NyLogger.info(
|
||||
@ -91,7 +91,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
itemBuilder:
|
||||
(BuildContext context, int index) {
|
||||
PaymentType paymentType =
|
||||
paymentTypes[index];
|
||||
paymentTypes[index]!;
|
||||
return ListTile(
|
||||
contentPadding: EdgeInsets.only(
|
||||
top: 10,
|
||||
@ -139,7 +139,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: ThemeColor.get(context).backgroundContainer,
|
||||
color: ThemeColor.get(context)!.backgroundContainer,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow:
|
||||
(Theme.of(context).brightness == Brightness.light)
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:collection/collection.dart' show IterableExtension;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/models/cart.dart';
|
||||
import 'package:flutter_app/app/models/cart_line_item.dart';
|
||||
@ -20,7 +21,7 @@ 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_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/shipping_method.dart';
|
||||
|
||||
class CheckoutShippingTypePage extends StatefulWidget {
|
||||
@ -36,7 +37,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
|
||||
bool _isShippingSupported = true, _isLoading = true;
|
||||
final List<Map<String, dynamic>> _wsShippingOptions = [];
|
||||
WSShipping _shipping;
|
||||
WSShipping? _shipping;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -46,12 +47,12 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
|
||||
_getShippingMethods() async {
|
||||
List<WSShipping> wsShipping =
|
||||
await appWooSignal((api) => api.getShippingMethods());
|
||||
await (appWooSignal((api) => api.getShippingMethods()));
|
||||
|
||||
CustomerAddress customerAddress =
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||
String postalCode = customerAddress.postalCode;
|
||||
CustomerCountry customerCountry = customerAddress.customerCountry;
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress!;
|
||||
String? postalCode = customerAddress.postalCode;
|
||||
CustomerCountry? customerCountry = customerAddress.customerCountry;
|
||||
|
||||
if (customerCountry == null) {
|
||||
setState(() {
|
||||
@ -65,7 +66,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
continue;
|
||||
}
|
||||
|
||||
Locations location = shipping.locations.firstWhere(
|
||||
Locations? location = shipping.locations!.firstWhereOrNull(
|
||||
(ws) {
|
||||
if (customerCountry.countryCode == null || ws.code == null) {
|
||||
return false;
|
||||
@ -74,7 +75,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
if (ws.type == "state") {
|
||||
if (customerCountry.state != null &&
|
||||
(customerCountry.state?.code ?? "") != "") {
|
||||
return ws.code == customerCountry.state.code;
|
||||
return ws.code == customerCountry.state!.code;
|
||||
}
|
||||
}
|
||||
|
||||
@ -88,7 +89,6 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
|
||||
return false;
|
||||
},
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (location != null) {
|
||||
@ -100,8 +100,8 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
await _handleShippingZones(_shipping);
|
||||
|
||||
if (_shipping == null) {
|
||||
WSShipping noZones = wsShipping
|
||||
.firstWhere((element) => element.parentId == 0, orElse: () => null);
|
||||
WSShipping? noZones =
|
||||
wsShipping.firstWhereOrNull((element) => element.parentId == 0);
|
||||
await _handleShippingZones(noZones);
|
||||
}
|
||||
if (_wsShippingOptions.isEmpty) {
|
||||
@ -117,38 +117,40 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
double total = 0;
|
||||
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
||||
|
||||
total +=
|
||||
await workoutShippingCostWC(sum: _wsShippingOptions[index]['cost']);
|
||||
total += (await (workoutShippingCostWC(
|
||||
sum: _wsShippingOptions[index]['cost']))) ??
|
||||
0;
|
||||
|
||||
switch (_wsShippingOptions[index]['method_id']) {
|
||||
case "flat_rate":
|
||||
FlatRate flatRate = (_wsShippingOptions[index]['object'] as FlatRate);
|
||||
FlatRate? flatRate = (_wsShippingOptions[index]['object'] as FlatRate?);
|
||||
|
||||
if (cartLineItem.firstWhere(
|
||||
(t) => t.shippingClassId == null || t.shippingClassId == "0",
|
||||
orElse: () => null) !=
|
||||
if (cartLineItem.firstWhereOrNull(
|
||||
(t) => t.shippingClassId == null || t.shippingClassId == "0") !=
|
||||
null) {
|
||||
total += await workoutShippingClassCostWC(
|
||||
sum: flatRate.classCost,
|
||||
cartLineItem: cartLineItem
|
||||
.where((t) =>
|
||||
t.shippingClassId == null || t.shippingClassId == "0")
|
||||
.toList());
|
||||
total += await (workoutShippingClassCostWC(
|
||||
sum: flatRate!.classCost,
|
||||
cartLineItem: cartLineItem
|
||||
.where((t) =>
|
||||
t.shippingClassId == null || t.shippingClassId == "0")
|
||||
.toList())) ??
|
||||
0;
|
||||
}
|
||||
|
||||
List<CartLineItem> cItemsWithShippingClasses = cartLineItem
|
||||
.where((t) => t.shippingClassId != null && t.shippingClassId != "0")
|
||||
.toList();
|
||||
for (int i = 0; i < cItemsWithShippingClasses.length; i++) {
|
||||
ShippingClasses shippingClasses = flatRate.shippingClasses.firstWhere(
|
||||
(d) => d.id == cItemsWithShippingClasses[i].shippingClassId,
|
||||
orElse: () => null);
|
||||
ShippingClasses? shippingClasses = flatRate!.shippingClasses!
|
||||
.firstWhereOrNull(
|
||||
(d) => d.id == cItemsWithShippingClasses[i].shippingClassId);
|
||||
if (shippingClasses != null) {
|
||||
double classTotal = await workoutShippingClassCostWC(
|
||||
sum: shippingClasses.cost,
|
||||
cartLineItem: cartLineItem
|
||||
.where((g) => g.shippingClassId == shippingClasses.id)
|
||||
.toList());
|
||||
double classTotal = await (workoutShippingClassCostWC(
|
||||
sum: shippingClasses.cost,
|
||||
cartLineItem: cartLineItem
|
||||
.where((g) => g.shippingClassId == shippingClasses.id)
|
||||
.toList())) ??
|
||||
0;
|
||||
total += classTotal;
|
||||
}
|
||||
}
|
||||
@ -159,13 +161,10 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
return (total).toString();
|
||||
}
|
||||
|
||||
_handleShippingZones(WSShipping shipping) async {
|
||||
_handleShippingZones(WSShipping? shipping) async {
|
||||
if (shipping != null && shipping.methods != null) {
|
||||
if (shipping.methods.flatRate != null) {
|
||||
shipping.methods.flatRate
|
||||
.where((t) => t != null)
|
||||
.toList()
|
||||
.forEach((flatRate) {
|
||||
if (shipping.methods!.flatRate != null) {
|
||||
shipping.methods!.flatRate!.toList().forEach((flatRate) {
|
||||
Map<String, dynamic> tmpShippingOption = {};
|
||||
tmpShippingOption = {
|
||||
"id": flatRate.id,
|
||||
@ -178,11 +177,8 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
});
|
||||
}
|
||||
|
||||
if (shipping.methods.localPickup != null) {
|
||||
shipping.methods.localPickup
|
||||
.where((t) => t != null)
|
||||
.toList()
|
||||
.forEach((localPickup) {
|
||||
if (shipping.methods!.localPickup != null) {
|
||||
shipping.methods!.localPickup!.toList().forEach((localPickup) {
|
||||
Map<String, dynamic> tmpShippingOption = {};
|
||||
tmpShippingOption = {
|
||||
"id": localPickup.id,
|
||||
@ -195,23 +191,21 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
});
|
||||
}
|
||||
|
||||
if (shipping.methods.freeShipping != null) {
|
||||
List<FreeShipping> freeShipping =
|
||||
shipping.methods.freeShipping.where((t) => t != null).toList();
|
||||
if (shipping.methods!.freeShipping != null) {
|
||||
List<FreeShipping> freeShipping = shipping.methods!.freeShipping!;
|
||||
|
||||
for (int i = 0; i < freeShipping.length; i++) {
|
||||
if (isNumeric(freeShipping[i].cost) ||
|
||||
freeShipping[i].cost == 'min_amount') {
|
||||
if (freeShipping[i].cost == 'min_amount') {
|
||||
String total = await Cart.getInstance.getTotal();
|
||||
if (total != null) {
|
||||
double doubleTotal = double.parse(total);
|
||||
double doubleMinimumValue =
|
||||
double.parse(freeShipping[i].minimumOrderAmount);
|
||||
|
||||
if (doubleTotal < doubleMinimumValue) {
|
||||
continue;
|
||||
}
|
||||
double doubleTotal = double.parse(total);
|
||||
double doubleMinimumValue =
|
||||
double.parse(freeShipping[i].minimumOrderAmount!);
|
||||
|
||||
if (doubleTotal < doubleMinimumValue) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,7 +282,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
_wsShippingOptions[index]['title'],
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.subtitle1
|
||||
.subtitle1!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
@ -343,19 +337,15 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
style: Theme.of(
|
||||
context)
|
||||
.textTheme
|
||||
.bodyText2
|
||||
.bodyText2!
|
||||
.copyWith(
|
||||
fontSize:
|
||||
14))
|
||||
]
|
||||
.where((e) =>
|
||||
e != null)
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
trailing: (CheckoutSession.getInstance
|
||||
@ -363,7 +353,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
null &&
|
||||
CheckoutSession
|
||||
.getInstance
|
||||
.shippingType
|
||||
.shippingType!
|
||||
.object ==
|
||||
_wsShippingOptions[index]
|
||||
["object"]
|
||||
@ -389,7 +379,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
||||
],
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: ThemeColor.get(context).backgroundContainer,
|
||||
color: ThemeColor.get(context)!.backgroundContainer,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
boxShadow:
|
||||
(Theme.of(context).brightness == Brightness.light)
|
||||
|
||||
@ -14,29 +14,28 @@ import 'package:flutter_app/app/models/cart.dart';
|
||||
import 'package:flutter_app/app/models/checkout_session.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/resources/widgets/buttons.dart';
|
||||
import 'package:nylo_support/widgets/ny_state.dart';
|
||||
import 'package:nylo_support/widgets/ny_stateful_widget.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
import 'package:woosignal/models/response/order.dart' as ws_order;
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
|
||||
|
||||
import '../widgets/woosignal_ui.dart';
|
||||
|
||||
class CheckoutStatusPage extends NyStatefulWidget {
|
||||
final CheckoutStatusController controller = CheckoutStatusController();
|
||||
CheckoutStatusPage({Key key}) : super(key: key);
|
||||
CheckoutStatusPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CheckoutStatusState createState() => _CheckoutStatusState();
|
||||
}
|
||||
|
||||
class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
||||
ws_order.Order _order;
|
||||
ws_order.Order? _order;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
super.widgetDidLoad();
|
||||
init() async {
|
||||
_order = widget.controller.data();
|
||||
Cart.getInstance.clear();
|
||||
await Cart.getInstance.clear();
|
||||
CheckoutSession.getInstance.clear();
|
||||
}
|
||||
|
||||
@ -81,7 +80,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
Text(
|
||||
"${trans("Order Ref")}. #${_order.id.toString()}",
|
||||
"${trans("Order Ref")}. #${_order!.id.toString()}",
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
@ -123,10 +122,11 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount:
|
||||
_order.lineItems == null ? 0 : _order.lineItems.length,
|
||||
itemCount: _order!.lineItems == null
|
||||
? 0
|
||||
: _order!.lineItems!.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
ws_order.LineItems lineItem = _order.lineItems[index];
|
||||
ws_order.LineItems lineItem = _order!.lineItems![index];
|
||||
return Container(
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
@ -139,7 +139,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
||||
MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
lineItem.name,
|
||||
lineItem.name!,
|
||||
style:
|
||||
Theme.of(context).textTheme.bodyText1,
|
||||
softWrap: false,
|
||||
|
||||
@ -20,7 +20,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
|
||||
final couponController = TextEditingController();
|
||||
|
||||
_showAlert({String message, ToastNotificationStyleType style}) {
|
||||
_showAlert({required String message, ToastNotificationStyleType? style}) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans('Coupon'),
|
||||
@ -42,9 +42,9 @@ class _CouponPageState extends State<CouponPage> {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
||||
_coupons = await appWooSignal(
|
||||
_coupons = await (appWooSignal(
|
||||
(api) => api.getCoupons(code: couponCode, perPage: 100),
|
||||
);
|
||||
));
|
||||
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
@ -81,7 +81,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
autofocus: true,
|
||||
controller: couponController,
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
if (value!.isEmpty) {
|
||||
return trans('Please enter coupon to redeem');
|
||||
}
|
||||
return null;
|
||||
@ -98,7 +98,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
Radius.circular(8.0),
|
||||
),
|
||||
borderSide: BorderSide(
|
||||
color: ThemeColor.get(context).primaryAccent)),
|
||||
color: ThemeColor.get(context)!.primaryAccent)),
|
||||
filled: true,
|
||||
hintStyle: TextStyle(color: Colors.grey[800]),
|
||||
hintText: trans('Add coupon code'),
|
||||
@ -126,7 +126,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
_applyCoupon(CheckoutSession checkoutSession) async {
|
||||
await findCoupon(couponController.text);
|
||||
|
||||
if (_formKey.currentState.validate()) {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
// No coupons found
|
||||
if (_coupons.isEmpty) {
|
||||
_showAlert(
|
||||
@ -139,11 +139,11 @@ class _CouponPageState extends State<CouponPage> {
|
||||
|
||||
DateTime dateNow = DateTime.now();
|
||||
List<CartLineItem> cart = await Cart.getInstance.getCart();
|
||||
List<int> productIds = cart.map((e) => e.productId).toList();
|
||||
List<int?> productIds = cart.map((e) => e.productId).toList();
|
||||
|
||||
// Check excludedProductIds
|
||||
for (var productId in productIds) {
|
||||
if (coupon.excludedProductIds.contains(productId)) {
|
||||
if (coupon.excludedProductIds!.contains(productId)) {
|
||||
_showAlert(
|
||||
message:
|
||||
"${trans('Sorry, this coupon can not be used with your cart')}.",
|
||||
@ -153,9 +153,9 @@ class _CouponPageState extends State<CouponPage> {
|
||||
}
|
||||
|
||||
// Check email restrictions
|
||||
String emailAddress =
|
||||
checkoutSession.billingDetails.billingAddress.emailAddress;
|
||||
if (coupon.emailRestrictions.contains(emailAddress)) {
|
||||
String? emailAddress =
|
||||
checkoutSession.billingDetails!.billingAddress!.emailAddress;
|
||||
if (coupon.emailRestrictions!.contains(emailAddress)) {
|
||||
_showAlert(
|
||||
message: trans('You cannot redeem this coupon'),
|
||||
style: ToastNotificationStyleType.DANGER);
|
||||
@ -163,7 +163,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
}
|
||||
|
||||
// Check for minimum amount
|
||||
double minimumAmount = double.parse(coupon.minimumAmount);
|
||||
double minimumAmount = double.parse(coupon.minimumAmount!);
|
||||
String strSubtotal = await Cart.getInstance.getSubtotal();
|
||||
double doubleSubtotal = double.parse(strSubtotal);
|
||||
if (minimumAmount != 0 && doubleSubtotal < minimumAmount) {
|
||||
@ -175,7 +175,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
}
|
||||
|
||||
// Check maximum amount
|
||||
double maximumAmount = double.parse(coupon.maximumAmount);
|
||||
double maximumAmount = double.parse(coupon.maximumAmount!);
|
||||
if (maximumAmount != 0 && doubleSubtotal > maximumAmount) {
|
||||
_showAlert(
|
||||
message: trans("Spend less than maximumAmount to redeem",
|
||||
@ -187,7 +187,7 @@ class _CouponPageState extends State<CouponPage> {
|
||||
// Check if coupon has expired
|
||||
if (coupon.dateExpires != null &&
|
||||
dateNow.isAfter(
|
||||
DateTime.parse(coupon.dateExpires),
|
||||
DateTime.parse(coupon.dateExpires!),
|
||||
)) {
|
||||
_showAlert(
|
||||
message: trans("This coupon has expired"),
|
||||
@ -196,7 +196,8 @@ class _CouponPageState extends State<CouponPage> {
|
||||
}
|
||||
|
||||
// Check usage limit
|
||||
if (coupon.usageLimit != null && coupon.usageCount >= coupon.usageLimit) {
|
||||
if (coupon.usageLimit != null &&
|
||||
coupon.usageCount! >= coupon.usageLimit!) {
|
||||
_showAlert(
|
||||
message: trans("Usage limit has been reached"),
|
||||
style: ToastNotificationStyleType.WARNING);
|
||||
@ -204,11 +205,11 @@ class _CouponPageState extends State<CouponPage> {
|
||||
}
|
||||
|
||||
// Check usage limit per user
|
||||
int limitPerUser = coupon.usageLimitPerUser;
|
||||
int? limitPerUser = coupon.usageLimitPerUser;
|
||||
if (limitPerUser != null &&
|
||||
coupon.usedBy
|
||||
coupon.usedBy!
|
||||
.map((e) => e.toLowerCase())
|
||||
.where((usedBy) => usedBy == emailAddress.toLowerCase())
|
||||
.where((usedBy) => usedBy == emailAddress!.toLowerCase())
|
||||
.length >=
|
||||
limitPerUser) {
|
||||
_showAlert(
|
||||
|
||||
@ -13,7 +13,7 @@ import 'package:flutter_app/app/models/default_shipping.dart';
|
||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class CustomerCountriesPage extends StatefulWidget {
|
||||
CustomerCountriesPage();
|
||||
@ -64,7 +64,7 @@ class _CustomerCountriesPageState extends State<CustomerCountriesPage> {
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
color: ThemeColor.get(context).background),
|
||||
color: ThemeColor.get(context)!.background),
|
||||
height: 60,
|
||||
child: Row(
|
||||
children: [
|
||||
@ -106,11 +106,11 @@ class _CustomerCountriesPageState extends State<CustomerCountriesPage> {
|
||||
decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
border: Border.all(color: Colors.grey[200])),
|
||||
border: Border.all(color: Colors.grey[200]!)),
|
||||
margin: EdgeInsets.symmetric(vertical: 4),
|
||||
padding:
|
||||
EdgeInsets.symmetric(vertical: 16, horizontal: 8),
|
||||
child: Text(defaultShipping.country),
|
||||
child: Text(defaultShipping.country!),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -125,7 +125,7 @@ class _CustomerCountriesPageState extends State<CustomerCountriesPage> {
|
||||
_handleOnChanged(String value) {
|
||||
_activeShippingResults = _defaultShipping
|
||||
.where((element) =>
|
||||
element.country.toLowerCase().contains(value.toLowerCase()))
|
||||
element.country!.toLowerCase().contains(value.toLowerCase()))
|
||||
.toList();
|
||||
setState(() {});
|
||||
}
|
||||
@ -151,7 +151,7 @@ class _CustomerCountriesPageState extends State<CustomerCountriesPage> {
|
||||
return InkWell(
|
||||
child: Container(
|
||||
child: Text(
|
||||
state.name,
|
||||
state.name!,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||
@ -173,7 +173,7 @@ class _CustomerCountriesPageState extends State<CustomerCountriesPage> {
|
||||
}
|
||||
|
||||
_popWithShippingResult(DefaultShipping defaultShipping,
|
||||
{DefaultShippingState state}) {
|
||||
{DefaultShippingState? state}) {
|
||||
if (state != null) {
|
||||
defaultShipping.states = [];
|
||||
defaultShipping.states.add(state);
|
||||
|
||||
@ -26,16 +26,16 @@ class _HomePageState extends State<HomePage> {
|
||||
_HomePageState();
|
||||
|
||||
final GlobalKey _key = GlobalKey();
|
||||
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
|
||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget theme =
|
||||
MelloThemeWidget(globalKey: _key, wooSignalApp: _wooSignalApp);
|
||||
if (AppHelper.instance.appConfig.theme == "notic") {
|
||||
if (AppHelper.instance.appConfig!.theme == "notic") {
|
||||
theme = NoticThemeWidget(globalKey: _key, wooSignalApp: _wooSignalApp);
|
||||
}
|
||||
if (AppHelper.instance.appConfig.theme == "compo") {
|
||||
if (AppHelper.instance.appConfig!.theme == "compo") {
|
||||
theme = CompoThemeWidget(globalKey: _key, wooSignalApp: _wooSignalApp);
|
||||
}
|
||||
return theme;
|
||||
|
||||
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/resources/widgets/buttons.dart';
|
||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
import '../widgets/woosignal_ui.dart';
|
||||
|
||||
@ -37,7 +37,7 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
||||
Navigator.pushNamed(context, "/product-search",
|
||||
arguments: _txtSearchController.text)
|
||||
.then((search) {
|
||||
if (["notic", "compo"].contains(AppHelper.instance.appConfig.theme) ==
|
||||
if (["notic", "compo"].contains(AppHelper.instance.appConfig!.theme) ==
|
||||
false) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
|
||||
@ -26,24 +26,24 @@ import '../../app/controllers/leave_review_controller.dart';
|
||||
class LeaveReviewPage extends NyStatefulWidget {
|
||||
final LeaveReviewController controller = LeaveReviewController();
|
||||
|
||||
LeaveReviewPage({Key key}) : super(key: key);
|
||||
LeaveReviewPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LeaveReviewPageState createState() => _LeaveReviewPageState();
|
||||
}
|
||||
|
||||
class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
LineItems _lineItem;
|
||||
Order _order;
|
||||
LineItems? _lineItem;
|
||||
Order? _order;
|
||||
|
||||
TextEditingController _textEditingController;
|
||||
int _rating;
|
||||
TextEditingController? _textEditingController;
|
||||
int? _rating;
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
_lineItem = widget.controller.data()['line_item'] as LineItems;
|
||||
_order = widget.controller.data()['order'] as Order;
|
||||
init() async {
|
||||
_lineItem = widget.controller.data()['line_item'] as LineItems?;
|
||||
_order = widget.controller.data()['order'] as Order?;
|
||||
_textEditingController = TextEditingController();
|
||||
_rating = 5;
|
||||
}
|
||||
@ -74,7 +74,7 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
trans("How would you rate"),
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
),
|
||||
Text(_lineItem.name),
|
||||
Text(_lineItem!.name!),
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: TextField(
|
||||
@ -92,7 +92,7 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
padding: EdgeInsets.only(bottom: 16),
|
||||
),
|
||||
RatingBar.builder(
|
||||
initialRating: _rating.toDouble(),
|
||||
initialRating: _rating!.toDouble(),
|
||||
minRating: 1,
|
||||
direction: Axis.horizontal,
|
||||
allowHalfRating: false,
|
||||
@ -120,8 +120,8 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
String review = _textEditingController.text;
|
||||
wc_customer_info.Data wcCustomerInfo = await _fetchWpUserData();
|
||||
String review = _textEditingController!.text;
|
||||
wc_customer_info.Data? wcCustomerInfo = await _fetchWpUserData();
|
||||
if (wcCustomerInfo == null) {
|
||||
showToastNotification(
|
||||
context,
|
||||
@ -138,17 +138,19 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
try {
|
||||
validator(rules: {"review": "min:5"}, data: {"review": review});
|
||||
|
||||
ProductReview productReview =
|
||||
await appWooSignal((api) => api.createProductReview(
|
||||
productId: _lineItem.productId,
|
||||
ProductReview? productReview =
|
||||
await (appWooSignal((api) => api.createProductReview(
|
||||
productId: _lineItem!.productId,
|
||||
verified: true,
|
||||
review: review,
|
||||
status: "approved",
|
||||
reviewer: [_order.billing.firstName, _order.billing.lastName]
|
||||
.join(" "),
|
||||
reviewer: [
|
||||
_order!.billing!.firstName,
|
||||
_order!.billing!.lastName
|
||||
].join(" "),
|
||||
rating: _rating,
|
||||
reviewerEmail: _order.billing.email,
|
||||
));
|
||||
reviewerEmail: _order!.billing!.email,
|
||||
)));
|
||||
|
||||
if (productReview == null) {
|
||||
showToastNotification(context,
|
||||
@ -171,13 +173,13 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<wc_customer_info.Data> _fetchWpUserData() async {
|
||||
String userToken = await readAuthToken();
|
||||
Future<wc_customer_info.Data?> _fetchWpUserData() async {
|
||||
String? userToken = await readAuthToken();
|
||||
|
||||
wc_customer_info.WCCustomerInfoResponse wcCustomerInfoResponse;
|
||||
wc_customer_info.WCCustomerInfoResponse? wcCustomerInfoResponse;
|
||||
try {
|
||||
wcCustomerInfoResponse = await WPJsonAPI.instance
|
||||
.api((request) => request.wcCustomerInfo(userToken));
|
||||
.api((request) => request.wcCustomerInfo(userToken!));
|
||||
|
||||
if (wcCustomerInfoResponse == null) {
|
||||
return null;
|
||||
|
||||
@ -65,7 +65,7 @@ class _NoConnectionPageState extends State<NoConnectionPage> {
|
||||
}
|
||||
|
||||
_retry() async {
|
||||
WooSignalApp wooSignalApp = await appWooSignal((api) => api.getApp());
|
||||
WooSignalApp? wooSignalApp = await (appWooSignal((api) => api.getApp()));
|
||||
|
||||
if (wooSignalApp == null) {
|
||||
showToastNotification(context,
|
||||
|
||||
@ -30,7 +30,7 @@ import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
class ProductDetailPage extends NyStatefulWidget {
|
||||
@override
|
||||
final ProductDetailController controller = ProductDetailController();
|
||||
ProductDetailPage({Key key}) : super(key: key);
|
||||
ProductDetailPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ProductDetailState createState() => _ProductDetailState();
|
||||
@ -38,16 +38,16 @@ class ProductDetailPage extends NyStatefulWidget {
|
||||
|
||||
class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
bool _isLoading = true;
|
||||
ws_product.Product _product;
|
||||
ws_product.Product? _product;
|
||||
|
||||
List<ws_product_variation.ProductVariation> _productVariations = [];
|
||||
final Map<int, dynamic> _tmpAttributeObj = {};
|
||||
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
|
||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
init() async {
|
||||
_product = widget.controller.data();
|
||||
if (_product.type == "variable") {
|
||||
if (_product!.type == "variable") {
|
||||
await _fetchProductVariations();
|
||||
return;
|
||||
}
|
||||
@ -62,15 +62,15 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
|
||||
bool isFetching = true;
|
||||
while (isFetching) {
|
||||
List<ws_product_variation.ProductVariation> tmp = await appWooSignal(
|
||||
(api) => api.getProductVariations(_product.id,
|
||||
List<ws_product_variation.ProductVariation> tmp = await (appWooSignal(
|
||||
(api) => api.getProductVariations(_product!.id!,
|
||||
perPage: 100, page: currentPage),
|
||||
);
|
||||
if (tmp != null && tmp.isNotEmpty) {
|
||||
));
|
||||
if (tmp.isNotEmpty) {
|
||||
tmpVariations.addAll(tmp);
|
||||
}
|
||||
|
||||
if (tmp != null && tmp.length >= 100) {
|
||||
if (tmp.length >= 100) {
|
||||
currentPage += 1;
|
||||
} else {
|
||||
isFetching = false;
|
||||
@ -85,26 +85,27 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
_modalBottomSheetOptionsForAttribute(int attributeIndex) {
|
||||
wsModalBottom(
|
||||
context,
|
||||
title: "${trans("Select a")} ${_product.attributes[attributeIndex].name}",
|
||||
title:
|
||||
"${trans("Select a")} ${_product!.attributes[attributeIndex].name}",
|
||||
bodyWidget: ListView.separated(
|
||||
itemCount: _product.attributes[attributeIndex].options.length,
|
||||
itemCount: _product!.attributes[attributeIndex].options!.length,
|
||||
separatorBuilder: (BuildContext context, int index) => Divider(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text(
|
||||
_product.attributes[attributeIndex].options[index],
|
||||
_product!.attributes[attributeIndex].options![index],
|
||||
style: Theme.of(context).textTheme.subtitle1,
|
||||
),
|
||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(attributeIndex) &&
|
||||
_tmpAttributeObj[attributeIndex]["value"] ==
|
||||
_product.attributes[attributeIndex].options[index])
|
||||
_product!.attributes[attributeIndex].options![index])
|
||||
? Icon(Icons.check, color: Colors.blueAccent)
|
||||
: null,
|
||||
onTap: () {
|
||||
_tmpAttributeObj[attributeIndex] = {
|
||||
"name": _product.attributes[attributeIndex].name,
|
||||
"value": _product.attributes[attributeIndex].options[index]
|
||||
"name": _product!.attributes[attributeIndex].name,
|
||||
"value": _product!.attributes[attributeIndex].options![index]
|
||||
};
|
||||
Navigator.pop(context, () {});
|
||||
Navigator.pop(context);
|
||||
@ -117,7 +118,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
}
|
||||
|
||||
_modalBottomSheetAttributes() {
|
||||
ws_product_variation.ProductVariation productVariation = widget.controller
|
||||
ws_product_variation.ProductVariation? productVariation = widget.controller
|
||||
.findProductVariation(
|
||||
tmpAttributeObj: _tmpAttributeObj,
|
||||
productVariations: _productVariations);
|
||||
@ -125,21 +126,21 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
context,
|
||||
title: trans("Options"),
|
||||
bodyWidget: ListView.separated(
|
||||
itemCount: _product.attributes.length,
|
||||
itemCount: _product!.attributes.length,
|
||||
separatorBuilder: (BuildContext context, int index) => Divider(
|
||||
color: Colors.black12,
|
||||
thickness: 1,
|
||||
),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return ListTile(
|
||||
title: Text(_product.attributes[index].name,
|
||||
title: Text(_product!.attributes[index].name!,
|
||||
style: Theme.of(context).textTheme.subtitle1),
|
||||
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Text(_tmpAttributeObj[index]["value"],
|
||||
style: Theme.of(context).textTheme.bodyText1)
|
||||
: Text(
|
||||
"${trans("Select a")} ${_product.attributes[index].name}"),
|
||||
"${trans("Select a")} ${_product!.attributes[index].name}"),
|
||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||
_tmpAttributeObj.containsKey(index))
|
||||
? Icon(Icons.check, color: Colors.blueAccent)
|
||||
@ -157,7 +158,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
Text(
|
||||
(productVariation != null
|
||||
? "${trans("Price")}: ${formatStringCurrency(total: productVariation.price)}"
|
||||
: (((_product.attributes.length ==
|
||||
: (((_product!.attributes.length ==
|
||||
_tmpAttributeObj.values.length) &&
|
||||
productVariation == null)
|
||||
? trans("This variation is unavailable")
|
||||
@ -175,7 +176,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
PrimaryButton(
|
||||
title: trans("Add to cart"),
|
||||
action: () async {
|
||||
if (_product.attributes.length !=
|
||||
if (_product!.attributes.length !=
|
||||
_tmpAttributeObj.values.length) {
|
||||
showToastNotification(context,
|
||||
title: trans("Oops"),
|
||||
@ -208,7 +209,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
CartLineItem cartLineItem = CartLineItem.fromProductVariation(
|
||||
quantityAmount: widget.controller.quantity,
|
||||
options: options,
|
||||
product: _product,
|
||||
product: _product!,
|
||||
productVariation: productVariation,
|
||||
);
|
||||
|
||||
@ -230,10 +231,10 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
actions: <Widget>[
|
||||
if (_wooSignalApp.wishlistEnabled)
|
||||
if (_wooSignalApp!.wishlistEnabled!)
|
||||
FutureBuildWidget(
|
||||
asyncFuture: hasAddedWishlistProduct(_product.id),
|
||||
onValue: (isInFavourites) {
|
||||
asyncFuture: hasAddedWishlistProduct(_product!.id),
|
||||
onValue: (dynamic isInFavourites) {
|
||||
return isInFavourites
|
||||
? IconButton(
|
||||
onPressed: () => widget.controller.toggleWishList(
|
||||
@ -244,8 +245,9 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
onPressed: () => widget.controller.toggleWishList(
|
||||
onSuccess: () => setState(() {}),
|
||||
wishlistAction: WishlistAction.add),
|
||||
icon: Icon(Icons.favorite_border,
|
||||
color: Colors.black54));
|
||||
icon: Icon(
|
||||
Icons.favorite_border,
|
||||
));
|
||||
}),
|
||||
CartIconWidget(),
|
||||
],
|
||||
@ -286,11 +288,11 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
}
|
||||
|
||||
_addItemToCart() async {
|
||||
if (_product.type != "simple") {
|
||||
if (_product!.type != "simple") {
|
||||
_modalBottomSheetAttributes();
|
||||
return;
|
||||
}
|
||||
if (_product.stockStatus != "instock") {
|
||||
if (_product!.stockStatus != "instock") {
|
||||
showToastNotification(context,
|
||||
title: trans("Sorry"),
|
||||
description: trans("This item is out of stock"),
|
||||
@ -301,7 +303,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||
|
||||
await widget.controller.itemAddToCart(
|
||||
cartLineItem: CartLineItem.fromProduct(
|
||||
quantityAmount: widget.controller.quantity, product: _product),
|
||||
quantityAmount: widget.controller.quantity, product: _product!),
|
||||
onSuccess: () => setState(() {}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,23 +12,25 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/controllers/product_image_viewer_controller.dart';
|
||||
import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||
import 'package:flutter_swiper/flutter_swiper.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_support/widgets/ny_state.dart';
|
||||
import 'package:nylo_support/widgets/ny_stateful_widget.dart';
|
||||
import 'package:flutter_swiper_tv/flutter_swiper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
class ProductImageViewerPage extends NyStatefulWidget {
|
||||
@override
|
||||
final ProductImageViewerController controller =
|
||||
ProductImageViewerController();
|
||||
ProductImageViewerPage({Key key}) : super(key: key);
|
||||
ProductImageViewerPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ProductImageViewerPageState createState() => _ProductImageViewerPageState();
|
||||
}
|
||||
|
||||
class _ProductImageViewerPageState extends NyState<ProductImageViewerPage> {
|
||||
int _initialIndex;
|
||||
List<String> _arrImageSrc;
|
||||
int? _initialIndex;
|
||||
List<String?> _arrImageSrc = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -43,10 +45,10 @@ class _ProductImageViewerPageState extends NyState<ProductImageViewerPage> {
|
||||
return Scaffold(
|
||||
body: SafeAreaWidget(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
children: [
|
||||
Expanded(
|
||||
child: Swiper(
|
||||
index: _initialIndex,
|
||||
index: _initialIndex!,
|
||||
itemBuilder: (BuildContext context, int index) =>
|
||||
CachedImageWidget(
|
||||
image: (_arrImageSrc.isEmpty
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/app/controllers/product_reviews_loader_controller.dart';
|
||||
@ -25,7 +26,7 @@ import '../../app/controllers/product_reviews_controller.dart';
|
||||
class ProductReviewsPage extends NyStatefulWidget {
|
||||
final ProductReviewsController controller = ProductReviewsController();
|
||||
|
||||
ProductReviewsPage({Key key}) : super(key: key);
|
||||
ProductReviewsPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_ProductReviewsPageState createState() => _ProductReviewsPageState();
|
||||
@ -34,14 +35,14 @@ class ProductReviewsPage extends NyStatefulWidget {
|
||||
class _ProductReviewsPageState extends NyState<ProductReviewsPage> {
|
||||
final RefreshController _refreshController =
|
||||
RefreshController(initialRefresh: false);
|
||||
Product _product;
|
||||
Product? _product;
|
||||
bool _shouldStopRequests = false, _isLoading = true;
|
||||
final ProductReviewsLoaderController _productReviewsLoaderController =
|
||||
ProductReviewsLoaderController();
|
||||
|
||||
@override
|
||||
widgetDidLoad() async {
|
||||
_product = widget.data() as Product;
|
||||
init() async {
|
||||
_product = widget.data() as Product?;
|
||||
await fetchProductReviews();
|
||||
}
|
||||
|
||||
@ -63,113 +64,116 @@ class _ProductReviewsPageState extends NyState<ProductReviewsPage> {
|
||||
? AppLoaderWidget()
|
||||
: SafeArea(
|
||||
child: Column(
|
||||
// shrinkWrap: true,
|
||||
children: [
|
||||
Container(
|
||||
height: mediaQuery.size.height / 5,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
margin: EdgeInsets.symmetric(vertical: 16),
|
||||
decoration: BoxDecoration(
|
||||
border:
|
||||
Border(bottom: BorderSide(color: Colors.black12))),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
child: Text(
|
||||
_product.name,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
_product.ratingCount.toString() + " Reviews",
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 8),
|
||||
child: Text(
|
||||
_product.averageRating + " Stars",
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
),
|
||||
// shrinkWrap: true,
|
||||
children: [
|
||||
Container(
|
||||
height: mediaQuery.size.height / 5,
|
||||
padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
margin: EdgeInsets.symmetric(vertical: 16),
|
||||
decoration: BoxDecoration(
|
||||
border:
|
||||
Border(bottom: BorderSide(color: Colors.black12))),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
child: Text(
|
||||
_product!.name!,
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
RatingBarIndicator(
|
||||
rating: double.parse(_product.averageRating),
|
||||
itemBuilder: (context, index) => Icon(
|
||||
Icons.star,
|
||||
color: Colors.amber,
|
||||
),
|
||||
itemCount: 5,
|
||||
itemSize: 20.0,
|
||||
direction: Axis.horizontal,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: Text(
|
||||
_product!.ratingCount.toString() + " Reviews",
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(right: 8),
|
||||
child: Text(
|
||||
_product!.averageRating! + " Stars",
|
||||
style: Theme.of(context).textTheme.bodyText2,
|
||||
),
|
||||
),
|
||||
RatingBarIndicator(
|
||||
rating: double.parse(_product!.averageRating!),
|
||||
itemBuilder: (context, index) => Icon(
|
||||
Icons.star,
|
||||
color: Colors.amber,
|
||||
),
|
||||
itemCount: 5,
|
||||
itemSize: 20.0,
|
||||
direction: Axis.horizontal,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
Expanded(
|
||||
child: SmartRefresher(
|
||||
enablePullDown: true,
|
||||
enablePullUp: true,
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode) {
|
||||
Widget body;
|
||||
if (mode == LoadStatus.idle) {
|
||||
body = Text(trans("pull up load"));
|
||||
} else if (mode == LoadStatus.loading) {
|
||||
body = CupertinoActivityIndicator();
|
||||
} else if (mode == LoadStatus.failed) {
|
||||
body = Text(trans("Load Failed! Click retry!"));
|
||||
} else if (mode == LoadStatus.canLoading) {
|
||||
body = Text(trans("release to load more"));
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return Container(
|
||||
height: 55.0,
|
||||
child: Center(child: body),
|
||||
);
|
||||
},
|
||||
),
|
||||
controller: _refreshController,
|
||||
onRefresh: _onRefresh,
|
||||
onLoading: _onLoading,
|
||||
child: (productReviews.length != null &&
|
||||
productReviews.isNotEmpty
|
||||
? StaggeredGridView.countBuilder(
|
||||
crossAxisCount: 2,
|
||||
scrollDirection: Axis.vertical,
|
||||
itemCount: productReviews.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
ProductReview productReview = productReviews[index];
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 8),
|
||||
margin: EdgeInsets.only(bottom: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom:
|
||||
BorderSide(color: Colors.black12))),
|
||||
child: ProductReviewItemContainerWidget(
|
||||
productReview: productReview),
|
||||
);
|
||||
},
|
||||
staggeredTileBuilder: (int index) {
|
||||
return StaggeredTile.fit(2);
|
||||
},
|
||||
mainAxisSpacing: 4.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
)
|
||||
: NoResultsForProductsWidget()),
|
||||
))
|
||||
],
|
||||
)),
|
||||
enablePullDown: true,
|
||||
enablePullUp: true,
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus? mode) {
|
||||
Widget body;
|
||||
if (mode == LoadStatus.idle) {
|
||||
body = Text(trans("pull up load"));
|
||||
} else if (mode == LoadStatus.loading) {
|
||||
body = CupertinoActivityIndicator();
|
||||
} else if (mode == LoadStatus.failed) {
|
||||
body = Text(trans("Load Failed! Click retry!"));
|
||||
} else if (mode == LoadStatus.canLoading) {
|
||||
body = Text(trans("release to load more"));
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
return Container(
|
||||
height: 55.0,
|
||||
child: Center(child: body),
|
||||
);
|
||||
},
|
||||
),
|
||||
controller: _refreshController,
|
||||
onRefresh: _onRefresh,
|
||||
onLoading: _onLoading,
|
||||
child: (productReviews.isNotEmpty
|
||||
? StaggeredGrid.count(
|
||||
crossAxisCount: 2,
|
||||
axisDirection: AxisDirection.down,
|
||||
children:
|
||||
productReviews.mapIndexed((index, value) {
|
||||
ProductReview productReview =
|
||||
productReviews[index];
|
||||
|
||||
return StaggeredGridTile.fit(
|
||||
crossAxisCellCount: 2,
|
||||
// mainAxisCellCount: 2,
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 16, vertical: 8),
|
||||
margin: EdgeInsets.only(bottom: 8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: Colors.black12))),
|
||||
child: ProductReviewItemContainerWidget(
|
||||
productReview: productReview),
|
||||
));
|
||||
}).toList(),
|
||||
mainAxisSpacing: 4.0,
|
||||
crossAxisSpacing: 4.0,
|
||||
)
|
||||
: NoResultsForProductsWidget()),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,7 @@ class WishListPageWidget extends StatefulWidget {
|
||||
|
||||
class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
List<Product> _products = [];
|
||||
bool isLoading;
|
||||
bool? isLoading;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -31,12 +31,12 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
});
|
||||
return;
|
||||
}
|
||||
_products = await appWooSignal((api) => api.getProducts(
|
||||
_products = await (appWooSignal((api) => api.getProducts(
|
||||
include: productIds,
|
||||
perPage: 100,
|
||||
status: "publish",
|
||||
stockStatus: "instock",
|
||||
));
|
||||
)));
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
@ -50,7 +50,7 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
title: Text(trans("Wishlist")),
|
||||
),
|
||||
body: SafeArea(
|
||||
child: isLoading
|
||||
child: isLoading!
|
||||
? AppLoaderWidget()
|
||||
: _products.isEmpty && isLoading == false
|
||||
? Center(
|
||||
@ -68,9 +68,9 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
Text(trans("No items found"),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline6
|
||||
.setColor(
|
||||
context, (color) => color.primaryContent))
|
||||
.headline6!
|
||||
.setColor(context,
|
||||
(color) => color!.primaryContent))
|
||||
],
|
||||
),
|
||||
)
|
||||
@ -86,6 +86,7 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 8),
|
||||
child: CachedImageWidget(
|
||||
image: (product.images.isNotEmpty
|
||||
? product.images.first.src
|
||||
@ -103,7 +104,7 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(product.name),
|
||||
Text(product.name!, style: TextStyle(fontWeight: FontWeight.bold), maxLines: 2, overflow: TextOverflow.ellipsis,),
|
||||
Text(
|
||||
formatStringCurrency(
|
||||
total: product.price),
|
||||
@ -113,7 +114,7 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: 100,
|
||||
width: MediaQuery.of(context).size.width / 5,
|
||||
alignment: Alignment.center,
|
||||
child: IconButton(
|
||||
icon: Icon(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/config/app_font.dart';
|
||||
import 'package:flutter_app/config/font.dart';
|
||||
import 'package:flutter_app/resources/themes/styles/base_styles.dart';
|
||||
import 'package:flutter_app/resources/themes/text_theme/default_text_theme.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -11,14 +11,14 @@ import 'package:nylo_framework/nylo_framework.dart';
|
||||
|--------------------------------------------------------------------------
|
||||
| Dark Theme
|
||||
|
|
||||
| Theme Config - config/app_theme.dart
|
||||
| Theme Config - config/theme.dart
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ThemeData darkTheme(BaseColorStyles darkColors) {
|
||||
try {
|
||||
appFont = GoogleFonts.getFont(
|
||||
AppHelper.instance.appConfig.themeFont ?? "Poppins");
|
||||
AppHelper.instance.appConfig!.themeFont ?? "Poppins");
|
||||
} on Exception catch (e) {
|
||||
if (getEnv('APP_DEBUG') == true) {
|
||||
NyLogger.error(e.toString());
|
||||
@ -37,7 +37,7 @@ ThemeData darkTheme(BaseColorStyles darkColors) {
|
||||
scaffoldBackgroundColor: darkColors.background,
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: darkColors.appBarBackground,
|
||||
titleTextStyle: darkTheme.headline6
|
||||
titleTextStyle: darkTheme.headline6!
|
||||
.copyWith(color: darkColors.appBarPrimaryContent),
|
||||
iconTheme: IconThemeData(color: darkColors.appBarPrimaryContent),
|
||||
elevation: 1.0,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||
import 'package:flutter_app/config/app_font.dart';
|
||||
import 'package:flutter_app/config/font.dart';
|
||||
import 'package:flutter_app/resources/themes/styles/base_styles.dart';
|
||||
import 'package:flutter_app/resources/themes/text_theme/default_text_theme.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -11,14 +11,14 @@ import 'package:nylo_framework/nylo_framework.dart';
|
||||
|--------------------------------------------------------------------------
|
||||
| Light Theme
|
||||
|
|
||||
| Theme Config - config/app_theme.dart
|
||||
| Theme Config - config/theme.dart
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
ThemeData lightTheme(BaseColorStyles lightColors) {
|
||||
try {
|
||||
appFont = GoogleFonts.getFont(
|
||||
AppHelper.instance.appConfig.themeFont ?? "Poppins");
|
||||
AppHelper.instance.appConfig!.themeFont ?? "Poppins");
|
||||
} on Exception catch (e) {
|
||||
if (getEnv('APP_DEBUG') == true) {
|
||||
NyLogger.error(e.toString());
|
||||
@ -38,7 +38,7 @@ ThemeData lightTheme(BaseColorStyles lightColors) {
|
||||
hintColor: lightColors.primaryAccent,
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: lightColors.appBarBackground,
|
||||
titleTextStyle: lightTheme.headline6
|
||||
titleTextStyle: lightTheme.headline6!
|
||||
.copyWith(color: lightColors.appBarPrimaryContent),
|
||||
iconTheme: IconThemeData(color: lightColors.appBarPrimaryContent),
|
||||
elevation: 1.0,
|
||||
|
||||
@ -12,13 +12,13 @@ class DarkThemeColors implements BaseColorStyles {
|
||||
// general
|
||||
@override
|
||||
Color get background => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['background']));
|
||||
AppHelper.instance.appConfig!.themeColors!['dark']['background']));
|
||||
@override
|
||||
Color get backgroundContainer => const Color(0xFF4a4a4a);
|
||||
|
||||
@override
|
||||
Color get primaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['primary_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['dark']['primary_text']));
|
||||
@override
|
||||
Color get primaryAccent => const Color(0xFF818181);
|
||||
|
||||
@ -29,11 +29,12 @@ class DarkThemeColors implements BaseColorStyles {
|
||||
|
||||
// app bar
|
||||
@override
|
||||
Color get appBarBackground => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['app_bar_background']));
|
||||
Color get appBarBackground =>
|
||||
Color(int.parse(AppHelper.instance.appConfig!.themeColors!['dark']
|
||||
['app_bar_background']));
|
||||
@override
|
||||
Color get appBarPrimaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['app_bar_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['dark']['app_bar_text']));
|
||||
|
||||
@override
|
||||
Color get inputPrimaryContent => Colors.white;
|
||||
@ -41,10 +42,10 @@ class DarkThemeColors implements BaseColorStyles {
|
||||
// buttons
|
||||
@override
|
||||
Color get buttonBackground => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['button_background']));
|
||||
AppHelper.instance.appConfig!.themeColors!['dark']['button_background']));
|
||||
@override
|
||||
Color get buttonPrimaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['dark']['button_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['dark']['button_text']));
|
||||
|
||||
// bottom tab bar
|
||||
@override
|
||||
|
||||
@ -13,12 +13,12 @@ class LightThemeColors implements BaseColorStyles {
|
||||
|
||||
@override
|
||||
Color get background => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['background']));
|
||||
AppHelper.instance.appConfig!.themeColors!['light']['background']));
|
||||
@override
|
||||
Color get backgroundContainer => Colors.white;
|
||||
@override
|
||||
Color get primaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['primary_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['light']['primary_text']));
|
||||
@override
|
||||
Color get primaryAccent => const Color(0xFF87c694);
|
||||
|
||||
@ -29,22 +29,24 @@ class LightThemeColors implements BaseColorStyles {
|
||||
|
||||
// app bar
|
||||
@override
|
||||
Color get appBarBackground => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['app_bar_background']));
|
||||
Color get appBarBackground =>
|
||||
Color(int.parse(AppHelper.instance.appConfig!.themeColors!['light']
|
||||
['app_bar_background']));
|
||||
@override
|
||||
Color get appBarPrimaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['app_bar_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['light']['app_bar_text']));
|
||||
|
||||
@override
|
||||
Color get inputPrimaryContent => Colors.black;
|
||||
|
||||
// buttons
|
||||
@override
|
||||
Color get buttonBackground => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['button_background']));
|
||||
Color get buttonBackground =>
|
||||
Color(int.parse(AppHelper.instance.appConfig!.themeColors!['light']
|
||||
['button_background']));
|
||||
@override
|
||||
Color get buttonPrimaryContent => Color(int.parse(
|
||||
AppHelper.instance.appConfig.themeColors['light']['button_text']));
|
||||
AppHelper.instance.appConfig!.themeColors!['light']['button_text']));
|
||||
|
||||
// bottom tab bar
|
||||
@override
|
||||
|
||||
@ -68,7 +68,7 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
enablePullDown: true,
|
||||
enablePullUp: true,
|
||||
footer: CustomFooter(
|
||||
builder: (BuildContext context, LoadStatus mode) {
|
||||
builder: (BuildContext context, LoadStatus? mode) {
|
||||
Widget body;
|
||||
if (mode == LoadStatus.idle) {
|
||||
body = Text(trans("pull up load"));
|
||||
@ -120,7 +120,7 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
order.status.capitalize(),
|
||||
order.status!.capitalize(),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@ -141,17 +141,17 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
formatStringCurrency(total: order.total),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText2
|
||||
.bodyText2!
|
||||
.copyWith(fontWeight: FontWeight.w600),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
Text(
|
||||
order.lineItems.length.toString() +
|
||||
order.lineItems!.length.toString() +
|
||||
" " +
|
||||
trans("items"),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText1
|
||||
.bodyText1!
|
||||
.copyWith(fontWeight: FontWeight.w600),
|
||||
textAlign: TextAlign.left,
|
||||
),
|
||||
@ -159,16 +159,16 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
),
|
||||
Text(
|
||||
dateFormatted(
|
||||
date: order.dateCreated,
|
||||
date: order.dateCreated!,
|
||||
formatType: formatForDateTime(FormatType.date),
|
||||
) +
|
||||
"\n" +
|
||||
dateFormatted(
|
||||
date: order.dateCreated,
|
||||
date: order.dateCreated!,
|
||||
formatType: formatForDateTime(FormatType.time),
|
||||
),
|
||||
textAlign: TextAlign.right,
|
||||
style: Theme.of(context).textTheme.bodyText1.copyWith(
|
||||
style: Theme.of(context).textTheme.bodyText1!.copyWith(
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
@ -214,7 +214,7 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
}
|
||||
|
||||
fetchOrders() async {
|
||||
String userId = await readUserId();
|
||||
String? userId = await readUserId();
|
||||
if (userId == null) {
|
||||
setState(() {
|
||||
_isLoadingOrders = false;
|
||||
@ -238,7 +238,7 @@ class _AccountDetailOrdersWidgetState extends State<AccountDetailOrdersWidget> {
|
||||
userId: userId);
|
||||
}
|
||||
|
||||
_viewOrderDetail(int i, int orderId) => Navigator.pushNamed(
|
||||
_viewOrderDetail(int i, int? orderId) => Navigator.pushNamed(
|
||||
context,
|
||||
"/account-order-detail",
|
||||
arguments: orderId,
|
||||
|
||||
@ -13,7 +13,7 @@ import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class AccountDetailSettingsWidget extends StatelessWidget {
|
||||
const AccountDetailSettingsWidget({Key key, @required this.refreshAccount})
|
||||
const AccountDetailSettingsWidget({Key? key, required this.refreshAccount})
|
||||
: super(key: key);
|
||||
final Function refreshAccount;
|
||||
@override
|
||||
|
||||
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
class AppLoaderWidget extends StatelessWidget {
|
||||
const AppLoaderWidget({Key key}) : super(key: key);
|
||||
const AppLoaderWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@ -9,11 +9,11 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:nylo_support/helpers/helper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:package_info/package_info.dart';
|
||||
|
||||
class AppVersionWidget extends StatelessWidget {
|
||||
const AppVersionWidget({Key key}) : super(key: key);
|
||||
const AppVersionWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -29,15 +29,14 @@ class AppVersionWidget extends StatelessWidget {
|
||||
case ConnectionState.done:
|
||||
if (snapshot.hasError) return Text("");
|
||||
return Padding(
|
||||
child: Text("${trans("Version")}: ${snapshot.data.version}",
|
||||
child: Text("${trans("Version")}: ${snapshot.data!.version}",
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyText2
|
||||
.bodyText2!
|
||||
.copyWith(fontWeight: FontWeight.w300)),
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
);
|
||||
}
|
||||
return null; // unreachable
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -14,15 +14,12 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|
||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||
|
||||
class PrimaryButton extends StatelessWidget {
|
||||
const PrimaryButton({
|
||||
Key key,
|
||||
this.title,
|
||||
this.action,
|
||||
this.isLoading = false
|
||||
}) : super(key: key);
|
||||
const PrimaryButton(
|
||||
{Key? key, this.title, this.action, this.isLoading = false})
|
||||
: super(key: key);
|
||||
|
||||
final String title;
|
||||
final void Function() action;
|
||||
final String? title;
|
||||
final Function? action;
|
||||
final bool isLoading;
|
||||
|
||||
@override
|
||||
@ -31,30 +28,30 @@ class PrimaryButton extends StatelessWidget {
|
||||
title: title,
|
||||
action: action,
|
||||
isLoading: isLoading,
|
||||
textStyle: Theme.of(context).textTheme.button.copyWith(
|
||||
textStyle: Theme.of(context).textTheme.button!.copyWith(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: ThemeColor.get(context).buttonPrimaryContent),
|
||||
bgColor: ThemeColor.get(context).buttonBackground,
|
||||
color: ThemeColor.get(context)!.buttonPrimaryContent),
|
||||
bgColor: ThemeColor.get(context)!.buttonBackground,
|
||||
);
|
||||
}
|
||||
|
||||
class SecondaryButton extends StatelessWidget {
|
||||
const SecondaryButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.title,
|
||||
this.action,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
final void Function() action;
|
||||
final String? title;
|
||||
final Function? action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => WooSignalButton(
|
||||
key: key,
|
||||
title: title,
|
||||
action: action,
|
||||
textStyle: Theme.of(context).textTheme.bodyText1.copyWith(
|
||||
textStyle: Theme.of(context).textTheme.bodyText1!.copyWith(
|
||||
color: Colors.black87,
|
||||
),
|
||||
bgColor: Color(0xFFF6F6F9),
|
||||
@ -63,34 +60,40 @@ class SecondaryButton extends StatelessWidget {
|
||||
|
||||
class LinkButton extends StatelessWidget {
|
||||
const LinkButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.title,
|
||||
this.action,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
final void Function() action;
|
||||
final String? title;
|
||||
final Function? action;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final double screenWidth = MediaQuery.of(context).size.width;
|
||||
return InkWell(
|
||||
key: key,
|
||||
child: Container(
|
||||
child: Container(
|
||||
height: (screenWidth >= 385 ? 55 : 49),
|
||||
width: double.infinity,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.transparent,
|
||||
),
|
||||
child: Center(child: Text(title, textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyText1,)),),
|
||||
onTap: action,
|
||||
child: Center(
|
||||
child: Text(
|
||||
title!,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
)),
|
||||
),
|
||||
onTap: action == null ? null : () async => await action!(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class WooSignalButton extends StatelessWidget {
|
||||
const WooSignalButton({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.title,
|
||||
this.action,
|
||||
this.textStyle,
|
||||
@ -98,10 +101,10 @@ class WooSignalButton extends StatelessWidget {
|
||||
this.bgColor,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
final void Function() action;
|
||||
final TextStyle textStyle;
|
||||
final Color bgColor;
|
||||
final String? title;
|
||||
final Function? action;
|
||||
final TextStyle? textStyle;
|
||||
final Color? bgColor;
|
||||
final bool isLoading;
|
||||
|
||||
@override
|
||||
@ -115,22 +118,28 @@ class WooSignalButton extends StatelessWidget {
|
||||
),
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
elevation: 0,
|
||||
primary: bgColor,
|
||||
shadowColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
),
|
||||
padding: EdgeInsets.all(8),
|
||||
elevation: 0,
|
||||
primary: bgColor,
|
||||
shadowColor: Colors.transparent,
|
||||
),
|
||||
child: isLoading ? AppLoaderWidget() : AutoSizeText(
|
||||
title,
|
||||
style: textStyle,
|
||||
maxLines: (screenWidth >= 385 ? 2 : 1),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
onPressed: isLoading == true ? () {} : action,
|
||||
child: isLoading
|
||||
? AppLoaderWidget()
|
||||
: AutoSizeText(
|
||||
title!,
|
||||
style: textStyle,
|
||||
maxLines: (screenWidth >= 385 ? 2 : 1),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
onPressed: (action == null || isLoading == true)
|
||||
? null
|
||||
: () async {
|
||||
await action!();
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ import 'package:flutter/material.dart';
|
||||
|
||||
class CachedImageWidget extends StatelessWidget {
|
||||
const CachedImageWidget({
|
||||
Key key,
|
||||
Key? key,
|
||||
this.image,
|
||||
this.height = 70,
|
||||
this.width = 70,
|
||||
@ -26,7 +26,7 @@ class CachedImageWidget extends StatelessWidget {
|
||||
this.fit = BoxFit.contain,
|
||||
}) : super(key: key);
|
||||
|
||||
final String image;
|
||||
final String? image;
|
||||
final double height;
|
||||
final double width;
|
||||
final Widget placeholder;
|
||||
@ -34,7 +34,7 @@ class CachedImageWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => CachedNetworkImage(
|
||||
imageUrl: image,
|
||||
imageUrl: image!,
|
||||
placeholder: (context, url) => placeholder,
|
||||
errorWidget: (context, url, error) => Icon(Icons.error),
|
||||
height: height,
|
||||
|
||||
@ -13,7 +13,7 @@ import 'package:flutter_app/app/models/cart.dart';
|
||||
import 'package:flutter_app/app/models/cart_line_item.dart';
|
||||
|
||||
class CartIconWidget extends StatefulWidget {
|
||||
CartIconWidget({Key key}) : super(key: key);
|
||||
CartIconWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_CartIconWidgetState createState() => _CartIconWidgetState();
|
||||
@ -45,12 +45,12 @@ class _CartIconWidgetState extends State<CartIconWidget> {
|
||||
if (snapshot.hasError) {
|
||||
return Text("");
|
||||
} else {
|
||||
List<int> cartItems =
|
||||
snapshot.data.map((e) => e.quantity).toList();
|
||||
List<int?> cartItems =
|
||||
snapshot.data!.map((e) => e.quantity).toList();
|
||||
String cartValue = "0";
|
||||
if (cartItems.isNotEmpty) {
|
||||
cartValue = cartItems
|
||||
.reduce((value, element) => value + element)
|
||||
.reduce((value, element) => value! + element!)
|
||||
.toString();
|
||||
}
|
||||
return Text(
|
||||
|
||||
@ -7,7 +7,7 @@ import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class CheckoutCouponAmountWidget extends StatelessWidget {
|
||||
const CheckoutCouponAmountWidget({Key key, @required this.checkoutSession})
|
||||
const CheckoutCouponAmountWidget({Key? key, required this.checkoutSession})
|
||||
: super(key: key);
|
||||
|
||||
final CheckoutSession checkoutSession;
|
||||
@ -29,7 +29,7 @@ class CheckoutCouponAmountWidget extends StatelessWidget {
|
||||
}
|
||||
return Padding(
|
||||
child: CheckoutMetaLine(
|
||||
title: "${trans('Coupon')}: ${checkoutSession.coupon.code}",
|
||||
title: "${trans('Coupon')}: ${checkoutSession.coupon!.code}",
|
||||
amount: "-" + formatStringCurrency(total: snapshot.data),
|
||||
),
|
||||
padding: EdgeInsets.only(bottom: 0, top: 0),
|
||||
|
||||
@ -5,14 +5,14 @@ import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class CheckoutPaymentTypeWidget extends StatelessWidget {
|
||||
const CheckoutPaymentTypeWidget(
|
||||
{Key key,
|
||||
@required this.context,
|
||||
@required this.checkoutSession,
|
||||
{Key? key,
|
||||
required this.context,
|
||||
required this.checkoutSession,
|
||||
this.resetState})
|
||||
: super(key: key);
|
||||
final CheckoutSession checkoutSession;
|
||||
final BuildContext context;
|
||||
final Function resetState;
|
||||
final Function? resetState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -23,13 +23,13 @@ class CheckoutPaymentTypeWidget extends StatelessWidget {
|
||||
? Container(
|
||||
color: Colors.white,
|
||||
child: Image.asset(
|
||||
getImageAsset(checkoutSession.paymentType.assetImage),
|
||||
getImageAsset(checkoutSession.paymentType!.assetImage),
|
||||
width: 70,
|
||||
),
|
||||
)
|
||||
: Icon(Icons.payment),
|
||||
leadTitle: hasPaymentType
|
||||
? checkoutSession.paymentType.desc
|
||||
? checkoutSession.paymentType!.desc
|
||||
: trans("Select a payment method"),
|
||||
action: _actionPayWith,
|
||||
showBorderBottom: true,
|
||||
@ -38,6 +38,6 @@ class CheckoutPaymentTypeWidget extends StatelessWidget {
|
||||
|
||||
_actionPayWith() {
|
||||
Navigator.pushNamed(context, "/checkout-payment-type")
|
||||
.then((value) => resetState());
|
||||
.then((value) => resetState!());
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,9 +12,9 @@ import 'package:webview_flutter/webview_flutter.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
class PayPalCheckout extends StatefulWidget {
|
||||
final String description;
|
||||
final String amount;
|
||||
final List<CartLineItem> cartLineItems;
|
||||
final String? description;
|
||||
final String? amount;
|
||||
final List<CartLineItem>? cartLineItems;
|
||||
|
||||
PayPalCheckout({this.description, this.amount, this.cartLineItems});
|
||||
|
||||
@ -26,49 +26,49 @@ class WebViewState extends NyState<PayPalCheckout> {
|
||||
final Completer<WebViewController> _controller =
|
||||
Completer<WebViewController>();
|
||||
|
||||
String payerId = '';
|
||||
String? payerId = '';
|
||||
int intCount = 0;
|
||||
StreamSubscription<String> _onUrlChanged;
|
||||
final WooSignalApp _wooSignalApp = AppHelper.instance.appConfig;
|
||||
String formCheckoutShippingAddress;
|
||||
StreamSubscription<String>? _onUrlChanged;
|
||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||
String? formCheckoutShippingAddress;
|
||||
|
||||
setCheckoutShippingAddress(CustomerAddress customerAddress) {
|
||||
String tmp = "";
|
||||
if (customerAddress.firstName != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="first_name" value="${customerAddress.firstName.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="first_name" value="${customerAddress.firstName!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.lastName != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="last_name" value="${customerAddress.lastName.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="last_name" value="${customerAddress.lastName!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.addressLine != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="address1" value="${customerAddress.addressLine.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="address1" value="${customerAddress.addressLine!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.city != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="city" value="${customerAddress.city.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="city" value="${customerAddress.city!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.customerCountry.hasState() &&
|
||||
customerAddress.customerCountry.state.name != null) {
|
||||
if (customerAddress.customerCountry!.hasState() &&
|
||||
customerAddress.customerCountry!.state!.name != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="state" value="${customerAddress.customerCountry.state.name.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="state" value="${customerAddress.customerCountry!.state!.name!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.postalCode != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="zip" value="${customerAddress.postalCode.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="zip" value="${customerAddress.postalCode!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
if (customerAddress.customerCountry.countryCode != null) {
|
||||
if (customerAddress.customerCountry!.countryCode != null) {
|
||||
tmp +=
|
||||
'<input type="hidden" name="country" value="${customerAddress.customerCountry.countryCode.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
'<input type="hidden" name="country" value="${customerAddress.customerCountry!.countryCode!.replaceAll(RegExp(r'[^\d\w\s,\-+]+'), '')}">\n';
|
||||
}
|
||||
formCheckoutShippingAddress = tmp;
|
||||
}
|
||||
|
||||
String getPayPalItemName() {
|
||||
return truncateString(
|
||||
widget.description.replaceAll(RegExp(r'[^\w\s]+'), ''), 124);
|
||||
widget.description!.replaceAll(RegExp(r'[^\w\s]+'), ''), 124);
|
||||
}
|
||||
|
||||
String getPayPalPaymentType() {
|
||||
@ -76,8 +76,8 @@ class WebViewState extends NyState<PayPalCheckout> {
|
||||
}
|
||||
|
||||
String getPayPalUrl() {
|
||||
bool liveMode =
|
||||
envVal('PAYPAL_LIVE_MODE', defaultValue: _wooSignalApp.paypalLiveMode);
|
||||
bool? liveMode =
|
||||
envVal('PAYPAL_LIVE_MODE', defaultValue: _wooSignalApp!.paypalLiveMode);
|
||||
return liveMode == true
|
||||
? "https://www.paypal.com/cgi-bin/webscr"
|
||||
: "https://www.sandbox.paypal.com/cgi-bin/webscr";
|
||||
@ -88,14 +88,14 @@ class WebViewState extends NyState<PayPalCheckout> {
|
||||
super.initState();
|
||||
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
|
||||
setCheckoutShippingAddress(
|
||||
CheckoutSession.getInstance.billingDetails.shippingAddress);
|
||||
CheckoutSession.getInstance.billingDetails!.shippingAddress!);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_onUrlChanged != null) {
|
||||
_onUrlChanged.cancel();
|
||||
_onUrlChanged!.cancel();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
@ -117,9 +117,9 @@ class WebViewState extends NyState<PayPalCheckout> {
|
||||
<form method="post" name="paypal_form" action="${getPayPalUrl()}">
|
||||
<input type="hidden" name="cmd" value="_xclick">
|
||||
<input type="hidden" name="amount" value="${widget.amount}">
|
||||
<input type="hidden" name="lc" value="${envVal('PAYPAL_LOCALE', defaultValue: _wooSignalApp.paypalLocale)}">
|
||||
<input type="hidden" name="currency_code" value="${_wooSignalApp.currencyMeta.code}">
|
||||
<input type="hidden" name="business" value="${envVal('PAYPAL_ACCOUNT_EMAIL', defaultValue: _wooSignalApp.paypalEmail)}">
|
||||
<input type="hidden" name="lc" value="${envVal('PAYPAL_LOCALE', defaultValue: _wooSignalApp!.paypalLocale)}">
|
||||
<input type="hidden" name="currency_code" value="${_wooSignalApp!.currencyMeta!.code}">
|
||||
<input type="hidden" name="business" value="${envVal('PAYPAL_ACCOUNT_EMAIL', defaultValue: _wooSignalApp!.paypalEmail)}">
|
||||
<input type="hidden" name="return" value="https://woosignal.com/paypal/payment~success">
|
||||
<input type="hidden" name="cancel_return" value="https://woosignal.com/paypal/payment~failure">
|
||||
<input type="hidden" name="item_name" value="${getPayPalItemName()}">
|
||||
|
||||
@ -4,10 +4,10 @@ import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class CheckoutSelectCouponWidget extends StatelessWidget {
|
||||
const CheckoutSelectCouponWidget(
|
||||
{Key key,
|
||||
@required this.context,
|
||||
@required this.checkoutSession,
|
||||
@required this.resetState})
|
||||
{Key? key,
|
||||
required this.context,
|
||||
required this.checkoutSession,
|
||||
required this.resetState})
|
||||
: super(key: key);
|
||||
|
||||
final CheckoutSession checkoutSession;
|
||||
@ -25,22 +25,21 @@ class CheckoutSelectCouponWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
hasCoupon == true
|
||||
? IconButton(
|
||||
padding: EdgeInsets.symmetric(vertical: 3),
|
||||
onPressed: _clearCoupon,
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
size: 19,
|
||||
))
|
||||
: null,
|
||||
if (hasCoupon == true)
|
||||
IconButton(
|
||||
padding: EdgeInsets.symmetric(vertical: 3),
|
||||
onPressed: _clearCoupon,
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
size: 19,
|
||||
)),
|
||||
Text(
|
||||
hasCoupon
|
||||
? "Coupon Applied: " + checkoutSession.coupon.code
|
||||
? "Coupon Applied: " + checkoutSession.coupon!.code!
|
||||
: trans('Apply Coupon'),
|
||||
style: Theme.of(context).textTheme.subtitle2,
|
||||
),
|
||||
].where((element) => element != null).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -52,7 +51,7 @@ class CheckoutSelectCouponWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
_actionCoupon() {
|
||||
if (checkoutSession.billingDetails.billingAddress == null) {
|
||||
if (checkoutSession.billingDetails!.billingAddress == null) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Oops"),
|
||||
@ -64,7 +63,7 @@ class CheckoutSelectCouponWidget extends StatelessWidget {
|
||||
|
||||
return;
|
||||
}
|
||||
if (checkoutSession.billingDetails.billingAddress.hasMissingFields()) {
|
||||
if (checkoutSession.billingDetails!.billingAddress!.hasMissingFields()) {
|
||||
showToastNotification(
|
||||
context,
|
||||
title: trans("Oops"),
|
||||
|
||||
@ -7,21 +7,21 @@ import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
class CheckoutShippingTypeWidget extends StatelessWidget {
|
||||
const CheckoutShippingTypeWidget(
|
||||
{Key key,
|
||||
@required this.context,
|
||||
@required this.wooSignalApp,
|
||||
@required this.checkoutSession,
|
||||
{Key? key,
|
||||
required this.context,
|
||||
required this.wooSignalApp,
|
||||
required this.checkoutSession,
|
||||
this.resetState})
|
||||
: super(key: key);
|
||||
|
||||
final CheckoutSession checkoutSession;
|
||||
final BuildContext context;
|
||||
final Function resetState;
|
||||
final WooSignalApp wooSignalApp;
|
||||
final Function? resetState;
|
||||
final WooSignalApp? wooSignalApp;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool hasDisableShipping = wooSignalApp.disableShipping == 1;
|
||||
bool hasDisableShipping = wooSignalApp!.disableShipping == 1;
|
||||
if (hasDisableShipping == true) {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
@ -31,7 +31,7 @@ class CheckoutShippingTypeWidget extends StatelessWidget {
|
||||
hasSelectedShippingType ? "Shipping selected" : "Select shipping"),
|
||||
leadImage: Icon(Icons.local_shipping),
|
||||
leadTitle: hasSelectedShippingType
|
||||
? checkoutSession.shippingType.getTitle()
|
||||
? checkoutSession.shippingType!.getTitle()
|
||||
: trans("Select a shipping option"),
|
||||
action: _actionSelectShipping,
|
||||
showBorderBottom: false,
|
||||
@ -39,8 +39,8 @@ class CheckoutShippingTypeWidget extends StatelessWidget {
|
||||
}
|
||||
|
||||
_actionSelectShipping() {
|
||||
CustomerAddress shippingAddress =
|
||||
checkoutSession.billingDetails.shippingAddress;
|
||||
CustomerAddress? shippingAddress =
|
||||
checkoutSession.billingDetails!.shippingAddress;
|
||||
if (shippingAddress == null || shippingAddress.customerCountry == null) {
|
||||
showToastNotification(
|
||||
context,
|
||||
@ -51,6 +51,6 @@ class CheckoutShippingTypeWidget extends StatelessWidget {
|
||||
return;
|
||||
}
|
||||
Navigator.pushNamed(context, "/checkout-shipping-type")
|
||||
.then((value) => resetState());
|
||||
.then((value) => resetState!());
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
|
||||
class CheckoutStoreHeadingWidget extends StatelessWidget {
|
||||
const CheckoutStoreHeadingWidget({Key key}) : super(key: key);
|
||||
const CheckoutStoreHeadingWidget({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@ -5,28 +5,28 @@ import 'package:nylo_framework/nylo_framework.dart';
|
||||
|
||||
class CheckoutUserDetailsWidget extends StatelessWidget {
|
||||
const CheckoutUserDetailsWidget(
|
||||
{Key key,
|
||||
@required this.context,
|
||||
@required this.checkoutSession,
|
||||
{Key? key,
|
||||
required this.context,
|
||||
required this.checkoutSession,
|
||||
this.resetState})
|
||||
: super(key: key);
|
||||
final CheckoutSession checkoutSession;
|
||||
final BuildContext context;
|
||||
final Function resetState;
|
||||
final Function? resetState;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
bool hasUserCheckoutInfo = (checkoutSession.billingDetails != null &&
|
||||
checkoutSession.billingDetails.billingAddress != null);
|
||||
checkoutSession.billingDetails!.billingAddress != null);
|
||||
return CheckoutRowLine(
|
||||
heading: trans("Billing/shipping details"),
|
||||
leadImage: Icon(Icons.home),
|
||||
leadTitle: hasUserCheckoutInfo
|
||||
? (checkoutSession.billingDetails == null ||
|
||||
checkoutSession.billingDetails.billingAddress
|
||||
checkoutSession.billingDetails!.billingAddress!
|
||||
.hasMissingFields()
|
||||
? trans("Billing address is incomplete")
|
||||
: checkoutSession.billingDetails.billingAddress.addressFull())
|
||||
: checkoutSession.billingDetails!.billingAddress!.addressFull())
|
||||
: trans("Add billing & shipping details"),
|
||||
action: _actionCheckoutDetails,
|
||||
showBorderBottom: true,
|
||||
@ -35,7 +35,7 @@ class CheckoutUserDetailsWidget extends StatelessWidget {
|
||||
|
||||
_actionCheckoutDetails() {
|
||||
Navigator.pushNamed(context, "/checkout-details").then((e) {
|
||||
resetState();
|
||||
resetState!();
|
||||
// setState(() {
|
||||
// _showFullLoader = true;
|
||||
// });
|
||||
|
||||
@ -6,16 +6,16 @@ import 'package:flutter_app/resources/widgets/buttons.dart';
|
||||
import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
|
||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||
import 'package:flutter_swiper/flutter_swiper.dart';
|
||||
import 'package:flutter_swiper_tv/flutter_swiper.dart';
|
||||
import 'package:nylo_framework/nylo_framework.dart';
|
||||
import 'package:woosignal/models/response/product_category.dart';
|
||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
import 'package:woosignal/models/response/products.dart';
|
||||
|
||||
class CompoHomeWidget extends StatefulWidget {
|
||||
CompoHomeWidget({Key key, @required this.wooSignalApp}) : super(key: key);
|
||||
CompoHomeWidget({Key? key, required this.wooSignalApp}) : super(key: key);
|
||||
|
||||
final WooSignalApp wooSignalApp;
|
||||
final WooSignalApp? wooSignalApp;
|
||||
|
||||
@override
|
||||
_CompoHomeWidgetState createState() => _CompoHomeWidgetState();
|
||||
@ -29,19 +29,19 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
}
|
||||
|
||||
_loadHome() async {
|
||||
categories = await appWooSignal((api) =>
|
||||
api.getProductCategories(parent: 0, perPage: 50, hideEmpty: true));
|
||||
categories = await (appWooSignal((api) =>
|
||||
api.getProductCategories(parent: 0, perPage: 50, hideEmpty: true)));
|
||||
categories.sort((category1, category2) =>
|
||||
category1.menuOrder.compareTo(category2.menuOrder));
|
||||
category1.menuOrder!.compareTo(category2.menuOrder!));
|
||||
|
||||
for (var category in categories) {
|
||||
List<Product> products = await appWooSignal(
|
||||
List<Product> products = await (appWooSignal(
|
||||
(api) => api.getProducts(
|
||||
perPage: 10,
|
||||
category: category.id.toString(),
|
||||
status: "publish",
|
||||
stockStatus: "instock"),
|
||||
);
|
||||
));
|
||||
if (products.isNotEmpty) {
|
||||
categoryAndProducts.addAll({category: products});
|
||||
setState(() {});
|
||||
@ -60,7 +60,7 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
List<String> bannerImages = widget.wooSignalApp.bannerImages;
|
||||
List<String>? bannerImages = widget.wooSignalApp!.bannerImages;
|
||||
return Scaffold(
|
||||
drawer: HomeDrawerWidget(wooSignalApp: widget.wooSignalApp),
|
||||
appBar: AppBar(
|
||||
@ -74,7 +74,7 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
: ListView(
|
||||
shrinkWrap: true,
|
||||
children: [
|
||||
if (bannerImages.isNotEmpty)
|
||||
if (bannerImages!.isNotEmpty)
|
||||
Container(
|
||||
child: Swiper(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
@ -101,17 +101,16 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
margin: EdgeInsets.only(top: 10),
|
||||
child: Column(
|
||||
children: [
|
||||
hasImage
|
||||
? InkWell(
|
||||
child: CachedImageWidget(
|
||||
image: catProds.key.image.src,
|
||||
height: containerHeight / 2,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
onTap: () => _showCategory(catProds.key),
|
||||
)
|
||||
: null,
|
||||
if (hasImage)
|
||||
InkWell(
|
||||
child: CachedImageWidget(
|
||||
image: catProds.key.image!.src,
|
||||
height: containerHeight / 2,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
onTap: () => _showCategory(catProds.key),
|
||||
),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minHeight: 50,
|
||||
@ -128,10 +127,10 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: AutoSizeText(
|
||||
catProds.key.name,
|
||||
catProds.key.name!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.subtitle1
|
||||
.subtitle1!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 22),
|
||||
@ -172,7 +171,7 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
|
||||
itemCount: catProds.value.length,
|
||||
),
|
||||
)
|
||||
].where((e) => e != null).toList(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
@ -26,9 +26,9 @@ import 'package:woosignal/models/response/woosignal_app.dart';
|
||||
|
||||
class CompoThemeWidget extends StatefulWidget {
|
||||
CompoThemeWidget(
|
||||
{Key key, @required this.globalKey, @required this.wooSignalApp})
|
||||
{Key? key, required this.globalKey, required this.wooSignalApp})
|
||||
: super(key: key);
|
||||
final WooSignalApp wooSignalApp;
|
||||
final WooSignalApp? wooSignalApp;
|
||||
final GlobalKey globalKey;
|
||||
|
||||
@override
|
||||
@ -36,10 +36,10 @@ class CompoThemeWidget extends StatefulWidget {
|
||||
}
|
||||
|
||||
class CcompoThemeWidgetState extends State<CompoThemeWidget> {
|
||||
Widget activeWidget;
|
||||
Widget? activeWidget;
|
||||
|
||||
int _currentIndex = 0;
|
||||
List<BottomNavItem> allNavWidgets;
|
||||
List<BottomNavItem> allNavWidgets = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -59,7 +59,7 @@ class CcompoThemeWidgetState extends State<CompoThemeWidget> {
|
||||
return Scaffold(
|
||||
body: activeWidget,
|
||||
resizeToAvoidBottomInset: false,
|
||||
bottomNavigationBar: allNavWidgets == null
|
||||
bottomNavigationBar: allNavWidgets.isEmpty
|
||||
? AppLoaderWidget()
|
||||
: BottomNavigationBar(
|
||||
onTap: (currentIndex) =>
|
||||
@ -102,7 +102,7 @@ class CcompoThemeWidgetState extends State<CompoThemeWidget> {
|
||||
tabWidget: HomeSearchPage()),
|
||||
);
|
||||
|
||||
if (AppHelper.instance.appConfig.wishlistEnabled == true) {
|
||||
if (AppHelper.instance.appConfig!.wishlistEnabled == true) {
|
||||
items.add(BottomNavItem(
|
||||
id: 3,
|
||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||
@ -120,7 +120,7 @@ class CcompoThemeWidgetState extends State<CompoThemeWidget> {
|
||||
tabWidget: CartPage(),
|
||||
));
|
||||
|
||||
if (AppHelper.instance.appConfig.wpLoginEnabled == 1) {
|
||||
if (AppHelper.instance.appConfig!.wpLoginEnabled == 1) {
|
||||
items.add(BottomNavItem(
|
||||
id: 5,
|
||||
bottomNavigationBarItem:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user