v6.5.0 updates

This commit is contained in:
Anthony 2023-03-04 12:41:33 +07:00
parent 95c9697830
commit c980407287
47 changed files with 738 additions and 475 deletions

View File

@ -1,3 +1,10 @@
## [6.5.0] - 2023-03-04
* When making payments via Stripe, it will now save the card for later.
* Small UI changes to the checkout confirmation page.
* New translation added.
* Pubspec.yaml dependency updates.
## [6.4.1] - 2023-02-23 ## [6.4.1] - 2023-02-23
* Upgrade to Nylo v4.1.3 * Upgrade to Nylo v4.1.3

View File

@ -4,7 +4,7 @@
# WooCommerce App: Label StoreMax # WooCommerce App: Label StoreMax
### Label StoreMax - v6.4.1 ### Label StoreMax - v6.5.0
[Official WooSignal WooCommerce App](https://woosignal.com) [Official WooSignal WooCommerce App](https://woosignal.com)

View File

@ -227,5 +227,6 @@
"Are you sure?": "Bist du dir sicher?", "Are you sure?": "Bist du dir sicher?",
"Yes, delete my account": "Ja, lösche mein Konto", "Yes, delete my account": "Ja, lösche mein Konto",
"Account deleted": "Konto gelöscht", "Account deleted": "Konto gelöscht",
"Shipping is not supported for your location, sorry": "Der Versand wird für Ihren Standort nicht unterstützt, tut mir leid" "Shipping is not supported for your location, sorry": "Der Versand wird für Ihren Standort nicht unterstützt, tut mir leid",
"Order Summary": "Bestellübersicht"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Are you sure?", "Are you sure?": "Are you sure?",
"Yes, delete my account": "Yes, delete my account", "Yes, delete my account": "Yes, delete my account",
"Account deleted": "Account deleted", "Account deleted": "Account deleted",
"Shipping is not supported for your location, sorry": "Shipping is not supported for your location, sorry" "Shipping is not supported for your location, sorry": "Shipping is not supported for your location, sorry",
"Order Summary": "Order Summary"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "¿Está seguro?", "Are you sure?": "¿Está seguro?",
"Yes, delete my account": "Sí, eliminar mi cuenta", "Yes, delete my account": "Sí, eliminar mi cuenta",
"Account deleted": "Cuenta borrada", "Account deleted": "Cuenta borrada",
"Shipping is not supported for your location, sorry": "El envío no es compatible para su ubicación, lo siento" "Shipping is not supported for your location, sorry": "El envío no es compatible para su ubicación, lo siento",
"Order Summary": "Resumen del pedido"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Êtes-vous sûr?", "Are you sure?": "Êtes-vous sûr?",
"Yes, delete my account": "Oui, supprimer mon compte", "Yes, delete my account": "Oui, supprimer mon compte",
"Account deleted": "Compte supprimé", "Account deleted": "Compte supprimé",
"Shipping is not supported for your location, sorry": "L'expédition n'est pas prise en charge pour votre emplacement, désolé" "Shipping is not supported for your location, sorry": "L'expédition n'est pas prise en charge pour votre emplacement, désolé",
"Order Summary": "Récapitulatif de la commande"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "kya aapako yakeen hai?", "Are you sure?": "kya aapako yakeen hai?",
"Yes, delete my account": "haan, mera akaunt dileet kar do", "Yes, delete my account": "haan, mera akaunt dileet kar do",
"Account deleted": "khaata hataaya gaya", "Account deleted": "khaata hataaya gaya",
"Shipping is not supported for your location, sorry": "aapake sthaan ke lie shiping samarthit nahin hai, kshama karen" "Shipping is not supported for your location, sorry": "aapake sthaan ke lie shiping samarthit nahin hai, kshama karen",
"Order Summary": "aadesh saaraansh"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Sei sicuro?", "Are you sure?": "Sei sicuro?",
"Yes, delete my account": "Sì, elimina il mio account", "Yes, delete my account": "Sì, elimina il mio account",
"Account deleted": "Account cancellato", "Account deleted": "Account cancellato",
"Shipping is not supported for your location, sorry": "La spedizione non è supportata per la tua posizione, mi dispiace" "Shipping is not supported for your location, sorry": "La spedizione non è supportata per la tua posizione, mi dispiace",
"Order Summary": "Riepilogo dell'ordine"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Weet je het zeker?", "Are you sure?": "Weet je het zeker?",
"Yes, delete my account": "Ja, verwijder mijn account", "Yes, delete my account": "Ja, verwijder mijn account",
"Account deleted": "Account verwijderd", "Account deleted": "Account verwijderd",
"Shipping is not supported for your location, sorry": "Verzending wordt niet ondersteund voor uw locatie, sorry" "Shipping is not supported for your location, sorry": "Verzending wordt niet ondersteund voor uw locatie, sorry",
"Order Summary": "Overzicht van de bestelling"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Tem certeza?", "Are you sure?": "Tem certeza?",
"Yes, delete my account": "Sim, excluir minha conta", "Yes, delete my account": "Sim, excluir minha conta",
"Account deleted": "Conta excluída", "Account deleted": "Conta excluída",
"Shipping is not supported for your location, sorry": "O envio não é suportado para a sua localização, desculpe" "Shipping is not supported for your location, sorry": "O envio não é suportado para a sua localização, desculpe",
"Order Summary": "Resumo do pedido"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "Emin misin?", "Are you sure?": "Emin misin?",
"Yes, delete my account": "Evet, hesabımı sil", "Yes, delete my account": "Evet, hesabımı sil",
"Account deleted": "Hesap silindi", "Account deleted": "Hesap silindi",
"Shipping is not supported for your location, sorry": "Bulunduğunuz yer için gönderim desteklenmiyor, üzgünüm" "Shipping is not supported for your location, sorry": "Bulunduğunuz yer için gönderim desteklenmiyor, üzgünüm",
"Order Summary": "Sipariş özeti"
} }

View File

@ -227,5 +227,6 @@
"Are you sure?": "你确定吗?", "Are you sure?": "你确定吗?",
"Yes, delete my account": "是的,删除我的帐户", "Yes, delete my account": "是的,删除我的帐户",
"Account deleted": "帐号已删除", "Account deleted": "帐号已删除",
"Shipping is not supported for your location, sorry": "您所在的位置不支持送货,抱歉" "Shipping is not supported for your location, sorry": "您所在的位置不支持送货,抱歉",
"Order Summary": "订单摘要"
} }

View File

