Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b279212a95 | |||
| ed1a9d70fb | |||
| 4f11e7bb00 | |||
|
|
2f9118085c | ||
|
|
c620aa71cc | ||
|
|
63244606be | ||
|
|
3b350dbefb | ||
|
|
6deab507d8 | ||
|
|
a2698557ea | ||
|
|
fedd76fc67 | ||
|
|
456f313056 | ||
|
|
f67f486838 | ||
|
|
688ce6bec8 | ||
|
|
05a7aedf54 | ||
|
|
adc32e730d | ||
|
|
f25a5c7a18 | ||
|
|
54f7689e40 | ||
|
|
ce9216ad94 | ||
|
|
da2301a2af | ||
|
|
004c146967 |
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@ -1,9 +1,9 @@
|
|||||||
# *<! ------ App ------!>*
|
# *<! ------ App ------!>*
|
||||||
|
|
||||||
APP_NAME="MyApp"
|
APP_NAME="Raster"
|
||||||
APP_ENV="local"
|
APP_ENV="local"
|
||||||
APP_DEBUG="true"
|
APP_DEBUG="true"
|
||||||
APP_URL="https://mywoocommercestore.com"
|
APP_URL="https://rasterdoo.com"
|
||||||
|
|
||||||
ASSET_PATH_PUBLIC="public/assets/"
|
ASSET_PATH_PUBLIC="public/assets/"
|
||||||
ASSET_PATH_IMAGES="public/assets/images"
|
ASSET_PATH_IMAGES="public/assets/images"
|
||||||
@ -14,12 +14,12 @@ DARK_THEME_ID="default_dark_theme"
|
|||||||
|
|
||||||
# *<! ------ Language ------!>*
|
# *<! ------ Language ------!>*
|
||||||
|
|
||||||
DEFAULT_LOCALE=null
|
DEFAULT_LOCALE="en"
|
||||||
# supports: "en" (English), "es" (Spanish), "fr" (French), "hi" (Hindi), "it" (Italian), "pt" (Portuguese) or "zh" (Simplified Chinese)
|
# supports: "en" (English), "es" (Spanish), "fr" (French), "hi" (Hindi), "it" (Italian), "pt" (Portuguese) or "zh" (Simplified Chinese)
|
||||||
|
|
||||||
# *<! ------ WooSignal Config ------!>*
|
# *<! ------ WooSignal Config ------!>*
|
||||||
|
|
||||||
APP_KEY="your app key"
|
APP_KEY="app_50818d11780aaba6b545076dea5b90"
|
||||||
# App key from WooSignal link: https://woosignal.com/dashboard
|
# App key from WooSignal link: https://woosignal.com/dashboard
|
||||||
|
|
||||||
# *<! ------ STRIPE (OPTIONAL) ------!>*
|
# *<! ------ STRIPE (OPTIONAL) ------!>*
|
||||||
@ -50,3 +50,9 @@ 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"
|
||||||
|
FCM_ENABLED=null
|
||||||
|
|
||||||
|
ENCRYPT_KEY=null
|
||||||
|
ENCRYPT_SECRET=null
|
||||||
@ -1,3 +1,66 @@
|
|||||||
|
## [6.10.1] - 2023-08-28
|
||||||
|
|
||||||
|
* Refactor project for Nylo 5.x.
|
||||||
|
* Fix AndroidManifest splash screen
|
||||||
|
* Pubspec.yaml dependency updates
|
||||||
|
|
||||||
|
## [6.10.0] - 2023-08-21
|
||||||
|
|
||||||
|
* Small refactor to project
|
||||||
|
* Pubspec.yaml dependency updates
|
||||||
|
|
||||||
|
## [6.9.0] - 2023-07-13
|
||||||
|
|
||||||
|
* Pull firebase config via woosignal api
|
||||||
|
* New encrypt key and secret added to .env
|
||||||
|
* fix fetchRelated to return "publish" products
|
||||||
|
* Pubspec.yaml dependency updates
|
||||||
|
|
||||||
|
## [6.8.2] - 2023-07-04
|
||||||
|
|
||||||
|
* Update gradle + kotlin versions.
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.8.1] - 2023-07-03
|
||||||
|
|
||||||
|
* Fix auth bug.
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.8.0] - 2023-07-03
|
||||||
|
|
||||||
|
* UI fixes.
|
||||||
|
* Fix price on coupon page error alerts.
|
||||||
|
* Fix issue where IOS builds were not using the correct build version.
|
||||||
|
* Small refactor to the project.
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.7.0] - 2023-06-20
|
||||||
|
|
||||||
|
* Refactor project for Nylo 5.x.
|
||||||
|
* New Firebase provider for FCM.
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.6.2] - 2023-06-14
|
||||||
|
|
||||||
|
* Page bug fixes
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.6.1] - 2023-05-28
|
||||||
|
|
||||||
|
* Refactor widgets + bug fixes
|
||||||
|
* Refactor extensions.dart
|
||||||
|
* Pubspec.yaml dependency updates.
|
||||||
|
|
||||||
|
## [6.6.0] - 2023-05-18
|
||||||
|
|
||||||
|
* Nylo v5.0.0 migration
|
||||||
|
* Refactor project
|
||||||
|
* Flutter v3.10.0 compatibility
|
||||||
|
|
||||||
|
## [6.5.1] - 2023-03-04
|
||||||
|
|
||||||
|
* New translation added.
|
||||||
|
|
||||||
## [6.5.0] - 2023-03-04
|
## [6.5.0] - 2023-03-04
|
||||||
|
|
||||||
* When making payments via Stripe, it will now save the card for later.
|
* When making payments via Stripe, it will now save the card for later.
|
||||||
@ -12,7 +75,7 @@
|
|||||||
* Fix the ThemeColor.get helper method to support ColorStyles.
|
* Fix the ThemeColor.get helper method to support ColorStyles.
|
||||||
* Pubspec.yaml dependency updates
|
* Pubspec.yaml dependency updates
|
||||||
|
|
||||||
* ## [6.4.0] - 2023-01-06
|
## [6.4.0] - 2023-01-06
|
||||||
|
|
||||||
* Upgrade to Nylo v4.0.0
|
* Upgrade to Nylo v4.0.0
|
||||||
* Update copyright
|
* Update copyright
|
||||||
|
|||||||
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
# WooCommerce App: Label StoreMax
|
# WooCommerce App: Label StoreMax
|
||||||
|
|
||||||
### Label StoreMax - v6.5.0
|
### Label StoreMax
|
||||||
|
|
||||||
|
|
||||||
[Official WooSignal WooCommerce App](https://woosignal.com)
|
[Official WooSignal WooCommerce App](https://woosignal.com)
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:label="Label StoreMax"
|
android:label="Raster Knjizara"
|
||||||
android:icon="@mipmap/launcher_icon">
|
android:icon="@mipmap/launcher_icon">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@ -31,15 +31,7 @@
|
|||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/>
|
/>
|
||||||
<!-- Displays an Android View that continues showing the launch screen
|
|
||||||
Drawable until Flutter paints its first frame, then this splash
|
|
||||||
screen fades out. A splash screen is useful to avoid any visual
|
|
||||||
gap between the end of Android's launch screen and the painting of
|
|
||||||
Flutter's first frame. -->
|
|
||||||
<meta-data
|
|
||||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
|
||||||
android:resource="@drawable/launch_background"
|
|
||||||
/>
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 8.8 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 12 KiB |
@ -1,12 +1,12 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.6.10'
|
ext.kotlin_version = '1.7.10'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:7.0.1'
|
classpath 'com.android.tools.build:gradle:7.3.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -26,6 +26,6 @@ subprojects {
|
|||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
|
||||||
task clean(type: Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
|
||||||
|
|||||||
49
LabelStoreMax/ios/Podfile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Uncomment this line to define a global platform for your project
|
||||||
|
# platform :ios, '11.0'
|
||||||
|
|
||||||
|
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||||
|
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||||
|
|
||||||
|
project 'Runner', {
|
||||||
|
'Debug' => :debug,
|
||||||
|
'Profile' => :release,
|
||||||
|
'Release' => :release,
|
||||||
|
}
|
||||||
|
|
||||||
|
def flutter_root
|
||||||
|
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||||
|
unless File.exist?(generated_xcode_build_settings_path)
|
||||||
|
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||||
|
end
|
||||||
|
|
||||||
|
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||||
|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||||
|
return matches[1].strip if matches
|
||||||
|
end
|
||||||
|
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||||
|
end
|
||||||
|
|
||||||
|
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||||
|
|
||||||
|
flutter_ios_podfile_setup
|
||||||
|
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
|
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
flutter_additional_ios_build_settings(target)
|
||||||
|
end
|
||||||
|
|
||||||
|
installer.generated_projects.each do |project|
|
||||||
|
project.targets.each do |target|
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -155,7 +155,7 @@
|
|||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1300;
|
LastUpgradeCheck = 1430;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
@ -204,6 +204,7 @@
|
|||||||
files = (
|
files = (
|
||||||
);
|
);
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
|
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||||
);
|
);
|
||||||
name = "Thin Binary";
|
name = "Thin Binary";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
@ -372,6 +373,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@ -510,6 +512,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
@ -542,6 +545,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 1.0.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
PRODUCT_BUNDLE_IDENTIFIER = com.flutter.app;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1300"
|
LastUpgradeVersion = "1430"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@ -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>
|
||||||
@ -15,13 +17,9 @@
|
|||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
<string>$(MARKETING_VERSION)</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>
|
||||||
@ -36,14 +34,20 @@
|
|||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
<string>$(CURRENT_PROJECT_VERSION)</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>
|
||||||
|
|||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Bestellübersicht",
|
||||||
|
"By completing this order, I agree to all": "Mit Abschluss dieser Bestellung stimme ich allem zu"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Order Summary",
|
||||||
|
"By completing this order, I agree to all": "By completing this order, I agree to all"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Resumen del pedido",
|
||||||
|
"By completing this order, I agree to all": "Al completar este pedido, acepto todos"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Récapitulatif de la commande",
|
||||||
|
"By completing this order, I agree to all": "En remplissant cette commande, j'accepte toutes"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "aadesh saaraansh",
|
||||||
|
"By completing this order, I agree to all": "is aadesh ko poora karake, main sabhee ke lie sahamat hoon"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Riepilogo dell'ordine",
|
||||||
|
"By completing this order, I agree to all": "Completando questo ordine, accetto tutto"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Overzicht van de bestelling",
|
||||||
|
"By completing this order, I agree to all": "Door deze bestelling te voltooien, ga ik akkoord met alles"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Resumo do pedido",
|
||||||
|
"By completing this order, I agree to all": "Ao concluir este pedido, concordo com todos"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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"
|
"Order Summary": "Sipariş özeti",
|
||||||
|
"By completing this order, I agree to all": "Bu siparişi tamamlayarak, tümünü kabul ediyorum"
|
||||||
}
|
}
|
||||||
@ -228,5 +228,6 @@
|
|||||||
"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": "订单摘要"
|
"Order Summary": "订单摘要",
|
||||||
|
"By completing this order, I agree to all": "通过完成此订单,我同意所有"
|
||||||
}
|
}
|
||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart';
|
import 'package:woosignal/models/response/product_category.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductCategorySearchLoaderController
|
class ProductCategorySearchLoaderController
|
||||||
extends WooSignalApiLoaderController<Product> {
|
extends WooSignalApiLoaderController<Product> {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import 'package:flutter_app/app/models/cart_line_item.dart';
|
|||||||
import 'package:flutter_app/bootstrap/enums/wishlist_action_enums.dart';
|
import 'package:flutter_app/bootstrap/enums/wishlist_action_enums.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';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import 'package:woosignal/models/response/product_variation.dart'
|
import 'package:woosignal/models/response/product_variation.dart'
|
||||||
as ws_product_variation;
|
as ws_product_variation;
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductLoaderController extends WooSignalApiLoaderController<Product> {
|
class ProductLoaderController extends WooSignalApiLoaderController<Product> {
|
||||||
ProductLoaderController();
|
ProductLoaderController();
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||||
import 'package:woosignal/models/response/product_review.dart';
|
import 'package:woosignal/models/response/product_review.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductReviewsLoaderController
|
class ProductReviewsLoaderController
|
||||||
extends WooSignalApiLoaderController<ProductReview> {
|
extends WooSignalApiLoaderController<ProductReview> {
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/woosignal_api_loader_controller.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductSearchLoaderController
|
class ProductSearchLoaderController
|
||||||
extends WooSignalApiLoaderController<Product> {
|
extends WooSignalApiLoaderController<Product> {
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
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';
|
||||||
import 'package:woosignal/models/response/product_variation.dart';
|
import 'package:woosignal/models/response/product_variation.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
|
|
||||||
class CartLineItem {
|
class CartLineItem {
|
||||||
String? name;
|
String? name;
|
||||||
|
|||||||
@ -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
|
User.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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ class BearerAuthInterceptor extends Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onError(DioError err, ErrorInterceptorHandler handler) {
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
||||||
handler.next(err);
|
handler.next(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class LoggingInterceptor extends Interceptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onError(DioError err, ErrorInterceptorHandler handler) {
|
void onError(DioException err, ErrorInterceptorHandler handler) {
|
||||||
print(
|
print(
|
||||||
'ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
|
'ERROR[${err.response?.statusCode}] => PATH: ${err.requestOptions.path}');
|
||||||
handler.next(err);
|
handler.next(err);
|
||||||
|
|||||||
@ -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';
|
||||||
@ -20,31 +22,10 @@ class AppProvider implements NyProvider {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await WooSignal.instance
|
await WooSignal.instance
|
||||||
.init(appKey: getEnv('APP_KEY'), debugMode: getEnv('APP_DEBUG'));
|
.init(appKey: getEnv('APP_KEY'), debugMode: getEnv('APP_DEBUG'),
|
||||||
|
encryptKey: getEnv('ENCRYPT_KEY', defaultValue: null),
|
||||||
// Notifications
|
encryptSecret: getEnv('ENCRYPT_SECRET', defaultValue: null)
|
||||||
/// await Firebase.initializeApp(
|
);
|
||||||
/// options: DefaultFirebaseOptions.currentPlatform,
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// FirebaseMessaging messaging = FirebaseMessaging.instance;
|
|
||||||
///
|
|
||||||
/// NotificationSettings settings = await messaging.requestPermission(
|
|
||||||
/// alert: true,
|
|
||||||
/// announcement: false,
|
|
||||||
/// badge: true,
|
|
||||||
/// carPlay: false,
|
|
||||||
/// criticalAlert: false,
|
|
||||||
/// provisional: false,
|
|
||||||
/// sound: true,
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// if (settings.authorizationStatus == AuthorizationStatus.authorized) {
|
|
||||||
/// String? token = await messaging.getToken();
|
|
||||||
/// if (token != null) {
|
|
||||||
/// WooSignal.instance.setFcmToken(token);
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
|
|
||||||
AppHelper.instance.appConfig = WooSignalApp();
|
AppHelper.instance.appConfig = WooSignalApp();
|
||||||
AppHelper.instance.appConfig!.themeFont = "Poppins";
|
AppHelper.instance.appConfig!.themeFont = "Poppins";
|
||||||
@ -68,7 +49,7 @@ class AppProvider implements NyProvider {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// WooSignal Setup
|
// WooSignal Setup
|
||||||
WooSignalApp? wooSignalApp = await (appWooSignal((api) => api.getApp()));
|
WooSignalApp? wooSignalApp = await (appWooSignal((api) => api.getApp(encrypted: shouldEncrypt())));
|
||||||
Locale locale = Locale('en');
|
Locale locale = Locale('en');
|
||||||
|
|
||||||
if (wooSignalApp != null) {
|
if (wooSignalApp != null) {
|
||||||
@ -112,12 +93,15 @@ 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.toastNotification = getToastNotificationWidget;
|
||||||
|
|
||||||
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 {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
49
LabelStoreMax/lib/app/providers/firebase_provider.dart
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
|
import 'package:flutter_app/firebase_options.dart';
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
import 'package:woosignal/woosignal.dart';
|
||||||
|
|
||||||
|
class FirebaseProvider implements NyProvider {
|
||||||
|
|
||||||
|
@override
|
||||||
|
boot(Nylo nylo) async {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
afterBoot(Nylo nylo) async {
|
||||||
|
bool? firebaseFcmIsEnabled = AppHelper.instance.appConfig?.firebaseFcmIsEnabled;
|
||||||
|
if (firebaseFcmIsEnabled == null) {
|
||||||
|
firebaseFcmIsEnabled = getEnv('FCM_ENABLED', defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firebaseFcmIsEnabled != true) return;
|
||||||
|
|
||||||
|
await Firebase.initializeApp(
|
||||||
|
options: DefaultFirebaseOptions.currentPlatform,
|
||||||
|
);
|
||||||
|
|
||||||
|
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
||||||
|
NotificationSettings settings = await messaging.requestPermission(
|
||||||
|
alert: true,
|
||||||
|
announcement: false,
|
||||||
|
badge: true,
|
||||||
|
carPlay: false,
|
||||||
|
criticalAlert: false,
|
||||||
|
provisional: false,
|
||||||
|
sound: true,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (settings.authorizationStatus != AuthorizationStatus.authorized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String? token = await messaging.getToken();
|
||||||
|
if (token != null) {
|
||||||
|
WooSignal.instance.setFcmToken(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -33,16 +33,16 @@ razorPay(context,
|
|||||||
Order? order = await appWooSignal((api) => api.createOrder(orderWC));
|
Order? order = await appWooSignal((api) => api.createOrder(orderWC));
|
||||||
|
|
||||||
if (order != null) {
|
if (order != null) {
|
||||||
Cart.getInstance.clear();
|
|
||||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
|
||||||
} else {
|
|
||||||
showToastNotification(
|
showToastNotification(
|
||||||
context,
|
context,
|
||||||
title: "Error".tr(),
|
title: "Error".tr(),
|
||||||
description: trans("Something went wrong, please contact our store"),
|
description: trans("Something went wrong, please contact our store"),
|
||||||
);
|
);
|
||||||
state.reloadState(showLoader: false);
|
state.reloadState(showLoader: false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
Cart.getInstance.clear();
|
||||||
|
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||||
});
|
});
|
||||||
|
|
||||||
razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) {
|
razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, (PaymentFailureResponse response) {
|
||||||
|
|||||||
@ -118,7 +118,7 @@ stripePay(context,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
routeTo('/checkout-status', navigationType: NavigationType.pushAndForgetAll, data: order);
|
||||||
} on StripeException catch (e) {
|
} on StripeException catch (e) {
|
||||||
if (getEnv('APP_DEBUG', defaultValue: true)) {
|
if (getEnv('APP_DEBUG', defaultValue: true)) {
|
||||||
NyLogger.error(e.error.message!);
|
NyLogger.error(e.error.message!);
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ 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: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/shared_pref/sp_auth.dart';
|
import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart';
|
||||||
import 'package:woosignal/models/payload/order_wc.dart';
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
@ -51,7 +52,7 @@ Future<OrderWC> buildOrderWC({TaxRate? taxRate, bool markPaid = true}) async {
|
|||||||
tmpLineItem.variationId = cartItem.variationId;
|
tmpLineItem.variationId = cartItem.variationId;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmpLineItem.subtotal = cartItem.subtotal;
|
tmpLineItem.subtotal = (parseWcPrice(cartItem.subtotal) * parseWcPrice(cartItem.quantity.toString())).toString();
|
||||||
lineItems.add(tmpLineItem);
|
lineItems.add(tmpLineItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,81 +1,9 @@
|
|||||||
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/themes/styles/color_styles.dart';
|
import 'package:flutter_app/resources/themes/styles/color_styles.dart';
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
extension NyText on Text {
|
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].
|
/// Sets the color from your [ColorStyles] or [Color].
|
||||||
Text setColor(
|
Text setColor(
|
||||||
BuildContext context, Color Function(ColorStyles color) newColor,
|
BuildContext context, Color Function(ColorStyles color) newColor,
|
||||||
@ -84,57 +12,38 @@ extension NyText on Text {
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: newColor(ThemeColor.get(context, themeId: themeId))));
|
color: newColor(ThemeColor.get(context, themeId: themeId))));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Aligns text to the left.
|
/// Check if the [Product] is new.
|
||||||
Text alignLeft() {
|
extension DateTimeExtension on DateTime? {
|
||||||
return copyWith(textAlign: TextAlign.left);
|
bool? isAfterOrEqualTo(DateTime dateTime) {
|
||||||
|
final date = this;
|
||||||
|
if (date != null) {
|
||||||
|
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||||
|
return isAtSameMomentAs | date.isAfter(dateTime);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aligns text to the right.
|
bool? isBeforeOrEqualTo(DateTime dateTime) {
|
||||||
Text alignRight() {
|
final date = this;
|
||||||
return copyWith(textAlign: TextAlign.right);
|
if (date != null) {
|
||||||
|
final isAtSameMomentAs = dateTime.isAtSameMomentAs(date);
|
||||||
|
return isAtSameMomentAs | date.isBefore(dateTime);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Aligns text to the center.
|
bool? isBetween(
|
||||||
Text alignCenter() {
|
DateTime fromDateTime,
|
||||||
return copyWith(textAlign: TextAlign.center);
|
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;
|
||||||
/// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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';
|
||||||
@ -37,7 +38,7 @@ import 'package:money_formatter/money_formatter.dart';
|
|||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:status_alert/status_alert.dart';
|
import 'package:status_alert/status_alert.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
import 'package:woosignal/woosignal.dart';
|
import 'package:woosignal/woosignal.dart';
|
||||||
import 'package:wp_json_api/models/responses/wp_user_info_response.dart';
|
import 'package:wp_json_api/models/responses/wp_user_info_response.dart';
|
||||||
@ -45,9 +46,9 @@ 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) 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,27 @@ 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldEncrypt() {
|
||||||
|
String? encryptKey = getEnv('ENCRYPT_KEY', defaultValue: "");
|
||||||
|
if (encryptKey == null || encryptKey == "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String? encryptSecret = getEnv('ENCRYPT_KEY', defaultValue: "");
|
||||||
|
if (encryptSecret == null || encryptSecret == "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter_app/app/models/user.dart';
|
||||||
import 'package:flutter_app/app/networking/api_service.dart';
|
import 'package:flutter_app/app/networking/api_service.dart';
|
||||||
import 'package:flutter_app/app/networking/dio/base_api_service.dart';
|
import 'package:flutter_app/app/networking/dio/base_api_service.dart';
|
||||||
|
|
||||||
@ -6,12 +7,13 @@ 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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final Map<Type, dynamic> modelDecoders = {
|
final Map<Type, dynamic> modelDecoders = {
|
||||||
// ...
|
// ...
|
||||||
|
User: (data) => User.fromJson(data)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -20,7 +22,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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter_app/config/toast_notification.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/toast_notification_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';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| 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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -16,3 +19,14 @@ Widget logo = StoreLogo();
|
|||||||
|
|
||||||
Widget loader = AppLoaderWidget();
|
Widget loader = AppLoaderWidget();
|
||||||
// resources/widgets/app_loader_widget.dart
|
// resources/widgets/app_loader_widget.dart
|
||||||
|
|
||||||
|
Widget getToastNotificationWidget({
|
||||||
|
required ToastNotificationStyleType style,
|
||||||
|
Function(ToastNotificationStyleMetaHelper helper)? toastNotificationStyleMeta, Function? onDismiss}) {
|
||||||
|
if (toastNotificationStyleMeta == null) return SizedBox.shrink();
|
||||||
|
|
||||||
|
ToastMeta toastMeta = toastNotificationStyleMeta(NyToastNotificationStyleMetaHelper(style));
|
||||||
|
|
||||||
|
return ToastNotification(toastMeta, onDismiss: onDismiss);
|
||||||
|
// resources/widgets/toast_notification.dart
|
||||||
|
}
|
||||||
@ -8,11 +8,12 @@ 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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final Map<Type, NyEvent> events = {
|
final Map<Type, NyEvent> events = {
|
||||||
LoginEvent: LoginEvent(),
|
LoginEvent: LoginEvent(),
|
||||||
LogoutEvent: LogoutEvent(),
|
LogoutEvent: LogoutEvent(),
|
||||||
|
AuthUserEvent: AuthUserEvent(),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const appPaymentGateways = [];
|
const appPaymentGateways = ["CashOnDelivery"];
|
||||||
// Available: "Stripe", "CashOnDelivery", "PayPal", "RazorPay"
|
// Available: "Stripe", "CashOnDelivery", "PayPal", "RazorPay"
|
||||||
// e.g. app_payment_gateways = ["Stripe", "CashOnDelivery"]; will only use Stripe and Cash on Delivery.
|
// e.g. app_payment_gateways = ["Stripe", "CashOnDelivery"]; will only use Stripe and Cash on Delivery.
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import '/app/providers/firebase_provider.dart';
|
||||||
import 'package:flutter_app/app/providers/app_provider.dart';
|
import 'package:flutter_app/app/providers/app_provider.dart';
|
||||||
import 'package:flutter_app/app/providers/event_provider.dart';
|
import 'package:flutter_app/app/providers/event_provider.dart';
|
||||||
import 'package:flutter_app/app/providers/route_provider.dart';
|
import 'package:flutter_app/app/providers/route_provider.dart';
|
||||||
@ -9,7 +10,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
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -17,4 +18,7 @@ final Map<Type, NyProvider> providers = {
|
|||||||
AppProvider: AppProvider(),
|
AppProvider: AppProvider(),
|
||||||
RouteProvider: RouteProvider(),
|
RouteProvider: RouteProvider(),
|
||||||
EventProvider: EventProvider(),
|
EventProvider: EventProvider(),
|
||||||
|
FirebaseProvider: FirebaseProvider(),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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...
|
||||||
}
|
}
|
||||||
|
|||||||
34
LabelStoreMax/lib/config/toast_notification.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
|
/// ToastNotificationStyleMetaHelper is used to return
|
||||||
|
/// the correct value for the [ToastNotificationStyleType] toast style.
|
||||||
|
class NyToastNotificationStyleMetaHelper extends ToastNotificationStyleMetaHelper {
|
||||||
|
|
||||||
|
NyToastNotificationStyleMetaHelper(ToastNotificationStyleType? style) : super(style);
|
||||||
|
|
||||||
|
onSuccess() {
|
||||||
|
return ToastMeta.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
onWarning() {
|
||||||
|
return ToastMeta.warning();
|
||||||
|
}
|
||||||
|
|
||||||
|
onInfo() {
|
||||||
|
return ToastMeta.info();
|
||||||
|
}
|
||||||
|
|
||||||
|
onDanger() {
|
||||||
|
return ToastMeta.danger();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example customizing a notification
|
||||||
|
// onSuccess() {
|
||||||
|
// return ToastMeta.success(
|
||||||
|
// title: "Hello",
|
||||||
|
// description: "World",
|
||||||
|
// action: () {},
|
||||||
|
// backgroundColor: Colors.Yellow
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
}
|
||||||
36
LabelStoreMax/lib/config/validation_rules.dart
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| 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<String, dynamic> validationRules = {
|
||||||
|
/// Example
|
||||||
|
// "simple_password": (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']);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
66
LabelStoreMax/lib/firebase_options.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
|
||||||
|
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
|
||||||
|
import 'package:flutter/foundation.dart'
|
||||||
|
show defaultTargetPlatform, kIsWeb, TargetPlatform;
|
||||||
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
|
|
||||||
|
/// Default [FirebaseOptions] for use with your Firebase apps.
|
||||||
|
class DefaultFirebaseOptions {
|
||||||
|
static FirebaseOptions get currentPlatform {
|
||||||
|
if (kIsWeb) {
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for web - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
switch (defaultTargetPlatform) {
|
||||||
|
case TargetPlatform.android:
|
||||||
|
if (AppHelper.instance.appConfig?.firebaseOptionsAndroid == null) {
|
||||||
|
throw UnsupportedError(
|
||||||
|
'Add a valid Firebase json config on https://woosignal.com for your WooCommerce store',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return FirebaseOptions(
|
||||||
|
apiKey: AppHelper.instance.appConfig!.firebaseOptionsAndroid!['apiKey'],
|
||||||
|
appId: AppHelper.instance.appConfig!.firebaseOptionsAndroid!['appId'],
|
||||||
|
messagingSenderId: AppHelper.instance.appConfig!.firebaseOptionsAndroid!['messagingSenderId'],
|
||||||
|
projectId: AppHelper.instance.appConfig!.firebaseOptionsAndroid!['projectId'],
|
||||||
|
storageBucket: AppHelper.instance.appConfig!.firebaseOptionsAndroid!['storageBucket'],
|
||||||
|
);
|
||||||
|
case TargetPlatform.iOS:
|
||||||
|
if (AppHelper.instance.appConfig?.firebaseOptionsIos == null) {
|
||||||
|
throw UnsupportedError(
|
||||||
|
'Add a valid Firebase plist config on https://woosignal.com for your WooCommerce store',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return FirebaseOptions(
|
||||||
|
apiKey: AppHelper.instance.appConfig!.firebaseOptionsIos!['apiKey'],
|
||||||
|
appId: AppHelper.instance.appConfig!.firebaseOptionsIos!['appId'],
|
||||||
|
messagingSenderId: AppHelper.instance.appConfig!.firebaseOptionsIos!['messagingSenderId'],
|
||||||
|
projectId: AppHelper.instance.appConfig!.firebaseOptionsIos!['projectId'],
|
||||||
|
storageBucket: AppHelper.instance.appConfig!.firebaseOptionsIos!['storageBucket'],
|
||||||
|
iosClientId: AppHelper.instance.appConfig!.firebaseOptionsIos!['iosClientId'],
|
||||||
|
iosBundleId: AppHelper.instance.appConfig!.firebaseOptionsIos!['iosBundleId'],
|
||||||
|
);
|
||||||
|
case TargetPlatform.macOS:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for macos - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
case TargetPlatform.windows:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for windows - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
case TargetPlatform.linux:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions have not been configured for linux - '
|
||||||
|
'you can reconfigure this by running the FlutterFire CLI again.',
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
throw UnsupportedError(
|
||||||
|
'DefaultFirebaseOptions are not supported for this platform.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -67,7 +67,8 @@ class _AccountDeletePageState extends NyState<AccountDeletePage> {
|
|||||||
PrimaryButton(
|
PrimaryButton(
|
||||||
title: trans("Yes, delete my account"),
|
title: trans("Yes, delete my account"),
|
||||||
isLoading: isLocked('delete_account'),
|
isLoading: isLocked('delete_account'),
|
||||||
action: _deleteAccount),
|
action: _deleteAccount,
|
||||||
|
),
|
||||||
LinkButton(title: trans("Back"), action: pop)
|
LinkButton(title: trans("Back"), action: pop)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -8,10 +8,10 @@
|
|||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/app/controllers/account_order_detail_controller.dart';
|
import 'package:flutter_app/app/controllers/account_order_detail_controller.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/safearea_widget.dart';
|
import 'package:flutter_app/resources/widgets/safearea_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';
|
||||||
@ -29,10 +29,14 @@ class AccountOrderDetailPage extends NyStatefulWidget {
|
|||||||
class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
||||||
int? _orderId;
|
int? _orderId;
|
||||||
Order? _order;
|
Order? _order;
|
||||||
bool _isLoading = true;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
init() async {
|
init() async {
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
boot() async {
|
||||||
_orderId = widget.controller.data();
|
_orderId = widget.controller.data();
|
||||||
await _fetchOrder();
|
await _fetchOrder();
|
||||||
}
|
}
|
||||||
@ -48,25 +52,22 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
),
|
),
|
||||||
margin: EdgeInsets.only(left: 0),
|
margin: EdgeInsets.only(left: 0),
|
||||||
),
|
),
|
||||||
title: Text("${trans("Order").capitalize()} #${_orderId.toString()}"),
|
title: afterNotNull(_orderId, child: () => Text("${trans("Order").capitalize()} #${_orderId.toString()}"), loading: CupertinoActivityIndicator()),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
body: SafeAreaWidget(
|
body: SafeAreaWidget(
|
||||||
child: _isLoading
|
child: afterLoad(child: () => Column(
|
||||||
? AppLoaderWidget()
|
|
||||||
: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
padding: EdgeInsets.only(top: 8),
|
padding: EdgeInsets.only(top: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${trans("Date Ordered").capitalize()}: " +
|
"${trans("Date Ordered").capitalize()}: ${dateFormatted(
|
||||||
dateFormatted(
|
date: _order?.dateCreated ?? "",
|
||||||
date: _order!.dateCreated!,
|
|
||||||
formatType: formatForDateTime(FormatType.date),
|
formatType: formatForDateTime(FormatType.date),
|
||||||
),
|
)}",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
@ -135,21 +136,34 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
Flexible(
|
Flexible(
|
||||||
child: Text(
|
child: Text(
|
||||||
lineItem.name!,
|
lineItem.name!,
|
||||||
maxLines: 1,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Container(
|
||||||
formatStringCurrency(total: lineItem.price)
|
width: 70,
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
child: Text(
|
||||||
|
formatStringCurrency(total: lineItem.total)
|
||||||
.capitalize(),
|
.capitalize(),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: Padding(
|
subtitle: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
top: BorderSide(color: Colors.grey[100]!)
|
||||||
|
)
|
||||||
|
),
|
||||||
padding: const EdgeInsets.only(top: 10),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
margin: EdgeInsets.only(top: 4),
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment:
|
mainAxisAlignment:
|
||||||
@ -162,7 +176,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
formatStringCurrency(
|
formatStringCurrency(
|
||||||
total: lineItem.total,
|
total: lineItem.price,
|
||||||
),
|
),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
@ -173,7 +187,7 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"x${lineItem.quantity.toString()}",
|
"x ${lineItem.quantity.toString()}",
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyLarge,
|
.bodyLarge,
|
||||||
@ -187,11 +201,11 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
itemCount: _order!.lineItems!.length,
|
itemCount: _order?.lineItems?.length ?? 0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -202,13 +216,6 @@ class _AccountOrderDetailPageState extends NyState<AccountOrderDetailPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_fetchOrder() async {
|
_fetchOrder() async {
|
||||||
_order = await (appWooSignal((api) {
|
_order = await (appWooSignal((api) => api.retrieveOrder(_orderId!)));
|
||||||
return api.retrieveOrder(_orderId!);
|
|
||||||
}));
|
|
||||||
if (_order != null) {
|
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/app/controllers/product_category_search_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/product_category_search_loader_controller.dart';
|
||||||
import 'package:flutter_app/app/controllers/browse_category_controller.dart';
|
import 'package:flutter_app/app/controllers/browse_category_controller.dart';
|
||||||
@ -20,7 +21,7 @@ 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:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart';
|
import 'package:woosignal/models/response/product_category.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
|
|
||||||
class BrowseCategoryPage extends NyStatefulWidget {
|
class BrowseCategoryPage extends NyStatefulWidget {
|
||||||
final BrowseCategoryController controller = BrowseCategoryController();
|
final BrowseCategoryController controller = BrowseCategoryController();
|
||||||
@ -64,7 +65,7 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans("Browse"),
|
Text(trans("Browse"),
|
||||||
style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context).textTheme.titleMedium),
|
||||||
Text(parseHtmlString(productCategory!.name))
|
afterNotNull(productCategory, child: () => Text(parseHtmlString(productCategory!.name)), loading: CupertinoActivityIndicator())
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
@ -85,7 +86,8 @@ class _BrowseCategoryPageState extends NyState<BrowseCategoryPage> {
|
|||||||
onRefresh: _onRefresh,
|
onRefresh: _onRefresh,
|
||||||
onLoading: _onLoading,
|
onLoading: _onLoading,
|
||||||
products: _productCategorySearchLoaderController.getResults(),
|
products: _productCategorySearchLoaderController.getResults(),
|
||||||
onTap: _showProduct),
|
onTap: _showProduct,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/app/controllers/browse_search_controller.dart';
|
import 'package:flutter_app/app/controllers/browse_search_controller.dart';
|
||||||
import 'package:flutter_app/app/controllers/product_search_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/product_search_loader_controller.dart';
|
||||||
@ -16,7 +17,7 @@ import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
|||||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
|
|
||||||
class BrowseSearchPage extends NyStatefulWidget {
|
class BrowseSearchPage extends NyStatefulWidget {
|
||||||
final BrowseSearchController controller = BrowseSearchController();
|
final BrowseSearchController controller = BrowseSearchController();
|
||||||
@ -56,7 +57,7 @@ class _BrowseSearchState extends NyState<BrowseSearchPage> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(trans("Search results for"),
|
Text(trans("Search results for"),
|
||||||
style: Theme.of(context).textTheme.titleMedium),
|
style: Theme.of(context).textTheme.titleMedium),
|
||||||
Text("\"" + _search! + "\"")
|
afterNotNull(_search, child: () => Text("\"" + _search! + "\""), loading: CupertinoActivityIndicator())
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
|
|||||||
@ -16,7 +16,6 @@ import 'package:flutter_app/app/models/customer_address.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/bootstrap/shared_pref/sp_auth.dart';
|
import 'package:flutter_app/bootstrap/shared_pref/sp_auth.dart';
|
||||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
|
||||||
import 'package:flutter_app/resources/widgets/buttons.dart';
|
import 'package:flutter_app/resources/widgets/buttons.dart';
|
||||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/text_row_widget.dart';
|
import 'package:flutter_app/resources/widgets/text_row_widget.dart';
|
||||||
@ -30,26 +29,19 @@ class CartPage extends StatefulWidget {
|
|||||||
_CartPageState createState() => _CartPageState();
|
_CartPageState createState() => _CartPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CartPageState extends State<CartPage> {
|
class _CartPageState extends NyState<CartPage> {
|
||||||
_CartPageState();
|
_CartPageState();
|
||||||
|
|
||||||
bool _isLoading = true, _isCartEmpty = false;
|
|
||||||
List<CartLineItem> _cartLines = [];
|
List<CartLineItem> _cartLines = [];
|
||||||
|
|
||||||
@override
|
boot() async {
|
||||||
void initState() {
|
await _cartCheck();
|
||||||
super.initState();
|
|
||||||
_cartCheck();
|
|
||||||
CheckoutSession.getInstance.coupon = null;
|
CheckoutSession.getInstance.coupon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cartCheck() async {
|
_cartCheck() async {
|
||||||
List<CartLineItem> cart = await Cart.getInstance.getCart();
|
List<CartLineItem> cart = await Cart.getInstance.getCart();
|
||||||
if (cart.isEmpty) {
|
if (cart.isEmpty) {
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
_isCartEmpty = true;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,25 +51,18 @@ class _CartPageState extends State<CartPage> {
|
|||||||
await (appWooSignal((api) => api.cartCheck(cartJSON)));
|
await (appWooSignal((api) => api.cartCheck(cartJSON)));
|
||||||
if (cartRes.isEmpty) {
|
if (cartRes.isEmpty) {
|
||||||
Cart.getInstance.saveCartToPref(cartLineItems: []);
|
Cart.getInstance.saveCartToPref(cartLineItems: []);
|
||||||
setState(() {
|
|
||||||
_isCartEmpty = true;
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
||||||
if (_cartLines.isNotEmpty) {
|
if (_cartLines.isNotEmpty) {
|
||||||
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
||||||
}
|
}
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _actionProceedToCheckout() async {
|
void _actionProceedToCheckout() async {
|
||||||
List<CartLineItem> cartLineItems = await Cart.getInstance.getCart();
|
List<CartLineItem> cartLineItems = await Cart.getInstance.getCart();
|
||||||
|
|
||||||
if (_isLoading == true) {
|
if (isLoading()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,9 +148,6 @@ class _CartPageState extends State<CartPage> {
|
|||||||
style: ToastNotificationStyleType.WARNING,
|
style: ToastNotificationStyleType.WARNING,
|
||||||
icon: Icons.remove_shopping_cart,
|
icon: Icons.remove_shopping_cart,
|
||||||
);
|
);
|
||||||
if (_cartLines.isEmpty) {
|
|
||||||
_isCartEmpty = true;
|
|
||||||
}
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +159,6 @@ class _CartPageState extends State<CartPage> {
|
|||||||
description: trans("Cart cleared"),
|
description: trans("Cart cleared"),
|
||||||
style: ToastNotificationStyleType.SUCCESS,
|
style: ToastNotificationStyleType.SUCCESS,
|
||||||
icon: Icons.delete_outline);
|
icon: Icons.delete_outline);
|
||||||
_isCartEmpty = true;
|
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,9 +195,8 @@ class _CartPageState extends State<CartPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_isCartEmpty
|
Expanded(
|
||||||
? Expanded(
|
child: afterLoad(child: () => _cartLines.isEmpty ? FractionallySizedBox(
|
||||||
child: FractionallySizedBox(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
@ -237,14 +217,7 @@ class _CartPageState extends State<CartPage> {
|
|||||||
),
|
),
|
||||||
heightFactor: 0.5,
|
heightFactor: 0.5,
|
||||||
widthFactor: 1,
|
widthFactor: 1,
|
||||||
),
|
) : ListView.builder(
|
||||||
)
|
|
||||||
: (_isLoading
|
|
||||||
? Expanded(
|
|
||||||
child: AppLoaderWidget(),
|
|
||||||
)
|
|
||||||
: Expanded(
|
|
||||||
child: ListView.builder(
|
|
||||||
padding: const EdgeInsets.all(8),
|
padding: const EdgeInsets.all(8),
|
||||||
itemCount: _cartLines.length,
|
itemCount: _cartLines.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
@ -260,9 +233,8 @@ class _CartPageState extends State<CartPage> {
|
|||||||
actionRemoveItem: () =>
|
actionRemoveItem: () =>
|
||||||
actionRemoveItem(index: index),
|
actionRemoveItem(index: index),
|
||||||
);
|
);
|
||||||
}),
|
})),
|
||||||
flex: 3,
|
),
|
||||||
)),
|
|
||||||
Divider(
|
Divider(
|
||||||
color: Colors.black45,
|
color: Colors.black45,
|
||||||
),
|
),
|
||||||
@ -271,7 +243,7 @@ class _CartPageState extends State<CartPage> {
|
|||||||
child: (BuildContext context, data) => Padding(
|
child: (BuildContext context, data) => Padding(
|
||||||
child: TextRowWidget(
|
child: TextRowWidget(
|
||||||
title: trans("Total"),
|
title: trans("Total"),
|
||||||
text: (_isLoading ? "" : data),
|
text: isLoading() ? '' : data,
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.only(bottom: 15, top: 15),
|
padding: EdgeInsets.only(bottom: 15, top: 15),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -16,7 +16,6 @@ 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';
|
||||||
@ -59,7 +58,6 @@ class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
|
|||||||
CheckoutSession.getInstance.paymentType = paymentTypes.firstWhere(
|
CheckoutSession.getInstance.paymentType = paymentTypes.firstWhere(
|
||||||
(paymentType) => paymentType?.id == 20,
|
(paymentType) => paymentType?.id == 20,
|
||||||
orElse: () => paymentTypes.first);
|
orElse: () => paymentTypes.first);
|
||||||
print(CheckoutSession.getInstance.paymentType?.name);
|
|
||||||
}
|
}
|
||||||
_getTaxes();
|
_getTaxes();
|
||||||
}
|
}
|
||||||
@ -186,7 +184,7 @@ class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(trans("Checkout")),
|
Text(trans("Checkout")),
|
||||||
Text(_wooSignalApp?.appName ?? getEnv('APP_NAME')).small(context),
|
Text(_wooSignalApp?.appName ?? getEnv('APP_NAME')).bodySmall(context),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
@ -204,13 +202,12 @@ class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
|
|||||||
resizeToAvoidBottomInset: false,
|
resizeToAvoidBottomInset: false,
|
||||||
body: SafeAreaWidget(
|
body: SafeAreaWidget(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
Expanded(
|
|
||||||
child: ListView(
|
child: ListView(
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
|
children: <Widget>[
|
||||||
|
ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: NeverScrollableScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
CheckoutStoreHeadingWidget(),
|
CheckoutStoreHeadingWidget(),
|
||||||
CheckoutUserDetailsWidget(
|
CheckoutUserDetailsWidget(
|
||||||
@ -287,14 +284,14 @@ class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
|
|||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
text: TextSpan(
|
text: TextSpan(
|
||||||
text:
|
text:
|
||||||
'By completing this order, I agree to all ',
|
'${trans('By completing this order, I agree to all')} ',
|
||||||
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
style: Theme.of(context).textTheme.bodySmall!.copyWith(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
),
|
),
|
||||||
children: <TextSpan>[
|
children: <TextSpan>[
|
||||||
TextSpan(
|
TextSpan(
|
||||||
recognizer: TapGestureRecognizer()..onTap = _openTermsLink,
|
recognizer: TapGestureRecognizer()..onTap = _openTermsLink,
|
||||||
text: "terms & conditions",
|
text: trans("Terms and conditions").toLowerCase(),
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodySmall!
|
.bodySmall!
|
||||||
@ -324,7 +321,6 @@ class CheckoutConfirmationPageState extends NyState<CheckoutConfirmationPage> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(16)
|
borderRadius: BorderRadius.circular(16)
|
||||||
|
|||||||
@ -34,6 +34,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
|||||||
_order = widget.controller.data();
|
_order = widget.controller.data();
|
||||||
await Cart.getInstance.clear();
|
await Cart.getInstance.clear();
|
||||||
CheckoutSession.getInstance.clear();
|
CheckoutSession.getInstance.clear();
|
||||||
|
setState(() { });
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -77,7 +78,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
|||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
"${trans("Order Ref")}. #${_order!.id.toString()}",
|
"${trans("Order Ref")}. #${_order?.id.toString()}",
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
textAlign: TextAlign.left,
|
textAlign: TextAlign.left,
|
||||||
),
|
),
|
||||||
@ -119,9 +120,9 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: _order!.lineItems == null
|
itemCount: _order?.lineItems == null
|
||||||
? 0
|
? 0
|
||||||
: _order!.lineItems!.length,
|
: _order?.lineItems?.length ?? 0,
|
||||||
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(
|
||||||
@ -161,7 +162,7 @@ class _CheckoutStatusState extends NyState<CheckoutStatusPage> {
|
|||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
formatStringCurrency(
|
formatStringCurrency(
|
||||||
total: lineItem.total.toString(),
|
total: lineItem.subtotal.toString(),
|
||||||
),
|
),
|
||||||
style: Theme.of(context).textTheme.bodyLarge,
|
style: Theme.of(context).textTheme.bodyLarge,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -179,7 +179,7 @@ class _CouponPageState extends State<CouponPage> {
|
|||||||
if (minimumAmount != 0 && doubleSubtotal < minimumAmount) {
|
if (minimumAmount != 0 && doubleSubtotal < minimumAmount) {
|
||||||
_showAlert(
|
_showAlert(
|
||||||
message: trans("Spend a minimum of minimumAmount to redeem",
|
message: trans("Spend a minimum of minimumAmount to redeem",
|
||||||
arguments: {"minimumAmount": minimumAmount.toString()}),
|
arguments: {"minimumAmount": formatStringCurrency(total: minimumAmount.toString())}),
|
||||||
style: ToastNotificationStyleType.DANGER);
|
style: ToastNotificationStyleType.DANGER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ class _CouponPageState extends State<CouponPage> {
|
|||||||
if (maximumAmount != 0 && doubleSubtotal > maximumAmount) {
|
if (maximumAmount != 0 && doubleSubtotal > maximumAmount) {
|
||||||
_showAlert(
|
_showAlert(
|
||||||
message: trans("Spend less than maximumAmount to redeem",
|
message: trans("Spend less than maximumAmount to redeem",
|
||||||
arguments: {"maximumAmount": maximumAmount.toString()}),
|
arguments: {"maximumAmount": formatStringCurrency(total: maximumAmount.toString())}),
|
||||||
style: ToastNotificationStyleType.DANGER);
|
style: ToastNotificationStyleType.DANGER);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -135,9 +135,10 @@ 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},
|
||||||
|
onSuccess: () async {
|
||||||
ProductReview? productReview =
|
ProductReview? productReview =
|
||||||
await (appWooSignal((api) => api.createProductReview(
|
await (appWooSignal((api) => api.createProductReview(
|
||||||
productId: _lineItem!.productId,
|
productId: _lineItem!.productId,
|
||||||
@ -164,14 +165,12 @@ class _LeaveReviewPageState extends NyState<LeaveReviewPage> {
|
|||||||
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 {
|
||||||
String? userToken = await readAuthToken();
|
String? userToken = await readAuthToken();
|
||||||
|
|||||||
@ -14,17 +14,15 @@ import 'package:flutter_app/app/models/cart_line_item.dart';
|
|||||||
import 'package:flutter_app/bootstrap/app_helper.dart';
|
import 'package:flutter_app/bootstrap/app_helper.dart';
|
||||||
import 'package:flutter_app/bootstrap/enums/wishlist_action_enums.dart';
|
import 'package:flutter_app/bootstrap/enums/wishlist_action_enums.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/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';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:woosignal/models/response/product_variation.dart'
|
import 'package:woosignal/models/response/product_variation.dart'
|
||||||
as ws_product_variation;
|
as ws_product_variation;
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class ProductDetailPage extends NyStatefulWidget {
|
class ProductDetailPage extends NyStatefulWidget {
|
||||||
@ -37,7 +35,6 @@ class ProductDetailPage extends NyStatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _ProductDetailState extends NyState<ProductDetailPage> {
|
class _ProductDetailState extends NyState<ProductDetailPage> {
|
||||||
bool _isLoading = true;
|
|
||||||
ws_product.Product? _product;
|
ws_product.Product? _product;
|
||||||
|
|
||||||
List<ws_product_variation.ProductVariation> _productVariations = [];
|
List<ws_product_variation.ProductVariation> _productVariations = [];
|
||||||
@ -46,14 +43,15 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
init() async {
|
init() async {
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
boot() async {
|
||||||
_product = widget.controller.data();
|
_product = widget.controller.data();
|
||||||
if (_product!.type == "variable") {
|
if (_product!.type == "variable") {
|
||||||
await _fetchProductVariations();
|
await _fetchProductVariations();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchProductVariations() async {
|
_fetchProductVariations() async {
|
||||||
@ -77,9 +75,6 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_productVariations = tmpVariations;
|
_productVariations = tmpVariations;
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_modalBottomSheetOptionsForAttribute(int attributeIndex) {
|
_modalBottomSheetOptionsForAttribute(int attributeIndex) {
|
||||||
@ -89,7 +84,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
"${trans("Select a")} ${_product!.attributes[attributeIndex].name}",
|
"${trans("Select a")} ${_product!.attributes[attributeIndex].name}",
|
||||||
bodyWidget: ListView.separated(
|
bodyWidget: ListView.separated(
|
||||||
itemCount: _product!.attributes[attributeIndex].options!.length,
|
itemCount: _product!.attributes[attributeIndex].options!.length,
|
||||||
separatorBuilder: (BuildContext context, int index) => Divider(),
|
separatorBuilder: (BuildContext context, int index) => Divider(color: Colors.black12),
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
@ -232,9 +227,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(
|
||||||
@ -257,9 +252,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: _isLoading
|
child: afterLoad(child: () => Column(
|
||||||
? AppLoaderWidget()
|
|
||||||
: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
@ -282,7 +275,7 @@ class _ProductDetailState extends NyState<ProductDetailPage> {
|
|||||||
quantity: widget.controller.quantity,
|
quantity: widget.controller.quantity,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
))
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
|||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/product_review.dart';
|
import 'package:woosignal/models/response/product_review.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import '../../app/controllers/product_reviews_controller.dart';
|
import '../../app/controllers/product_reviews_controller.dart';
|
||||||
|
|
||||||
class ProductReviewsPage extends NyStatefulWidget {
|
class ProductReviewsPage extends NyStatefulWidget {
|
||||||
|
|||||||
@ -10,25 +10,21 @@
|
|||||||
|
|
||||||
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/cached_image_widget.dart';
|
import 'package:flutter_app/resources/widgets/cached_image_widget.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/product.dart';
|
||||||
|
|
||||||
class WishListPageWidget extends StatefulWidget {
|
class WishListPageWidget extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_WishListPageWidgetState createState() => _WishListPageWidgetState();
|
_WishListPageWidgetState createState() => _WishListPageWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _WishListPageWidgetState extends State<WishListPageWidget> {
|
class _WishListPageWidgetState extends NyState<WishListPageWidget> {
|
||||||
List<Product> _products = [];
|
List<Product> _products = [];
|
||||||
bool? isLoading;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
boot() async {
|
||||||
super.initState();
|
await loadProducts();
|
||||||
isLoading = true;
|
|
||||||
loadProducts();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadProducts() async {
|
loadProducts() async {
|
||||||
@ -36,9 +32,6 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
|||||||
List<int> productIds =
|
List<int> productIds =
|
||||||
favouriteProducts.map((e) => e['id']).cast<int>().toList();
|
favouriteProducts.map((e) => e['id']).cast<int>().toList();
|
||||||
if (productIds.isEmpty) {
|
if (productIds.isEmpty) {
|
||||||
setState(() {
|
|
||||||
isLoading = false;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_products = await (appWooSignal((api) => api.getProducts(
|
_products = await (appWooSignal((api) => api.getProducts(
|
||||||
@ -47,9 +40,6 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
|||||||
status: "publish",
|
status: "publish",
|
||||||
stockStatus: "instock",
|
stockStatus: "instock",
|
||||||
)));
|
)));
|
||||||
setState(() {
|
|
||||||
isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -60,9 +50,8 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
|||||||
title: Text(trans("Wishlist")),
|
title: Text(trans("Wishlist")),
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: isLoading!
|
child: afterLoad(
|
||||||
? AppLoaderWidget()
|
child: () => _products.isEmpty
|
||||||
: _products.isEmpty && isLoading == false
|
|
||||||
? Center(
|
? Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
@ -150,6 +139,7 @@ class _WishListPageWidgetState extends State<WishListPageWidget> {
|
|||||||
return Divider();
|
return Divider();
|
||||||
},
|
},
|
||||||
itemCount: _products.length)),
|
itemCount: _products.length)),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -6,31 +6,45 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
/// light_theme_colors.dart and dark_theme_colors.dart.
|
/// light_theme_colors.dart and dark_theme_colors.dart.
|
||||||
abstract class ColorStyles extends BaseColorStyles {
|
abstract class ColorStyles extends BaseColorStyles {
|
||||||
// general
|
// general
|
||||||
|
@override
|
||||||
Color get background;
|
Color get background;
|
||||||
Color get backgroundContainer;
|
Color get backgroundContainer;
|
||||||
|
@override
|
||||||
Color get primaryContent;
|
Color get primaryContent;
|
||||||
|
@override
|
||||||
Color get primaryAccent;
|
Color get primaryAccent;
|
||||||
|
|
||||||
|
@override
|
||||||
Color get surfaceBackground;
|
Color get surfaceBackground;
|
||||||
|
@override
|
||||||
Color get surfaceContent;
|
Color get surfaceContent;
|
||||||
|
|
||||||
// app bar
|
// app bar
|
||||||
|
@override
|
||||||
Color get appBarBackground;
|
Color get appBarBackground;
|
||||||
|
@override
|
||||||
Color get appBarPrimaryContent;
|
Color get appBarPrimaryContent;
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
|
@override
|
||||||
Color get buttonBackground;
|
Color get buttonBackground;
|
||||||
|
@override
|
||||||
Color get buttonPrimaryContent;
|
Color get buttonPrimaryContent;
|
||||||
|
|
||||||
// bottom tab bar
|
// bottom tab bar
|
||||||
|
@override
|
||||||
Color get bottomTabBarBackground;
|
Color get bottomTabBarBackground;
|
||||||
|
|
||||||
// bottom tab bar - icons
|
// bottom tab bar - icons
|
||||||
|
@override
|
||||||
Color get bottomTabBarIconSelected;
|
Color get bottomTabBarIconSelected;
|
||||||
|
@override
|
||||||
Color get bottomTabBarIconUnselected;
|
Color get bottomTabBarIconUnselected;
|
||||||
|
|
||||||
// bottom tab bar - label
|
// bottom tab bar - label
|
||||||
|
@override
|
||||||
Color get bottomTabBarLabelUnselected;
|
Color get bottomTabBarLabelUnselected;
|
||||||
|
@override
|
||||||
Color get bottomTabBarLabelSelected;
|
Color get bottomTabBarLabelSelected;
|
||||||
|
|
||||||
Color get inputPrimaryContent;
|
Color get inputPrimaryContent;
|
||||||
|
|||||||
@ -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);
|
||||||
@ -20,7 +20,7 @@ class AppVersionWidget extends StatelessWidget {
|
|||||||
return NyFutureBuilder<PackageInfo>(
|
return NyFutureBuilder<PackageInfo>(
|
||||||
future: PackageInfo.fromPlatform(),
|
future: PackageInfo.fromPlatform(),
|
||||||
child: (BuildContext context, data) => Padding(
|
child: (BuildContext context, data) => Padding(
|
||||||
child: Text("${trans("Version")}: ${data.version}",
|
child: Text("${trans("Version")}: ${data?.version}",
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.bodyMedium!
|
.bodyMedium!
|
||||||
|
|||||||
@ -23,7 +23,9 @@ 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(
|
||||||
|
width: 70,
|
||||||
|
child: IconButton(
|
||||||
icon: Stack(
|
icon: Stack(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Positioned.fill(
|
Positioned.fill(
|
||||||
@ -39,6 +41,8 @@ class _CartIconWidgetState extends State<CartIconWidget> {
|
|||||||
future: Cart.getInstance.getCart(),
|
future: Cart.getInstance.getCart(),
|
||||||
child: (BuildContext context,
|
child: (BuildContext context,
|
||||||
data) {
|
data) {
|
||||||
|
if (data == null) return SizedBox.shrink();
|
||||||
|
|
||||||
List<int?> cartItems =
|
List<int?> cartItems =
|
||||||
data.map((e) => e.quantity).toList();
|
data.map((e) => e.quantity).toList();
|
||||||
String cartValue = "0";
|
String cartValue = "0";
|
||||||
@ -62,6 +66,7 @@ class _CartIconWidgetState extends State<CartIconWidget> {
|
|||||||
),
|
),
|
||||||
onPressed: () => Navigator.pushNamed(context, "/cart")
|
onPressed: () => Navigator.pushNamed(context, "/cart")
|
||||||
.then((value) => setState(() {})),
|
.then((value) => setState(() {})),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,10 +27,11 @@ class CheckoutSelectCouponWidget extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
bool hasCoupon = checkoutSession.coupon != null;
|
bool hasCoupon = checkoutSession.coupon != null;
|
||||||
return InkWell(
|
return Container(
|
||||||
onTap: _actionCoupon,
|
height: 50,
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 5),
|
padding: EdgeInsets.symmetric(vertical: 5),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: _actionCoupon,
|
||||||
child: Row(
|
child: Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
|||||||
@ -20,7 +20,7 @@ import 'package:flutter_swiper_view/flutter_swiper_view.dart';
|
|||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart';
|
import 'package:woosignal/models/response/product_category.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class CompoHomeWidget extends StatefulWidget {
|
class CompoHomeWidget extends StatefulWidget {
|
||||||
CompoHomeWidget({Key? key, required this.wooSignalApp}) : super(key: key);
|
CompoHomeWidget({Key? key, required this.wooSignalApp}) : super(key: key);
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import 'package:flutter_app/resources/pages/wishlist_page_widget.dart';
|
|||||||
import 'package:flutter_app/resources/pages/home_search_page.dart';
|
import 'package:flutter_app/resources/pages/home_search_page.dart';
|
||||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/compo_home_widget.dart';
|
import 'package:flutter_app/resources/widgets/compo_home_widget.dart';
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class CompoThemeWidget extends StatefulWidget {
|
class CompoThemeWidget extends StatefulWidget {
|
||||||
@ -87,7 +88,7 @@ class CompoThemeWidgetState extends State<CompoThemeWidget> {
|
|||||||
id: 1,
|
id: 1,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.home),
|
icon: Icon(Icons.home),
|
||||||
label: 'Home',
|
label: 'Home'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: CompoHomeWidget(wooSignalApp: widget.wooSignalApp)),
|
tabWidget: CompoHomeWidget(wooSignalApp: widget.wooSignalApp)),
|
||||||
);
|
);
|
||||||
@ -97,7 +98,7 @@ class CompoThemeWidgetState extends State<CompoThemeWidget> {
|
|||||||
id: 2,
|
id: 2,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.search),
|
icon: Icon(Icons.search),
|
||||||
label: 'Search',
|
label: 'Search'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: HomeSearchPage()),
|
tabWidget: HomeSearchPage()),
|
||||||
);
|
);
|
||||||
@ -107,7 +108,7 @@ class CompoThemeWidgetState extends State<CompoThemeWidget> {
|
|||||||
id: 3,
|
id: 3,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.favorite_border),
|
icon: Icon(Icons.favorite_border),
|
||||||
label: 'Wishlist',
|
label: 'Wishlist'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: WishListPageWidget(),
|
tabWidget: WishListPageWidget(),
|
||||||
));
|
));
|
||||||
@ -116,7 +117,7 @@ class CompoThemeWidgetState extends State<CompoThemeWidget> {
|
|||||||
items.add(BottomNavItem(
|
items.add(BottomNavItem(
|
||||||
id: 4,
|
id: 4,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart), label: 'Cart'),
|
icon: Icon(Icons.shopping_cart), label: 'Cart'.tr()),
|
||||||
tabWidget: CartPage(),
|
tabWidget: CartPage(),
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ class CompoThemeWidgetState extends State<CompoThemeWidget> {
|
|||||||
items.add(BottomNavItem(
|
items.add(BottomNavItem(
|
||||||
id: 5,
|
id: 5,
|
||||||
bottomNavigationBarItem:
|
bottomNavigationBarItem:
|
||||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Account'),
|
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Account'.tr()),
|
||||||
tabWidget: (await authCheck())
|
tabWidget: (await authCheck())
|
||||||
? AccountDetailPage(showLeadingBackButton: false)
|
? AccountDetailPage(showLeadingBackButton: false)
|
||||||
: AccountLandingPage(
|
: AccountLandingPage(
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -11,7 +11,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/app/controllers/product_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/product_loader_controller.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/cart_icon_widget.dart';
|
import 'package:flutter_app/resources/widgets/cart_icon_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
|
import 'package:flutter_app/resources/widgets/home_drawer_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
import 'package:flutter_app/resources/widgets/safearea_widget.dart';
|
||||||
@ -20,7 +19,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart' as ws_category;
|
import 'package:woosignal/models/response/product_category.dart' as ws_category;
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
|
|
||||||
class MelloThemeWidget extends StatefulWidget {
|
class MelloThemeWidget extends StatefulWidget {
|
||||||
MelloThemeWidget(
|
MelloThemeWidget(
|
||||||
@ -33,7 +32,7 @@ class MelloThemeWidget extends StatefulWidget {
|
|||||||
_MelloThemeWidgetState createState() => _MelloThemeWidgetState();
|
_MelloThemeWidgetState createState() => _MelloThemeWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MelloThemeWidgetState extends State<MelloThemeWidget> {
|
class _MelloThemeWidgetState extends NyState<MelloThemeWidget> {
|
||||||
final RefreshController _refreshController =
|
final RefreshController _refreshController =
|
||||||
RefreshController(initialRefresh: false);
|
RefreshController(initialRefresh: false);
|
||||||
final ProductLoaderController _productLoaderController =
|
final ProductLoaderController _productLoaderController =
|
||||||
@ -41,20 +40,21 @@ class _MelloThemeWidgetState extends State<MelloThemeWidget> {
|
|||||||
|
|
||||||
List<ws_category.ProductCategory> _categories = [];
|
List<ws_category.ProductCategory> _categories = [];
|
||||||
|
|
||||||
bool _shouldStopRequests = false, _isLoading = true;
|
bool _shouldStopRequests = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void init() async {
|
||||||
super.initState();
|
super.init();
|
||||||
_home();
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
boot() async {
|
||||||
|
await _home();
|
||||||
}
|
}
|
||||||
|
|
||||||
_home() async {
|
_home() async {
|
||||||
await fetchProducts();
|
await fetchProducts();
|
||||||
await _fetchCategories();
|
await _fetchCategories();
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchCategories() async {
|
_fetchCategories() async {
|
||||||
@ -110,9 +110,7 @@ class _MelloThemeWidgetState extends State<MelloThemeWidget> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: _isLoading
|
child: afterLoad(child: () => RefreshableScrollContainer(
|
||||||
? AppLoaderWidget()
|
|
||||||
: RefreshableScrollContainer(
|
|
||||||
controller: _refreshController,
|
controller: _refreshController,
|
||||||
onRefresh: _onRefresh,
|
onRefresh: _onRefresh,
|
||||||
onLoading: _onLoading,
|
onLoading: _onLoading,
|
||||||
@ -121,7 +119,7 @@ class _MelloThemeWidgetState extends State<MelloThemeWidget> {
|
|||||||
bannerHeight: MediaQuery.of(context).size.height / 3.5,
|
bannerHeight: MediaQuery.of(context).size.height / 3.5,
|
||||||
bannerImages: bannerImages,
|
bannerImages: bannerImages,
|
||||||
modalBottomSheetMenu: _modalBottomSheetMenu,
|
modalBottomSheetMenu: _modalBottomSheetMenu,
|
||||||
),
|
)),
|
||||||
flex: 1,
|
flex: 1,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_app/app/controllers/product_loader_controller.dart';
|
import 'package:flutter_app/app/controllers/product_loader_controller.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/home_drawer_widget.dart';
|
import 'package:flutter_app/resources/widgets/home_drawer_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';
|
||||||
@ -23,7 +22,7 @@ import 'package:nylo_framework/nylo_framework.dart';
|
|||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart' as ws_category;
|
import 'package:woosignal/models/response/product_category.dart' as ws_category;
|
||||||
import 'package:woosignal/models/response/products.dart' as ws_product;
|
import 'package:woosignal/models/response/product.dart' as ws_product;
|
||||||
|
|
||||||
class NoticHomeWidget extends StatefulWidget {
|
class NoticHomeWidget extends StatefulWidget {
|
||||||
NoticHomeWidget({Key? key, required this.wooSignalApp}) : super(key: key);
|
NoticHomeWidget({Key? key, required this.wooSignalApp}) : super(key: key);
|
||||||
@ -34,7 +33,7 @@ class NoticHomeWidget extends StatefulWidget {
|
|||||||
_NoticHomeWidgetState createState() => _NoticHomeWidgetState();
|
_NoticHomeWidgetState createState() => _NoticHomeWidgetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
class _NoticHomeWidgetState extends NyState<NoticHomeWidget> {
|
||||||
Widget? activeWidget;
|
Widget? activeWidget;
|
||||||
final RefreshController _refreshController =
|
final RefreshController _refreshController =
|
||||||
RefreshController(initialRefresh: false);
|
RefreshController(initialRefresh: false);
|
||||||
@ -43,20 +42,16 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
ProductLoaderController();
|
ProductLoaderController();
|
||||||
List<ws_category.ProductCategory> _categories = [];
|
List<ws_category.ProductCategory> _categories = [];
|
||||||
|
|
||||||
bool _shouldStopRequests = false, _isLoading = true;
|
bool _shouldStopRequests = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
boot() async {
|
||||||
super.initState();
|
await _home();
|
||||||
_home();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_home() async {
|
_home() async {
|
||||||
await fetchProducts();
|
await fetchProducts();
|
||||||
await _fetchCategories();
|
await _fetchCategories();
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchCategories() async {
|
_fetchCategories() async {
|
||||||
@ -114,10 +109,8 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
(_isLoading
|
Expanded(
|
||||||
? Expanded(child: AppLoaderWidget())
|
child: afterLoad(child: () => ListView(
|
||||||
: Expanded(
|
|
||||||
child: ListView(
|
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
@ -138,7 +131,7 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
height: MediaQuery.of(context).size.height / 2.5,
|
height: MediaQuery.of(context).size.height / 2.5,
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: 100,
|
height: 75,
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@ -149,7 +142,7 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.headlineMedium,
|
.headlineMedium,
|
||||||
maxLines: 2,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
@ -157,7 +150,7 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
height: 250,
|
height: 380,
|
||||||
child: SmartRefresher(
|
child: SmartRefresher(
|
||||||
enablePullDown: true,
|
enablePullDown: true,
|
||||||
enablePullUp: true,
|
enablePullUp: true,
|
||||||
@ -192,7 +185,6 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
shrinkWrap: false,
|
shrinkWrap: false,
|
||||||
itemBuilder: (cxt, i) {
|
itemBuilder: (cxt, i) {
|
||||||
return Container(
|
return Container(
|
||||||
// height: 200,
|
|
||||||
width:
|
width:
|
||||||
MediaQuery.of(context).size.width /
|
MediaQuery.of(context).size.width /
|
||||||
2.5,
|
2.5,
|
||||||
@ -208,8 +200,7 @@ class _NoticHomeWidgetState extends State<NoticHomeWidget> {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
flex: 1,
|
),flex: 1,),
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -22,6 +22,7 @@ import 'package:flutter_app/resources/pages/wishlist_page_widget.dart';
|
|||||||
import 'package:flutter_app/resources/pages/home_search_page.dart';
|
import 'package:flutter_app/resources/pages/home_search_page.dart';
|
||||||
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
import 'package:flutter_app/resources/widgets/app_loader_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/notic_home_widget.dart';
|
import 'package:flutter_app/resources/widgets/notic_home_widget.dart';
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class NoticThemeWidget extends StatefulWidget {
|
class NoticThemeWidget extends StatefulWidget {
|
||||||
@ -86,7 +87,7 @@ class _NoticThemeWidgetState extends State<NoticThemeWidget> {
|
|||||||
id: 1,
|
id: 1,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.home),
|
icon: Icon(Icons.home),
|
||||||
label: 'Home',
|
label: 'Home'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: NoticHomeWidget(wooSignalApp: widget.wooSignalApp)),
|
tabWidget: NoticHomeWidget(wooSignalApp: widget.wooSignalApp)),
|
||||||
);
|
);
|
||||||
@ -96,7 +97,7 @@ class _NoticThemeWidgetState extends State<NoticThemeWidget> {
|
|||||||
id: 2,
|
id: 2,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.search),
|
icon: Icon(Icons.search),
|
||||||
label: 'Search',
|
label: 'Search'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: HomeSearchPage()),
|
tabWidget: HomeSearchPage()),
|
||||||
);
|
);
|
||||||
@ -106,7 +107,7 @@ class _NoticThemeWidgetState extends State<NoticThemeWidget> {
|
|||||||
id: 3,
|
id: 3,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.favorite_border),
|
icon: Icon(Icons.favorite_border),
|
||||||
label: 'Wishlist',
|
label: 'Wishlist'.tr(),
|
||||||
),
|
),
|
||||||
tabWidget: WishListPageWidget(),
|
tabWidget: WishListPageWidget(),
|
||||||
));
|
));
|
||||||
@ -115,7 +116,9 @@ class _NoticThemeWidgetState extends State<NoticThemeWidget> {
|
|||||||
items.add(BottomNavItem(
|
items.add(BottomNavItem(
|
||||||
id: 4,
|
id: 4,
|
||||||
bottomNavigationBarItem: BottomNavigationBarItem(
|
bottomNavigationBarItem: BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.shopping_cart), label: 'Cart'),
|
icon: Icon(Icons.shopping_cart),
|
||||||
|
label: 'Cart'.tr(),
|
||||||
|
),
|
||||||
tabWidget: CartPage(),
|
tabWidget: CartPage(),
|
||||||
));
|
));
|
||||||
|
|
||||||
@ -123,7 +126,9 @@ class _NoticThemeWidgetState extends State<NoticThemeWidget> {
|
|||||||
items.add(BottomNavItem(
|
items.add(BottomNavItem(
|
||||||
id: 5,
|
id: 5,
|
||||||
bottomNavigationBarItem:
|
bottomNavigationBarItem:
|
||||||
BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Account'),
|
BottomNavigationBarItem(icon: Icon(Icons.person),
|
||||||
|
label: 'Account'.tr(),
|
||||||
|
),
|
||||||
tabWidget: (await authCheck())
|
tabWidget: (await authCheck())
|
||||||
? AccountDetailPage(showLeadingBackButton: false)
|
? AccountDetailPage(showLeadingBackButton: false)
|
||||||
: AccountLandingPage(
|
: AccountLandingPage(
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import 'package:flutter_app/resources/widgets/product_detail_image_swiper_widget
|
|||||||
import 'package:flutter_app/resources/widgets/product_detail_related_products_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_related_products_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/product_detail_reviews_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_reviews_widget.dart';
|
||||||
import 'package:flutter_app/resources/widgets/product_detail_upsell_widget.dart';
|
import 'package:flutter_app/resources/widgets/product_detail_upsell_widget.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class ProductDetailBodyWidget extends StatelessWidget {
|
class ProductDetailBodyWidget extends StatelessWidget {
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import 'package:flutter_app/resources/widgets/woosignal_ui.dart';
|
|||||||
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
|
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductDetailDescriptionWidget extends StatelessWidget {
|
class ProductDetailDescriptionWidget extends StatelessWidget {
|
||||||
const ProductDetailDescriptionWidget({Key? key, required this.product})
|
const ProductDetailDescriptionWidget({Key? key, required this.product})
|
||||||
|
|||||||
@ -13,7 +13,7 @@ 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/buttons.dart';
|
import 'package:flutter_app/resources/widgets/buttons.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/product.dart';
|
||||||
|
|
||||||
class ProductDetailFooterActionsWidget extends StatelessWidget {
|
class ProductDetailFooterActionsWidget extends StatelessWidget {
|
||||||
const ProductDetailFooterActionsWidget(
|
const ProductDetailFooterActionsWidget(
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
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:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
|
|
||||||
class ProductDetailHeaderWidget extends StatelessWidget {
|
class ProductDetailHeaderWidget extends StatelessWidget {
|
||||||
const ProductDetailHeaderWidget({Key? key, required this.product})
|
const ProductDetailHeaderWidget({Key? key, required this.product})
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
|
import 'package:flutter_app/resources/widgets/cached_image_widget.dart';
|
||||||
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
|
import 'package:flutter_swiper_view/flutter_swiper_view.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/product.dart';
|
||||||
|
|
||||||
class ProductDetailImageSwiperWidget extends StatelessWidget {
|
class ProductDetailImageSwiperWidget extends StatelessWidget {
|
||||||
const ProductDetailImageSwiperWidget(
|
const ProductDetailImageSwiperWidget(
|
||||||
|
|||||||
@ -10,11 +10,9 @@
|
|||||||
|
|
||||||
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/product.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class ProductDetailRelatedProductsWidget extends StatelessWidget {
|
class ProductDetailRelatedProductsWidget extends StatelessWidget {
|
||||||
@ -53,11 +51,13 @@ 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();
|
||||||
|
|
||||||
|
if (relatedProducts.isEmpty) {
|
||||||
return SizedBox.shrink();
|
return SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return ListView(
|
return ListView(
|
||||||
@ -70,16 +70,13 @@ class ProductDetailRelatedProductsWidget extends StatelessWidget {
|
|||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onLoading: AppLoaderWidget(),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<Product>> fetchRelated() async {
|
Future<List<Product>> fetchRelated() async => await (appWooSignal(
|
||||||
return await (appWooSignal(
|
(api) => api.getProducts(perPage: 100, include: product!.relatedIds, status: "publish"),
|
||||||
(api) => api.getProducts(perPage: 100, include: product!.relatedIds),
|
|
||||||
));
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,12 +12,11 @@ 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';
|
||||||
import 'package:woosignal/models/response/product_review.dart';
|
import 'package:woosignal/models/response/product_review.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class ProductDetailReviewsWidget extends StatefulWidget {
|
class ProductDetailReviewsWidget extends StatefulWidget {
|
||||||
@ -91,11 +90,17 @@ 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) {
|
if (reviews == null) {
|
||||||
return SizedBox.shrink();
|
return Container(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(
|
||||||
|
trans('There are no reviews yet.'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
int reviewsCount = reviews.length;
|
int reviewsCount = reviews.length;
|
||||||
List<Widget> childrenWidgets = [];
|
List<Widget> childrenWidgets = [];
|
||||||
@ -137,7 +142,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 +154,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"),
|
||||||
));
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import 'package:flutter_app/app/controllers/product_loader_controller.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/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/product.dart';
|
||||||
import 'package:woosignal/models/response/woosignal_app.dart';
|
import 'package:woosignal/models/response/woosignal_app.dart';
|
||||||
|
|
||||||
class ProductDetailUpsellWidget extends StatefulWidget {
|
class ProductDetailUpsellWidget extends StatefulWidget {
|
||||||
@ -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,
|
||||||
|
|||||||
@ -0,0 +1,90 @@
|
|||||||
|
import 'package:animate_do/animate_do.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
|
|
||||||
|
class ToastNotification extends StatelessWidget {
|
||||||
|
const ToastNotification(ToastMeta toastMeta, {Function? onDismiss, Key? key}) : _toastMeta = toastMeta, _dismiss = onDismiss, super(key: key);
|
||||||
|
|
||||||
|
final Function? _dismiss;
|
||||||
|
final ToastMeta _toastMeta;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(children: [
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
if (_toastMeta.action != null) {
|
||||||
|
_toastMeta.action!();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 18.0),
|
||||||
|
margin: EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
|
height: 100,
|
||||||
|
decoration: ShapeDecoration(
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
),
|
||||||
|
color: _toastMeta.color,
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Pulse(
|
||||||
|
child: Container(
|
||||||
|
child: Center(
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () {},
|
||||||
|
icon: _toastMeta.icon ?? SizedBox.shrink(),
|
||||||
|
padding: EdgeInsets.only(right: 16),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
infinite: true,
|
||||||
|
duration: Duration(milliseconds: 1500),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
_toastMeta.title.tr(),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.headlineSmall!
|
||||||
|
.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_toastMeta.description.tr(),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.textTheme
|
||||||
|
.bodyLarge!
|
||||||
|
.copyWith(color: Colors.white),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
top: 0,
|
||||||
|
right: 0,
|
||||||
|
child: IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
if (_dismiss != null) {
|
||||||
|
_dismiss!();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
icon: Icon(
|
||||||
|
Icons.close,
|
||||||
|
color: Colors.white,
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
|
|||||||
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
|
import 'package:flutter_swiper_view/flutter_swiper_view.dart';
|
||||||
import 'package:nylo_framework/nylo_framework.dart';
|
import 'package:nylo_framework/nylo_framework.dart';
|
||||||
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/product.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
class RefreshableScrollContainer extends StatelessWidget {
|
class RefreshableScrollContainer extends StatelessWidget {
|
||||||
@ -108,7 +108,7 @@ class RefreshableScrollContainer extends StatelessWidget {
|
|||||||
.map((product) => StaggeredGridTile.fit(
|
.map((product) => StaggeredGridTile.fit(
|
||||||
crossAxisCellCount: 1,
|
crossAxisCellCount: 1,
|
||||||
child: Container(
|
child: Container(
|
||||||
height: 200,
|
height: 300,
|
||||||
child: ProductItemContainer(
|
child: ProductItemContainer(
|
||||||
product: product,
|
product: product,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
@ -138,10 +138,19 @@ class CheckoutRowLine extends StatelessWidget {
|
|||||||
final bool showBorderBottom;
|
final bool showBorderBottom;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Flexible(
|
Widget build(BuildContext context) => Container(
|
||||||
child: InkWell(
|
|
||||||
child: Container(
|
|
||||||
height: 125,
|
height: 125,
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
decoration: showBorderBottom == true
|
||||||
|
? BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(color: Colors.black12, width: 1),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: BoxDecoration(),
|
||||||
|
child: InkWell(
|
||||||
|
onTap: action,
|
||||||
|
borderRadius: BorderRadius.circular(8),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
@ -190,19 +199,7 @@ class CheckoutRowLine extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.all(8),
|
|
||||||
decoration: showBorderBottom == true
|
|
||||||
? BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(color: Colors.black12, width: 1),
|
|
||||||
),
|
),
|
||||||
)
|
|
||||||
: BoxDecoration(),
|
|
||||||
),
|
|
||||||
onTap: action,
|
|
||||||
borderRadius: BorderRadius.circular(8),
|
|
||||||
),
|
|
||||||
flex: 3,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,16 +312,17 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
if (product == null) {
|
if (product == null) {
|
||||||
return SizedBox.shrink();
|
return SizedBox.shrink();
|
||||||
}
|
}
|
||||||
return LayoutBuilder(
|
|
||||||
builder: (cxt, constraints) => InkWell(
|
double height = 280;
|
||||||
|
return InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
margin: EdgeInsets.all(4),
|
margin: EdgeInsets.all(4),
|
||||||
child: Column(
|
child: ListView(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
shrinkWrap: true,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
physics: NeverScrollableScrollPhysics(),
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Container(
|
Container(
|
||||||
height: constraints.maxHeight / 2,
|
height: 180,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(3.0),
|
borderRadius: BorderRadius.circular(3.0),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
@ -339,9 +337,11 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
? product!.images.first.src
|
? product!.images.first.src
|
||||||
: getEnv("PRODUCT_PLACEHOLDER_IMAGE")),
|
: getEnv("PRODUCT_PLACEHOLDER_IMAGE")),
|
||||||
fit: BoxFit.contain,
|
fit: BoxFit.contain,
|
||||||
height: constraints.maxHeight / 2,
|
height: height,
|
||||||
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 +351,6 @@ 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),
|
|
||||||
),
|
),
|
||||||
child: RichText(
|
child: RichText(
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
@ -366,8 +365,8 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
.textTheme
|
.textTheme
|
||||||
.bodyLarge!
|
.bodyLarge!
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Colors.black87,
|
color: Colors.black,
|
||||||
fontSize: 11,
|
fontSize: 13,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -391,18 +390,18 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Flexible(
|
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")
|
||||||
@ -435,7 +434,6 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
].toList(),
|
].toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -443,7 +441,6 @@ class ProductItemContainer extends StatelessWidget {
|
|||||||
? onTap!(product)
|
? onTap!(product)
|
||||||
: Navigator.pushNamed(context, "/product-detail",
|
: Navigator.pushNamed(context, "/product-detail",
|
||||||
arguments: product),
|
arguments: product),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 77 KiB |
@ -1,14 +1,14 @@
|
|||||||
# Official WooSignal App Template for WooCommerce
|
# Official WooSignal App Template for WooCommerce
|
||||||
|
|
||||||
# Label StoreMax
|
# Label StoreMax
|
||||||
# Version: 6.5.0
|
# Version: 6.10.1
|
||||||
# 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
|
||||||
|
|
||||||
### Change App Icon
|
### Change App Icon
|
||||||
# 1 Replace: public/assets/icon/appicon.png (1024px1024px icon size)
|
# 1 Replace: public/assets/icon/appicon.png (1024px1024px icon size)
|
||||||
# 2 Run this command from the terminal: "flutter pub run flutter_launcher_icons:main"
|
# 2 Run this command from the terminal: "dart pub run flutter_launcher_icons:main"
|
||||||
|
|
||||||
### Uploading the IOS/Android app
|
### Uploading the IOS/Android app
|
||||||
# IOS https://flutter.dev/docs/deployment/ios
|
# IOS https://flutter.dev/docs/deployment/ios
|
||||||
@ -22,37 +22,36 @@ 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.5
|
||||||
analyzer: ^4.2.0
|
analyzer: ^5.12.0
|
||||||
intl: ^0.17.0
|
intl: ^0.18.0
|
||||||
nylo_framework: ^4.1.4
|
nylo_framework: ^5.3.2
|
||||||
woosignal: ^3.3.0
|
woosignal: ^3.8.0
|
||||||
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
|
||||||
package_info: ^2.0.2
|
package_info_plus: ^4.1.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.12
|
||||||
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
|
||||||
html: ^0.15.1
|
html: ^0.15.1
|
||||||
flutter_widget_from_html_core: ^0.10.0
|
flutter_widget_from_html_core: ^0.10.2
|
||||||
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.6.7
|
||||||
firebase_core: ^2.7.0
|
firebase_core: ^2.15.1
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
@ -61,16 +60,22 @@ dependencies:
|
|||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# 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.17.1
|
||||||
|
flutter_stripe: ^9.3.0
|
||||||
|
razorpay_flutter: ^1.3.5
|
||||||
|
animate_do: ^3.0.2
|
||||||
|
|
||||||
|
dependency_overrides:
|
||||||
|
http: ^1.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_launcher_icons: ^0.12.0
|
flutter_launcher_icons: ^0.13.1
|
||||||
lints: ^2.0.0
|
lints: ^2.1.1
|
||||||
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.0
|
### Label StoreMax
|
||||||
|
|
||||||
|
|
||||||
[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, RazorPay
|
||||||
- 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
|
||||||
|
|
||||||
|
|||||||