v6.6.0 updates
This commit is contained in:
parent
004c146967
commit
da2301a2af
@ -50,3 +50,5 @@ RAZORPAY_API_KEY=""
|
|||||||
|
|
||||||
PRODUCT_PLACEHOLDER_IMAGE="https://woosignal.com/images/woocommerce-placeholder.png"
|
PRODUCT_PLACEHOLDER_IMAGE="https://woosignal.com/images/woocommerce-placeholder.png"
|
||||||
# Sets the default placeholder image for products with no image
|
# Sets the default placeholder image for products with no image
|
||||||
|
|
||||||
|
AUTH_USER_KEY="AUTH_USER"
|
||||||
@ -1,3 +1,9 @@
|
|||||||
|
## [6.6.0] - 2023-05-18
|
||||||
|
|
||||||
|
* Nylo v5.0.0 migration
|
||||||
|
* Refactor project
|
||||||
|
* Flutter v3.10.0 compatibility
|
||||||
|
|
||||||
## [6.5.1] - 2023-03-04
|
## [6.5.1] - 2023-03-04
|
||||||
|
|
||||||
* New translation added.
|
* New translation added.
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# WooCommerce App: Label StoreMax
|
# WooCommerce App: Label StoreMax
|
||||||
|
|
||||||
### Label StoreMax - v6.5.1
|
### Label StoreMax - v6.6.0
|
||||||
|
|
||||||
|
|
||||||
[Official WooSignal WooCommerce App](https://woosignal.com)
|
[Official WooSignal WooCommerce App](https://woosignal.com)
|
||||||
@ -44,7 +44,7 @@ Full documentation this available [here](https://woosignal.com/docs/app/label-st
|
|||||||
- Browse products, make orders, customer login (via WordPress)
|
- Browse products, make orders, customer login (via WordPress)
|
||||||
- Change app name, logo, customize default language, currency + more
|
- Change app name, logo, customize default language, currency + more
|
||||||
- Light and dark mode
|
- Light and dark mode
|
||||||
- Stripe, Cash On Delivery, PayPal, RazorPay
|
- Stripe, Cash On Delivery, PayPal
|
||||||
- Localized for en, es, pt, it, hi, fr, zh, tr, nl, de
|
- Localized for en, es, pt, it, hi, fr, zh, tr, nl, de
|
||||||
- Orders show as normal in WooCommerce
|
- Orders show as normal in WooCommerce
|
||||||
|
|
||||||
|
|||||||
@ -204,6 +204,7 @@
|
|||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||||
);
|
);
|
||||||
name = "Thin Binary";
|
name = "Thin Binary";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
<true/>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
@ -16,12 +18,8 @@
|
|||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||||
<key>NSCameraUsageDescription</key>
|
|
||||||
<string>You can take photos of your payment details.</string>
|
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>MinimumOSVersion</key>
|
|
||||||
<string>13.0</string>
|
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
<array>
|
<array>
|
||||||
<dict>
|
<dict>
|
||||||
@ -39,11 +37,17 @@
|
|||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>13.0</string>
|
||||||
<key>NSAppTransportSecurity</key>
|
<key>NSAppTransportSecurity</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSAllowsArbitraryLoads</key>
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>You can take photos of your payment details.</string>
|
||||||
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
|
<true/>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
@ -61,9 +65,5 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
|
||||||
<true/>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
|
||||||
<true/>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -10,18 +10,16 @@
|
|||||||
|
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
class User extends Storable {
|
class User extends Model {
|
||||||
String? userId;
|
String? userId;
|
||||||
String? token;
|
String? token;
|
||||||
|
|
||||||
User();
|
User();
|
||||||
User.fromUserAuthResponse({this.userId, this.token});
|
User.fromUserAuthResponse({this.userId, this.token});
|
||||||
|
|
||||||
@override
|
toJson() => {"token": token, "user_id": userId};
|
||||||
toStorage() => {"token": token, "user_id": userId};
|
|
||||||
|
|
||||||
@override
|
fromJson(dynamic data) {
|
||||||
fromStorage(dynamic data) {
|
|
||||||
token = data['token'];
|
token = data['token'];
|
||||||
userId = data['user_id'];
|
userId = data['user_id'];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
| ApiService
|
| ApiService
|
||||||
| -------------------------------------------------------------------------
|
| -------------------------------------------------------------------------
|
||||||
| Define your API endpoints
|
| Define your API endpoints
|
||||||
| Learn more https://nylo.dev/docs/4.x/networking
|
| Learn more https://nylo.dev/docs/5.x/networking
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -4,8 +4,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||||
|
import 'package:flutter_app/config/decoders.dart';
|
||||||
import 'package:flutter_app/config/design.dart';
|
import 'package:flutter_app/config/design.dart';
|
||||||
import 'package:flutter_app/config/theme.dart';
|
import 'package:flutter_app/config/theme.dart';
|
||||||
|
import 'package:flutter_app/config/validation_rules.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:flutter_app/config/localization.dart';
|
import 'package:flutter_app/config/localization.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
@ -112,12 +114,14 @@ class AppProvider implements NyProvider {
|
|||||||
nylo.appLoader = loader;
|
nylo.appLoader = loader;
|
||||||
nylo.appLogo = logo;
|
nylo.appLogo = logo;
|
||||||
|
|
||||||
String initialRoute = AppHelper.instance.appConfig!.appStatus != null
|
nylo.addModelDecoders(modelDecoders);
|
||||||
? '/home'
|
nylo.addValidationRules(validationRules);
|
||||||
: '/no-connection';
|
|
||||||
|
|
||||||
nylo.initialRoute = initialRoute;
|
|
||||||
|
|
||||||
return nylo;
|
return nylo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
afterBoot(Nylo nylo) async {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,4 +8,9 @@ class EventProvider implements NyProvider {
|
|||||||
|
|
||||||
return nylo;
|
return nylo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
afterBoot(Nylo nylo) async {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,81 +0,0 @@
|
|||||||
//
|
|
||||||
// LabelCore
|
|
||||||
// Label StoreMAX
|
|
||||||
//
|
|
||||||
// Created by Anthony Gordon.
|
|
||||||
// 2023, WooSignal Ltd. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
//
|
|
||||||
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:flutter_app/app/models/cart.dart';
|
|
||||||
import 'package:flutter_app/bootstrap/data/order_wc.dart';
|
|
||||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
|
||||||
import 'package:flutter_app/resources/pages/checkout_confirmation_page.dart';
|
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
|
||||||
import 'package:razorpay_flutter/razorpay_flutter.dart';
|
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
|
||||||
import 'package:woosignal/models/payload/order_wc.dart';
|
|
||||||
import 'package:woosignal/models/response/order.dart';
|
|
||||||
|
|
||||||
razorPay(context,
|
|
||||||
{required CheckoutConfirmationPageState state, TaxRate? taxRate}) async {
|
|
||||||
Razorpay razorpay = Razorpay();
|
|
||||||
|
|
||||||
razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS,
|
|
||||||
(PaymentSuccessResponse response) async {
|
|
||||||
OrderWC orderWC = await buildOrderWC(taxRate: taxRate);
|
|
||||||
|
|
||||||
Order? order = await appWooSignal((api) => api.createOrder(orderWC));
|
|
||||||
|
|
||||||
if (order != null) {
|
|
||||||
Cart.getInstance.clear();
|
|
||||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
|
||||||
} else {
|
|
||||||
showToastNotification(
|
|
||||||
context,
|
|
||||||
title: "Error".tr(),
|
|
||||||
description: trans("Something went wrong, please contact our store"),
|
|
||||||
);
|
|
||||||
state.reloadState(showLoader: false);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) {
|
|
||||||
showToastNotification(context,
|
|
||||||
title: trans("Error"),
|
|
||||||
description: response.message ?? "",
|
|
||||||
style: ToastNotificationStyleType.WARNING);
|
|
||||||
state.reloadState(showLoader: false);
|
|
||||||
});
|
|
||||||
|
|
||||||
razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet);
|
|
||||||
|
|
||||||
// CHECKOUT HELPER
|
|
||||||
await checkout(taxRate, (total, billingDetails, cart) async {
|
|
||||||
var options = {
|
|
||||||
'key': getEnv('RAZORPAY_API_KEY'),
|
|
||||||
'amount': (double.parse(total) * 100).toInt(),
|
|
||||||
'name': getEnv('APP_NAME'),
|
|
||||||
'description': await cart.cartShortDesc(),
|
|
||||||
'prefill': {
|
|
||||||
"name": [
|
|
||||||
billingDetails!.billingAddress?.firstName,
|
|
||||||
billingDetails.billingAddress?.lastName
|
|
||||||
].where((t) => t != null || t != "").toList().join(" "),
|
|
||||||
"method": "card",
|
|
||||||
'email': billingDetails.billingAddress?.emailAddress ?? ""
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
state.reloadState(showLoader: true);
|
|
||||||
|
|
||||||
razorpay.open(options);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleExternalWallet(ExternalWalletResponse response) {}
|
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
import 'package:flutter_app/routes/router.dart';
|
import 'package:flutter_app/routes/router.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
@ -8,4 +9,12 @@ class RouteProvider implements NyProvider {
|
|||||||
|
|
||||||
return nylo;
|
return nylo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
afterBoot(Nylo nylo) async {
|
||||||
|
String initialRoute = AppHelper.instance.appConfig!.appStatus != null
|
||||||
|
? '/home'
|
||||||
|
: '/no-connection';
|
||||||
|
nylo.setInitialRoute(initialRoute);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,8 @@
|
|||||||
// import 'package:firebase_core/firebase_core.dart';
|
|
||||||
// import 'package:firebase_messaging/firebase_messaging.dart';
|
|
||||||
// import 'package:flutter_app/firebase_options.dart';
|
|
||||||
|
|
||||||
/// boot application
|
/// boot application
|
||||||
import 'package:flutter_app/config/providers.dart';
|
import 'package:flutter_app/config/providers.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
class Boot {
|
class Boot {
|
||||||
static Future<Nylo> nylo() async => await bootApplication(providers);
|
static Future<Nylo> nylo() async => await bootApplication(providers);
|
||||||
static Future<void> finished(Nylo nylo) async => await bootFinished(nylo);
|
static Future<void> finished(Nylo nylo) async => await bootFinished(nylo, providers);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -138,3 +138,37 @@ extension NyText on Text {
|
|||||||
style: style != null ? this.style?.merge(style) ?? style : this.style);
|
style: style != null ? this.style?.merge(style) ?? style : this.style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the [Product] is new.
|
||||||
|
extension DateTimeExtension on DateTime? {
|
||||||
|
bool? isAfterOrEqualTo(DateTime dateTime) {
|
||||||
|
final date = this;
|
||||||
|
if (date != null) {
|
||||||
|
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||||
|
return isAtSameMomentAs | date.isAfter(dateTime);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? isBeforeOrEqualTo(DateTime dateTime) {
|
||||||
|
final date = this;
|
||||||
|
if (date != null) {
|
||||||
|
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||||
|
return isAtSameMomentAs | date.isBefore(dateTime);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool? isBetween(
|
||||||
|
DateTime fromDateTime,
|
||||||
|
DateTime toDateTime,
|
||||||
|
) {
|
||||||
|
final date = this;
|
||||||
|
if (date != null) {
|
||||||
|
final isAfter = date.isAfterOrEqualTo(fromDateTime) ?? false;
|
||||||
|
final isBefore = date.isBeforeOrEqualTo(toDateTime) ?? false;
|
||||||
|
return isAfter && isBefore;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,7 @@ import 'package:flutter_app/app/models/payment_type.dart';
|
|||||||
import 'package:flutter_app/app/models/user.dart';
|
import 'package:flutter_app/app/models/user.dart';
|
||||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
|
import 'package:flutter_app/bootstrap/enums/symbol_position_enums.dart';
|
||||||
|
import 'package:flutter_app/bootstrap/extensions.dart';
|
||||||
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
import 'package:flutter_app/bootstrap/shared_pref/shared_key.dart';
|
||||||
import 'package:flutter_app/config/currency.dart';
|
import 'package:flutter_app/config/currency.dart';
|
||||||
import 'package:flutter_app/config/decoders.dart';
|
import 'package:flutter_app/config/decoders.dart';
|
||||||
@ -45,7 +46,7 @@ import '../resources/themes/styles/color_styles.dart';
|
|||||||
import 'package:flutter/services.dart' show rootBundle;
|
import 'package:flutter/services.dart' show rootBundle;
|
||||||
|
|
||||||
Future<User?> getUser() async =>
|
Future<User?> getUser() async =>
|
||||||
(await (NyStorage.read<User>(SharedKey.authUser, model: User())));
|
(await (NyStorage.read<User>(SharedKey.authUser)));
|
||||||
|
|
||||||
Future appWooSignal(Function(WooSignal) api) async {
|
Future appWooSignal(Function(WooSignal) api) async {
|
||||||
return await api(WooSignal.instance);
|
return await api(WooSignal.instance);
|
||||||
@ -156,6 +157,7 @@ String moneyFormatter(double amount) {
|
|||||||
amount: amount,
|
amount: amount,
|
||||||
settings: MoneyFormatterSettings(
|
settings: MoneyFormatterSettings(
|
||||||
symbol: AppHelper.instance.appConfig!.currencyMeta!.symbolNative,
|
symbol: AppHelper.instance.appConfig!.currencyMeta!.symbolNative,
|
||||||
|
symbolAndNumberSeparator: ""
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (appCurrencySymbolPosition == SymbolPositionType.left) {
|
if (appCurrencySymbolPosition == SymbolPositionType.left) {
|
||||||
@ -486,7 +488,7 @@ Widget refreshableScroll(context,
|
|||||||
return StaggeredGridTile.fit(
|
return StaggeredGridTile.fit(
|
||||||
crossAxisCellCount: 1,
|
crossAxisCellCount: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 200,
|
height: 350,
|
||||||
child: ProductItemContainer(
|
child: ProductItemContainer(
|
||||||
product: product,
|
product: product,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
@ -654,3 +656,15 @@ api<T>(dynamic Function(T) request, {BuildContext? context}) async =>
|
|||||||
|
|
||||||
/// Event helper
|
/// Event helper
|
||||||
event<T>({Map? data}) async => nyEvent<T>(params: data, events: events);
|
event<T>({Map? data}) async => nyEvent<T>(params: data, events: events);
|
||||||
|
|
||||||
|
/// Check if the [Product] is new.
|
||||||
|
bool isProductNew(Product? product) {
|
||||||
|
if (product?.dateCreatedGMT == null) false;
|
||||||
|
try {
|
||||||
|
DateTime dateTime = DateTime.parse(product!.dateCreatedGMT!);
|
||||||
|
return dateTime.isBetween(DateTime.now().subtract(Duration(days: 2)), DateTime.now()) ?? false;
|
||||||
|
} on Exception catch (e) {
|
||||||
|
NyLogger.error(e.toString());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import 'package:flutter_app/app/networking/dio/base_api_service.dart';
|
|||||||
| Model Decoders
|
| Model Decoders
|
||||||
| -------------------------------------------------------------------------
|
| -------------------------------------------------------------------------
|
||||||
| Model decoders are used in 'app/networking/' for morphing json payloads
|
| Model decoders are used in 'app/networking/' for morphing json payloads
|
||||||
| into Models. Learn more https://nylo.dev/docs/4.x/decoders#model-decoders
|
| into Models. Learn more https://nylo.dev/docs/5.x/decoders#model-decoders
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ final Map<Type, dynamic> modelDecoders = {
|
|||||||
| -------------------------------------------------------------------------
|
| -------------------------------------------------------------------------
|
||||||
| API decoders are used when you need to access an API service using the
|
| API decoders are used when you need to access an API service using the
|
||||||
| 'api' helper. E.g. api<MyApiService>((request) => request.fetchData());
|
| 'api' helper. E.g. api<MyApiService>((request) => request.fetchData());
|
||||||
| Learn more https://nylo.dev/docs/4.x/decoders#api-decoders
|
| Learn more https://nylo.dev/docs/5.x/decoders#api-decoders
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
|||||||
| Design
|
| Design
|
||||||
| Contains widgets used in the Nylo framework.
|
| Contains widgets used in the Nylo framework.
|
||||||
|
|
|
|
||||||
| Learn more: https://nylo.dev/docs/4.x/themes
|
| Learn more: https://nylo.dev/docs/5.x/themes
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
| Add your "app/events" here.
|
| Add your "app/events" here.
|
||||||
| Events can be fired using: event<MyEvent>();
|
| Events can be fired using: event<MyEvent>();
|
||||||
|
|
|
|
||||||
| Learn more: https://nylo.dev/docs/4.x/events
|
| Learn more: https://nylo.dev/docs/5.x/events
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter_app/app/models/payment_type.dart';
|
import 'package:flutter_app/app/models/payment_type.dart';
|
||||||
import 'package:flutter_app/app/providers/payments/cash_on_delivery.dart';
|
import 'package:flutter_app/app/providers/payments/cash_on_delivery.dart';
|
||||||
import 'package:flutter_app/app/providers/payments/paypal_pay.dart';
|
import 'package:flutter_app/app/providers/payments/paypal_pay.dart';
|
||||||
import 'package:flutter_app/app/providers/payments/razorpay_pay.dart';
|
|
||||||
import 'package:flutter_app/app/providers/payments/stripe_pay.dart';
|
import 'package:flutter_app/app/providers/payments/stripe_pay.dart';
|
||||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
@ -44,14 +43,6 @@ List<PaymentType> paymentTypeList = [
|
|||||||
pay: payPalPay,
|
pay: payPalPay,
|
||||||
),
|
),
|
||||||
|
|
||||||
addPayment(
|
|
||||||
id: 5,
|
|
||||||
name: "RazorPay",
|
|
||||||
description: trans("Debit or Credit Card"),
|
|
||||||
assetImage: "razorpay.png",
|
|
||||||
pay: razorPay,
|
|
||||||
),
|
|
||||||
|
|
||||||
// e.g. add more here
|
// e.g. add more here
|
||||||
|
|
||||||
// addPayment(
|
// addPayment(
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
| Add your "app/providers" here.
|
| Add your "app/providers" here.
|
||||||
| Providers are booted when your application start.
|
| Providers are booted when your application start.
|
||||||
|
|
|
|
||||||
| Learn more: https://nylo.dev/docs/4.x/providers
|
| Learn more: https://nylo.dev/docs/5.x/providers
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -5,12 +5,15 @@
|
|||||||
| E.g. static String userCoins = "USER_COINS";
|
| E.g. static String userCoins = "USER_COINS";
|
||||||
| String coins = NyStorage.read( StorageKey.userCoins );
|
| String coins = NyStorage.read( StorageKey.userCoins );
|
||||||
|
|
|
|
||||||
| Learn more: https://nylo.dev/docs/4.x/storage#storage-keys
|
| Learn more: https://nylo.dev/docs/5.x/storage#storage-keys
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
class StorageKey {
|
class StorageKey {
|
||||||
static String userToken = "USER_TOKEN";
|
static String userToken = "USER_TOKEN";
|
||||||
|
static String authUser = getEnv('AUTH_USER_KEY', defaultValue: 'AUTH_USER');
|
||||||
|
|
||||||
/// Add your storage keys here...
|
/// Add your storage keys here...
|
||||||
}
|
}
|
||||||
|
|||||||
37
LabelStoreMax/lib/config/validation_rules.dart
Normal file
37
LabelStoreMax/lib/config/validation_rules.dart
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Validation Rules
|
||||||
|
| -------------------------------------------------------------------------
|
||||||
|
| Add custom validation rules for your project in this file.
|
||||||
|
| Learn more https://nylo.dev/docs/5.x/validation#custom-validation-rules
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
final Map<Type, dynamic> validationRules = {
|
||||||
|
/// Example
|
||||||
|
// SimplePassword: (attribute) => SimplePassword(attribute)
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Example validation class
|
||||||
|
// class SimplePassword extends ValidationRule {
|
||||||
|
// SimplePassword(String attribute)
|
||||||
|
// : super(
|
||||||
|
// attribute: attribute,
|
||||||
|
// signature: "simple_password", // Use this signature for the validator
|
||||||
|
// description: "The $attribute field must be between 4 and 8 digits long and include at least one numeric digit", // Toast description when an error occurs
|
||||||
|
// textFieldMessage: "Must be between 4 and 8 digits long with one numeric digit"); // TextField description when an error occurs
|
||||||
|
//
|
||||||
|
// @override
|
||||||
|
// handle(Map<String, dynamic> info) {
|
||||||
|
// super.handle(info);
|
||||||
|
//
|
||||||
|
// /// info['rule'] = Validation rule i.e "min".
|
||||||
|
// /// info['data'] = Data the user has passed into the validation.
|
||||||
|
// /// info['message'] = Overriding message to be displayed for validation (optional).
|
||||||
|
//
|
||||||
|
// RegExp regExp = RegExp(r'^(?=.*\d).{4,8}$');
|
||||||
|
// return regExp.hasMatch(info['data']);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
@ -11,7 +11,7 @@ void main() async {
|
|||||||
AppBuild(
|
AppBuild(
|
||||||
navigatorKey: NyNavigator.instance.router.navigatorKey,
|
navigatorKey: NyNavigator.instance.router.navigatorKey,
|
||||||
onGenerateRoute: nylo.router!.generator(),
|
onGenerateRoute: nylo.router!.generator(),
|
||||||
initialRoute: nylo.initialRoute,
|
initialRoute: nylo.getInitialRoute(),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -35,11 +35,6 @@ class _AccountLandingPageState extends NyState<AccountLandingPage> {
|
|||||||
final TextEditingController _tfEmailController = TextEditingController(),
|
final TextEditingController _tfEmailController = TextEditingController(),
|
||||||
_tfPasswordController = TextEditingController();
|
_tfPasswordController = TextEditingController();
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -231,7 +226,7 @@ class _AccountLandingPageState extends NyState<AccountLandingPage> {
|
|||||||
String? token = wpUserLoginResponse.data!.userToken;
|
String? token = wpUserLoginResponse.data!.userToken;
|
||||||
String userId = wpUserLoginResponse.data!.userId.toString();
|
String userId = wpUserLoginResponse.data!.userId.toString();
|
||||||
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
||||||
await user.save(SharedKey.authUser);
|
await Auth.set(user, key: SharedKey.authUser);
|
||||||
|
|
||||||
showToastNotification(context,
|
showToastNotification(context,
|
||||||
title: trans("Hello"),
|
title: trans("Hello"),
|
||||||
|
|||||||
@ -48,11 +48,6 @@ class _AccountRegistrationPageState extends NyState<AccountRegistrationPage> {
|
|||||||
|
|
||||||
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
@ -241,7 +236,7 @@ class _AccountRegistrationPageState extends NyState<AccountRegistrationPage> {
|
|||||||
String? token = wpUserRegisterResponse.data!.userToken;
|
String? token = wpUserRegisterResponse.data!.userToken;
|
||||||
String userId = wpUserRegisterResponse.data!.userId.toString();
|
String userId = wpUserRegisterResponse.data!.userId.toString();
|
||||||
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
User user = User.fromUserAuthResponse(token: token, userId: userId);
|
||||||
await user.save(SharedKey.authUser);
|
await Auth.set(user, key: SharedKey.authUser);
|
||||||
|
|
||||||
await WPJsonAPI.instance.api((request) => request.wpUpdateUserInfo(token,
|
await WPJsonAPI.instance.api((request) => request.wpUpdateUserInfo(token,
|
||||||
firstName: firstName, lastName: lastName));
|
firstName: firstName, lastName: lastName));
|
||||||
|
|||||||
@ -85,7 +85,8 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
|||||||
onRefresh: _onRefresh,
|
onRefresh: _onRefresh,
|
||||||
onLoading: _onLoading,
|
onLoading: _onLoading,
|
||||||
products: _productCategorySearchLoaderController.getResults(),
|
products: _productCategorySearchLoaderController.getResults(),
|
||||||
onTap: _showProduct),
|
onTap: _showProduct,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -135,42 +135,41 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
await validate(
|
||||||
validator(rules: {"review": "min:5"}, data: {"review": review});
|
rules: {"review": "min:5"},
|
||||||
|
data: {"review": review},
|
||||||
ProductReview? productReview =
|
onSuccess: () async {
|
||||||
|
ProductReview? productReview =
|
||||||
await (appWooSignal((api) => api.createProductReview(
|
await (appWooSignal((api) => api.createProductReview(
|
||||||
productId: _lineItem!.productId,
|
productId: _lineItem!.productId,
|
||||||
verified: true,
|
verified: true,
|
||||||
review: review,
|
review: review,
|
||||||
status: "approved",
|
status: "approved",
|
||||||
reviewer: [
|
reviewer: [
|
||||||
_order!.billing!.firstName,
|
_order!.billing!.firstName,
|
||||||
_order!.billing!.lastName
|
_order!.billing!.lastName
|
||||||
].join(" "),
|
].join(" "),
|
||||||
rating: _rating,
|
rating: _rating,
|
||||||
reviewerEmail: _order!.billing!.email,
|
reviewerEmail: _order!.billing!.email,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
if (productReview == null) {
|
if (productReview == null) {
|
||||||
showToastNotification(context,
|
showToastNotification(context,
|
||||||
title: trans("Oops"),
|
title: trans("Oops"),
|
||||||
description: trans("Something went wrong"),
|
description: trans("Something went wrong"),
|
||||||
style: ToastNotificationStyleType.INFO);
|
style: ToastNotificationStyleType.INFO);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
showToastNotification(context,
|
showToastNotification(context,
|
||||||
title: trans("Success"),
|
title: trans("Success"),
|
||||||
description: trans("Your review has been submitted"),
|
description: trans("Your review has been submitted"),
|
||||||
style: ToastNotificationStyleType.SUCCESS);
|
style: ToastNotificationStyleType.SUCCESS);
|
||||||
pop(result: _lineItem);
|
pop(result: _lineItem);
|
||||||
} on ValidationException catch (e) {
|
});
|
||||||
NyLogger.error(e.toString());
|
|
||||||
} finally {
|
setState(() {
|
||||||
setState(() {
|
_isLoading = false;
|
||||||
_isLoading = false;
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<wc_customer_info.Data?> _fetchWpUserData() async {
|
Future<wc_customer_info.Data?> _fetchWpUserData() async {
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import 'package:flutter_app/bootstrap/helpers.dart';
|
|||||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/buttons.dart';
|
import 'package:flutter_app/resources/widgets/buttons.dart';
|
||||||
import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
|
import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/future_build_widget.dart';
|
|
||||||
import 'package:flutter_app/resources/widgets/product_detail_body_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_body_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/product_detail_footer_actions_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_footer_actions_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||||
@ -232,9 +231,9 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
if (_wooSignalApp!.wishlistEnabled!)
|
if (_wooSignalApp!.wishlistEnabled!)
|
||||||
FutureBuildWidget(
|
NyFutureBuilder(
|
||||||
asyncFuture: hasAddedWishlistProduct(_product!.id),
|
future: hasAddedWishlistProduct(_product!.id),
|
||||||
onValue: (dynamic isInFavourites) {
|
child: (context, dynamic isInFavourites) {
|
||||||
return isInFavourites
|
return isInFavourites
|
||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () => widget.controller.toggleWishList(
|
onPressed: () => widget.controller.toggleWishList(
|
||||||
|
|||||||
@ -29,6 +29,7 @@ ThemeData lightTheme(ColorStyles lightColors) {
|
|||||||
getAppTextTheme(appFont, defaultTextTheme.merge(_textTheme(lightColors)));
|
getAppTextTheme(appFont, defaultTextTheme.merge(_textTheme(lightColors)));
|
||||||
|
|
||||||
return ThemeData(
|
return ThemeData(
|
||||||
|
useMaterial3: true,
|
||||||
primaryColor: lightColors.primaryContent,
|
primaryColor: lightColors.primaryContent,
|
||||||
primaryColorLight: lightColors.primaryAccent,
|
primaryColorLight: lightColors.primaryAccent,
|
||||||
focusColor: lightColors.primaryContent,
|
focusColor: lightColors.primaryContent,
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
|
||||||
class AppVersionWidget extends StatelessWidget {
|
class AppVersionWidget extends StatelessWidget {
|
||||||
const AppVersionWidget({Key? key}) : super(key: key);
|
const AppVersionWidget({Key? key}) : super(key: key);
|
||||||
|
|||||||
@ -23,45 +23,48 @@ class CartIconWidget extends StatefulWidget {
|
|||||||
class _CartIconWidgetState extends State<CartIconWidget> {
|
class _CartIconWidgetState extends State<CartIconWidget> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return IconButton(
|
return Container(
|
||||||
icon: Stack(
|
width: 70,
|
||||||
children: <Widget>[
|
child: IconButton(
|
||||||
Positioned.fill(
|
icon: Stack(
|
||||||
child: Align(
|
children: <Widget>[
|
||||||
child: Icon(Icons.shopping_cart, size: 20),
|
Positioned.fill(
|
||||||
alignment: Alignment.bottomCenter,
|
child: Align(
|
||||||
),
|
child: Icon(Icons.shopping_cart, size: 20),
|
||||||
bottom: 0,
|
alignment: Alignment.bottomCenter,
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
child: Align(
|
|
||||||
child: NyFutureBuilder<List<CartLineItem>>(
|
|
||||||
future: Cart.getInstance.getCart(),
|
|
||||||
child: (BuildContext context,
|
|
||||||
data) {
|
|
||||||
List<int?> cartItems =
|
|
||||||
data.map((e) => e.quantity).toList();
|
|
||||||
String cartValue = "0";
|
|
||||||
if (cartItems.isNotEmpty) {
|
|
||||||
cartValue = cartItems
|
|
||||||
.reduce((value, element) => value! + element!)
|
|
||||||
.toString();
|
|
||||||
}
|
|
||||||
return Text(
|
|
||||||
cartValue,
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.topCenter,
|
bottom: 0,
|
||||||
),
|
),
|
||||||
top: 0,
|
Positioned.fill(
|
||||||
)
|
child: Align(
|
||||||
],
|
child: NyFutureBuilder<List<CartLineItem>>(
|
||||||
|
future: Cart.getInstance.getCart(),
|
||||||
|
child: (BuildContext context,
|
||||||
|
data) {
|
||||||
|
List<int?> cartItems =
|
||||||
|
data.map((e) => e.quantity).toList();
|
||||||
|
String cartValue = "0";
|
||||||
|
if (cartItems.isNotEmpty) {
|
||||||
|
cartValue = cartItems
|
||||||
|
.reduce((value, element) => value! + element!)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
return Text(
|
||||||
|
cartValue,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
),
|
||||||
|
top: 0,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () => Navigator.pushNamed(context, "/cart")
|
||||||
|
.then((value) => setState(() {})),
|
||||||
),
|
),
|
||||||
onPressed: () => Navigator.pushNamed(context, "/cart")
|
|
||||||
.then((value) => setState(() {})),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +0,0 @@
|
|||||||
// Label StoreMax
|
|
||||||
//
|
|
||||||
// Created by Anthony Gordon.
|
|
||||||
// 2023, WooSignal Ltd. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
class FutureBuildWidget<T> extends StatelessWidget {
|
|
||||||
const FutureBuildWidget(
|
|
||||||
{Key? key,
|
|
||||||
required this.asyncFuture,
|
|
||||||
required this.onValue,
|
|
||||||
this.onLoading})
|
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
final Widget Function(T? value) onValue;
|
|
||||||
final Widget? onLoading;
|
|
||||||
final Future asyncFuture;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return FutureBuilder<T>(
|
|
||||||
future: asyncFuture.then((value) => value as T),
|
|
||||||
builder: (BuildContext context, AsyncSnapshot<T> snapshot) {
|
|
||||||
switch (snapshot.connectionState) {
|
|
||||||
case ConnectionState.waiting:
|
|
||||||
return onLoading ?? Container();
|
|
||||||
default:
|
|
||||||
if (snapshot.hasError) {
|
|
||||||
return SizedBox.shrink();
|
|
||||||
} else {
|
|
||||||
return onValue(snapshot.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,8 +10,6 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
|
||||||
import 'package:flutter_app/resources/widgets/future_build_widget.dart';
|
|
||||||
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/products.dart';
|
||||||
@ -53,10 +51,10 @@ class ProductDetailRelatedProductsWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: 200,
|
height: 300,
|
||||||
child: FutureBuildWidget<List<Product>>(
|
child: NyFutureBuilder<List<Product>>(
|
||||||
asyncFuture: fetchRelated(),
|
future: fetchRelated(),
|
||||||
onValue: (relatedProducts) {
|
child: (context, relatedProducts) {
|
||||||
if (relatedProducts == null) {
|
if (relatedProducts == null) {
|
||||||
return SizedBox.shrink();
|
return SizedBox.shrink();
|
||||||
}
|
}
|
||||||
@ -70,7 +68,6 @@ class ProductDetailRelatedProductsWidget extends StatelessWidget {
|
|||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onLoading: AppLoaderWidget(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import 'package:auto_size_text/auto_size_text.dart';
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/bootstrap/helpers.dart';
|
import 'package:flutter_app/bootstrap/helpers.dart';
|
||||||
import 'package:flutter_app/resources/widgets/future_build_widget.dart';
|
|
||||||
import 'package:flutter_app/resources/widgets/product_detail_review_tile_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_review_tile_widget.dart';
|
||||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
@ -91,12 +90,9 @@ class _ProductDetailReviewsWidgetState
|
|||||||
initiallyExpanded: false,
|
initiallyExpanded: false,
|
||||||
children: [
|
children: [
|
||||||
if (_ratingExpanded == true)
|
if (_ratingExpanded == true)
|
||||||
FutureBuildWidget<List<ProductReview>>(
|
NyFutureBuilder<List<ProductReview>>(
|
||||||
asyncFuture: fetchReviews(),
|
future: fetchReviews(),
|
||||||
onValue: (reviews) {
|
child: (context, reviews) {
|
||||||
if (reviews == null) {
|
|
||||||
return SizedBox.shrink();
|
|
||||||
}
|
|
||||||
int reviewsCount = reviews.length;
|
int reviewsCount = reviews.length;
|
||||||
List<Widget> childrenWidgets = [];
|
List<Widget> childrenWidgets = [];
|
||||||
List<ProductDetailReviewTileWidget> children = reviews
|
List<ProductDetailReviewTileWidget> children = reviews
|
||||||
@ -137,7 +133,7 @@ class _ProductDetailReviewsWidgetState
|
|||||||
: childrenWidgets,
|
: childrenWidgets,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onLoading: Padding(
|
loading: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
child: CupertinoActivityIndicator(),
|
child: CupertinoActivityIndicator(),
|
||||||
),
|
),
|
||||||
@ -149,9 +145,9 @@ class _ProductDetailReviewsWidgetState
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<List<ProductReview>> fetchReviews() async {
|
Future<List<ProductReview>> fetchReviews() async {
|
||||||
return await (appWooSignal(
|
return await appWooSignal(
|
||||||
(api) => api.getProductReviews(
|
(api) => api.getProductReviews(
|
||||||
perPage: 5, product: [widget.product!.id!], status: "approved"),
|
perPage: 5, product: [widget.product!.id!], status: "approved"),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,7 +75,7 @@ class _ProductDetailUpsellWidgetState extends State<ProductDetailUpsellWidget> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: 200,
|
height: 300,
|
||||||
child: ListView(
|
child: ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
|
|||||||
@ -315,6 +315,7 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
if (product == null) {
|
if (product == null) {
|
||||||
return SizedBox.shrink();
|
return SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayoutBuilder(
|
return LayoutBuilder(
|
||||||
builder: (cxt, constraints) => InkWell(
|
builder: (cxt, constraints) => InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -324,7 +325,7 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: constraints.maxHeight / 2,
|
height: constraints.maxHeight / 1.6,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(3.0),
|
borderRadius: BorderRadius.circular(3.0),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
@ -338,10 +339,12 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
image: (product!.images.isNotEmpty
|
image: (product!.images.isNotEmpty
|
||||||
? product!.images.first.src
|
? product!.images.first.src
|
||||||
: getEnv("PRODUCT_PLACEHOLDER_IMAGE")),
|
: getEnv("PRODUCT_PLACEHOLDER_IMAGE")),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.cover,
|
||||||
height: constraints.maxHeight / 2,
|
height: constraints.maxHeight / 1.6,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
),
|
),
|
||||||
|
if (isProductNew(product))
|
||||||
|
Container(padding: EdgeInsets.all(4), child: Text("New", style: TextStyle(color: Colors.white),), decoration: BoxDecoration(color: Colors.black),),
|
||||||
if (product!.onSale! && product!.type != "variable")
|
if (product!.onSale! && product!.type != "variable")
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
@ -351,7 +354,7 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
padding: EdgeInsets.all(3),
|
padding: EdgeInsets.all(3),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white70,
|
color: Colors.white70,
|
||||||
borderRadius: BorderRadius.circular(4),
|
// borderRadius: BorderRadius.circular(4),
|
||||||
),
|
),
|
||||||
child: RichText(
|
child: RichText(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@ -366,8 +369,8 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyLarge!
|
.bodyLarge!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Colors.black87,
|
color: Colors.black,
|
||||||
fontSize: 11,
|
fontSize: 13,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -393,16 +396,17 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
|
padding: EdgeInsets.only(top: 4),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
AutoSizeText(
|
AutoSizeText(
|
||||||
"${formatStringCurrency(total: product!.price)} ",
|
"${formatStringCurrency(total: product!.price)} ",
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyLarge!
|
||||||
.copyWith(fontWeight: FontWeight.w600),
|
.copyWith(fontWeight: FontWeight.w800),
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
if (product!.onSale! && product!.type != "variable")
|
if (product!.onSale! && product!.type != "variable")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
# Official WooSignal App Template for WooCommerce
|
# Official WooSignal App Template for WooCommerce
|
||||||
|
|
||||||
# Label StoreMax
|
# Label StoreMax
|
||||||
# Version: 6.5.1
|
# Version: 6.6.0
|
||||||
# Author: Anthony Gordon
|
# Author: Anthony Gordon
|
||||||
# Homepage: https://woosignal.com
|
# Homepage: https://woosignal.com
|
||||||
# Documentation: https://woosignal.com/docs/app/label-storemax
|
# Documentation: https://woosignal.com/docs/app/label-storemax
|
||||||
@ -22,27 +22,29 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <3.0.0'
|
sdk: ">=2.17.0 <3.0.0"
|
||||||
|
flutter: ">=3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
google_fonts: ^4.0.3
|
google_fonts: ^4.0.3
|
||||||
analyzer: ^4.2.0
|
analyzer: ^5.12.0
|
||||||
intl: ^0.17.0
|
intl: ^0.18.0
|
||||||
nylo_framework: ^4.1.4
|
nylo_framework: ^5.0.0
|
||||||
woosignal: ^3.3.0
|
# woosignal: ^3.3.0
|
||||||
flutter_stripe: ^8.0.0+1
|
woosignal:
|
||||||
|
path: /Users/anthony/StudioProjects/woosignal-api
|
||||||
|
# flutter_stripe: ^9.2.0
|
||||||
wp_json_api: ^3.3.2
|
wp_json_api: ^3.3.2
|
||||||
cached_network_image: ^3.2.3
|
cached_network_image: ^3.2.3
|
||||||
package_info: ^2.0.2
|
package_info_plus: ^4.0.0
|
||||||
money_formatter: ^0.0.3
|
money_formatter: ^0.0.3
|
||||||
flutter_web_browser: ^0.17.1
|
flutter_web_browser: ^0.17.1
|
||||||
webview_flutter: ^3.0.4
|
webview_flutter: ^3.0.4
|
||||||
pull_to_refresh_flutter3: 2.0.1
|
pull_to_refresh_flutter3: 2.0.1
|
||||||
url_launcher: ^6.1.6
|
url_launcher: ^6.1.6
|
||||||
bubble_tab_indicator: ^0.1.5
|
bubble_tab_indicator: ^0.1.5
|
||||||
razorpay_flutter: ^1.3.4
|
|
||||||
status_alert: ^1.0.1
|
status_alert: ^1.0.1
|
||||||
math_expressions: ^2.3.1
|
math_expressions: ^2.4.0
|
||||||
validated: ^2.0.0
|
validated: ^2.0.0
|
||||||
flutter_spinkit: ^5.1.0
|
flutter_spinkit: ^5.1.0
|
||||||
auto_size_text: ^3.0.0
|
auto_size_text: ^3.0.0
|
||||||
@ -51,8 +53,8 @@ dependencies:
|
|||||||
flutter_rating_bar: ^4.0.1
|
flutter_rating_bar: ^4.0.1
|
||||||
flutter_staggered_grid_view: ^0.6.2
|
flutter_staggered_grid_view: ^0.6.2
|
||||||
flutter_swiper_view: ^1.1.8
|
flutter_swiper_view: ^1.1.8
|
||||||
firebase_messaging: ^14.2.5
|
firebase_messaging: ^14.4.1
|
||||||
firebase_core: ^2.7.0
|
firebase_core: ^2.10.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
@ -62,15 +64,16 @@ dependencies:
|
|||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.5
|
cupertino_icons: ^1.0.5
|
||||||
collection: ^1.15.0
|
collection: ^1.15.0
|
||||||
|
flutter_stripe: ^9.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_launcher_icons: ^0.12.0
|
flutter_launcher_icons: ^0.13.1
|
||||||
lints: ^2.0.0
|
lints: ^2.0.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
# APP ICON
|
# APP ICON
|
||||||
flutter_icons:
|
flutter_launcher_icons:
|
||||||
android: true
|
android: true
|
||||||
ios: true
|
ios: true
|
||||||
image_path: "public/assets/app_icon/appicon.png"
|
image_path: "public/assets/app_icon/appicon.png"
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# WooCommerce App: Label StoreMax
|
# WooCommerce App: Label StoreMax
|
||||||
|
|
||||||
### Label StoreMax - v6.5.1
|
### Label StoreMax - v6.6.0
|
||||||
|
|
||||||
|
|
||||||
[Official WooSignal WooCommerce App](https://woosignal.com)
|
[Official WooSignal WooCommerce App](https://woosignal.com)
|
||||||
@ -45,7 +45,7 @@ Full documentation this available [here](https://woosignal.com/docs/app/ios/labe
|
|||||||
- Change app name, logo, customize default language, currency + more
|
- Change app name, logo, customize default language, currency + more
|
||||||
- Light and dark mode
|
- Light and dark mode
|
||||||
- Theme customization
|
- Theme customization
|
||||||
- Stripe, Cash On Delivery, PayPal and RazorPay
|
- Stripe, Cash On Delivery, PayPal
|
||||||
- Localized for en, es, pt, it, hi, fr, zh, tr, nl
|
- Localized for en, es, pt, it, hi, fr, zh, tr, nl
|
||||||
- Orders show as normal in WooCommerce
|
- Orders show as normal in WooCommerce
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user