@ -22,6 +22,37 @@ class BillingDetails {
shippingAddress = CustomerAddress(); shippingAddress = CustomerAddress();
} }
Map<String, dynamic> createStripeDetails() => {
'address': {
if (billingAddress?.addressLine != null)
'line1': billingAddress?.addressLine,
if (billingAddress?.city != null) 'city': billingAddress?.city,
if (billingAddress?.postalCode != null)
'postal_code': billingAddress?.postalCode,
if (billingAddress?.customerCountry?.state?.name != null)
'state': billingAddress?.customerCountry?.state?.name,
if (billingAddress?.customerCountry?.countryCode != null)
'country': billingAddress?.customerCountry?.countryCode,
},
'shipping': {
if (shippingAddress?.nameFull() != null)
'name': shippingAddress?.nameFull(),
if (shippingAddress?.city != null) 'city': shippingAddress?.city,
if (shippingAddress?.postalCode != null)
'postal_code': shippingAddress?.postalCode,
if (shippingAddress?.customerCountry?.state?.name != null)
'state': shippingAddress?.customerCountry?.state?.name,
if (shippingAddress?.customerCountry?.countryCode != null)
'country': shippingAddress?.customerCountry?.countryCode,
},
if (billingAddress?.emailAddress != null)
'email': billingAddress?.emailAddress,
if (billingAddress?.nameFull() != null)
'name': billingAddress?.nameFull(),
if (billingAddress?.phoneNumber != null)
'phone': billingAddress?.phoneNumber
};
Map<String, String?> getShippingAddressStripe() => { Map<String, String?> getShippingAddressStripe() => {
"name": shippingAddress?.nameFull(), "name": shippingAddress?.nameFull(),
"line1": shippingAddress!.addressLine, "line1": shippingAddress!.addressLine,

View File

@ -167,8 +167,7 @@ class CustomerAddress {
WpMetaData(key: "${type}_phone", value: phoneNumber), WpMetaData(key: "${type}_phone", value: phoneNumber),
if (type != "shipping") if (type != "shipping")
WpMetaData(key: "${type}_email", value: emailAddress), WpMetaData(key: "${type}_email", value: emailAddress),
WpMetaData( WpMetaData(key: "${type}_country", value: customerCountry?.countryCode),
key: "${type}_country", value: customerCountry?.countryCode),
WpMetaData( WpMetaData(
key: "${type}_state", key: "${type}_state",
value: customerCountry?.state?.code value: customerCountry?.state?.code

View File

@ -14,7 +14,6 @@ class BaseApiService extends NyBaseApiService {
/// Default interceptors /// Default interceptors
@override @override
final interceptors = { final interceptors = {
if (getEnv('APP_DEBUG') == true) if (getEnv('APP_DEBUG') == true) LoggingInterceptor: LoggingInterceptor()
LoggingInterceptor: LoggingInterceptor()
}; };
} }

View File

@ -47,16 +47,17 @@ stripePay(context,
} }
try { try {
dynamic rsp = {}; Map<String, dynamic>? rsp = {};
// // CHECKOUT HELPER // // CHECKOUT HELPER
await checkout(taxRate, (total, billingDetails, cart) async { await checkout(taxRate, (total, billingDetails, cart) async {
String cartShortDesc = await cart.cartShortDesc(); String cartShortDesc = await cart.cartShortDesc();
rsp = await appWooSignal((api) => api.stripePaymentIntent( rsp = await appWooSignal((api) => api.stripePaymentIntentV2(
amount: total, amount: total,
email: billingDetails?.billingAddress?.emailAddress, email: billingDetails?.billingAddress?.emailAddress,
desc: cartShortDesc, desc: cartShortDesc,
shipping: billingDetails?.getShippingAddressStripe(), shipping: billingDetails?.getShippingAddressStripe(),
customerDetails: billingDetails?.createStripeDetails(),
)); ));
}); });
@ -77,11 +78,31 @@ stripePay(context,
: ThemeMode.dark, : ThemeMode.dark,
merchantDisplayName: merchantDisplayName:
envVal('APP_NAME', defaultValue: wooSignalApp?.appName), envVal('APP_NAME', defaultValue: wooSignalApp?.appName),
paymentIntentClientSecret: rsp['client_secret'], customerId: rsp!['customer'],
)); paymentIntentClientSecret: rsp!['client_secret'],
customerEphemeralKeySecret: rsp!['ephemeral_key'],
setupIntentClientSecret: rsp!['setup_intent_secret']),
);
await Stripe.instance.presentPaymentSheet(); await Stripe.instance.presentPaymentSheet();
PaymentIntent paymentIntent =
await Stripe.instance.retrievePaymentIntent(rsp!['client_secret']);
if (paymentIntent.status == PaymentIntentsStatus.Unknown) {
showToastNotification(
context,
title: trans("Oops!"),
description: trans("Something went wrong, please try again."),
icon: Icons.payment,
style: ToastNotificationStyleType.WARNING,
);
}
if (paymentIntent.status != PaymentIntentsStatus.Succeeded) {
return;
}
state.reloadState(showLoader: true); state.reloadState(showLoader: true);
OrderWC orderWC = await buildOrderWC(taxRate: taxRate); OrderWC orderWC = await buildOrderWC(taxRate: taxRate);

View File

@ -60,7 +60,8 @@ class AppBuild extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Nylo nylo = Backpack.instance.read('nylo'); Nylo nylo = Backpack.instance.read('nylo');
List<AppTheme> appThemes = nylo.appThemes.map((appTheme) => appTheme.toAppTheme()).toList(); List<AppTheme> appThemes =
nylo.appThemes.map((appTheme) => appTheme.toAppTheme()).toList();
return LocalizedApp( return LocalizedApp(
child: ThemeProvider( child: ThemeProvider(
themes: appThemes, themes: appThemes,
@ -89,7 +90,12 @@ class AppBuild extends StatelessWidget {
title: title ?? "", title: title ?? "",
initialRoute: initialRoute, initialRoute: initialRoute,
onGenerateRoute: onGenerateRoute, onGenerateRoute: onGenerateRoute,
darkTheme: darkTheme ?? appThemes.firstWhere((theme) => theme.id == getEnv('DARK_THEME_ID'), orElse: () => appThemes.first).data, darkTheme: darkTheme ??
appThemes
.firstWhere(
(theme) => theme.id == getEnv('DARK_THEME_ID'),
orElse: () => appThemes.first)
.data,
theme: themeData ?? ThemeProvider.themeOf(context).data, theme: themeData ?? ThemeProvider.themeOf(context).data,
localeResolutionCallback: localeResolutionCallback:
(Locale? locale, Iterable<Locale> supportedLocales) { (Locale? locale, Iterable<Locale> supportedLocales) {

View File

@ -0,0 +1,140 @@
import 'package:flutter/material.dart';
import 'package:flutter_app/bootstrap/helpers.dart';
import 'package:flutter_app/resources/themes/styles/color_styles.dart';
extension NyText on Text {
/// Set the Style to use [displayLarge].
Text displayLarge(BuildContext context) {
return setStyle(Theme.of(context).textTheme.displayLarge);
}
/// Set the Style to use [displayMedium].
Text displayMedium(BuildContext context) {
return setStyle(Theme.of(context).textTheme.displayMedium);
}
/// Set the Style to use [displaySmall].
Text displaySmall(BuildContext context) {
return setStyle(Theme.of(context).textTheme.displaySmall);
}
/// Set the Style to use [headlineLarge].
Text headingLarge(BuildContext context) {
return setStyle(Theme.of(context).textTheme.headlineLarge);
}
/// Set the Style to use [headlineMedium].
Text headingMedium(BuildContext context) {
return setStyle(Theme.of(context).textTheme.headlineMedium);
}
/// Set the Style to use [headlineSmall].
Text headingSmall(BuildContext context) {
return setStyle(Theme.of(context).textTheme.headlineSmall);
}
/// Set the Style to use [titleLarge].
Text titleLarge(BuildContext context) {
return setStyle(Theme.of(context).textTheme.titleLarge);
}
/// Set the Style to use [titleMedium].
Text titleMedium(BuildContext context) {
return setStyle(Theme.of(context).textTheme.titleMedium);
}
/// Set the Style to use [titleSmall].
Text titleSmall(BuildContext context) {
return setStyle(Theme.of(context).textTheme.titleSmall);
}
/// Set the Style to use [bodyLarge].
Text large(BuildContext context) {
return setStyle(Theme.of(context).textTheme.bodyLarge);
}
/// Set the Style to use [bodyMedium].
Text medium(BuildContext context) {
return setStyle(Theme.of(context).textTheme.bodyMedium);
}
/// Set the Style to use [bodySmall].
Text small(BuildContext context) {
return setStyle(Theme.of(context).textTheme.bodySmall);
}
/// Make the font bold.
Text fontWeightBold() {
return copyWith(style: TextStyle(fontWeight: FontWeight.bold));
}
/// Make the font light.
Text fontWeightLight() {
return copyWith(style: TextStyle(fontWeight: FontWeight.w300));
}
/// Change the [style].
Text setStyle(TextStyle? style) => copyWith(style: style);
/// Sets the color from your [ColorStyles] or [Color].
Text setColor(
BuildContext context, Color Function(ColorStyles color) newColor,
{String? themeId}) {
return copyWith(
style: TextStyle(
color: newColor(ThemeColor.get(context, themeId: themeId))));
}
/// Aligns text to the left.
Text alignLeft() {
return copyWith(textAlign: TextAlign.left);
}
/// Aligns text to the right.
Text alignRight() {
return copyWith(textAlign: TextAlign.right);
}
/// Aligns text to the center.
Text alignCenter() {
return copyWith(textAlign: TextAlign.center);
}
/// Aligns text to the center.
Text setMaxLines(int maxLines) {
return copyWith(maxLines: maxLines);
}
/// Change the [fontFamily].
Text setFontFamily(String fontFamily) =>
copyWith(style: TextStyle(fontFamily: fontFamily));
/// Helper to apply changes.
Text copyWith(
{Key? key,
StrutStyle? strutStyle,
TextAlign? textAlign,
TextDirection? textDirection = TextDirection.ltr,
Locale? locale,
bool? softWrap,
TextOverflow? overflow,
double? textScaleFactor,
int? maxLines,
String? semanticsLabel,
TextWidthBasis? textWidthBasis,
TextStyle? style}) {
return Text(data ?? "",
key: key ?? this.key,
strutStyle: strutStyle ?? this.strutStyle,
textAlign: textAlign ?? this.textAlign,
textDirection: textDirection ?? this.textDirection,
locale: locale ?? this.locale,
softWrap: softWrap ?? this.softWrap,
overflow: overflow ?? this.overflow,
textScaleFactor: textScaleFactor ?? this.textScaleFactor,
maxLines: maxLines ?? this.maxLines,
semanticsLabel: semanticsLabel ?? this.semanticsLabel,
textWidthBasis: textWidthBasis ?? this.textWidthBasis,
style: style != null ? this.style?.merge(style) ?? style : this.style);
}
}

View File

@ -54,20 +54,24 @@ Future appWooSignal(Function(WooSignal) api) async {
/// helper to find correct color from the [context]. /// helper to find correct color from the [context].
class ThemeColor { class ThemeColor {
static ColorStyles get(BuildContext context, {String? themeId}) { static ColorStyles get(BuildContext context, {String? themeId}) {
Nylo nylo = Backpack.instance.read('nylo'); Nylo nylo = Backpack.instance.read('nylo');
List<BaseThemeConfig<ColorStyles>> appThemes = nylo.appThemes as List<BaseThemeConfig<ColorStyles>>; List<BaseThemeConfig<ColorStyles>> appThemes =
nylo.appThemes as List<BaseThemeConfig<ColorStyles>>;
if (themeId == null) { if (themeId == null) {
BaseThemeConfig<ColorStyles> themeFound = appThemes BaseThemeConfig<ColorStyles> themeFound = appThemes.firstWhere(
.firstWhere( (theme) =>
(theme) => theme.id == getEnv(Theme.of(context).brightness == Brightness.light ? 'LIGHT_THEME_ID' : 'DARK_THEME_ID'), theme.id ==
orElse: () => appThemes.first getEnv(Theme.of(context).brightness == Brightness.light
); ? 'LIGHT_THEME_ID'
: 'DARK_THEME_ID'),
orElse: () => appThemes.first);
return themeFound.colors; return themeFound.colors;
} }
BaseThemeConfig<ColorStyles> baseThemeConfig = appThemes.firstWhere((theme) => theme.id == themeId, orElse: () => appThemes.first); BaseThemeConfig<ColorStyles> baseThemeConfig = appThemes.firstWhere(
(theme) => theme.id == themeId,
orElse: () => appThemes.first);
return baseThemeConfig.colors; return baseThemeConfig.colors;
} }
} }
@ -80,7 +84,7 @@ extension ColorsHelper on TextStyle {
} }
} }
List<PaymentType?> getPaymentTypes() { Future<List<PaymentType?>> getPaymentTypes() async {
List<PaymentType?> paymentTypes = []; List<PaymentType?> paymentTypes = [];
for (var appPaymentGateway in appPaymentGateways) { for (var appPaymentGateway in appPaymentGateways) {
if (paymentTypes.firstWhere( if (paymentTypes.firstWhere(
@ -501,7 +505,8 @@ class UserAuth {
} }
Future<List<DefaultShipping>> getDefaultShipping() async { Future<List<DefaultShipping>> getDefaultShipping() async {
String data = await rootBundle.loadString('public/assets/json/default_shipping.json'); String data =
await rootBundle.loadString('public/assets/json/default_shipping.json');
dynamic dataJson = json.decode(data); dynamic dataJson = json.decode(data);
List<DefaultShipping> shipping = []; List<DefaultShipping> shipping = [];
@ -521,29 +526,39 @@ Future<List<DefaultShipping>> getDefaultShipping() async {
Future<DefaultShipping?> findCountryMetaForShipping(String countryCode) async { Future<DefaultShipping?> findCountryMetaForShipping(String countryCode) async {
List<DefaultShipping> defaultShipping = await getDefaultShipping(); List<DefaultShipping> defaultShipping = await getDefaultShipping();
List<DefaultShipping> shippingByCountryCode = defaultShipping.where((element) => element.code == countryCode).toList(); List<DefaultShipping> shippingByCountryCode =
defaultShipping.where((element) => element.code == countryCode).toList();
if (shippingByCountryCode.isNotEmpty) { if (shippingByCountryCode.isNotEmpty) {
return shippingByCountryCode.first; return shippingByCountryCode.first;
} }
return null; return null;
} }
DefaultShippingState? findDefaultShippingStateByCode(DefaultShipping defaultShipping, String code) { DefaultShippingState? findDefaultShippingStateByCode(
List<DefaultShippingState> defaultShippingStates = defaultShipping.states.where((state) => state.code == code).toList(); DefaultShipping defaultShipping, String code) {
List<DefaultShippingState> defaultShippingStates =
defaultShipping.states.where((state) => state.code == code).toList();
if (defaultShippingStates.isEmpty) { if (defaultShippingStates.isEmpty) {
return null; return null;
} }
DefaultShippingState defaultShippingState = defaultShippingStates.first; DefaultShippingState defaultShippingState = defaultShippingStates.first;
return DefaultShippingState(code: defaultShippingState.code, name: defaultShippingState.name); return DefaultShippingState(
code: defaultShippingState.code, name: defaultShippingState.name);
} }
bool hasKeyInMeta(WPUserInfoResponse wpUserInfoResponse, String key) { bool hasKeyInMeta(WPUserInfoResponse wpUserInfoResponse, String key) {
return (wpUserInfoResponse.data!.metaData ?? []).where((meta) => meta.key == key).toList().isNotEmpty; return (wpUserInfoResponse.data!.metaData ?? [])
.where((meta) => meta.key == key)
.toList()
.isNotEmpty;
} }
String fetchValueInMeta(WPUserInfoResponse wpUserInfoResponse, String key) { String fetchValueInMeta(WPUserInfoResponse wpUserInfoResponse, String key) {
String value = ""; String value = "";
List<dynamic>? metaDataValue = (wpUserInfoResponse.data!.metaData ?? []).where((meta) => meta.key == key).first.value; List<dynamic>? metaDataValue = (wpUserInfoResponse.data!.metaData ?? [])
.where((meta) => meta.key == key)
.first
.value;
if (metaDataValue != null && metaDataValue.isNotEmpty) { if (metaDataValue != null && metaDataValue.isNotEmpty) {
return metaDataValue.first ?? ""; return metaDataValue.first ?? "";
} }
@ -592,7 +607,8 @@ removeWishlistProduct({required Product? product}) async {
await NyStorage.store(SharedKey.wishlistProducts, json); await NyStorage.store(SharedKey.wishlistProducts, json);
} }
Future<BillingDetails> billingDetailsFromWpUserInfoResponse(wpUserInfoResponse) async { Future<BillingDetails> billingDetailsFromWpUserInfoResponse(
wpUserInfoResponse) async {
List<String> metaDataAddress = [ List<String> metaDataAddress = [
'billing_first_name', 'billing_first_name',
'billing_last_name', 'billing_last_name',

View File

@ -0,0 +1,16 @@
/*
|--------------------------------------------------------------------------
| Storage Keys
| Add your storage keys here and then use them later to retrieve data.
| E.g. static String userCoins = "USER_COINS";
| String coins = NyStorage.read( StorageKey.userCoins );
|
| Learn more: https://nylo.dev/docs/4.x/storage#storage-keys
|--------------------------------------------------------------------------
*/
class StorageKey {
static String userToken = "USER_TOKEN";
/// Add your storage keys here...
}

View File

@ -64,7 +64,10 @@ class _AccountLandingPageState extends NyState<AccountLandingPage> {
child: Text( child: Text(
trans("Login"), trans("Login"),
textAlign: TextAlign.left, textAlign: TextAlign.left,
style: Theme.of(context).textTheme.headlineMedium!.copyWith( style: Theme.of(context)
.textTheme
.headlineMedium!
.copyWith(
fontSize: 24, fontSize: 24,
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),

View File

@ -62,7 +62,8 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text(trans("Browse"), style: Theme.of(context).textTheme.titleMedium), Text(trans("Browse"),
style: Theme.of(context).textTheme.titleMedium),
Text(parseHtmlString(productCategory!.name)) Text(parseHtmlString(productCategory!.name))
], ],
), ),

View File

@ -266,26 +266,16 @@ class _CartPageState extends State<CartPage> {
Divider( Divider(
color: Colors.black45, color: Colors.black45,
), ),
FutureBuilder<String>( NyFutureBuilder<String>(
future: Cart.getInstance.getTotal(withFormat: true), future: Cart.getInstance.getTotal(withFormat: true),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) { child: (BuildContext context, data) => Padding(
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text("");
default:
if (snapshot.hasError) {
return Text("");
} else {
return Padding(
child: TextRowWidget( child: TextRowWidget(
title: trans("Total"), title: trans("Total"),
text: (_isLoading ? "" : snapshot.data), text: (_isLoading ? "" : data),
), ),
padding: EdgeInsets.only(bottom: 15, top: 15), padding: EdgeInsets.only(bottom: 15, top: 15),
); ),
} loading: SizedBox.shrink(),
}
},
), ),
PrimaryButton( PrimaryButton(
title: trans("PROCEED TO CHECKOUT"), title: trans("PROCEED TO CHECKOUT"),

View File

@ -9,12 +9,14 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
import 'package:collection/collection.dart' show IterableExtension; import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/app/models/cart.dart';
import 'package:flutter_app/app/models/checkout_session.dart'; import 'package:flutter_app/app/models/checkout_session.dart';
import 'package:flutter_app/app/models/customer_country.dart'; import 'package:flutter_app/app/models/customer_country.dart';
import 'package:flutter_app/app/models/payment_type.dart'; import 'package:flutter_app/app/models/payment_type.dart';
import 'package:flutter_app/bootstrap/app_helper.dart'; import 'package:flutter_app/bootstrap/app_helper.dart';
import 'package:flutter_app/bootstrap/extensions.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/app_loader_widget.dart';
import 'package:flutter_app/resources/widgets/buttons.dart'; import 'package:flutter_app/resources/widgets/buttons.dart';
@ -38,23 +40,26 @@ class CheckoutConfirmationPage extends StatefulWidget {
CheckoutConfirmationPageState(); CheckoutConfirmationPageState();
} }
class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> { class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
CheckoutConfirmationPageState(); CheckoutConfirmationPageState();
bool _showFullLoader = true, _isProcessingPayment = false; bool _showFullLoader = true, _isProcessingPayment = false;
final List<TaxRate> _taxRates = []; final List<TaxRate> _taxRates = [];
TaxRate? _taxRate; TaxRate? _taxRate;
final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig; final WooSignalApp? _wooSignalApp = AppHelper.instance.appConfig;
@override @override
void initState() { init() async {
super.initState(); super.init();
CheckoutSession.getInstance.coupon = null; CheckoutSession.getInstance.coupon = null;
List<PaymentType?> paymentTypes = getPaymentTypes(); List<PaymentType?> paymentTypes = await getPaymentTypes();
if (CheckoutSession.getInstance.paymentType == null && if (CheckoutSession.getInstance.paymentType == null &&
paymentTypes.isNotEmpty) { paymentTypes.isNotEmpty) {
CheckoutSession.getInstance.paymentType = paymentTypes.first; CheckoutSession.getInstance.paymentType = paymentTypes.firstWhere(
(paymentType) => paymentType?.id == 20,
orElse: () => paymentTypes.first);
print(CheckoutSession.getInstance.paymentType?.name);
} }
_getTaxes(); _getTaxes();
} }
@ -176,8 +181,15 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(trans("Checkout")), title: Column(
centerTitle: true, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(trans("Checkout")),
Text(_wooSignalApp?.appName ?? getEnv('APP_NAME')).small(context),
],
),
centerTitle: false,
leading: Container( leading: Container(
child: IconButton( child: IconButton(
icon: Icon(Icons.arrow_back_ios), icon: Icon(Icons.arrow_back_ios),
@ -191,25 +203,15 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
), ),
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
body: SafeAreaWidget( body: SafeAreaWidget(
child: Container(
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: Container( child: ListView(
padding: EdgeInsets.only(left: 10, right: 10), shrinkWrap: true,
decoration: BoxDecoration( children: [
color: ThemeColor.get(context).backgroundContainer,
borderRadius: BorderRadius.circular(10),
boxShadow: (Theme.of(context).brightness == Brightness.light)
? wsBoxShadow()
: null,
),
margin: EdgeInsets.only(top: 5, bottom: 5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
CheckoutStoreHeadingWidget(), CheckoutStoreHeadingWidget(),
CheckoutUserDetailsWidget( CheckoutUserDetailsWidget(
context: context, context: context,
@ -232,42 +234,105 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
resetState: () => setState(() {}), resetState: () => setState(() {}),
wooSignalApp: _wooSignalApp, wooSignalApp: _wooSignalApp,
), ),
]),
),
),
if (_wooSignalApp!.couponEnabled == true) if (_wooSignalApp!.couponEnabled == true)
CheckoutSelectCouponWidget( CheckoutSelectCouponWidget(
context: context, context: context,
checkoutSession: checkoutSession, checkoutSession: checkoutSession,
resetState: () => setState(() {}), resetState: () => setState(() {}),
), ),
Container(
decoration: BoxDecoration(
boxShadow: wsBoxShadow(),
color: Colors.white,
// borderRadius: BorderRadius.circular(16)
),
padding: EdgeInsets.symmetric(vertical: 16),
margin: EdgeInsets.only(top: 20),
child: Column(
children: [
Container(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Row(
children: [
Icon(Icons.receipt),
Padding(padding: EdgeInsets.only(right: 8),),
Text(trans("Order Summary")).fontWeightBold()
],
),
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
Divider( Padding(padding: EdgeInsets.only(top: 16)),
color: Colors.black12,
thickness: 1,
),
CheckoutSubtotal( CheckoutSubtotal(
title: trans("Subtotal"), title: trans("Subtotal"),
), ),
CheckoutCouponAmountWidget(checkoutSession: checkoutSession), CheckoutCouponAmountWidget(
checkoutSession: checkoutSession),
if (_wooSignalApp!.disableShipping != 1) if (_wooSignalApp!.disableShipping != 1)
CheckoutMetaLine( CheckoutMetaLine(
title: trans("Shipping fee"), title: trans("Shipping fee"),
amount: CheckoutSession.getInstance.shippingType == null amount: CheckoutSession
.getInstance.shippingType ==
null
? trans("Select shipping") ? trans("Select shipping")
: CheckoutSession.getInstance.shippingType! : CheckoutSession
.getInstance.shippingType!
.getTotal(withFormatting: true)), .getTotal(withFormatting: true)),
if (_taxRate != null) CheckoutTaxTotal(taxRate: _taxRate), if (_taxRate != null)
CheckoutTotal(title: trans("Total"), taxRate: _taxRate), CheckoutTaxTotal(taxRate: _taxRate),
Divider( Padding(padding: EdgeInsets.only(top: 8, left: 8, right: 8)),
color: Colors.black12, Padding(padding: EdgeInsets.symmetric(horizontal: 8), child: RichText(
thickness: 1, textAlign: TextAlign.left,
text: TextSpan(
text:
'By completing this order, I agree to all ',
style: Theme.of(context).textTheme.bodySmall!.copyWith(
fontSize: 12,
),
children: <TextSpan>[
TextSpan(
recognizer: TapGestureRecognizer()..onTap = _openTermsLink,
text: "terms & conditions",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: ThemeColor.get(context)
.primaryAccent,
fontSize: 12,
),
),
TextSpan(
text: ".",
style: Theme.of(context)
.textTheme
.bodySmall!
.copyWith(
color: Colors.black87,
fontSize: 12,
),
), ),
], ],
), ),
)),
],
),
],
),
)
],
),
),
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16)
),
child: Column(
children: [
CheckoutTotal(title: trans("Total"), taxRate: _taxRate),
Padding(padding: EdgeInsets.only(bottom: 8)),
PrimaryButton( PrimaryButton(
title: _isProcessingPayment title: _isProcessingPayment
? "${trans("PROCESSING")}..." ? "${trans("PROCESSING")}..."
@ -276,10 +341,16 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
), ),
], ],
), ),
)
],
),
),
), ),
); );
} }
_openTermsLink() => openBrowserTab(url: AppHelper.instance.appConfig?.appTermsLink ?? "");
_handleCheckout() async { _handleCheckout() async {
CheckoutSession checkoutSession = CheckoutSession.getInstance; CheckoutSession checkoutSession = CheckoutSession.getInstance;
if (checkoutSession.billingDetails!.billingAddress == null) { if (checkoutSession.billingDetails!.billingAddress == null) {
@ -368,8 +439,12 @@ class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
_isProcessingPayment = true; _isProcessingPayment = true;
}); });
try {
await checkoutSession.paymentType! await checkoutSession.paymentType!
.pay(context, state: this, taxRate: _taxRate); .pay(context, state: this, taxRate: _taxRate);
} on Exception catch (e) {
print(e.toString());
}
setState(() { setState(() {
_isProcessingPayment = false; _isProcessingPayment = false;

View File

@ -25,28 +25,35 @@ class CheckoutPaymentTypePage extends StatefulWidget {
_CheckoutPaymentTypePageState(); _CheckoutPaymentTypePageState();
} }
class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> { class _CheckoutPaymentTypePageState extends NyState<CheckoutPaymentTypePage> {
_CheckoutPaymentTypePageState(); _CheckoutPaymentTypePageState();
@override List<PaymentType?> _paymentTypes = [];
void initState() {
super.initState();
@override
init() async {
super.init();
_paymentTypes = await getPaymentTypes();
if (_paymentTypes.isEmpty &&
getEnv('APP_DEBUG', defaultValue: false) == true) {
NyLogger.info(
'You have no payment methods set. Visit the WooSignal dashboard (https://woosignal.com/dashboard) to set a payment method.');
}
// print(CheckoutSession.getInstance.paymentType?.name);
if (CheckoutSession.getInstance.paymentType == null) { if (CheckoutSession.getInstance.paymentType == null) {
if (getPaymentTypes().isNotEmpty) { if (_paymentTypes.isNotEmpty) {
CheckoutSession.getInstance.paymentType = getPaymentTypes().first; CheckoutSession.getInstance.paymentType = _paymentTypes.firstWhere(
(paymentType) => paymentType?.id == 20,
orElse: () => _paymentTypes.first);
} }
} }
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<PaymentType?> paymentTypes = getPaymentTypes();
if (paymentTypes.isEmpty &&
getEnv('APP_DEBUG', defaultValue: false) == true) {
NyLogger.info(
'You have no payment methods set. Visit the WooSignal dashboard (https://woosignal.com/dashboard) to set a payment method.');
}
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
appBar: AppBar( appBar: AppBar(
@ -76,7 +83,7 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: paymentTypes.isEmpty child: _paymentTypes.isEmpty
? Container( ? Container(
padding: EdgeInsets.only(top: 20), padding: EdgeInsets.only(top: 20),
child: Text( child: Text(
@ -86,11 +93,12 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
), ),
) )
: ListView.separated( : ListView.separated(
itemCount: paymentTypes.length, itemCount: _paymentTypes.length,
itemBuilder: itemBuilder:
(BuildContext context, int index) { (BuildContext context, int index) {
PaymentType paymentType = PaymentType paymentType =
paymentTypes[index]!; _paymentTypes[index]!;
return ListTile( return ListTile(
contentPadding: EdgeInsets.only( contentPadding: EdgeInsets.only(
top: 10, top: 10,
@ -114,9 +122,9 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
.textTheme .textTheme
.titleMedium), .titleMedium),
selected: true, selected: true,
trailing: (CheckoutSession trailing: (CheckoutSession.getInstance
.getInstance.paymentType == .paymentType?.id ==
paymentType paymentType.id
? Icon(Icons.check) ? Icon(Icons.check)
: null), : null),
onTap: () { onTap: () {

View File

@ -288,22 +288,10 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
), ),
), ),
selected: true, selected: true,
subtitle: FutureBuilder<String>( subtitle: NyFutureBuilder<String>(
future: _getShippingPrice(index), future: _getShippingPrice(index),
builder: (BuildContext context, child: (BuildContext context,
AsyncSnapshot<String> data) {
snapshot) {
switch (
snapshot.connectionState) {
case ConnectionState.none:
return Text('');
case ConnectionState.active:
case ConnectionState.waiting:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text('');
} else {
Map<String, dynamic> Map<String, dynamic>
shippingOption = shippingOption =
_wsShippingOptions[ _wsShippingOptions[
@ -324,7 +312,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
) )
: TextSpan( : TextSpan(
text: text:
"${trans("Price")}: ${formatStringCurrency(total: snapshot.data)}", "${trans("Price")}: ${formatStringCurrency(total: data)}",
)), )),
if (shippingOption[ if (shippingOption[
"min_amount"] != "min_amount"] !=
@ -342,8 +330,6 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
], ],
), ),
); );
}
}
}, },
), ),
trailing: (CheckoutSession.getInstance trailing: (CheckoutSession.getInstance

View File

@ -125,6 +125,14 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
ws_order.LineItems lineItem = _order!.lineItems![index]; ws_order.LineItems lineItem = _order!.lineItems![index];
return Container( return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
boxShadow: wsBoxShadow(),
color:
(Theme.of(context).brightness == Brightness.light)
? Colors.white
: null,
),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -161,10 +169,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
), ),
padding: EdgeInsets.all(16), padding: EdgeInsets.all(16),
margin: EdgeInsets.all(8), margin: EdgeInsets.all(8),
color: );
(Theme.of(context).brightness == Brightness.light)
? Colors.white
: null);
}), }),
), ),
Align( Align(

View File

@ -25,8 +25,8 @@ ThemeData darkTheme(ColorStyles darkColors) {
} }
} }
TextTheme darkTheme = getAppTextTheme( TextTheme darkTheme =
appFont, defaultTextTheme.merge(_textTheme(darkColors))); getAppTextTheme(appFont, defaultTextTheme.merge(_textTheme(darkColors)));
return ThemeData( return ThemeData(
primaryColor: darkColors.primaryContent, primaryColor: darkColors.primaryContent,
primaryColorDark: darkColors.primaryContent, primaryColorDark: darkColors.primaryContent,
@ -64,7 +64,8 @@ ThemeData darkTheme(ColorStyles darkColors) {
TextStyle(color: darkColors.bottomTabBarLabelSelected), TextStyle(color: darkColors.bottomTabBarLabelSelected),
selectedItemColor: darkColors.bottomTabBarLabelSelected, selectedItemColor: darkColors.bottomTabBarLabelSelected,
), ),
textTheme: darkTheme, colorScheme: ColorScheme.dark().copyWith(background: darkColors.background), textTheme: darkTheme,
colorScheme: ColorScheme.dark().copyWith(background: darkColors.background),
); );
} }
@ -81,6 +82,5 @@ TextTheme _textTheme(ColorStyles colors) {
titleLarge: TextStyle(color: primaryContent.withOpacity(0.8)), titleLarge: TextStyle(color: primaryContent.withOpacity(0.8)),
labelLarge: TextStyle(color: primaryContent.withOpacity(0.8)), labelLarge: TextStyle(color: primaryContent.withOpacity(0.8)),
bodySmall: TextStyle(color: primaryContent.withOpacity(0.8)), bodySmall: TextStyle(color: primaryContent.withOpacity(0.8)),
bodyMedium: TextStyle(color: primaryContent.withOpacity(0.8)) bodyMedium: TextStyle(color: primaryContent.withOpacity(0.8)));
);
} }

View File

@ -25,8 +25,8 @@ ThemeData lightTheme(ColorStyles lightColors) {
} }
} }
TextTheme lightTheme = getAppTextTheme( TextTheme lightTheme =
appFont, defaultTextTheme.merge(_textTheme(lightColors))); getAppTextTheme(appFont, defaultTextTheme.merge(_textTheme(lightColors)));
return ThemeData( return ThemeData(
primaryColor: lightColors.primaryContent, primaryColor: lightColors.primaryContent,
@ -66,7 +66,9 @@ ThemeData lightTheme(ColorStyles lightColors) {
TextStyle(color: lightColors.bottomTabBarLabelSelected), TextStyle(color: lightColors.bottomTabBarLabelSelected),
selectedItemColor: lightColors.bottomTabBarLabelSelected, selectedItemColor: lightColors.bottomTabBarLabelSelected,
), ),
textTheme: lightTheme, colorScheme: ColorScheme.light().copyWith(background: lightColors.background), textTheme: lightTheme,
colorScheme:
ColorScheme.light().copyWith(background: lightColors.background),
); );
} }

View File

@ -17,27 +17,17 @@ class AppVersionWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<PackageInfo>( return NyFutureBuilder<PackageInfo>(
future: PackageInfo.fromPlatform(), future: PackageInfo.fromPlatform(),
builder: (BuildContext context, AsyncSnapshot<PackageInfo> snapshot) { child: (BuildContext context, data) => Padding(
switch (snapshot.connectionState) { child: Text("${trans("Version")}: ${data.version}",
case ConnectionState.none:
return Text("");
case ConnectionState.active:
case ConnectionState.waiting:
return Text("");
case ConnectionState.done:
if (snapshot.hasError) return Text("");
return Padding(
child: Text("${trans("Version")}: ${snapshot.data!.version}",
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.bodyMedium! .bodyMedium!
.copyWith(fontWeight: FontWeight.w300)), .copyWith(fontWeight: FontWeight.w300)),
padding: EdgeInsets.only(top: 15, bottom: 15), padding: EdgeInsets.only(top: 15, bottom: 15),
); ),
} loading: SizedBox.shrink(),
},
); );
} }
} }

View File

@ -120,7 +120,8 @@ class WooSignalButton extends StatelessWidget {
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12.0), borderRadius: BorderRadius.circular(12.0),
), backgroundColor: bgColor, ),
backgroundColor: bgColor,
padding: EdgeInsets.all(8), padding: EdgeInsets.all(8),
elevation: 0, elevation: 0,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,

View File

@ -11,6 +11,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/app/models/cart.dart';
import 'package:flutter_app/app/models/cart_line_item.dart'; import 'package:flutter_app/app/models/cart_line_item.dart';
import 'package:nylo_framework/nylo_framework.dart';
class CartIconWidget extends StatefulWidget { class CartIconWidget extends StatefulWidget {
CartIconWidget({Key? key}) : super(key: key); CartIconWidget({Key? key}) : super(key: key);
@ -34,19 +35,12 @@ class _CartIconWidgetState extends State<CartIconWidget> {
), ),
Positioned.fill( Positioned.fill(
child: Align( child: Align(
child: FutureBuilder<List<CartLineItem>>( child: NyFutureBuilder<List<CartLineItem>>(
future: Cart.getInstance.getCart(), future: Cart.getInstance.getCart(),
builder: (BuildContext context, child: (BuildContext context,
AsyncSnapshot<List<CartLineItem>> snapshot) { data) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text("");
default:
if (snapshot.hasError) {
return Text("");
} else {
List<int?> cartItems = List<int?> cartItems =
snapshot.data!.map((e) => e.quantity).toList(); data.map((e) => e.quantity).toList();
String cartValue = "0"; String cartValue = "0";
if (cartItems.isNotEmpty) { if (cartItems.isNotEmpty) {
cartValue = cartItems cartValue = cartItems
@ -58,8 +52,6 @@ class _CartIconWidgetState extends State<CartIconWidget> {
style: Theme.of(context).textTheme.bodyMedium, style: Theme.of(context).textTheme.bodyMedium,
textAlign: TextAlign.center, textAlign: TextAlign.center,
); );
}
}
}, },
), ),
alignment: Alignment.topCenter, alignment: Alignment.topCenter,

View File

@ -12,7 +12,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_app/app/models/cart.dart'; import 'package:flutter_app/app/models/cart.dart';
import 'package:flutter_app/app/models/checkout_session.dart'; import 'package:flutter_app/app/models/checkout_session.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/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';
@ -24,29 +23,18 @@ class CheckoutCouponAmountWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FutureBuilder<String>(
future: Cart.getInstance.couponDiscountAmount(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return AppLoaderWidget();
default:
if (snapshot.hasError) {
return Text("");
} else {
if (checkoutSession.coupon == null) { if (checkoutSession.coupon == null) {
return SizedBox.shrink(); return SizedBox.shrink();
} }
return Padding( return NyFutureBuilder<String>(
future: Cart.getInstance.couponDiscountAmount(),
child: (BuildContext context, data) => Padding(
child: CheckoutMetaLine( child: CheckoutMetaLine(
title: "${trans('Coupon')}: ${checkoutSession.coupon!.code}", title: "${trans('Coupon')}: ${checkoutSession.coupon?.code}",
amount: "-" + formatStringCurrency(total: snapshot.data), amount: "-" + formatStringCurrency(total: data),
), ),
padding: EdgeInsets.only(bottom: 0, top: 0), padding: EdgeInsets.only(bottom: 0, top: 0),
); ),
}
}
},
); );
} }
} }

View File

@ -44,7 +44,7 @@ class CheckoutShippingTypeWidget extends StatelessWidget {
? checkoutSession.shippingType!.getTitle() ? checkoutSession.shippingType!.getTitle()
: trans("Select a shipping option"), : trans("Select a shipping option"),
action: _actionSelectShipping, action: _actionSelectShipping,
showBorderBottom: false, showBorderBottom: true,
); );
} }

View File

@ -18,9 +18,6 @@ class CheckoutStoreHeadingWidget extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
boxShadow: (Theme.of(context).brightness == Brightness.light)
? wsBoxShadow(blurRadius: 10)
: null,
color: Colors.transparent, color: Colors.transparent,
), ),
padding: EdgeInsets.all(2), padding: EdgeInsets.all(2),

View File

@ -138,7 +138,7 @@ class _CompoHomeWidgetState extends State<CompoHomeWidget> {
children: [ children: [
Expanded( Expanded(
child: AutoSizeText( child: AutoSizeText(
catProds.key.name!, parseHtmlString(catProds.key.name!),
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.titleMedium! .titleMedium!

View File

@ -146,7 +146,9 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
Flexible( Flexible(
child: Text( child: Text(
trans("Our selection of new items"), trans("Our selection of new items"),
style: Theme.of(context).textTheme.headlineMedium, style: Theme.of(context)
.textTheme
.headlineMedium,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -40,8 +40,10 @@ class ProductDetailDescriptionWidget extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Text( Text(
trans("Description"), trans("Description"),
style: style: Theme.of(context)
Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 18), .textTheme
.bodySmall!
.copyWith(fontSize: 18),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
if (product!.shortDescription!.isNotEmpty && if (product!.shortDescription!.isNotEmpty &&

View File

@ -43,8 +43,10 @@ class ProductDetailRelatedProductsWidget extends StatelessWidget {
children: <Widget>[ children: <Widget>[
Text( Text(
trans("Related products"), trans("Related products"),
style: style: Theme.of(context)
Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 18), .textTheme
.bodySmall!
.copyWith(fontSize: 18),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],

View File

@ -65,8 +65,10 @@ class _ProductDetailUpsellWidgetState extends State<ProductDetailUpsellWidget> {
children: <Widget>[ children: <Widget>[
Text( Text(
trans("${trans('You may also like')}"), trans("${trans('You may also like')}"),
style: style: Theme.of(context)
Theme.of(context).textTheme.bodySmall!.copyWith(fontSize: 18), .textTheme
.bodySmall!
.copyWith(fontSize: 18),
textAlign: TextAlign.left, textAlign: TextAlign.left,
), ),
], ],

View File

@ -16,7 +16,6 @@ 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/checkout_session.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/resources/widgets/app_loader_widget.dart';
import 'package:flutter_app/resources/widgets/cached_image_widget.dart'; import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart'; import 'package:flutter_app/resources/widgets/no_results_for_products_widget.dart';
import 'package:flutter_app/resources/widgets/top_nav_widget.dart'; import 'package:flutter_app/resources/widgets/top_nav_widget.dart';
@ -142,6 +141,7 @@ class CheckoutRowLine extends StatelessWidget {
Widget build(BuildContext context) => Flexible( Widget build(BuildContext context) => Flexible(
child: InkWell( child: InkWell(
child: Container( child: Container(
height: 125,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@ -171,7 +171,8 @@ class CheckoutRowLine extends StatelessWidget {
child: Container( child: Container(
child: Text( child: Text(
leadTitle!, leadTitle!,
style: Theme.of(context).textTheme.titleMedium, style:
Theme.of(context).textTheme.titleMedium,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
softWrap: false, softWrap: false,
@ -227,14 +228,13 @@ class TextEditingRow extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
if (heading != null)
Flexible( Flexible(
child: Padding( child: Padding(
child: AutoSizeText( child: AutoSizeText(
heading!, heading!,
style: Theme.of(context) style: Theme.of(context).textTheme.bodyLarge!.copyWith(
.textTheme color: ThemeColor.get(context).primaryContent),
.bodyLarge!
.copyWith(color: ThemeColor.get(context).primaryContent),
), ),
padding: EdgeInsets.only(bottom: 2), padding: EdgeInsets.only(bottom: 2),
), ),
@ -253,7 +253,7 @@ class TextEditingRow extends StatelessWidget {
], ],
), ),
padding: EdgeInsets.all(2), padding: EdgeInsets.all(2),
height: 78, height: heading == null ? 50 : 78,
); );
} }
@ -263,14 +263,16 @@ class CheckoutMetaLine extends StatelessWidget {
final String? title, amount; final String? title, amount;
@override @override
Widget build(BuildContext context) => Row( Widget build(BuildContext context) => Container(
padding: EdgeInsets.symmetric(horizontal: 8),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[ children: <Widget>[
Flexible( Flexible(
child: Container( child: Container(
child: AutoSizeText(title!, child: AutoSizeText(title!,
style: Theme.of(context).textTheme.bodyMedium), style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontWeight: FontWeight.bold)),
), ),
flex: 3, flex: 3,
), ),
@ -282,6 +284,7 @@ class CheckoutMetaLine extends StatelessWidget {
flex: 3, flex: 3,
) )
], ],
),
); );
} }
@ -507,24 +510,14 @@ class CheckoutTotal extends StatelessWidget {
final TaxRate? taxRate; final TaxRate? taxRate;
@override @override
Widget build(BuildContext context) => FutureBuilder<String>( Widget build(BuildContext context) => NyFutureBuilder<String>(
future: CheckoutSession.getInstance future: CheckoutSession.getInstance
.total(withFormat: true, taxRate: taxRate), .total(withFormat: true, taxRate: taxRate),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) { child: (BuildContext context, data) => Padding(
switch (snapshot.connectionState) { child: CheckoutMetaLine(title: title, amount: data),
case ConnectionState.waiting:
return AppLoaderWidget();
default:
if (snapshot.hasError) {
return Text("");
} else {
return Padding(
child: CheckoutMetaLine(title: title, amount: snapshot.data),
padding: EdgeInsets.only(bottom: 0, top: 15), padding: EdgeInsets.only(bottom: 0, top: 15),
); ),
} loading: SizedBox.shrink(),
}
},
); );
} }
@ -534,28 +527,17 @@ class CheckoutTaxTotal extends StatelessWidget {
final TaxRate? taxRate; final TaxRate? taxRate;
@override @override
Widget build(BuildContext context) => FutureBuilder<String>( Widget build(BuildContext context) => NyFutureBuilder<String>(
future: Cart.getInstance.taxAmount(taxRate), future: Cart.getInstance.taxAmount(taxRate),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) { child: (BuildContext context, data) => (data == "0"
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return AppLoaderWidget();
default:
if (snapshot.hasError) {
return Text("");
} else {
return (snapshot.data == "0"
? Container() ? Container()
: Padding( : Padding(
child: CheckoutMetaLine( child: CheckoutMetaLine(
title: trans("Tax"), title: trans("Tax"),
amount: formatStringCurrency(total: snapshot.data), amount: formatStringCurrency(total: data),
), ),
padding: EdgeInsets.only(bottom: 0, top: 0), padding: EdgeInsets.only(bottom: 0, top: 0),
)); )),
}
}
},
); );
} }
@ -565,26 +547,16 @@ class CheckoutSubtotal extends StatelessWidget {
final String? title; final String? title;
@override @override
Widget build(BuildContext context) => FutureBuilder<String>( Widget build(BuildContext context) => NyFutureBuilder<String>(
future: Cart.getInstance.getSubtotal(withFormat: true), future: Cart.getInstance.getSubtotal(withFormat: true),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) { child: (BuildContext context, data) => Padding(
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return AppLoaderWidget();
default:
if (snapshot.hasError) {
return Text("");
} else {
return Padding(
child: CheckoutMetaLine( child: CheckoutMetaLine(
title: title, title: title,
amount: snapshot.data, amount: data,
), ),
padding: EdgeInsets.only(bottom: 0, top: 0), padding: EdgeInsets.only(bottom: 0, top: 0),
); ),
} loading: SizedBox.shrink(),
}
},
); );
} }

View File

@ -106,4 +106,4 @@ appRouter() => nyRoutes((router) {
router.route("/account-shipping-details", router.route("/account-shipping-details",
(context) => AccountShippingDetailsPage()); (context) => AccountShippingDetailsPage());
}); });

View File

@ -205,10 +205,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: dio name: dio
sha256: "9fdbf71baeb250fc9da847f6cb2052196f62c19906a3657adfc18631a667d316" sha256: "3709d74615bba5e443eb141f6a7f4bcc4788f8fae6f743edadfb79c2a8e6287e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.0.0" version: "5.0.1"
eventify: eventify:
dependency: transitive dependency: transitive
description: description:
@ -330,10 +330,10 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_launcher_icons name: flutter_launcher_icons
sha256: ce0e501cfc258907842238e4ca605e74b7fd1cdf04b3b43e86c43f3e40a1592c sha256: "02dcaf49d405f652b7160e882bacfc02cb497041bb2eab2a49b1c393cf9aac12"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.11.0" version: "0.12.0"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -529,10 +529,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image name: image
sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" sha256: "483a389d6ccb292b570c31b3a193779b1b0178e7eb571986d9a49904b6861227"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.0" version: "4.0.15"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
@ -625,18 +625,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: nylo_framework name: nylo_framework
sha256: "3cc0379e73a56b2f2864f5fd850fdc582fc1908c5c8025e96a3ae7dbd3efa2f2" sha256: "9ed065fdd5570de42c5e96f6269740de7b568593c2af78584cdc38572cf52ebe"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.1.3" version: "4.1.4"
nylo_support: nylo_support:
dependency: transitive dependency: transitive
description: description:
name: nylo_support name: nylo_support
sha256: b662441b463a1e68c1642cd2711af026f66fb2122ecc1ae331fc8300a7bc4be7 sha256: e710481287d8c4db42b51e10a1a726cc6da7239fdd334e204eadda635a9766ff
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.3.0" version: "4.3.1"
octo_image: octo_image:
dependency: transitive dependency: transitive
description: description:
@ -865,10 +865,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences name: shared_preferences
sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" sha256: ee6257848f822b8481691f20c3e6d2bfee2e9eccb2a3d249907fcfb198c55b41
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.17" version: "2.0.18"
shared_preferences_android: shared_preferences_android:
dependency: transitive dependency: transitive
description: description:
@ -1182,10 +1182,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: woosignal name: woosignal
sha256: "0236c5a4568d39140be544b44cbabd9932a425f28285694e99d6daec85809fef" sha256: "888629274da9083aca94102b45e963c92f820c8d6b8154eebf0424adfc4089c6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.3" version: "3.3.0"
wp_json_api: wp_json_api:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1219,5 +1219,5 @@ packages:
source: hosted source: hosted
version: "3.1.1" version: "3.1.1"
sdks: sdks:
dart: ">=2.19.0 <4.0.0" dart: ">=2.19.0 <3.0.0"
flutter: ">=3.7.0-0" flutter: ">=3.7.0-0"

View File

@ -1,7 +1,7 @@
# Official WooSignal App Template for WooCommerce # Official WooSignal App Template for WooCommerce
# Label StoreMax # Label StoreMax
# Version: 6.4.1 # Version: 6.5.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
@ -28,8 +28,8 @@ dependencies:
google_fonts: ^4.0.3 google_fonts: ^4.0.3
analyzer: ^4.2.0 analyzer: ^4.2.0
intl: ^0.17.0 intl: ^0.17.0
nylo_framework: ^4.1.3 nylo_framework: ^4.1.4
woosignal: ^3.2.3 woosignal: ^3.3.0
flutter_stripe: ^8.0.0+1 flutter_stripe: ^8.0.0+1
wp_json_api: ^3.3.2 wp_json_api: ^3.3.2
cached_network_image: ^3.2.3 cached_network_image: ^3.2.3
@ -64,7 +64,7 @@ dependencies:
collection: ^1.15.0 collection: ^1.15.0
dev_dependencies: dev_dependencies:
flutter_launcher_icons: ^0.11.0 flutter_launcher_icons: ^0.12.0
lints: ^2.0.0 lints: ^2.0.0
flutter_test: flutter_test:
sdk: flutter sdk: flutter

View File

@ -4,7 +4,7 @@
# WooCommerce App: Label StoreMax # WooCommerce App: Label StoreMax
### Label StoreMax - v6.3.1 ### Label StoreMax - v6.5.0
[Official WooSignal WooCommerce App](https://woosignal.com) [Official WooSignal WooCommerce App](https://woosignal.com)