Changes and tweaks
This commit is contained in:
parent
b578ac63d4
commit
b3eef2047d
1
LabelStoreMax/.flutter-plugins-dependencies
Normal file
1
LabelStoreMax/.flutter-plugins-dependencies
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"device_info","dependencies":[]},{"name":"flutter_money_formatter","dependencies":[]},{"name":"flutter_web_browser","dependencies":[]},{"name":"fluttertoast","dependencies":[]},{"name":"package_info","dependencies":[]},{"name":"path_provider","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]},{"name":"sqflite","dependencies":[]},{"name":"woosignal_stripe","dependencies":[]}]}
|
||||||
@ -25,6 +25,12 @@ apply plugin: 'com.android.application'
|
|||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
|
def keystoreProperties = new Properties()
|
||||||
|
def keystorePropertiesFile = rootProject.file('key.properties')
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 28
|
||||||
|
|
||||||
@ -37,7 +43,6 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
|
||||||
applicationId "com.woosignal.label_storemax"
|
applicationId "com.woosignal.label_storemax"
|
||||||
minSdkVersion 28
|
minSdkVersion 28
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
@ -47,13 +52,20 @@ android {
|
|||||||
multiDexEnabled = true
|
multiDexEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
// TODO: Add your own signing config for the release build.
|
keyAlias keystoreProperties['keyAlias']
|
||||||
// Signing with the debug keys for now, so `flutter run --release` works.
|
keyPassword keystoreProperties['keyPassword']
|
||||||
signingConfig signingConfigs.debug
|
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
|
||||||
|
storePassword keystoreProperties['storePassword']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
|||||||
4
LabelStoreMax/android/key.properties
Normal file
4
LabelStoreMax/android/key.properties
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
storePassword=<password>
|
||||||
|
keyPassword=<password>
|
||||||
|
keyAlias=key
|
||||||
|
storeFile=<location of the key store file, e.g. /Users/<user name>/key.jks>
|
||||||
18
LabelStoreMax/ios/Flutter/Flutter.podspec
Normal file
18
LabelStoreMax/ios/Flutter/Flutter.podspec
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#
|
||||||
|
# NOTE: This podspec is NOT to be published. It is only used as a local source!
|
||||||
|
#
|
||||||
|
|
||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'Flutter'
|
||||||
|
s.version = '1.0.0'
|
||||||
|
s.summary = 'High-performance, high-fidelity mobile apps.'
|
||||||
|
s.description = <<-DESC
|
||||||
|
Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS.
|
||||||
|
DESC
|
||||||
|
s.homepage = 'https://flutter.io'
|
||||||
|
s.license = { :type => 'MIT' }
|
||||||
|
s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' }
|
||||||
|
s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s }
|
||||||
|
s.ios.deployment_target = '8.0'
|
||||||
|
s.vendored_frameworks = 'Flutter.framework'
|
||||||
|
end
|
||||||
90
LabelStoreMax/ios/Podfile
Normal file
90
LabelStoreMax/ios/Podfile
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Uncomment this line to define a global platform for your project
|
||||||
|
# platform :ios, '9.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 parse_KV_file(file, separator='=')
|
||||||
|
file_abs_path = File.expand_path(file)
|
||||||
|
if !File.exists? file_abs_path
|
||||||
|
return [];
|
||||||
|
end
|
||||||
|
generated_key_values = {}
|
||||||
|
skip_line_start_symbols = ["#", "/"]
|
||||||
|
File.foreach(file_abs_path) do |line|
|
||||||
|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||||
|
plugin = line.split(pattern=separator)
|
||||||
|
if plugin.length == 2
|
||||||
|
podname = plugin[0].strip()
|
||||||
|
path = plugin[1].strip()
|
||||||
|
podpath = File.expand_path("#{path}", file_abs_path)
|
||||||
|
generated_key_values[podname] = podpath
|
||||||
|
else
|
||||||
|
puts "Invalid plugin specification: #{line}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
generated_key_values
|
||||||
|
end
|
||||||
|
|
||||||
|
target 'Runner' do
|
||||||
|
use_frameworks!
|
||||||
|
use_modular_headers!
|
||||||
|
|
||||||
|
# Flutter Pod
|
||||||
|
|
||||||
|
copied_flutter_dir = File.join(__dir__, 'Flutter')
|
||||||
|
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
|
||||||
|
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
|
||||||
|
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
|
||||||
|
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
|
||||||
|
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
|
||||||
|
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
||||||
|
|
||||||
|
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
|
||||||
|
unless File.exist?(generated_xcode_build_settings_path)
|
||||||
|
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||||
|
end
|
||||||
|
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
|
||||||
|
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
|
||||||
|
|
||||||
|
unless File.exist?(copied_framework_path)
|
||||||
|
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
|
||||||
|
end
|
||||||
|
unless File.exist?(copied_podspec_path)
|
||||||
|
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||||
|
pod 'Flutter', :path => 'Flutter'
|
||||||
|
|
||||||
|
# Plugin Pods
|
||||||
|
|
||||||
|
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||||
|
# referring to absolute paths on developers' machines.
|
||||||
|
system('rm -rf .symlinks')
|
||||||
|
system('mkdir -p .symlinks/plugins')
|
||||||
|
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||||
|
plugin_pods.each do |name, path|
|
||||||
|
symlink = File.join('.symlinks', 'plugins', name)
|
||||||
|
File.symlink(path, symlink)
|
||||||
|
pod name, :path => File.join(symlink, 'ios')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system.
|
||||||
|
install! 'cocoapods', :disable_input_output_paths => true
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
95
LabelStoreMax/ios/Podfile.lock
Normal file
95
LabelStoreMax/ios/Podfile.lock
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
PODS:
|
||||||
|
- device_info (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- Flutter (1.0.0)
|
||||||
|
- flutter_money_formatter (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- flutter_web_browser (0.11.0):
|
||||||
|
- Flutter
|
||||||
|
- fluttertoast (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- FMDB (2.7.5):
|
||||||
|
- FMDB/standard (= 2.7.5)
|
||||||
|
- FMDB/standard (2.7.5)
|
||||||
|
- package_info (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- path_provider (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- shared_preferences (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- shared_preferences_macos (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- shared_preferences_web (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- sqflite (0.0.1):
|
||||||
|
- Flutter
|
||||||
|
- FMDB (~> 2.7.2)
|
||||||
|
- Stripe (19.0.1)
|
||||||
|
- woosignal_stripe (0.0.4):
|
||||||
|
- Flutter
|
||||||
|
- Stripe (= 19.0.1)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||||
|
- Flutter (from `Flutter`)
|
||||||
|
- flutter_money_formatter (from `.symlinks/plugins/flutter_money_formatter/ios`)
|
||||||
|
- flutter_web_browser (from `.symlinks/plugins/flutter_web_browser/ios`)
|
||||||
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
|
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||||
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
|
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||||
|
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
|
||||||
|
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)
|
||||||
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
|
- woosignal_stripe (from `.symlinks/plugins/woosignal_stripe/ios`)
|
||||||
|
|
||||||
|
SPEC REPOS:
|
||||||
|
trunk:
|
||||||
|
- FMDB
|
||||||
|
- Stripe
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
device_info:
|
||||||
|
:path: ".symlinks/plugins/device_info/ios"
|
||||||
|
Flutter:
|
||||||
|
:path: Flutter
|
||||||
|
flutter_money_formatter:
|
||||||
|
:path: ".symlinks/plugins/flutter_money_formatter/ios"
|
||||||
|
flutter_web_browser:
|
||||||
|
:path: ".symlinks/plugins/flutter_web_browser/ios"
|
||||||
|
fluttertoast:
|
||||||
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
|
package_info:
|
||||||
|
:path: ".symlinks/plugins/package_info/ios"
|
||||||
|
path_provider:
|
||||||
|
:path: ".symlinks/plugins/path_provider/ios"
|
||||||
|
shared_preferences:
|
||||||
|
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||||
|
shared_preferences_macos:
|
||||||
|
:path: ".symlinks/plugins/shared_preferences_macos/ios"
|
||||||
|
shared_preferences_web:
|
||||||
|
:path: ".symlinks/plugins/shared_preferences_web/ios"
|
||||||
|
sqflite:
|
||||||
|
:path: ".symlinks/plugins/sqflite/ios"
|
||||||
|
woosignal_stripe:
|
||||||
|
:path: ".symlinks/plugins/woosignal_stripe/ios"
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
device_info: cbf09d2ec12aa7110e0b09fabe54b5bd6c8efe74
|
||||||
|
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||||
|
flutter_money_formatter: d0d18ddc5be333fad8d09964d741b59fa11a91dc
|
||||||
|
flutter_web_browser: bdea232160dec44dec86540bee05168cc844ef7c
|
||||||
|
fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b
|
||||||
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
package_info: 48b108e75b8802c2d5e126f208ef540561c98aef
|
||||||
|
path_provider: f96fff6166a8867510d2c25fdcc346327cc4b259
|
||||||
|
shared_preferences: 430726339841afefe5142b9c1f50cb6bd7793e01
|
||||||
|
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
|
||||||
|
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9
|
||||||
|
sqflite: ff1d9da63c06588cc8d1faf7256d741f16989d5a
|
||||||
|
Stripe: 03313f9520a0786e2c00d9a7a2672c11e08821af
|
||||||
|
woosignal_stripe: 55c9a08f483aae42ca1c9769f5c474802b865f17
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 1b66dae606f75376c5f2135a8290850eeb09ae83
|
||||||
|
|
||||||
|
COCOAPODS: 1.9.1
|
||||||
@ -90,5 +90,7 @@
|
|||||||
"About Us": "About Us",
|
"About Us": "About Us",
|
||||||
"Something went wrong": "Something went wrong",
|
"Something went wrong": "Something went wrong",
|
||||||
"Product variation does not exist": "Product variation does not exist",
|
"Product variation does not exist": "Product variation does not exist",
|
||||||
"This variation is unavailable": "This variation is unavailable"
|
"This variation is unavailable": "This variation is unavailable",
|
||||||
|
"Sorry, something went wrong": "Sorry, something went wrong",
|
||||||
|
"Back": "Back"
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
|||||||
29
LabelStoreMax/lib/app_payment_methods.dart
Normal file
29
LabelStoreMax/lib/app_payment_methods.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/payment_type.dart';
|
||||||
|
import 'package:label_storemax/providers/stripe_pay.dart';
|
||||||
|
|
||||||
|
// Payment methods available for uses in the app
|
||||||
|
// To use use a payment method, include the PaymentType "name" in the app_payment_methods variable in #labelconfig.dart
|
||||||
|
|
||||||
|
List<PaymentType> arrPaymentMethods = [
|
||||||
|
addPayment(
|
||||||
|
PaymentType(
|
||||||
|
id: 1,
|
||||||
|
name: "Stripe",
|
||||||
|
desc: "Debit or Credit Card",
|
||||||
|
assetImage: "dark_powered_by_stripe.png",
|
||||||
|
pay: stripePay,),
|
||||||
|
),
|
||||||
|
|
||||||
|
// e.g. add more here
|
||||||
|
|
||||||
|
// addPayment(
|
||||||
|
// PaymentType(
|
||||||
|
// id: 2,
|
||||||
|
// name: "MyNewPaymentMethod",
|
||||||
|
// desc: "Debit or Credit Card",
|
||||||
|
// assetImage: "add icon image to assets/images/myimage.png",
|
||||||
|
// pay: stripePay
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
];
|
||||||
@ -1,72 +0,0 @@
|
|||||||
// Label StoreMAX
|
|
||||||
//
|
|
||||||
// Created by Anthony Gordon.
|
|
||||||
// Copyright © 2019 WooSignal. 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.
|
|
||||||
|
|
||||||
var appCountryOptions = [
|
|
||||||
{"code": "*", "title": "Match all states"},
|
|
||||||
{"code": "AL", "title": "Alabama"},
|
|
||||||
{"code": "AK", "title": "Alaska"},
|
|
||||||
{"code": "AS", "title": "American Samoa"},
|
|
||||||
{"code": "AZ", "title": "Arizona"},
|
|
||||||
{"code": "AR", "title": "Arkansas"},
|
|
||||||
{"code": "CA", "title": "California"},
|
|
||||||
{"code": "CO", "title": "Colorado"},
|
|
||||||
{"code": "CT", "title": "Connecticut"},
|
|
||||||
{"code": "DE", "title": "Delaware"},
|
|
||||||
{"code": "DC", "title": "District Of Columbia"},
|
|
||||||
{"code": "FM", "title": "Federated States Of Micronesia"},
|
|
||||||
{"code": "FL", "title": "Florida"},
|
|
||||||
{"code": "GA", "title": "Georgia"},
|
|
||||||
{"code": "GU", "title": "Guam"},
|
|
||||||
{"code": "HI", "title": "Hawaii"},
|
|
||||||
{"code": "ID", "title": "Idaho"},
|
|
||||||
{"code": "IL", "title": "Illinois"},
|
|
||||||
{"code": "IN", "title": "Indiana"},
|
|
||||||
{"code": "IA", "title": "Iowa"},
|
|
||||||
{"code": "KS", "title": "Kansas"},
|
|
||||||
{"code": "KY", "title": "Kentucky"},
|
|
||||||
{"code": "LA", "title": "Louisiana"},
|
|
||||||
{"code": "ME", "title": "Maine"},
|
|
||||||
{"code": "MH", "title": "Marshall Islands"},
|
|
||||||
{"code": "MD", "title": "Maryland"},
|
|
||||||
{"code": "MA", "title": "Massachusetts"},
|
|
||||||
{"code": "MI", "title": "Michigan"},
|
|
||||||
{"code": "MN", "title": "Minnesota"},
|
|
||||||
{"code": "MS", "title": "Mississippi"},
|
|
||||||
{"code": "MO", "title": "Missouri"},
|
|
||||||
{"code": "MT", "title": "Montana"},
|
|
||||||
{"code": "NE", "title": "Nebraska"},
|
|
||||||
{"code": "NV", "title": "Nevada"},
|
|
||||||
{"code": "NH", "title": "New Hampshire"},
|
|
||||||
{"code": "NJ", "title": "New Jersey"},
|
|
||||||
{"code": "NM", "title": "New Mexico"},
|
|
||||||
{"code": "NY", "title": "New York"},
|
|
||||||
{"code": "NC", "title": "North Carolina"},
|
|
||||||
{"code": "ND", "title": "North Dakota"},
|
|
||||||
{"code": "MP", "title": "Northern Mariana Islands"},
|
|
||||||
{"code": "OH", "title": "Ohio"},
|
|
||||||
{"code": "OK", "title": "Oklahoma"},
|
|
||||||
{"code": "OR", "title": "Oregon"},
|
|
||||||
{"code": "PW", "title": "Palau"},
|
|
||||||
{"code": "PA", "title": "Pennsylvania"},
|
|
||||||
{"code": "PR", "title": "Puerto Rico"},
|
|
||||||
{"code": "RI", "title": "Rhode Island"},
|
|
||||||
{"code": "SC", "title": "South Carolina"},
|
|
||||||
{"code": "SD", "title": "South Dakota"},
|
|
||||||
{"code": "TN", "title": "Tennessee"},
|
|
||||||
{"code": "TX", "title": "Texas"},
|
|
||||||
{"code": "UT", "title": "Utah"},
|
|
||||||
{"code": "VT", "title": "Vermont"},
|
|
||||||
{"code": "VI", "title": "Virgin Islands"},
|
|
||||||
{"code": "VA", "title": "Virginia"},
|
|
||||||
{"code": "WA", "title": "Washington"},
|
|
||||||
{"code": "WV", "title": "West Virginia"},
|
|
||||||
{"code": "WI", "title": "Wisconsin"},
|
|
||||||
{"code": "WY", "title": "Wyoming"}
|
|
||||||
];
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -14,6 +14,8 @@ import 'dart:convert';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
import '../labelconfig.dart';
|
||||||
|
|
||||||
class AppLocalizations {
|
class AppLocalizations {
|
||||||
final Locale locale;
|
final Locale locale;
|
||||||
|
|
||||||
@ -48,7 +50,8 @@ class _AppLocalizationsDelegate
|
|||||||
const _AppLocalizationsDelegate();
|
const _AppLocalizationsDelegate();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
|
bool isSupported(Locale locale) =>
|
||||||
|
app_locales_supported.contains(locale.languageCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
bool shouldReload(_AppLocalizationsDelegate old) => false;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
|||||||
100
LabelStoreMax/lib/helpers/data/order_wc.dart
Normal file
100
LabelStoreMax/lib/helpers/data/order_wc.dart
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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 'dart:io';
|
||||||
|
|
||||||
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
|
import 'package:label_storemax/models/billing_details.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
|
Future<OrderWC> buildOrderWC({TaxRate taxRate}) async {
|
||||||
|
OrderWC orderWC = OrderWC();
|
||||||
|
|
||||||
|
String paymentMethodName = CheckoutSession.getInstance.paymentType.name ?? "";
|
||||||
|
|
||||||
|
orderWC.paymentMethod = Platform.isAndroid
|
||||||
|
? "$paymentMethodName - Android App"
|
||||||
|
: "$paymentMethodName - IOS App";
|
||||||
|
|
||||||
|
orderWC.paymentMethodTitle = paymentMethodName.toLowerCase();
|
||||||
|
|
||||||
|
orderWC.setPaid = true;
|
||||||
|
orderWC.status = "pending";
|
||||||
|
orderWC.currency = app_currency_iso.toUpperCase();
|
||||||
|
|
||||||
|
List<LineItems> lineItems = [];
|
||||||
|
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||||
|
cartItems.forEach((cartItem) {
|
||||||
|
LineItems tmpLineItem = LineItems();
|
||||||
|
tmpLineItem.quantity = cartItem.quantity;
|
||||||
|
tmpLineItem.name = cartItem.name;
|
||||||
|
tmpLineItem.productId = cartItem.productId;
|
||||||
|
if (cartItem.variationId != null && cartItem.variationId != 0) {
|
||||||
|
tmpLineItem.variationId = cartItem.variationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmpLineItem.total = cartItem.total;
|
||||||
|
tmpLineItem.subtotal = cartItem.subtotal;
|
||||||
|
|
||||||
|
lineItems.add(tmpLineItem);
|
||||||
|
});
|
||||||
|
|
||||||
|
orderWC.lineItems = lineItems;
|
||||||
|
|
||||||
|
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||||
|
|
||||||
|
Billing billing = Billing();
|
||||||
|
billing.firstName = billingDetails.billingAddress.firstName;
|
||||||
|
billing.lastName = billingDetails.billingAddress.lastName;
|
||||||
|
billing.address1 = billingDetails.billingAddress.addressLine;
|
||||||
|
billing.city = billingDetails.billingAddress.city;
|
||||||
|
billing.postcode = billingDetails.billingAddress.postalCode;
|
||||||
|
billing.country = billingDetails.billingAddress.country;
|
||||||
|
billing.email = billingDetails.billingAddress.emailAddress;
|
||||||
|
|
||||||
|
orderWC.billing = billing;
|
||||||
|
|
||||||
|
Shipping shipping = Shipping();
|
||||||
|
shipping.firstName = billingDetails.shippingAddress.firstName;
|
||||||
|
shipping.lastName = billingDetails.shippingAddress.lastName;
|
||||||
|
shipping.address1 = billingDetails.shippingAddress.addressLine;
|
||||||
|
shipping.city = billingDetails.shippingAddress.city;
|
||||||
|
shipping.postcode = billingDetails.shippingAddress.postalCode;
|
||||||
|
shipping.country = billingDetails.shippingAddress.country;
|
||||||
|
|
||||||
|
orderWC.shipping = shipping;
|
||||||
|
|
||||||
|
orderWC.shippingLines = [];
|
||||||
|
Map<String, dynamic> shippingLineFeeObj =
|
||||||
|
CheckoutSession.getInstance.shippingType.toShippingLineFee();
|
||||||
|
if (shippingLineFeeObj != null) {
|
||||||
|
ShippingLines shippingLine = ShippingLines();
|
||||||
|
shippingLine.methodId = shippingLineFeeObj['method_id'];
|
||||||
|
shippingLine.methodTitle = shippingLineFeeObj['method_title'];
|
||||||
|
shippingLine.total = shippingLineFeeObj['total'];
|
||||||
|
orderWC.shippingLines.add(shippingLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taxRate != null) {
|
||||||
|
orderWC.feeLines = [];
|
||||||
|
FeeLines feeLines = FeeLines();
|
||||||
|
feeLines.name = taxRate.name;
|
||||||
|
feeLines.total = await Cart.getInstance.taxAmount(taxRate);
|
||||||
|
feeLines.taxClass = "";
|
||||||
|
feeLines.taxStatus = "taxable";
|
||||||
|
orderWC.feeLines.add(feeLines);
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderWC;
|
||||||
|
}
|
||||||
28
LabelStoreMax/lib/helpers/shared_pref.dart
Normal file
28
LabelStoreMax/lib/helpers/shared_pref.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
|
class SharedPref {
|
||||||
|
read(String key) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
return prefs.getString(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
save(String key, value) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.setString(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(String key) async {
|
||||||
|
final prefs = await SharedPreferences.getInstance();
|
||||||
|
prefs.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,50 +1,42 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
// 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:label_storemax/app_payment_methods.dart';
|
||||||
import 'package:label_storemax/helpers/app_localizations.dart';
|
import 'package:label_storemax/helpers/app_localizations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
import 'package:edge_alert/edge_alert.dart';
|
import 'package:edge_alert/edge_alert.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:label_storemax/models/billing_details.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/payment_type.dart';
|
||||||
import 'package:html/parser.dart';
|
import 'package:html/parser.dart';
|
||||||
import 'package:flutter_web_browser/flutter_web_browser.dart';
|
import 'package:flutter_web_browser/flutter_web_browser.dart';
|
||||||
import 'dart:convert';
|
|
||||||
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
|
import 'package:flutter_money_formatter/flutter_money_formatter.dart';
|
||||||
import 'package:woosignal/models/response/shipping_method.dart';
|
import 'package:status_alert/status_alert.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
import 'package:woosignal/woosignal.dart';
|
||||||
|
|
||||||
// CONFIG FOR WOOSIGNAL API
|
appWooSignal(Function(WooSignal) api) async {
|
||||||
var wsConfig = {"appKey": app_key, "debugMode": app_debug};
|
WooSignal wooSignal = await WooSignal.getInstance(
|
||||||
|
config: {"appKey": app_key, "debugMode": app_debug});
|
||||||
// MARK: PaymentMethodType
|
return await api(wooSignal);
|
||||||
class PaymentType {
|
|
||||||
int id;
|
|
||||||
String name;
|
|
||||||
String assetImage;
|
|
||||||
|
|
||||||
PaymentType({this.id, this.name, this.assetImage});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<PaymentType> arrPaymentMethods = [
|
|
||||||
(paymentMethods.contains("Stripe")
|
|
||||||
? (PaymentType(
|
|
||||||
id: 1,
|
|
||||||
name: "Debit or Credit Card",
|
|
||||||
assetImage: "dark_powered_by_stripe.png"))
|
|
||||||
: null)
|
|
||||||
];
|
|
||||||
|
|
||||||
List<PaymentType> getPaymentTypes() {
|
List<PaymentType> getPaymentTypes() {
|
||||||
return arrPaymentMethods;
|
return arrPaymentMethods.where((v) => v != null).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
PaymentType addPayment(PaymentType paymentType) {
|
||||||
|
return app_payment_methods.contains(paymentType.name) ? paymentType : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class HexColor extends Color {
|
class HexColor extends Color {
|
||||||
@ -65,29 +57,12 @@ String truncateWithEllipsis(int cutoff, String myString) {
|
|||||||
: '${myString.substring(0, cutoff)}...';
|
: '${myString.substring(0, cutoff)}...';
|
||||||
}
|
}
|
||||||
|
|
||||||
class TextFieldMaker extends TextField {
|
|
||||||
static TextField makeWith(labelTitle) {
|
|
||||||
return TextField(
|
|
||||||
decoration: InputDecoration(
|
|
||||||
labelText: labelTitle,
|
|
||||||
labelStyle: TextStyle(
|
|
||||||
fontFamily: 'Overpass',
|
|
||||||
fontWeight: FontWeight.bold,
|
|
||||||
color: Colors.grey),
|
|
||||||
focusedBorder: UnderlineInputBorder(
|
|
||||||
borderSide: BorderSide(color: Colors.green))),
|
|
||||||
keyboardAppearance: Brightness.light,
|
|
||||||
keyboardType: TextInputType.emailAddress,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void showToastWith({String message, String statusType}) {
|
void showToastWith({String message, String statusType}) {
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
msg: message,
|
msg: message,
|
||||||
toastLength: Toast.LENGTH_SHORT,
|
toastLength: Toast.LENGTH_SHORT,
|
||||||
gravity: ToastGravity.CENTER,
|
gravity: ToastGravity.CENTER,
|
||||||
timeInSecForIos: 3,
|
timeInSecForIosWeb: 3,
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
(statusType == "error" ? HexColor("#b5123a") : Colors.grey),
|
(statusType == "error" ? HexColor("#b5123a") : Colors.grey),
|
||||||
textColor: (statusType == "error" ? Colors.white : Colors.black),
|
textColor: (statusType == "error" ? Colors.white : Colors.black),
|
||||||
@ -98,26 +73,15 @@ void showToastNetworkError() {
|
|||||||
showToastWith(message: "Oops, something went wrong");
|
showToastWith(message: "Oops, something went wrong");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEmail(String em) {
|
showStatusAlert(context,
|
||||||
String p =
|
{@required String title, String subtitle, IconData icon, int duration}) {
|
||||||
r'^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
|
StatusAlert.show(
|
||||||
RegExp regExp = new RegExp(p);
|
context,
|
||||||
return regExp.hasMatch(em);
|
duration: Duration(seconds: duration ?? 2),
|
||||||
}
|
title: title,
|
||||||
|
subtitle: subtitle,
|
||||||
// 6 LENGTH, 1 DIGIT
|
configuration: IconConfiguration(icon: icon ?? Icons.done, size: 50),
|
||||||
bool validPassword(String pw) {
|
);
|
||||||
String p = r'^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,}$';
|
|
||||||
RegExp regExp = new RegExp(p);
|
|
||||||
return regExp.hasMatch(pw);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget showAppLoader() {
|
|
||||||
return SpinKitDoubleBounce(color: HexColor("#393318"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future delayFunction(void Function() action) {
|
|
||||||
return Future.delayed(const Duration(milliseconds: 300), action);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class PaymentMethodType {
|
class PaymentMethodType {
|
||||||
@ -176,218 +140,19 @@ void showEdgeAlertWith(context,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void errorWithNetworkDefault(BuildContext context) {
|
|
||||||
showEdgeAlertWith(context,
|
|
||||||
title: trans(context, "Oops"),
|
|
||||||
desc: trans(context, "Something went wrong"),
|
|
||||||
style: EdgeAlertStyle.DANGER);
|
|
||||||
}
|
|
||||||
|
|
||||||
String parseHtmlString(String htmlString) {
|
String parseHtmlString(String htmlString) {
|
||||||
var document = parse(htmlString);
|
var document = parse(htmlString);
|
||||||
String parsedString = parse(document.body.text).documentElement.text;
|
String parsedString = parse(document.body.text).documentElement.text;
|
||||||
return parsedString;
|
return parsedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CartLineItem {
|
|
||||||
String name;
|
|
||||||
int productId;
|
|
||||||
int variationId;
|
|
||||||
int quantity;
|
|
||||||
bool isManagedStock;
|
|
||||||
int stockQuantity;
|
|
||||||
String shippingClassId;
|
|
||||||
String taxStatus;
|
|
||||||
String taxClass;
|
|
||||||
bool shippingIsTaxable;
|
|
||||||
String subtotal;
|
|
||||||
String total;
|
|
||||||
String imageSrc;
|
|
||||||
String variationOptions;
|
|
||||||
String stockStatus;
|
|
||||||
Object metaData = {};
|
|
||||||
|
|
||||||
CartLineItem(
|
|
||||||
{this.name,
|
|
||||||
this.productId,
|
|
||||||
this.variationId,
|
|
||||||
this.isManagedStock,
|
|
||||||
this.stockQuantity,
|
|
||||||
this.quantity,
|
|
||||||
this.stockStatus,
|
|
||||||
this.shippingClassId,
|
|
||||||
this.taxStatus,
|
|
||||||
this.taxClass,
|
|
||||||
this.shippingIsTaxable,
|
|
||||||
this.variationOptions,
|
|
||||||
this.imageSrc,
|
|
||||||
this.subtotal,
|
|
||||||
this.total,
|
|
||||||
this.metaData});
|
|
||||||
|
|
||||||
CartLineItem.fromJson(Map<String, dynamic> json)
|
|
||||||
: name = json['name'],
|
|
||||||
productId = json['product_id'],
|
|
||||||
variationId = json['variation_id'],
|
|
||||||
quantity = json['quantity'],
|
|
||||||
shippingClassId = json['shipping_class_id'].toString(),
|
|
||||||
taxStatus = json['tax_status'],
|
|
||||||
stockQuantity = json['stock_quantity'],
|
|
||||||
isManagedStock = json['is_managed_stock'],
|
|
||||||
shippingIsTaxable = json['shipping_is_taxable'],
|
|
||||||
subtotal = json['subtotal'],
|
|
||||||
total = json['total'],
|
|
||||||
taxClass = json['tax_class'],
|
|
||||||
stockStatus = json['stock_status'],
|
|
||||||
imageSrc = json['image_src'],
|
|
||||||
variationOptions = json['variation_options'],
|
|
||||||
metaData = json['metaData'];
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
|
||||||
'name': name,
|
|
||||||
'product_id': productId,
|
|
||||||
'variation_id': variationId,
|
|
||||||
'quantity': quantity,
|
|
||||||
'shipping_class_id': shippingClassId,
|
|
||||||
'tax_status': taxStatus,
|
|
||||||
'tax_class': taxClass,
|
|
||||||
'stock_status': stockStatus,
|
|
||||||
'is_managed_stock': isManagedStock,
|
|
||||||
'stock_quantity': stockQuantity,
|
|
||||||
'shipping_is_taxable': shippingIsTaxable,
|
|
||||||
'image_src': imageSrc,
|
|
||||||
'variation_options': variationOptions,
|
|
||||||
'subtotal': subtotal,
|
|
||||||
'total': total,
|
|
||||||
'meta_data': metaData,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
class SharedPref {
|
|
||||||
read(String key) async {
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
|
||||||
return prefs.getString(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
save(String key, value) async {
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
|
||||||
prefs.setString(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
remove(String key) async {
|
|
||||||
final prefs = await SharedPreferences.getInstance();
|
|
||||||
prefs.remove(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CustomerAddress {
|
|
||||||
String firstName;
|
|
||||||
String lastName;
|
|
||||||
String addressLine;
|
|
||||||
String city;
|
|
||||||
String postalCode;
|
|
||||||
String country;
|
|
||||||
String emailAddress;
|
|
||||||
|
|
||||||
CustomerAddress(
|
|
||||||
{this.firstName,
|
|
||||||
this.lastName,
|
|
||||||
this.addressLine,
|
|
||||||
this.city,
|
|
||||||
this.postalCode,
|
|
||||||
this.country,
|
|
||||||
this.emailAddress});
|
|
||||||
|
|
||||||
void initAddress() {
|
|
||||||
firstName = "";
|
|
||||||
lastName = "";
|
|
||||||
addressLine = "";
|
|
||||||
city = "";
|
|
||||||
postalCode = "";
|
|
||||||
country = "";
|
|
||||||
emailAddress = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasMissingFields() {
|
|
||||||
return (this.firstName.isEmpty ||
|
|
||||||
this.lastName.isEmpty ||
|
|
||||||
this.addressLine.isEmpty ||
|
|
||||||
this.city.isEmpty ||
|
|
||||||
this.postalCode.isEmpty);
|
|
||||||
}
|
|
||||||
|
|
||||||
String addressFull() {
|
|
||||||
List<String> tmpArrAddress = new List<String>();
|
|
||||||
if (addressLine != "") {
|
|
||||||
tmpArrAddress.add(addressLine);
|
|
||||||
}
|
|
||||||
if (city != "") {
|
|
||||||
tmpArrAddress.add(city);
|
|
||||||
}
|
|
||||||
if (postalCode != "") {
|
|
||||||
tmpArrAddress.add(postalCode);
|
|
||||||
}
|
|
||||||
if (country != "") {
|
|
||||||
tmpArrAddress.add(country);
|
|
||||||
}
|
|
||||||
return tmpArrAddress.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
String nameFull() {
|
|
||||||
List<String> tmpArrName = new List<String>();
|
|
||||||
if (firstName != "") {
|
|
||||||
tmpArrName.add(firstName);
|
|
||||||
}
|
|
||||||
if (lastName != "") {
|
|
||||||
tmpArrName.add(lastName);
|
|
||||||
}
|
|
||||||
return tmpArrName.join(", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomerAddress.fromJson(Map<String, dynamic> json) {
|
|
||||||
firstName = json['first_name'];
|
|
||||||
lastName = json['last_name'];
|
|
||||||
addressLine = json['address_line'];
|
|
||||||
city = json['city'];
|
|
||||||
postalCode = json['postal_code'];
|
|
||||||
country = json['country'];
|
|
||||||
emailAddress = json['email_address'];
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
final Map<String, dynamic> data = new Map<String, dynamic>();
|
|
||||||
data['first_name'] = this.firstName;
|
|
||||||
data['last_name'] = this.lastName;
|
|
||||||
data['address_line'] = this.addressLine;
|
|
||||||
data['city'] = this.city;
|
|
||||||
data['postal_code'] = this.postalCode;
|
|
||||||
data['country'] = this.country;
|
|
||||||
data['email_address'] = this.emailAddress;
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class BillingDetails {
|
|
||||||
CustomerAddress billingAddress;
|
|
||||||
CustomerAddress shippingAddress;
|
|
||||||
bool rememberDetails;
|
|
||||||
|
|
||||||
void initSession() {
|
|
||||||
billingAddress = CustomerAddress();
|
|
||||||
shippingAddress = CustomerAddress();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PaymentDetails {
|
|
||||||
String method;
|
|
||||||
}
|
|
||||||
|
|
||||||
String formatDoubleCurrency({double total}) {
|
String formatDoubleCurrency({double total}) {
|
||||||
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
||||||
amount: total,
|
amount: total,
|
||||||
settings: MoneyFormatterSettings(
|
settings: MoneyFormatterSettings(
|
||||||
symbol: app_currency_symbol,
|
symbol: app_currency_symbol,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
return fmf.output.symbolOnLeft;
|
return fmf.output.symbolOnLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,338 +164,15 @@ String formatStringCurrency({String total}) {
|
|||||||
tmpVal = double.parse(total);
|
tmpVal = double.parse(total);
|
||||||
}
|
}
|
||||||
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
FlutterMoneyFormatter fmf = FlutterMoneyFormatter(
|
||||||
amount: tmpVal,
|
amount: tmpVal,
|
||||||
settings: MoneyFormatterSettings(
|
settings: MoneyFormatterSettings(
|
||||||
symbol: app_currency_symbol,
|
symbol: app_currency_symbol,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
return fmf.output.symbolOnLeft;
|
return fmf.output.symbolOnLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShippingType {
|
openBrowserTab({@required String url}) async {
|
||||||
String methodId;
|
|
||||||
String cost;
|
|
||||||
dynamic object;
|
|
||||||
|
|
||||||
ShippingType({this.methodId, this.object, this.cost});
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() =>
|
|
||||||
{'methodId': methodId, 'object': object, 'cost': cost};
|
|
||||||
|
|
||||||
String getTotal({bool withFormatting}) {
|
|
||||||
if (this.methodId != null && this.object != null) {
|
|
||||||
switch (this.methodId) {
|
|
||||||
case "flat_rate":
|
|
||||||
FlatRate flatRate = (this.object as FlatRate);
|
|
||||||
return (withFormatting == true
|
|
||||||
? formatStringCurrency(total: cost)
|
|
||||||
: flatRate.cost);
|
|
||||||
case "free_shipping":
|
|
||||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
|
||||||
return (withFormatting == true
|
|
||||||
? formatStringCurrency(total: cost)
|
|
||||||
: freeShipping.cost);
|
|
||||||
case "local_pickup":
|
|
||||||
LocalPickup localPickup = (this.object as LocalPickup);
|
|
||||||
return (withFormatting == true
|
|
||||||
? formatStringCurrency(total: cost)
|
|
||||||
: localPickup.cost);
|
|
||||||
default:
|
|
||||||
return "0";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
|
|
||||||
String getTitle() {
|
|
||||||
if (this.methodId != null && this.object != null) {
|
|
||||||
switch (this.methodId) {
|
|
||||||
case "flat_rate":
|
|
||||||
FlatRate flatRate = (this.object as FlatRate);
|
|
||||||
return flatRate.title;
|
|
||||||
case "free_shipping":
|
|
||||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
|
||||||
return freeShipping.title;
|
|
||||||
case "local_pickup":
|
|
||||||
LocalPickup localPickup = (this.object as LocalPickup);
|
|
||||||
return localPickup.title;
|
|
||||||
default:
|
|
||||||
return "";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, dynamic> toShippingLineFee() {
|
|
||||||
if (this.methodId != null && this.object != null) {
|
|
||||||
Map<String, dynamic> tmpShippingLinesObj = {};
|
|
||||||
|
|
||||||
switch (this.methodId) {
|
|
||||||
case "flat_rate":
|
|
||||||
FlatRate flatRate = (this.object as FlatRate);
|
|
||||||
tmpShippingLinesObj["method_title"] = flatRate.title;
|
|
||||||
tmpShippingLinesObj["method_id"] = flatRate.methodId;
|
|
||||||
tmpShippingLinesObj["total"] = this.cost;
|
|
||||||
break;
|
|
||||||
case "free_shipping":
|
|
||||||
FreeShipping freeShipping = (this.object as FreeShipping);
|
|
||||||
tmpShippingLinesObj["method_title"] = freeShipping.title;
|
|
||||||
tmpShippingLinesObj["method_id"] = freeShipping.methodId;
|
|
||||||
tmpShippingLinesObj["total"] = this.cost;
|
|
||||||
break;
|
|
||||||
case "local_pickup":
|
|
||||||
LocalPickup localPickup = (this.object as LocalPickup);
|
|
||||||
tmpShippingLinesObj["method_title"] = localPickup.title;
|
|
||||||
tmpShippingLinesObj["method_id"] = localPickup.methodId;
|
|
||||||
tmpShippingLinesObj["total"] = this.cost;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return tmpShippingLinesObj;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CheckoutSession {
|
|
||||||
String sfKeyCheckout = "CS_BILLING_DETAILS";
|
|
||||||
CheckoutSession._privateConstructor();
|
|
||||||
static final CheckoutSession getInstance =
|
|
||||||
CheckoutSession._privateConstructor();
|
|
||||||
|
|
||||||
BillingDetails billingDetails;
|
|
||||||
ShippingType shippingType;
|
|
||||||
PaymentType paymentType;
|
|
||||||
|
|
||||||
void initSession() {
|
|
||||||
billingDetails = BillingDetails();
|
|
||||||
shippingType = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveBillingAddress() {
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
CustomerAddress customerAddress =
|
|
||||||
CheckoutSession.getInstance.billingDetails.billingAddress;
|
|
||||||
|
|
||||||
String billingAddress = jsonEncode(customerAddress.toJson());
|
|
||||||
sharedPref.save(sfKeyCheckout, billingAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<CustomerAddress> getBillingAddress() async {
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
|
|
||||||
String strCheckoutDetails = await sharedPref.read(sfKeyCheckout);
|
|
||||||
|
|
||||||
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
|
||||||
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearBillingAddress() {
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
sharedPref.remove(sfKeyCheckout);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
|
||||||
double totalCart = double.parse(await Cart.getInstance.getTotal());
|
|
||||||
double totalShipping = 0;
|
|
||||||
if (shippingType != null && shippingType.object != null) {
|
|
||||||
switch (shippingType.methodId) {
|
|
||||||
case "flat_rate":
|
|
||||||
totalShipping = double.parse(shippingType.cost);
|
|
||||||
break;
|
|
||||||
case "free_shipping":
|
|
||||||
totalShipping = double.parse(shippingType.cost);
|
|
||||||
break;
|
|
||||||
case "local_pickup":
|
|
||||||
totalShipping = double.parse(shippingType.cost);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double total = totalCart + totalShipping;
|
|
||||||
|
|
||||||
if (taxRate != null) {
|
|
||||||
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
|
||||||
total += double.parse(taxAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (withFormat != null && withFormat == true) {
|
|
||||||
return formatDoubleCurrency(total: total);
|
|
||||||
}
|
|
||||||
return total.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Cart {
|
|
||||||
String _keyCart = "CART_SESSION";
|
|
||||||
|
|
||||||
Cart._privateConstructor();
|
|
||||||
static final Cart getInstance = Cart._privateConstructor();
|
|
||||||
|
|
||||||
Future<List<CartLineItem>> getCart() async {
|
|
||||||
List<CartLineItem> cartLineItems = [];
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
String currentCartArrJSON = (await sharedPref.read(_keyCart) as String);
|
|
||||||
if (currentCartArrJSON == null) {
|
|
||||||
cartLineItems = List<CartLineItem>();
|
|
||||||
} else {
|
|
||||||
cartLineItems = (jsonDecode(currentCartArrJSON) as List<dynamic>)
|
|
||||||
.map((i) => CartLineItem.fromJson(i))
|
|
||||||
.toList();
|
|
||||||
}
|
|
||||||
return cartLineItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
void addToCart({CartLineItem cartLineItem}) async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
var firstCartItem = cartLineItems.firstWhere(
|
|
||||||
(i) =>
|
|
||||||
i.productId == cartLineItem.productId ||
|
|
||||||
i.productId == cartLineItem.productId &&
|
|
||||||
i.variationId == cartLineItem.variationId, orElse: () {
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
if (firstCartItem != null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cartLineItems.add(cartLineItem);
|
|
||||||
|
|
||||||
saveCartToPref(cartLineItems: cartLineItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> getTotal({bool withFormat}) async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
double total = 0;
|
|
||||||
cartLineItems.forEach((cartItem) {
|
|
||||||
total += (double.parse(cartItem.total) * cartItem.quantity);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (withFormat != null && withFormat == true) {
|
|
||||||
return formatDoubleCurrency(total: total);
|
|
||||||
}
|
|
||||||
return total.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> getSubtotal({bool withFormat}) async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
double subtotal = 0;
|
|
||||||
cartLineItems.forEach((cartItem) {
|
|
||||||
subtotal += (double.parse(cartItem.subtotal) * cartItem.quantity);
|
|
||||||
});
|
|
||||||
if (withFormat != null && withFormat == true) {
|
|
||||||
return formatDoubleCurrency(total: subtotal);
|
|
||||||
}
|
|
||||||
return subtotal.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateQuantity(
|
|
||||||
{CartLineItem cartLineItem, int incrementQuantity}) async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
List<CartLineItem> tmpCartItem = new List<CartLineItem>();
|
|
||||||
cartLineItems.forEach((cartItem) {
|
|
||||||
if (cartItem.variationId == cartLineItem.variationId &&
|
|
||||||
cartItem.productId == cartLineItem.productId) {
|
|
||||||
if ((cartItem.quantity + incrementQuantity) > 0) {
|
|
||||||
cartItem.quantity += incrementQuantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmpCartItem.add(cartItem);
|
|
||||||
});
|
|
||||||
saveCartToPref(cartLineItems: tmpCartItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> cartShortDesc() async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
var tmpShortItemDesc = [];
|
|
||||||
cartLineItems.forEach((cartItem) {
|
|
||||||
tmpShortItemDesc
|
|
||||||
.add(cartItem.quantity.toString() + " x | " + cartItem.name);
|
|
||||||
});
|
|
||||||
return tmpShortItemDesc.join(",");
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeCartItemForIndex({int index}) async {
|
|
||||||
List<CartLineItem> cartLineItems = await getCart();
|
|
||||||
cartLineItems.removeAt(index);
|
|
||||||
saveCartToPref(cartLineItems: cartLineItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear() {
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
List<CartLineItem> cartLineItems = new List<CartLineItem>();
|
|
||||||
String jsonArrCartItems =
|
|
||||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
|
||||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveCartToPref({List<CartLineItem> cartLineItems}) {
|
|
||||||
SharedPref sharedPref = SharedPref();
|
|
||||||
String jsonArrCartItems =
|
|
||||||
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
|
||||||
sharedPref.save(_keyCart, jsonArrCartItems);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> taxAmount(TaxRate taxRate) async {
|
|
||||||
double subtotal = 0;
|
|
||||||
double shippingTotal = 0;
|
|
||||||
|
|
||||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
|
||||||
if (cartItems.every((c) => c.taxStatus == 'none')) {
|
|
||||||
return "0";
|
|
||||||
}
|
|
||||||
List<CartLineItem> taxableCartLines =
|
|
||||||
cartItems.where((c) => c.taxStatus == 'taxable').toList();
|
|
||||||
double cartSubtotal = 0;
|
|
||||||
|
|
||||||
if (taxableCartLines.length > 0) {
|
|
||||||
cartSubtotal = taxableCartLines
|
|
||||||
.map<double>((m) => double.parse(m.subtotal))
|
|
||||||
.reduce((a, b) => a + b);
|
|
||||||
}
|
|
||||||
|
|
||||||
subtotal = cartSubtotal;
|
|
||||||
|
|
||||||
ShippingType shippingType = CheckoutSession.getInstance.shippingType;
|
|
||||||
|
|
||||||
if (shippingType != null) {
|
|
||||||
switch (shippingType.methodId) {
|
|
||||||
case "flat_rate":
|
|
||||||
FlatRate flatRate = (shippingType.object as FlatRate);
|
|
||||||
if (flatRate.taxable != null && flatRate.taxable) {
|
|
||||||
shippingTotal += double.parse(shippingType.cost);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "local_pickup":
|
|
||||||
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
|
||||||
if (localPickup.taxable != null && localPickup.taxable) {
|
|
||||||
shippingTotal += double.parse(localPickup.cost);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double total = 0;
|
|
||||||
if (subtotal != 0) {
|
|
||||||
total += ((double.parse(taxRate.rate) * subtotal) / 100);
|
|
||||||
}
|
|
||||||
if (shippingTotal != 0) {
|
|
||||||
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
|
|
||||||
}
|
|
||||||
return (total).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openBrowserTab({String url}) async {
|
|
||||||
await FlutterWebBrowser.openWebPage(
|
await FlutterWebBrowser.openWebPage(
|
||||||
url: url, androidToolbarColor: Colors.white70);
|
url: url, androidToolbarColor: Colors.white70);
|
||||||
}
|
}
|
||||||
@ -739,26 +181,21 @@ EdgeInsets safeAreaDefault() {
|
|||||||
return EdgeInsets.only(left: 16, right: 16, bottom: 8);
|
return EdgeInsets.only(left: 16, right: 16, bottom: 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SlideRightRoute extends PageRouteBuilder {
|
|
||||||
final Widget widget;
|
|
||||||
SlideRightRoute({this.widget})
|
|
||||||
: super(pageBuilder: (BuildContext context, Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation) {
|
|
||||||
return widget;
|
|
||||||
}, transitionsBuilder: (BuildContext context,
|
|
||||||
Animation<double> animation,
|
|
||||||
Animation<double> secondaryAnimation,
|
|
||||||
Widget child) {
|
|
||||||
return new SlideTransition(
|
|
||||||
position: new Tween<Offset>(
|
|
||||||
begin: const Offset(-1.0, 0.0),
|
|
||||||
end: Offset.zero,
|
|
||||||
).animate(animation),
|
|
||||||
child: child,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
String trans(BuildContext context, String key) {
|
String trans(BuildContext context, String key) {
|
||||||
return AppLocalizations.of(context).trans(key);
|
return AppLocalizations.of(context).trans(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isNumeric(String str) {
|
||||||
|
if (str == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return double.tryParse(str) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkout(TaxRate taxRate, Function(String total, BillingDetails billingDetails, Cart cart) completeCheckout) async {
|
||||||
|
String cartTotal = await CheckoutSession.getInstance
|
||||||
|
.total(withFormat: false, taxRate: taxRate);
|
||||||
|
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
||||||
|
Cart cart = Cart.getInstance;
|
||||||
|
return await completeCheckout(cartTotal, billingDetails, cart);
|
||||||
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -14,7 +14,7 @@
|
|||||||
Developer Notes
|
Developer Notes
|
||||||
|
|
||||||
SUPPORT EMAIL - support@woosignal.com
|
SUPPORT EMAIL - support@woosignal.com
|
||||||
VERSION - 1.0
|
VERSION - 2.0
|
||||||
https://woosignal.com
|
https://woosignal.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
const app_name = "MyApp";
|
const app_name = "MyApp";
|
||||||
|
|
||||||
const app_key = "your app key";
|
const app_key =
|
||||||
|
"app_affb6434339b34443a297c2e40a3edab7102137e6d67de9abfe612b749bd";
|
||||||
|
|
||||||
const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
|
const app_logo_url = "https://woosignal.com/images/120x120_woosignal.png";
|
||||||
|
|
||||||
@ -31,7 +32,9 @@ const app_privacy_url = "https://yourdomain.com/privacy";
|
|||||||
|
|
||||||
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
/*<! ------ STRIPE (OPTIONAL) ------!>*/
|
||||||
|
|
||||||
const app_stripe_account = "your StripeAccount key"; // Your StripeAccount key from WooSignal
|
const app_stripe_account =
|
||||||
|
"acct_1DNNUgADlQ9NE89O"; // Your StripeAccount key from WooSignal
|
||||||
|
|
||||||
const app_stripe_live_mode = false; // SET true for live payments
|
const app_stripe_live_mode = false; // SET true for live payments
|
||||||
|
|
||||||
/*<! ------ APP CURRENCY ------!>*/
|
/*<! ------ APP CURRENCY ------!>*/
|
||||||
@ -40,7 +43,7 @@ const app_currency_symbol = "\£";
|
|||||||
const app_currency_iso = "gbp";
|
const app_currency_iso = "gbp";
|
||||||
const app_locales_supported = ['en'];
|
const app_locales_supported = ['en'];
|
||||||
|
|
||||||
const paymentMethods = ["Stripe"];
|
const app_payment_methods = ["Stripe", "RazorPay"];
|
||||||
|
|
||||||
/*<! ------ DEBUGGER ENABLED ------!>*/
|
/*<! ------ DEBUGGER ENABLED ------!>*/
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:label_storemax/pages/error_page.dart';
|
||||||
|
import 'package:woosignal/models/response/order.dart';
|
||||||
|
import 'package:woosignal/models/response/product_category.dart';
|
||||||
|
import 'package:woosignal/models/response/products.dart';
|
||||||
import 'labelconfig.dart';
|
import 'labelconfig.dart';
|
||||||
import 'package:label_storemax/pages/checkout_details.dart';
|
import 'package:label_storemax/pages/checkout_details.dart';
|
||||||
import 'package:label_storemax/pages/home.dart';
|
import 'package:label_storemax/pages/home.dart';
|
||||||
@ -32,7 +36,7 @@ import 'package:label_storemax/helpers/app_localizations.dart';
|
|||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
await SystemChrome.setPreferredOrientations([
|
await SystemChrome.setPreferredOrientations([
|
||||||
DeviceOrientation.portraitUp,
|
DeviceOrientation.portraitUp,
|
||||||
]);
|
]);
|
||||||
@ -46,43 +50,106 @@ void main() async {
|
|||||||
routes: <String, WidgetBuilder>{
|
routes: <String, WidgetBuilder>{
|
||||||
'/home': (BuildContext context) => new HomePage(),
|
'/home': (BuildContext context) => new HomePage(),
|
||||||
'/cart': (BuildContext context) => new CartPage(),
|
'/cart': (BuildContext context) => new CartPage(),
|
||||||
'/browse-category': (BuildContext context) => new BrowseCategoryPage(),
|
'/error': (BuildContext context) => new ErrorPage(),
|
||||||
'/product-search': (BuildContext context) => new BrowseSearchPage(),
|
|
||||||
'/product-detail': (BuildContext context) => new ProductDetailPage(),
|
|
||||||
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
|
'/checkout': (BuildContext context) => new CheckoutConfirmationPage(),
|
||||||
'/checkout-status': (BuildContext context) => new CheckoutStatusPage(),
|
|
||||||
},
|
},
|
||||||
onGenerateRoute: (settings) {
|
onGenerateRoute: (settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
|
case '/browse-category':
|
||||||
|
if (settings.arguments != null) {
|
||||||
|
final ProductCategory category =
|
||||||
|
settings.arguments as ProductCategory;
|
||||||
|
return PageTransition(
|
||||||
|
child: BrowseCategoryPage(productCategory: category),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return PageTransition(
|
||||||
|
child: ErrorPage(),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
|
||||||
|
case '/product-search':
|
||||||
|
if (settings.arguments != null) {
|
||||||
|
final String search = settings.arguments as String;
|
||||||
|
return PageTransition(
|
||||||
|
child: BrowseSearchPage(search: search),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return PageTransition(
|
||||||
|
child: ErrorPage(),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
|
||||||
|
case '/product-detail':
|
||||||
|
if (settings.arguments != null) {
|
||||||
|
final Product product = settings.arguments as Product;
|
||||||
|
return PageTransition(
|
||||||
|
child: ProductDetailPage(product: product),
|
||||||
|
type: PageTransitionType.rightToLeftWithFade,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return PageTransition(
|
||||||
|
child: ErrorPage(),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
|
||||||
|
case '/checkout-status':
|
||||||
|
if (settings.arguments != null) {
|
||||||
|
final Order order = settings.arguments as Order;
|
||||||
|
return PageTransition(
|
||||||
|
child: CheckoutStatusPage(order: order),
|
||||||
|
type: PageTransitionType.rightToLeftWithFade,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return PageTransition(
|
||||||
|
child: ErrorPage(),
|
||||||
|
type: PageTransitionType.fade,
|
||||||
|
);
|
||||||
|
|
||||||
case '/home-menu':
|
case '/home-menu':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: HomeMenuPage(), type: PageTransitionType.leftToRight);
|
child: HomeMenuPage(),
|
||||||
|
type: PageTransitionType.leftToRightWithFade,
|
||||||
|
);
|
||||||
|
|
||||||
case '/checkout-details':
|
case '/checkout-details':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: CheckoutDetailsPage(),
|
child: CheckoutDetailsPage(),
|
||||||
type: PageTransitionType.downToUp);
|
type: PageTransitionType.downToUp,
|
||||||
|
);
|
||||||
|
|
||||||
case '/about':
|
case '/about':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: AboutPage(), type: PageTransitionType.leftToRight);
|
child: AboutPage(),
|
||||||
|
type: PageTransitionType.leftToRightWithFade,
|
||||||
|
);
|
||||||
|
|
||||||
case '/checkout-payment-type':
|
case '/checkout-payment-type':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: CheckoutPaymentTypePage(),
|
child: CheckoutPaymentTypePage(),
|
||||||
type: PageTransitionType.downToUp);
|
type: PageTransitionType.downToUp,
|
||||||
|
);
|
||||||
|
|
||||||
case '/checkout-shipping-type':
|
case '/checkout-shipping-type':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: CheckoutShippingTypePage(),
|
child: CheckoutShippingTypePage(),
|
||||||
type: PageTransitionType.downToUp);
|
type: PageTransitionType.downToUp,
|
||||||
|
);
|
||||||
|
|
||||||
case '/home-search':
|
case '/home-search':
|
||||||
return PageTransition(
|
return PageTransition(
|
||||||
child: HomeSearchPage(), type: PageTransitionType.downToUp);
|
child: HomeSearchPage(),
|
||||||
|
type: PageTransitionType.downToUp,
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
supportedLocales: [Locale('en')],
|
supportedLocales: [
|
||||||
|
Locale('en'),
|
||||||
|
],
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
AppLocalizations.delegate,
|
AppLocalizations.delegate,
|
||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
@ -106,14 +173,15 @@ void main() async {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
textTheme: textThemeAppBar(),
|
textTheme: textThemeAppBar(),
|
||||||
elevation: 0.0,
|
elevation: 0.0,
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
iconTheme: IconThemeData(color: Colors.black),
|
iconTheme: IconThemeData(color: Colors.black),
|
||||||
actionsIconTheme: IconThemeData(
|
actionsIconTheme: IconThemeData(
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
)),
|
),
|
||||||
|
),
|
||||||
accentColor: Colors.black,
|
accentColor: Colors.black,
|
||||||
accentTextTheme: textThemeAccent(),
|
accentTextTheme: textThemeAccent(),
|
||||||
textTheme: textThemeMain(),
|
textTheme: textThemeMain(),
|
||||||
|
|||||||
22
LabelStoreMax/lib/models/billing_details.dart
Normal file
22
LabelStoreMax/lib/models/billing_details.dart
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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:label_storemax/models/customer_address.dart';
|
||||||
|
|
||||||
|
class BillingDetails {
|
||||||
|
CustomerAddress billingAddress;
|
||||||
|
CustomerAddress shippingAddress;
|
||||||
|
bool rememberDetails;
|
||||||
|
|
||||||
|
void initSession() {
|
||||||
|
billingAddress = CustomerAddress();
|
||||||
|
shippingAddress = CustomerAddress();
|
||||||
|
}
|
||||||
|
}
|
||||||
181
LabelStoreMax/lib/models/cart.dart
Normal file
181
LabelStoreMax/lib/models/cart.dart
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:label_storemax/helpers/shared_pref.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/shipping_type.dart';
|
||||||
|
import 'package:woosignal/models/response/shipping_method.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
|
import '../helpers/tools.dart';
|
||||||
|
|
||||||
|
class Cart {
|
||||||
|
String _keyCart = "CART_SESSION";
|
||||||
|
|
||||||
|
Cart._privateConstructor();
|
||||||
|
static final Cart getInstance = Cart._privateConstructor();
|
||||||
|
|
||||||
|
Future<List<CartLineItem>> getCart() async {
|
||||||
|
List<CartLineItem> cartLineItems = [];
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
String currentCartArrJSON = (await sharedPref.read(_keyCart) as String);
|
||||||
|
if (currentCartArrJSON == null) {
|
||||||
|
cartLineItems = List<CartLineItem>();
|
||||||
|
} else {
|
||||||
|
cartLineItems = (jsonDecode(currentCartArrJSON) as List<dynamic>)
|
||||||
|
.map((i) => CartLineItem.fromJson(i))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
return cartLineItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addToCart({CartLineItem cartLineItem}) async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
var firstCartItem = cartLineItems.firstWhere(
|
||||||
|
(i) =>
|
||||||
|
i.productId == cartLineItem.productId ||
|
||||||
|
i.productId == cartLineItem.productId &&
|
||||||
|
i.variationId == cartLineItem.variationId, orElse: () {
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
if (firstCartItem != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cartLineItems.add(cartLineItem);
|
||||||
|
|
||||||
|
saveCartToPref(cartLineItems: cartLineItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getTotal({bool withFormat}) async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
double total = 0;
|
||||||
|
cartLineItems.forEach((cartItem) {
|
||||||
|
total += (double.parse(cartItem.total) * cartItem.quantity);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (withFormat != null && withFormat == true) {
|
||||||
|
return formatDoubleCurrency(total: total);
|
||||||
|
}
|
||||||
|
return total.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getSubtotal({bool withFormat}) async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
double subtotal = 0;
|
||||||
|
cartLineItems.forEach((cartItem) {
|
||||||
|
subtotal += (double.parse(cartItem.subtotal) * cartItem.quantity);
|
||||||
|
});
|
||||||
|
if (withFormat != null && withFormat == true) {
|
||||||
|
return formatDoubleCurrency(total: subtotal);
|
||||||
|
}
|
||||||
|
return subtotal.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateQuantity(
|
||||||
|
{CartLineItem cartLineItem, int incrementQuantity}) async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
List<CartLineItem> tmpCartItem = new List<CartLineItem>();
|
||||||
|
cartLineItems.forEach((cartItem) {
|
||||||
|
if (cartItem.variationId == cartLineItem.variationId &&
|
||||||
|
cartItem.productId == cartLineItem.productId) {
|
||||||
|
if ((cartItem.quantity + incrementQuantity) > 0) {
|
||||||
|
cartItem.quantity += incrementQuantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tmpCartItem.add(cartItem);
|
||||||
|
});
|
||||||
|
saveCartToPref(cartLineItems: tmpCartItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> cartShortDesc() async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
var tmpShortItemDesc = [];
|
||||||
|
cartLineItems.forEach((cartItem) {
|
||||||
|
tmpShortItemDesc
|
||||||
|
.add(cartItem.quantity.toString() + " x | " + cartItem.name);
|
||||||
|
});
|
||||||
|
return tmpShortItemDesc.join(",");
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeCartItemForIndex({int index}) async {
|
||||||
|
List<CartLineItem> cartLineItems = await getCart();
|
||||||
|
cartLineItems.removeAt(index);
|
||||||
|
saveCartToPref(cartLineItems: cartLineItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
List<CartLineItem> cartLineItems = new List<CartLineItem>();
|
||||||
|
String jsonArrCartItems =
|
||||||
|
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||||
|
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveCartToPref({List<CartLineItem> cartLineItems}) {
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
String jsonArrCartItems =
|
||||||
|
jsonEncode(cartLineItems.map((i) => i.toJson()).toList());
|
||||||
|
sharedPref.save(_keyCart, jsonArrCartItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> taxAmount(TaxRate taxRate) async {
|
||||||
|
double subtotal = 0;
|
||||||
|
double shippingTotal = 0;
|
||||||
|
|
||||||
|
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
||||||
|
if (cartItems.every((c) => c.taxStatus == 'none')) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
List<CartLineItem> taxableCartLines =
|
||||||
|
cartItems.where((c) => c.taxStatus == 'taxable').toList();
|
||||||
|
double cartSubtotal = 0;
|
||||||
|
|
||||||
|
if (taxableCartLines.length > 0) {
|
||||||
|
cartSubtotal = taxableCartLines
|
||||||
|
.map<double>((m) => double.parse(m.subtotal))
|
||||||
|
.reduce((a, b) => a + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
subtotal = cartSubtotal;
|
||||||
|
|
||||||
|
ShippingType shippingType = CheckoutSession.getInstance.shippingType;
|
||||||
|
|
||||||
|
if (shippingType != null) {
|
||||||
|
switch (shippingType.methodId) {
|
||||||
|
case "flat_rate":
|
||||||
|
FlatRate flatRate = (shippingType.object as FlatRate);
|
||||||
|
if (flatRate.taxable != null && flatRate.taxable) {
|
||||||
|
shippingTotal += double.parse(shippingType.cost);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "local_pickup":
|
||||||
|
LocalPickup localPickup = (shippingType.object as LocalPickup);
|
||||||
|
if (localPickup.taxable != null && localPickup.taxable) {
|
||||||
|
shippingTotal += double.parse(localPickup.cost);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double total = 0;
|
||||||
|
if (subtotal != 0) {
|
||||||
|
total += ((double.parse(taxRate.rate) * subtotal) / 100);
|
||||||
|
}
|
||||||
|
if (shippingTotal != 0) {
|
||||||
|
total += ((double.parse(taxRate.rate) * shippingTotal) / 100);
|
||||||
|
}
|
||||||
|
return (total).toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
83
LabelStoreMax/lib/models/cart_line_item.dart
Normal file
83
LabelStoreMax/lib/models/cart_line_item.dart
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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.
|
||||||
|
|
||||||
|
class CartLineItem {
|
||||||
|
String name;
|
||||||
|
int productId;
|
||||||
|
int variationId;
|
||||||
|
int quantity;
|
||||||
|
bool isManagedStock;
|
||||||
|
int stockQuantity;
|
||||||
|
String shippingClassId;
|
||||||
|
String taxStatus;
|
||||||
|
String taxClass;
|
||||||
|
bool shippingIsTaxable;
|
||||||
|
String subtotal;
|
||||||
|
String total;
|
||||||
|
String imageSrc;
|
||||||
|
String variationOptions;
|
||||||
|
String stockStatus;
|
||||||
|
Object metaData = {};
|
||||||
|
|
||||||
|
CartLineItem(
|
||||||
|
{this.name,
|
||||||
|
this.productId,
|
||||||
|
this.variationId,
|
||||||
|
this.isManagedStock,
|
||||||
|
this.stockQuantity,
|
||||||
|
this.quantity,
|
||||||
|
this.stockStatus,
|
||||||
|
this.shippingClassId,
|
||||||
|
this.taxStatus,
|
||||||
|
this.taxClass,
|
||||||
|
this.shippingIsTaxable,
|
||||||
|
this.variationOptions,
|
||||||
|
this.imageSrc,
|
||||||
|
this.subtotal,
|
||||||
|
this.total,
|
||||||
|
this.metaData});
|
||||||
|
|
||||||
|
CartLineItem.fromJson(Map<String, dynamic> json)
|
||||||
|
: name = json['name'],
|
||||||
|
productId = json['product_id'],
|
||||||
|
variationId = json['variation_id'],
|
||||||
|
quantity = json['quantity'],
|
||||||
|
shippingClassId = json['shipping_class_id'].toString(),
|
||||||
|
taxStatus = json['tax_status'],
|
||||||
|
stockQuantity = json['stock_quantity'],
|
||||||
|
isManagedStock = json['is_managed_stock'],
|
||||||
|
shippingIsTaxable = json['shipping_is_taxable'],
|
||||||
|
subtotal = json['subtotal'],
|
||||||
|
total = json['total'],
|
||||||
|
taxClass = json['tax_class'],
|
||||||
|
stockStatus = json['stock_status'],
|
||||||
|
imageSrc = json['image_src'],
|
||||||
|
variationOptions = json['variation_options'],
|
||||||
|
metaData = json['metaData'];
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => {
|
||||||
|
'name': name,
|
||||||
|
'product_id': productId,
|
||||||
|
'variation_id': variationId,
|
||||||
|
'quantity': quantity,
|
||||||
|
'shipping_class_id': shippingClassId,
|
||||||
|
'tax_status': taxStatus,
|
||||||
|
'tax_class': taxClass,
|
||||||
|
'stock_status': stockStatus,
|
||||||
|
'is_managed_stock': isManagedStock,
|
||||||
|
'stock_quantity': stockQuantity,
|
||||||
|
'shipping_is_taxable': shippingIsTaxable,
|
||||||
|
'image_src': imageSrc,
|
||||||
|
'variation_options': variationOptions,
|
||||||
|
'subtotal': subtotal,
|
||||||
|
'total': total,
|
||||||
|
'meta_data': metaData,
|
||||||
|
};
|
||||||
|
}
|
||||||
94
LabelStoreMax/lib/models/checkout_session.dart
Normal file
94
LabelStoreMax/lib/models/checkout_session.dart
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:label_storemax/helpers/shared_pref.dart';
|
||||||
|
import 'package:label_storemax/models/billing_details.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/customer_address.dart';
|
||||||
|
import 'package:label_storemax/models/payment_type.dart';
|
||||||
|
import 'package:label_storemax/models/shipping_type.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
|
||||||
|
import '../helpers/tools.dart';
|
||||||
|
|
||||||
|
class CheckoutSession {
|
||||||
|
String sfKeyCheckout = "CS_BILLING_DETAILS";
|
||||||
|
CheckoutSession._privateConstructor();
|
||||||
|
static final CheckoutSession getInstance =
|
||||||
|
CheckoutSession._privateConstructor();
|
||||||
|
|
||||||
|
BillingDetails billingDetails;
|
||||||
|
ShippingType shippingType;
|
||||||
|
PaymentType paymentType;
|
||||||
|
|
||||||
|
void initSession() {
|
||||||
|
billingDetails = BillingDetails();
|
||||||
|
shippingType = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveBillingAddress() {
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
CustomerAddress customerAddress =
|
||||||
|
CheckoutSession.getInstance.billingDetails.billingAddress;
|
||||||
|
|
||||||
|
String billingAddress = jsonEncode(customerAddress.toJson());
|
||||||
|
sharedPref.save(sfKeyCheckout, billingAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<CustomerAddress> getBillingAddress() async {
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
|
||||||
|
String strCheckoutDetails = await sharedPref.read(sfKeyCheckout);
|
||||||
|
|
||||||
|
if (strCheckoutDetails != null && strCheckoutDetails != "") {
|
||||||
|
return CustomerAddress.fromJson(jsonDecode(strCheckoutDetails));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearBillingAddress() {
|
||||||
|
SharedPref sharedPref = SharedPref();
|
||||||
|
sharedPref.remove(sfKeyCheckout);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> total({bool withFormat, TaxRate taxRate}) async {
|
||||||
|
double totalCart = double.parse(await Cart.getInstance.getTotal());
|
||||||
|
double totalShipping = 0;
|
||||||
|
if (shippingType != null && shippingType.object != null) {
|
||||||
|
switch (shippingType.methodId) {
|
||||||
|
case "flat_rate":
|
||||||
|
totalShipping = double.parse(shippingType.cost);
|
||||||
|
break;
|
||||||
|
case "free_shipping":
|
||||||
|
totalShipping = double.parse(shippingType.cost);
|
||||||
|
break;
|
||||||
|
case "local_pickup":
|
||||||
|
totalShipping = double.parse(shippingType.cost);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double total = totalCart + totalShipping;
|
||||||
|
|
||||||
|
if (taxRate != null) {
|
||||||
|
String taxAmount = await Cart.getInstance.taxAmount(taxRate);
|
||||||
|
total += double.parse(taxAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withFormat != null && withFormat == true) {
|
||||||
|
return formatDoubleCurrency(total: total);
|
||||||
|
}
|
||||||
|
return total.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
96
LabelStoreMax/lib/models/customer_address.dart
Normal file
96
LabelStoreMax/lib/models/customer_address.dart
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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.
|
||||||
|
|
||||||
|
class CustomerAddress {
|
||||||
|
String firstName;
|
||||||
|
String lastName;
|
||||||
|
String addressLine;
|
||||||
|
String city;
|
||||||
|
String postalCode;
|
||||||
|
String country;
|
||||||
|
String emailAddress;
|
||||||
|
|
||||||
|
CustomerAddress(
|
||||||
|
{this.firstName,
|
||||||
|
this.lastName,
|
||||||
|
this.addressLine,
|
||||||
|
this.city,
|
||||||
|
this.postalCode,
|
||||||
|
this.country,
|
||||||
|
this.emailAddress});
|
||||||
|
|
||||||
|
void initAddress() {
|
||||||
|
firstName = "";
|
||||||
|
lastName = "";
|
||||||
|
addressLine = "";
|
||||||
|
city = "";
|
||||||
|
postalCode = "";
|
||||||
|
country = "";
|
||||||
|
emailAddress = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasMissingFields() {
|
||||||
|
return (this.firstName.isEmpty ||
|
||||||
|
this.lastName.isEmpty ||
|
||||||
|
this.addressLine.isEmpty ||
|
||||||
|
this.city.isEmpty ||
|
||||||
|
this.postalCode.isEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
String addressFull() {
|
||||||
|
List<String> tmpArrAddress = new List<String>();
|
||||||
|
if (addressLine != "") {
|
||||||
|
tmpArrAddress.add(addressLine);
|
||||||
|
}
|
||||||
|
if (city != "") {
|
||||||
|
tmpArrAddress.add(city);
|
||||||
|
}
|
||||||
|
if (postalCode != "") {
|
||||||
|
tmpArrAddress.add(postalCode);
|
||||||
|
}
|
||||||
|
if (country != "") {
|
||||||
|
tmpArrAddress.add(country);
|
||||||
|
}
|
||||||
|
return tmpArrAddress.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
String nameFull() {
|
||||||
|
List<String> tmpArrName = new List<String>();
|
||||||
|
if (firstName != "") {
|
||||||
|
tmpArrName.add(firstName);
|
||||||
|
}
|
||||||
|
if (lastName != "") {
|
||||||
|
tmpArrName.add(lastName);
|
||||||
|
}
|
||||||
|
return tmpArrName.join(", ");
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomerAddress.fromJson(Map<String, dynamic> json) {
|
||||||
|
firstName = json['first_name'];
|
||||||
|
lastName = json['last_name'];
|
||||||
|
addressLine = json['address_line'];
|
||||||
|
city = json['city'];
|
||||||
|
postalCode = json['postal_code'];
|
||||||
|
country = json['country'];
|
||||||
|
emailAddress = json['email_address'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['first_name'] = this.firstName;
|
||||||
|
data['last_name'] = this.lastName;
|
||||||
|
data['address_line'] = this.addressLine;
|
||||||
|
data['city'] = this.city;
|
||||||
|
data['postal_code'] = this.postalCode;
|
||||||
|
data['country'] = this.country;
|
||||||
|
data['email_address'] = this.emailAddress;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
LabelStoreMax/lib/models/payment_type.dart
Normal file
19
LabelStoreMax/lib/models/payment_type.dart
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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.
|
||||||
|
|
||||||
|
class PaymentType {
|
||||||
|
int id;
|
||||||
|
String name;
|
||||||
|
String desc;
|
||||||
|
String assetImage;
|
||||||
|
Function pay;
|
||||||
|
|
||||||
|
PaymentType({this.id, this.name, this.desc, this.assetImage, this.pay});
|
||||||
|
}
|
||||||
103
LabelStoreMax/lib/models/shipping_type.dart
Normal file
103
LabelStoreMax/lib/models/shipping_type.dart
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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:woosignal/models/response/shipping_method.dart';
|
||||||
|
|
||||||
|
import '../helpers/tools.dart';
|
||||||
|
|
||||||
|
class ShippingType {
|
||||||
|
String methodId;
|
||||||
|
String cost;
|
||||||
|
dynamic object;
|
||||||
|
|
||||||
|
ShippingType({this.methodId, this.object, this.cost});
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
{'methodId': methodId, 'object': object, 'cost': cost};
|
||||||
|
|
||||||
|
String getTotal({bool withFormatting}) {
|
||||||
|
if (this.methodId != null && this.object != null) {
|
||||||
|
switch (this.methodId) {
|
||||||
|
case "flat_rate":
|
||||||
|
FlatRate flatRate = (this.object as FlatRate);
|
||||||
|
return (withFormatting == true
|
||||||
|
? formatStringCurrency(total: cost)
|
||||||
|
: flatRate.cost);
|
||||||
|
case "free_shipping":
|
||||||
|
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||||
|
return (withFormatting == true
|
||||||
|
? formatStringCurrency(total: cost)
|
||||||
|
: freeShipping.cost);
|
||||||
|
case "local_pickup":
|
||||||
|
LocalPickup localPickup = (this.object as LocalPickup);
|
||||||
|
return (withFormatting == true
|
||||||
|
? formatStringCurrency(total: cost)
|
||||||
|
: localPickup.cost);
|
||||||
|
default:
|
||||||
|
return "0";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
String getTitle() {
|
||||||
|
if (this.methodId != null && this.object != null) {
|
||||||
|
switch (this.methodId) {
|
||||||
|
case "flat_rate":
|
||||||
|
FlatRate flatRate = (this.object as FlatRate);
|
||||||
|
return flatRate.title;
|
||||||
|
case "free_shipping":
|
||||||
|
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||||
|
return freeShipping.title;
|
||||||
|
case "local_pickup":
|
||||||
|
LocalPickup localPickup = (this.object as LocalPickup);
|
||||||
|
return localPickup.title;
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toShippingLineFee() {
|
||||||
|
if (this.methodId != null && this.object != null) {
|
||||||
|
Map<String, dynamic> tmpShippingLinesObj = {};
|
||||||
|
|
||||||
|
switch (this.methodId) {
|
||||||
|
case "flat_rate":
|
||||||
|
FlatRate flatRate = (this.object as FlatRate);
|
||||||
|
tmpShippingLinesObj["method_title"] = flatRate.title;
|
||||||
|
tmpShippingLinesObj["method_id"] = flatRate.methodId;
|
||||||
|
tmpShippingLinesObj["total"] = this.cost;
|
||||||
|
break;
|
||||||
|
case "free_shipping":
|
||||||
|
FreeShipping freeShipping = (this.object as FreeShipping);
|
||||||
|
tmpShippingLinesObj["method_title"] = freeShipping.title;
|
||||||
|
tmpShippingLinesObj["method_id"] = freeShipping.methodId;
|
||||||
|
tmpShippingLinesObj["total"] = this.cost;
|
||||||
|
break;
|
||||||
|
case "local_pickup":
|
||||||
|
LocalPickup localPickup = (this.object as LocalPickup);
|
||||||
|
tmpShippingLinesObj["method_title"] = localPickup.title;
|
||||||
|
tmpShippingLinesObj["method_id"] = localPickup.methodId;
|
||||||
|
tmpShippingLinesObj["total"] = this.cost;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return tmpShippingLinesObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -11,6 +11,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
|
import 'package:label_storemax/widgets/menu_item.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info/package_info.dart';
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,20 +10,23 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.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;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class BrowseCategoryPage extends StatefulWidget {
|
class BrowseCategoryPage extends StatefulWidget {
|
||||||
BrowseCategoryPage();
|
final ProductCategory productCategory;
|
||||||
|
const BrowseCategoryPage({Key key, @required this.productCategory})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BrowseCategoryPageState createState() => _BrowseCategoryPageState();
|
_BrowseCategoryPageState createState() =>
|
||||||
|
_BrowseCategoryPageState(productCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
||||||
_BrowseCategoryPageState();
|
_BrowseCategoryPageState(this._selectedCategory);
|
||||||
|
|
||||||
List<WS.Product> _products = [];
|
List<WS.Product> _products = [];
|
||||||
var _productsController = ScrollController();
|
var _productsController = ScrollController();
|
||||||
@ -44,6 +47,11 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
|
||||||
|
_fetchProductsForCategory();
|
||||||
|
_addScrollListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
_addScrollListener() async {
|
||||||
_productsController.addListener(() {
|
_productsController.addListener(() {
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
double maxScroll = _productsController.position.maxScrollExtent;
|
||||||
double currentScroll = _productsController.position.pixels;
|
double currentScroll = _productsController.position.pixels;
|
||||||
@ -55,44 +63,35 @@ class _BrowseCategoryPageState extends State<BrowseCategoryPage> {
|
|||||||
if (waitForNextRequest) {
|
if (waitForNextRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
|
||||||
waitForNextRequest = true;
|
_fetchMoreProducts();
|
||||||
_page = _page + 1;
|
|
||||||
wcStore
|
|
||||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
|
||||||
.then((products) {
|
|
||||||
waitForNextRequest = false;
|
|
||||||
if (products.length == 0) {
|
|
||||||
_shouldStopRequests = true;
|
|
||||||
}
|
|
||||||
_products.addAll(products.toList());
|
|
||||||
setState(() {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchProductsForCategory() {
|
_fetchMoreProducts() async {
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
waitForNextRequest = true;
|
||||||
wcStore
|
List<WS.Product> products = await appWooSignal((api) {
|
||||||
.getProducts(category: _selectedCategory.id.toString(), perPage: 50)
|
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||||
.then((products) {
|
|
||||||
_products = products;
|
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
_products.addAll(products);
|
||||||
|
waitForNextRequest = false;
|
||||||
|
_page = _page + 1;
|
||||||
|
|
||||||
|
waitForNextRequest = false;
|
||||||
|
if (products.length == 0) {
|
||||||
|
_shouldStopRequests = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
_fetchProductsForCategory() async {
|
||||||
void didChangeDependencies() {
|
_products = await appWooSignal((api) {
|
||||||
super.didChangeDependencies();
|
return api.getProducts(
|
||||||
if (_isLoading) {
|
category: _selectedCategory.id.toString(), perPage: 50);
|
||||||
_selectedCategory = ModalRoute.of(context).settings.arguments;
|
});
|
||||||
_fetchProductsForCategory();
|
setState(() {
|
||||||
}
|
_isLoading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,19 +10,20 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class BrowseSearchPage extends StatefulWidget {
|
class BrowseSearchPage extends StatefulWidget {
|
||||||
BrowseSearchPage();
|
final String search;
|
||||||
|
BrowseSearchPage({Key key, @required this.search}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BrowseSearchState createState() => _BrowseSearchState();
|
_BrowseSearchState createState() => _BrowseSearchState(search);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BrowseSearchState extends State<BrowseSearchPage> {
|
class _BrowseSearchState extends State<BrowseSearchPage> {
|
||||||
_BrowseSearchState();
|
_BrowseSearchState(this._search);
|
||||||
|
|
||||||
var _productsController = ScrollController();
|
var _productsController = ScrollController();
|
||||||
List<WS.Product> _products = [];
|
List<WS.Product> _products = [];
|
||||||
@ -41,6 +42,11 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
|
||||||
|
_fetchProductsForSearch(_page);
|
||||||
|
_addScrollListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
_addScrollListener() async {
|
||||||
_productsController.addListener(() {
|
_productsController.addListener(() {
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
double maxScroll = _productsController.position.maxScrollExtent;
|
||||||
double currentScroll = _productsController.position.pixels;
|
double currentScroll = _productsController.position.pixels;
|
||||||
@ -57,33 +63,20 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetchProductsForSearch(int page) {
|
_fetchProductsForSearch(int page) async {
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
waitForNextRequest = true;
|
||||||
waitForNextRequest = true;
|
List<WS.Product> products = await appWooSignal((api) {
|
||||||
_page = _page + 1;
|
_page = _page + 1;
|
||||||
wcStore
|
return api.getProducts(
|
||||||
.getProducts(
|
search: _search, perPage: 100, page: page, status: "publish");
|
||||||
search: _search, perPage: 100, page: page, status: "publish")
|
|
||||||
.then((products) {
|
|
||||||
waitForNextRequest = false;
|
|
||||||
if (products.length == 0) {
|
|
||||||
_shouldStopRequests = true;
|
|
||||||
}
|
|
||||||
_products.addAll(products.toList());
|
|
||||||
setState(() {
|
|
||||||
_isLoading = false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
if (products.length == 0) {
|
||||||
|
_shouldStopRequests = true;
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
if (_isLoading) {
|
|
||||||
_search = ModalRoute.of(context).settings.arguments;
|
|
||||||
_fetchProductsForSearch(_page);
|
|
||||||
}
|
}
|
||||||
|
setState(() {
|
||||||
|
_products.addAll(products.toList());
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -122,10 +115,14 @@ class _BrowseSearchState extends State<BrowseSearchPage> {
|
|||||||
? GridView.count(
|
? GridView.count(
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
controller: _productsController,
|
controller: _productsController,
|
||||||
children: List.generate(_products.length, (index) {
|
children: List.generate(
|
||||||
return wsCardProductItem(context,
|
_products.length,
|
||||||
index: index, product: _products[index]);
|
(index) {
|
||||||
}))
|
return wsCardProductItem(context,
|
||||||
|
index: index, product: _products[index]);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
: wsNoResults(context)),
|
: wsNoResults(context)),
|
||||||
flex: 1,
|
flex: 1,
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -11,8 +11,13 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/customer_address.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
|
|
||||||
class CartPage extends StatefulWidget {
|
class CartPage extends StatefulWidget {
|
||||||
CartPage();
|
CartPage();
|
||||||
@ -45,10 +50,12 @@ class _CartPageState extends State<CartPage> {
|
|||||||
});
|
});
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
|
||||||
List<Map<String, dynamic>> cartJSON = cart.map((c) => c.toJson()).toList();
|
List<Map<String, dynamic>> cartJSON = cart.map((c) => c.toJson()).toList();
|
||||||
|
|
||||||
List<dynamic> cartRes = await wooSignal.cartCheck(cartJSON);
|
List<dynamic> cartRes = await appWooSignal((api) {
|
||||||
|
return api.cartCheck(cartJSON);
|
||||||
|
});
|
||||||
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
_cartLines = cartRes.map((json) => CartLineItem.fromJson(json)).toList();
|
||||||
if (_cartLines.length > 0) {
|
if (_cartLines.length > 0) {
|
||||||
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
Cart.getInstance.saveCartToPref(cartLineItems: _cartLines);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -9,27 +9,28 @@
|
|||||||
// 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/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/app_payment_methods.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/customer_address.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:woosignal/models/response/tax_rate.dart';
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
import 'package:woosignal_stripe/woosignal_stripe.dart';
|
|
||||||
import 'package:woosignal/models/payload/order_wc.dart';
|
|
||||||
import 'package:woosignal/models/response/order.dart' as WS;
|
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'dart:io';
|
|
||||||
import 'package:label_storemax/app_country_options.dart';
|
import 'package:label_storemax/app_country_options.dart';
|
||||||
|
|
||||||
class CheckoutConfirmationPage extends StatefulWidget {
|
class CheckoutConfirmationPage extends StatefulWidget {
|
||||||
CheckoutConfirmationPage();
|
CheckoutConfirmationPage({Key key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_CheckoutConfirmationPageState createState() =>
|
CheckoutConfirmationPageState createState() =>
|
||||||
_CheckoutConfirmationPageState();
|
CheckoutConfirmationPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
class CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
||||||
_CheckoutConfirmationPageState();
|
CheckoutConfirmationPageState();
|
||||||
|
|
||||||
|
GlobalKey<CheckoutConfirmationPageState> _key = GlobalKey<CheckoutConfirmationPageState>();
|
||||||
|
|
||||||
bool _showFullLoader;
|
bool _showFullLoader;
|
||||||
|
|
||||||
@ -48,9 +49,17 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
_getTaxes();
|
_getTaxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reloadState({bool showLoader}) {
|
||||||
|
setState(() {
|
||||||
|
_showFullLoader = showLoader ?? false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
_getTaxes() async {
|
_getTaxes() async {
|
||||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
_taxRates = await appWooSignal((api) {
|
||||||
_taxRates = await wooSignal.getTaxRates(page: 1, perPage: 100);
|
return api.getTaxRates(page: 1, perPage: 100);
|
||||||
|
});
|
||||||
|
|
||||||
if (CheckoutSession.getInstance.billingDetails.shippingAddress == null) {
|
if (CheckoutSession.getInstance.billingDetails.shippingAddress == null) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_showFullLoader = false;
|
_showFullLoader = false;
|
||||||
@ -150,7 +159,8 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
30,
|
30,
|
||||||
CheckoutSession.getInstance
|
CheckoutSession.getInstance
|
||||||
.billingDetails.billingAddress
|
.billingDetails.billingAddress
|
||||||
.addressFull())),
|
.addressFull(),
|
||||||
|
)),
|
||||||
action: _actionCheckoutDetails,
|
action: _actionCheckoutDetails,
|
||||||
showBorderBottom: true)
|
showBorderBottom: true)
|
||||||
: wsCheckoutRow(context,
|
: wsCheckoutRow(context,
|
||||||
@ -170,7 +180,7 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
.paymentType.assetImage),
|
.paymentType.assetImage),
|
||||||
width: 70),
|
width: 70),
|
||||||
leadTitle: CheckoutSession
|
leadTitle: CheckoutSession
|
||||||
.getInstance.paymentType.name,
|
.getInstance.paymentType.desc,
|
||||||
action: _actionPayWith,
|
action: _actionPayWith,
|
||||||
showBorderBottom: true)
|
showBorderBottom: true)
|
||||||
: wsCheckoutRow(context,
|
: wsCheckoutRow(context,
|
||||||
@ -236,8 +246,13 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
showAppLoader(),
|
showAppLoader(),
|
||||||
Text(trans(context, "One moment") + "...",
|
Padding(
|
||||||
style: Theme.of(context).primaryTextTheme.subhead)
|
padding: const EdgeInsets.only(top: 15),
|
||||||
|
child: Text(
|
||||||
|
trans(context, "One moment") + "...",
|
||||||
|
style: Theme.of(context).primaryTextTheme.subhead,
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -284,168 +299,7 @@ class _CheckoutConfirmationPageState extends State<CheckoutConfirmationPage> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pay();
|
CheckoutSession.getInstance.paymentType
|
||||||
}
|
.pay(context, state: this, taxRate: _taxRate);
|
||||||
|
|
||||||
Future<OrderWC> _buildOrderWC() async {
|
|
||||||
OrderWC orderWC = OrderWC();
|
|
||||||
if (Platform.isAndroid) {
|
|
||||||
orderWC.paymentMethod = "Stripe - Android App";
|
|
||||||
orderWC.paymentMethodTitle = "stripe";
|
|
||||||
} else if (Platform.isIOS) {
|
|
||||||
orderWC.paymentMethod = "Stripe - IOS App";
|
|
||||||
orderWC.paymentMethodTitle = "stripe";
|
|
||||||
}
|
|
||||||
|
|
||||||
orderWC.setPaid = true;
|
|
||||||
orderWC.status = "pending";
|
|
||||||
orderWC.currency = app_currency_iso.toUpperCase();
|
|
||||||
|
|
||||||
List<LineItems> lineItems = [];
|
|
||||||
List<CartLineItem> cartItems = await Cart.getInstance.getCart();
|
|
||||||
cartItems.forEach((cartItem) {
|
|
||||||
LineItems tmpLineItem = LineItems();
|
|
||||||
tmpLineItem.quantity = cartItem.quantity;
|
|
||||||
tmpLineItem.name = cartItem.name;
|
|
||||||
tmpLineItem.productId = cartItem.productId;
|
|
||||||
if (cartItem.variationId != null && cartItem.variationId != 0) {
|
|
||||||
tmpLineItem.variationId = cartItem.variationId;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmpLineItem.total = cartItem.total;
|
|
||||||
tmpLineItem.subtotal = cartItem.subtotal;
|
|
||||||
|
|
||||||
lineItems.add(tmpLineItem);
|
|
||||||
});
|
|
||||||
|
|
||||||
orderWC.lineItems = lineItems;
|
|
||||||
|
|
||||||
BillingDetails billingDetails = CheckoutSession.getInstance.billingDetails;
|
|
||||||
|
|
||||||
Billing billing = Billing();
|
|
||||||
billing.firstName = billingDetails.billingAddress.firstName;
|
|
||||||
billing.lastName = billingDetails.billingAddress.lastName;
|
|
||||||
billing.address1 = billingDetails.billingAddress.addressLine;
|
|
||||||
billing.city = billingDetails.billingAddress.city;
|
|
||||||
billing.postcode = billingDetails.billingAddress.postalCode;
|
|
||||||
billing.country = billingDetails.billingAddress.country;
|
|
||||||
billing.email = billingDetails.billingAddress.emailAddress;
|
|
||||||
|
|
||||||
orderWC.billing = billing;
|
|
||||||
|
|
||||||
Shipping shipping = Shipping();
|
|
||||||
shipping.firstName = billingDetails.shippingAddress.firstName;
|
|
||||||
shipping.lastName = billingDetails.shippingAddress.lastName;
|
|
||||||
shipping.address1 = billingDetails.shippingAddress.addressLine;
|
|
||||||
shipping.city = billingDetails.shippingAddress.city;
|
|
||||||
shipping.postcode = billingDetails.shippingAddress.postalCode;
|
|
||||||
shipping.country = billingDetails.shippingAddress.country;
|
|
||||||
|
|
||||||
orderWC.shipping = shipping;
|
|
||||||
|
|
||||||
orderWC.shippingLines = [];
|
|
||||||
Map<String, dynamic> shippingLineFeeObj =
|
|
||||||
CheckoutSession.getInstance.shippingType.toShippingLineFee();
|
|
||||||
if (shippingLineFeeObj != null) {
|
|
||||||
ShippingLines shippingLine = ShippingLines();
|
|
||||||
shippingLine.methodId = shippingLineFeeObj['method_id'];
|
|
||||||
shippingLine.methodTitle = shippingLineFeeObj['method_title'];
|
|
||||||
shippingLine.total = shippingLineFeeObj['total'];
|
|
||||||
orderWC.shippingLines.add(shippingLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_taxRate != null) {
|
|
||||||
orderWC.feeLines = [];
|
|
||||||
FeeLines feeLines = FeeLines();
|
|
||||||
feeLines.name = _taxRate.name;
|
|
||||||
feeLines.total = await Cart.getInstance.taxAmount(_taxRate);
|
|
||||||
feeLines.taxClass = "";
|
|
||||||
feeLines.taxStatus = "taxable";
|
|
||||||
orderWC.feeLines.add(feeLines);
|
|
||||||
}
|
|
||||||
|
|
||||||
return orderWC;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pay() async {
|
|
||||||
WooSignal wsStore = await WooSignal.getInstance(config: wsConfig);
|
|
||||||
|
|
||||||
String cartTotal = await CheckoutSession.getInstance
|
|
||||||
.total(withFormat: false, taxRate: _taxRate);
|
|
||||||
|
|
||||||
FlutterStripePayment.setStripeSettings(
|
|
||||||
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
|
||||||
|
|
||||||
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
|
||||||
|
|
||||||
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
|
||||||
setState(() {
|
|
||||||
_showFullLoader = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
BillingDetails checkoutDetails =
|
|
||||||
CheckoutSession.getInstance.billingDetails;
|
|
||||||
|
|
||||||
Map<String, dynamic> address = {
|
|
||||||
"name": checkoutDetails.billingAddress.nameFull(),
|
|
||||||
"line1": checkoutDetails.shippingAddress.addressLine,
|
|
||||||
"city": checkoutDetails.shippingAddress.city,
|
|
||||||
"postal_code": checkoutDetails.shippingAddress.postalCode,
|
|
||||||
"country": checkoutDetails.shippingAddress.country
|
|
||||||
};
|
|
||||||
|
|
||||||
String cartShortDesc = await Cart.getInstance.cartShortDesc();
|
|
||||||
|
|
||||||
dynamic rsp = await wsStore.stripePaymentIntent(
|
|
||||||
amount: cartTotal,
|
|
||||||
email: checkoutDetails.billingAddress.emailAddress,
|
|
||||||
desc: cartShortDesc,
|
|
||||||
shipping: address);
|
|
||||||
|
|
||||||
if (rsp == null) {
|
|
||||||
showToastNetworkError();
|
|
||||||
setState(() {
|
|
||||||
_showFullLoader = false;
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String clientSecret = rsp["client_secret"];
|
|
||||||
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
|
||||||
clientSecret,
|
|
||||||
paymentResponse.paymentMethodId,
|
|
||||||
(double.parse(cartTotal) * 100));
|
|
||||||
|
|
||||||
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
|
||||||
OrderWC orderWC = await _buildOrderWC();
|
|
||||||
WS.Order order = await wsStore.createOrder(orderWC);
|
|
||||||
|
|
||||||
if (order != null) {
|
|
||||||
Cart.getInstance.clear();
|
|
||||||
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
|
||||||
} else {
|
|
||||||
showEdgeAlertWith(context,
|
|
||||||
title: trans(context, "Error"),
|
|
||||||
desc: trans(
|
|
||||||
context, "Something went wrong, please contact our store"));
|
|
||||||
setState(() {
|
|
||||||
_showFullLoader = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
|
||||||
if (app_debug) {
|
|
||||||
print(intentResponse.errorMessage);
|
|
||||||
}
|
|
||||||
showEdgeAlertWith(context,
|
|
||||||
title: trans(context, "Error"), desc: intentResponse.errorMessage);
|
|
||||||
setState(() {
|
|
||||||
_showFullLoader = false;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
_showFullLoader = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/billing_details.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/customer_address.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:label_storemax/app_country_options.dart';
|
import 'package:label_storemax/app_country_options.dart';
|
||||||
|
|
||||||
@ -82,27 +86,34 @@ class _CheckoutDetailsPageState extends State<CheckoutDetailsPage> {
|
|||||||
wsModalBottom(context,
|
wsModalBottom(context,
|
||||||
title: trans(context, "Select a country"),
|
title: trans(context, "Select a country"),
|
||||||
bodyWidget: Expanded(
|
bodyWidget: Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.separated(
|
||||||
itemCount: appCountryOptions.length,
|
itemCount: appCountryOptions.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
Map<String, String> strName = appCountryOptions[index];
|
Map<String, String> strName = appCountryOptions[index];
|
||||||
|
|
||||||
return InkWell(
|
return InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(strName["name"],
|
child: Text(strName["name"],
|
||||||
style: Theme.of(context).primaryTextTheme.body2),
|
style: Theme.of(context).primaryTextTheme.body2),
|
||||||
padding: EdgeInsets.only(top: 25, bottom: 25),
|
padding: EdgeInsets.only(top: 25, bottom: 25),
|
||||||
),
|
),
|
||||||
splashColor: Colors.grey,
|
splashColor: Colors.grey,
|
||||||
highlightColor: Colors.black12,
|
highlightColor: Colors.black12,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_strBillingCountry = strName["name"];
|
_strBillingCountry = strName["name"];
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}),
|
},
|
||||||
|
separatorBuilder: (cxt, i) {
|
||||||
|
return Divider(
|
||||||
|
height: 0,
|
||||||
|
color: Colors.black12,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class CheckoutPaymentTypePage extends StatefulWidget {
|
class CheckoutPaymentTypePage extends StatefulWidget {
|
||||||
@ -26,6 +28,12 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
|
if (CheckoutSession.getInstance.paymentType == null) {
|
||||||
|
if (getPaymentTypes() != null && getPaymentTypes().length > 0) {
|
||||||
|
CheckoutSession.getInstance.paymentType = getPaymentTypes().first;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -78,12 +86,16 @@ class _CheckoutPaymentTypePageState extends State<CheckoutPaymentTypePage> {
|
|||||||
width: 60,
|
width: 60,
|
||||||
fit: BoxFit.fitHeight,
|
fit: BoxFit.fitHeight,
|
||||||
alignment: Alignment.center),
|
alignment: Alignment.center),
|
||||||
title: Text(getPaymentTypes()[index].name,
|
title: Text(getPaymentTypes()[index].desc,
|
||||||
style: Theme.of(context)
|
style: Theme.of(context)
|
||||||
.primaryTextTheme
|
.primaryTextTheme
|
||||||
.subhead),
|
.subhead),
|
||||||
selected: true,
|
selected: true,
|
||||||
trailing: Icon(Icons.check),
|
trailing: (CheckoutSession
|
||||||
|
.getInstance.paymentType ==
|
||||||
|
getPaymentTypes()[index]
|
||||||
|
? Icon(Icons.check)
|
||||||
|
: null),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
CheckoutSession.getInstance.paymentType =
|
CheckoutSession.getInstance.paymentType =
|
||||||
getPaymentTypes()[index];
|
getPaymentTypes()[index];
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,9 +10,14 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/models/customer_address.dart';
|
||||||
|
import 'package:label_storemax/models/shipping_type.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:woosignal/models/response/shipping_method.dart';
|
import 'package:woosignal/models/response/shipping_method.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'package:label_storemax/app_country_options.dart';
|
import 'package:label_storemax/app_country_options.dart';
|
||||||
|
|
||||||
class CheckoutShippingTypePage extends StatefulWidget {
|
class CheckoutShippingTypePage extends StatefulWidget {
|
||||||
@ -43,8 +48,9 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_getShippingMethods() async {
|
_getShippingMethods() async {
|
||||||
WooSignal wooSignal = await WooSignal.getInstance(config: wsConfig);
|
List<WSShipping> wsShipping = await appWooSignal((api) {
|
||||||
List<WSShipping> wsShipping = await wooSignal.getShippingMethods();
|
return api.getShippingMethods();
|
||||||
|
});
|
||||||
CustomerAddress customerAddress =
|
CustomerAddress customerAddress =
|
||||||
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
CheckoutSession.getInstance.billingDetails.shippingAddress;
|
||||||
String postalCode = customerAddress.postalCode;
|
String postalCode = customerAddress.postalCode;
|
||||||
@ -96,7 +102,7 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
|
|
||||||
if (_shipping.methods.freeShipping != null) {
|
if (_shipping.methods.freeShipping != null) {
|
||||||
_shipping.methods.freeShipping.forEach((freeShipping) {
|
_shipping.methods.freeShipping.forEach((freeShipping) {
|
||||||
if (_isNumeric(freeShipping.cost)) {
|
if (isNumeric(freeShipping.cost)) {
|
||||||
Map<String, dynamic> tmpShippingOption = {};
|
Map<String, dynamic> tmpShippingOption = {};
|
||||||
tmpShippingOption = {
|
tmpShippingOption = {
|
||||||
"id": freeShipping.id,
|
"id": freeShipping.id,
|
||||||
@ -120,13 +126,6 @@ class _CheckoutShippingTypePageState extends State<CheckoutShippingTypePage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isNumeric(String str) {
|
|
||||||
if(str == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return double.tryParse(str) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> _getShippingPrice(int index) async {
|
Future<String> _getShippingPrice(int index) async {
|
||||||
double total = 0;
|
double total = 0;
|
||||||
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
List<CartLineItem> cartLineItem = await Cart.getInstance.getCart();
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,19 +10,21 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:woosignal/models/response/order.dart' as WS;
|
import 'package:woosignal/models/response/order.dart' as WS;
|
||||||
|
|
||||||
|
import '../widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class CheckoutStatusPage extends StatefulWidget {
|
class CheckoutStatusPage extends StatefulWidget {
|
||||||
CheckoutStatusPage();
|
final WS.Order order;
|
||||||
|
CheckoutStatusPage({Key key, @required this.order}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_CheckoutStatusState createState() => _CheckoutStatusState();
|
_CheckoutStatusState createState() => _CheckoutStatusState(this.order);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
||||||
_CheckoutStatusState();
|
_CheckoutStatusState(this._order);
|
||||||
|
|
||||||
WS.Order _order;
|
WS.Order _order;
|
||||||
|
|
||||||
@ -31,19 +33,13 @@ class _CheckoutStatusState extends State<CheckoutStatusPage> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
_order = ModalRoute.of(context).settings.arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
elevation: 0.0,
|
elevation: 0.0,
|
||||||
title: Image.network(app_logo_url, height: 100),
|
title: storeLogo(height: 60),
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
|
|||||||
62
LabelStoreMax/lib/pages/error_page.dart
Normal file
62
LabelStoreMax/lib/pages/error_page.dart
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
|
|
||||||
|
class ErrorPage extends StatefulWidget {
|
||||||
|
ErrorPage();
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ErrorPageState createState() => _ErrorPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ErrorPageState extends State<ErrorPage> {
|
||||||
|
_ErrorPageState();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: SafeArea(
|
||||||
|
minimum: safeAreaDefault(),
|
||||||
|
child: Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Icon(
|
||||||
|
Icons.error_outline,
|
||||||
|
size: 100,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
child: Text(
|
||||||
|
trans(context, "Sorry, something went wrong"),
|
||||||
|
style: Theme.of(context).primaryTextTheme.body1,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
wsLinkButton(context, title: trans(context, "Back"), action: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,9 +10,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:label_storemax/widgets/cart_icon.dart';
|
||||||
import 'package:woosignal/models/response/product_category.dart' as WS;
|
import 'package:woosignal/models/response/product_category.dart' as WS;
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
@ -42,9 +43,33 @@ class _HomePageState extends State<HomePage> {
|
|||||||
_isLoading = true;
|
_isLoading = true;
|
||||||
|
|
||||||
_page = 1;
|
_page = 1;
|
||||||
|
_home();
|
||||||
|
_addScrollListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
_home() async {
|
||||||
|
await _fetchProducts();
|
||||||
|
await _fetchCategories();
|
||||||
_shouldStopRequests = false;
|
_shouldStopRequests = false;
|
||||||
waitForNextRequest = false;
|
waitForNextRequest = false;
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_fetchProducts() async {
|
||||||
|
_products = await appWooSignal((api) {
|
||||||
|
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_fetchCategories() async {
|
||||||
|
_categories = await appWooSignal((api) {
|
||||||
|
return api.getProductCategories();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_addScrollListener() async {
|
||||||
_productsController.addListener(() {
|
_productsController.addListener(() {
|
||||||
double maxScroll = _productsController.position.maxScrollExtent;
|
double maxScroll = _productsController.position.maxScrollExtent;
|
||||||
double currentScroll = _productsController.position.pixels;
|
double currentScroll = _productsController.position.pixels;
|
||||||
@ -56,86 +81,75 @@ class _HomePageState extends State<HomePage> {
|
|||||||
if (waitForNextRequest) {
|
if (waitForNextRequest) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
_fetchMoreProducts();
|
||||||
waitForNextRequest = true;
|
|
||||||
_page = _page + 1;
|
|
||||||
wcStore
|
|
||||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
|
||||||
.then((products) {
|
|
||||||
waitForNextRequest = false;
|
|
||||||
if (products.length == 0) {
|
|
||||||
_shouldStopRequests = true;
|
|
||||||
}
|
|
||||||
_products.addAll(products.toList());
|
|
||||||
setState(() {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
_fetchMoreProducts() async {
|
||||||
wcStore
|
waitForNextRequest = true;
|
||||||
.getProducts(perPage: 50, page: _page, status: "publish")
|
List<WS.Product> products = await appWooSignal((api) {
|
||||||
.then((products) {
|
_page = _page + 1;
|
||||||
_products = products;
|
return api.getProducts(perPage: 50, page: _page, status: "publish");
|
||||||
setState(() {
|
});
|
||||||
_isLoading = false;
|
if (products.length == 0) {
|
||||||
});
|
_shouldStopRequests = true;
|
||||||
});
|
}
|
||||||
|
setState(() {
|
||||||
wcStore.getProductCategories().then((categories) {
|
_products.addAll(products.toList());
|
||||||
_categories = categories;
|
|
||||||
setState(() {});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _modalBottomSheetMenu() {
|
void _modalBottomSheetMenu() {
|
||||||
showModalBottomSheet(
|
showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
builder: (builder) {
|
builder: (builder) {
|
||||||
return new Container(
|
return new Container(
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
width: double.infinity - 10,
|
width: double.infinity - 10,
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
child: new Container(
|
child: new Container(
|
||||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: new BorderRadius.only(
|
borderRadius: new BorderRadius.only(
|
||||||
topLeft: const Radius.circular(10.0),
|
topLeft: const Radius.circular(10.0),
|
||||||
topRight: const Radius.circular(10.0))),
|
topRight: const Radius.circular(10.0)),
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Text(trans(context, "Categories"),
|
|
||||||
style: Theme.of(context).primaryTextTheme.display1,
|
|
||||||
textAlign: TextAlign.left),
|
|
||||||
Expanded(
|
|
||||||
child: new ListView.builder(
|
|
||||||
itemCount: _categories.length,
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return InkWell(
|
|
||||||
child: Container(
|
|
||||||
child: Text(_categories[index].name),
|
|
||||||
padding: EdgeInsets.all(15),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
border: Border(
|
|
||||||
bottom: BorderSide(
|
|
||||||
color: HexColor("#f2f2f2"),
|
|
||||||
width: 2))),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
Navigator.pushNamed(context, "/browse-category",
|
|
||||||
arguments: _categories[index]);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
child: Column(
|
||||||
});
|
children: <Widget>[
|
||||||
|
Text(trans(context, "Categories"),
|
||||||
|
style: Theme.of(context).primaryTextTheme.display1,
|
||||||
|
textAlign: TextAlign.left),
|
||||||
|
Expanded(
|
||||||
|
child: new ListView.builder(
|
||||||
|
itemCount: _categories.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return InkWell(
|
||||||
|
child: Container(
|
||||||
|
child: Text(_categories[index].name),
|
||||||
|
padding: EdgeInsets.all(15),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border(
|
||||||
|
bottom: BorderSide(
|
||||||
|
color: HexColor("#f2f2f2"), width: 2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
Navigator.pushNamed(context, "/browse-category",
|
||||||
|
arguments: _categories[index]);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -207,12 +221,13 @@ class _HomePageState extends State<HomePage> {
|
|||||||
? Expanded(child: showAppLoader())
|
? Expanded(child: showAppLoader())
|
||||||
: Expanded(
|
: Expanded(
|
||||||
child: GridView.count(
|
child: GridView.count(
|
||||||
controller: _productsController,
|
controller: _productsController,
|
||||||
crossAxisCount: 2,
|
crossAxisCount: 2,
|
||||||
children: List.generate(_products.length, (index) {
|
children: List.generate(_products.length, (index) {
|
||||||
return wsCardProductItem(context,
|
return wsCardProductItem(context,
|
||||||
index: index, product: _products[index]);
|
index: index, product: _products[index]);
|
||||||
})),
|
}),
|
||||||
|
),
|
||||||
flex: 1,
|
flex: 1,
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -9,10 +9,11 @@
|
|||||||
// 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/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/widgets/menu_item.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
|
||||||
|
import '../widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class HomeMenuPage extends StatefulWidget {
|
class HomeMenuPage extends StatefulWidget {
|
||||||
HomeMenuPage();
|
HomeMenuPage();
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ class _HomeMenuPageState extends State<HomeMenuPage> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Image.network(app_logo_url, height: 100),
|
storeLogo(height: 100),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,8 +10,9 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
|
||||||
|
import '../widgets/woosignal_ui.dart';
|
||||||
|
|
||||||
class HomeSearchPage extends StatefulWidget {
|
class HomeSearchPage extends StatefulWidget {
|
||||||
HomeSearchPage();
|
HomeSearchPage();
|
||||||
@ -45,8 +46,7 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
title: Image.network(app_logo_url,
|
title: storeLogo(height: 60),
|
||||||
height: 60, alignment: Alignment.center),
|
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
@ -60,14 +60,21 @@ class _HomeSearchPageState extends State<HomeSearchPage> {
|
|||||||
margin: EdgeInsets.only(bottom: 20),
|
margin: EdgeInsets.only(bottom: 20),
|
||||||
),
|
),
|
||||||
TextField(
|
TextField(
|
||||||
controller: _txtSearchController,
|
controller: _txtSearchController,
|
||||||
style: Theme.of(context).primaryTextTheme.display2,
|
style: Theme.of(context).primaryTextTheme.display2,
|
||||||
keyboardType: TextInputType.text,
|
keyboardType: TextInputType.text,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
textCapitalization: TextCapitalization.sentences),
|
textCapitalization: TextCapitalization.sentences,
|
||||||
wsPrimaryButton(context,
|
),
|
||||||
title: trans(context, "Search"), action: _actionSearch)
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(top: 10),
|
||||||
|
child: wsPrimaryButton(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Search"),
|
||||||
|
action: _actionSearch,
|
||||||
|
),
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -9,27 +9,53 @@
|
|||||||
// 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/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/painting.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
|
import 'package:label_storemax/widgets/buttons.dart';
|
||||||
|
import 'package:label_storemax/widgets/cart_icon.dart';
|
||||||
import 'package:woosignal/models/response/product_variation.dart' as WS;
|
import 'package:woosignal/models/response/product_variation.dart' as WS;
|
||||||
import 'package:woosignal/models/response/products.dart' as WS;
|
import 'package:woosignal/models/response/products.dart' as WS;
|
||||||
import 'package:woosignal/woosignal.dart';
|
|
||||||
import 'package:flutter_swiper/flutter_swiper.dart';
|
import 'package:flutter_swiper/flutter_swiper.dart';
|
||||||
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
import 'package:label_storemax/widgets/woosignal_ui.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
|
||||||
|
class ProductDetailPage extends StatefulWidget {
|
||||||
|
final WS.Product product;
|
||||||
|
const ProductDetailPage({Key key, @required this.product}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
_ProductDetailState createState() => _ProductDetailState(this.product);
|
||||||
|
}
|
||||||
|
|
||||||
class _ProductDetailState extends State<ProductDetailPage> {
|
class _ProductDetailState extends State<ProductDetailPage> {
|
||||||
_ProductDetailState();
|
_ProductDetailState(this._product);
|
||||||
|
|
||||||
bool _isLoading;
|
bool _isLoading;
|
||||||
WS.Product _product;
|
WS.Product _product;
|
||||||
|
int _quantityIndicator = 1;
|
||||||
List<WS.ProductVariation> _productVariations = [];
|
List<WS.ProductVariation> _productVariations = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
if (_product.type == "variable") {
|
||||||
|
_isLoading = true;
|
||||||
|
_fetchProductVariations();
|
||||||
|
} else {
|
||||||
|
_isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_isLoading = true;
|
_fetchProductVariations() async {
|
||||||
|
_productVariations = await appWooSignal((api) {
|
||||||
|
return api.getProductVariations(_product.id);
|
||||||
|
});
|
||||||
|
setState(() {
|
||||||
|
_isLoading = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<int, dynamic> _tmpAttributeObj = {};
|
Map<int, dynamic> _tmpAttributeObj = {};
|
||||||
@ -94,159 +120,146 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
|
|
||||||
_itemAddToCart({CartLineItem cartLineItem}) {
|
_itemAddToCart({CartLineItem cartLineItem}) {
|
||||||
Cart.getInstance.addToCart(cartLineItem: cartLineItem);
|
Cart.getInstance.addToCart(cartLineItem: cartLineItem);
|
||||||
showToastWith(message: trans(context, "Added to cart"), statusType: "");
|
showStatusAlert(context,
|
||||||
|
title: "Success",
|
||||||
|
subtitle: trans(context, "Added to cart"),
|
||||||
|
duration: 1,
|
||||||
|
icon: Icons.add_shopping_cart);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _modalBottomSheetAttributes() {
|
void _modalBottomSheetAttributes() {
|
||||||
wsModalBottom(context,
|
wsModalBottom(
|
||||||
title: trans(context, "Options"),
|
context,
|
||||||
bodyWidget: Expanded(
|
title: trans(context, "Options"),
|
||||||
child: ListView.separated(
|
bodyWidget: Expanded(
|
||||||
itemCount: _product.attributes.length,
|
child: ListView.separated(
|
||||||
separatorBuilder: (BuildContext context, int index) => Divider(
|
itemCount: _product.attributes.length,
|
||||||
color: Colors.black12,
|
separatorBuilder: (BuildContext context, int index) => Divider(
|
||||||
thickness: 1,
|
color: Colors.black12,
|
||||||
),
|
thickness: 1,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
),
|
||||||
return ListTile(
|
itemBuilder: (BuildContext context, int index) {
|
||||||
title: Text(_product.attributes[index].name,
|
return ListTile(
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
title: Text(_product.attributes[index].name,
|
||||||
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
style: Theme.of(context).primaryTextTheme.subhead),
|
||||||
_tmpAttributeObj.containsKey(index))
|
subtitle: (_tmpAttributeObj.isNotEmpty &&
|
||||||
? Text(_tmpAttributeObj[index]["value"],
|
_tmpAttributeObj.containsKey(index))
|
||||||
style: Theme.of(context).primaryTextTheme.body2)
|
? Text(_tmpAttributeObj[index]["value"],
|
||||||
: Text(trans(context, "Select a") +
|
style: Theme.of(context).primaryTextTheme.body2)
|
||||||
" " +
|
: Text(trans(context, "Select a") +
|
||||||
_product.attributes[index].name),
|
" " +
|
||||||
trailing: (_tmpAttributeObj.isNotEmpty &&
|
_product.attributes[index].name),
|
||||||
_tmpAttributeObj.containsKey(index))
|
trailing: (_tmpAttributeObj.isNotEmpty &&
|
||||||
? Icon(Icons.check, color: Colors.blueAccent)
|
_tmpAttributeObj.containsKey(index))
|
||||||
: null,
|
? Icon(Icons.check, color: Colors.blueAccent)
|
||||||
onTap: () {
|
: null,
|
||||||
_modalBottomSheetOptionsForAttribute(index);
|
onTap: () {
|
||||||
},
|
_modalBottomSheetOptionsForAttribute(index);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
)),
|
},
|
||||||
extraWidget: Container(
|
)),
|
||||||
decoration: BoxDecoration(
|
extraWidget: Container(
|
||||||
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
decoration: BoxDecoration(
|
||||||
padding: EdgeInsets.only(top: 10),
|
border: Border(top: BorderSide(color: Colors.black12, width: 1))),
|
||||||
child: Column(
|
padding: EdgeInsets.only(top: 10),
|
||||||
children: <Widget>[
|
child: Column(
|
||||||
Text(
|
children: <Widget>[
|
||||||
(findProductVariation() != null
|
Text(
|
||||||
? trans(context, "Price") +
|
|
||||||
": " +
|
|
||||||
formatStringCurrency(
|
|
||||||
total: findProductVariation().price)
|
|
||||||
: (((_product.attributes.length ==
|
|
||||||
_tmpAttributeObj.values.length) &&
|
|
||||||
findProductVariation() == null)
|
|
||||||
? trans(context, "This variation is unavailable")
|
|
||||||
: trans(context, "Choose your options"))),
|
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
|
||||||
Text(
|
|
||||||
(findProductVariation() != null
|
(findProductVariation() != null
|
||||||
? findProductVariation().stockStatus != "instock"
|
? trans(context, "Price") +
|
||||||
? trans(context, "Out of stock")
|
": " +
|
||||||
: ""
|
formatStringCurrency(
|
||||||
: ""),
|
total: findProductVariation().price)
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
: (((_product.attributes.length ==
|
||||||
),
|
_tmpAttributeObj.values.length) &&
|
||||||
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
findProductVariation() == null)
|
||||||
action: () {
|
? trans(context, "This variation is unavailable")
|
||||||
if (_product.attributes.length !=
|
: trans(context, "Choose your options"))),
|
||||||
_tmpAttributeObj.values.length) {
|
style: Theme.of(context).primaryTextTheme.subhead),
|
||||||
|
Text(
|
||||||
|
(findProductVariation() != null
|
||||||
|
? findProductVariation().stockStatus != "instock"
|
||||||
|
? trans(context, "Out of stock")
|
||||||
|
: ""
|
||||||
|
: ""),
|
||||||
|
style: Theme.of(context).primaryTextTheme.subhead,
|
||||||
|
),
|
||||||
|
wsPrimaryButton(context, title: trans(context, "Add to cart"),
|
||||||
|
action: () {
|
||||||
|
if (_product.attributes.length !=
|
||||||
|
_tmpAttributeObj.values.length) {
|
||||||
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Oops"),
|
||||||
|
desc: trans(context, "Please select valid options first"),
|
||||||
|
style: EdgeAlertStyle.WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findProductVariation() == null) {
|
||||||
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Oops"),
|
||||||
|
desc: trans(context, "Product variation does not exist"),
|
||||||
|
style: EdgeAlertStyle.WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (findProductVariation() != null) {
|
||||||
|
if (findProductVariation().stockStatus != "instock") {
|
||||||
showEdgeAlertWith(context,
|
showEdgeAlertWith(context,
|
||||||
title: trans(context, "Oops"),
|
title: trans(context, "Sorry"),
|
||||||
desc: trans(context, "Please select valid options first"),
|
desc: trans(context, "This item is not in stock"),
|
||||||
style: EdgeAlertStyle.WARNING);
|
style: EdgeAlertStyle.WARNING);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (findProductVariation() == null) {
|
List<String> options = [];
|
||||||
showEdgeAlertWith(context,
|
_tmpAttributeObj.forEach((k, v) {
|
||||||
title: trans(context, "Oops"),
|
options.add(v["name"] + ": " + v["value"]);
|
||||||
desc: trans(context, "Product variation does not exist"),
|
});
|
||||||
style: EdgeAlertStyle.WARNING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (findProductVariation() != null) {
|
CartLineItem cartLineItem = CartLineItem(
|
||||||
if (findProductVariation().stockStatus != "instock") {
|
name: _product.name,
|
||||||
showEdgeAlertWith(context,
|
productId: _product.id,
|
||||||
title: trans(context, "Sorry"),
|
variationId: findProductVariation().id,
|
||||||
desc: trans(context, "This item is not in stock"),
|
quantity: 1,
|
||||||
style: EdgeAlertStyle.WARNING);
|
taxStatus: findProductVariation().taxStatus,
|
||||||
return;
|
shippingClassId:
|
||||||
}
|
findProductVariation().shippingClassId.toString(),
|
||||||
}
|
subtotal: findProductVariation().price,
|
||||||
|
stockQuantity: findProductVariation().stockQuantity,
|
||||||
|
isManagedStock: findProductVariation().manageStock,
|
||||||
|
taxClass: findProductVariation().taxClass,
|
||||||
|
imageSrc: (findProductVariation().image != null
|
||||||
|
? findProductVariation().image.src
|
||||||
|
: _product.images.first.src),
|
||||||
|
shippingIsTaxable: _product.shippingTaxable,
|
||||||
|
variationOptions: options.join(", "),
|
||||||
|
total: findProductVariation().price);
|
||||||
|
|
||||||
List<String> options = [];
|
_itemAddToCart(cartLineItem: cartLineItem);
|
||||||
_tmpAttributeObj.forEach((k, v) {
|
Navigator.of(context).pop();
|
||||||
options.add(v["name"] + ": " + v["value"]);
|
}),
|
||||||
});
|
],
|
||||||
|
),
|
||||||
CartLineItem cartLineItem = CartLineItem(
|
margin: EdgeInsets.only(bottom: 10),
|
||||||
name: _product.name,
|
),
|
||||||
productId: _product.id,
|
);
|
||||||
variationId: findProductVariation().id,
|
|
||||||
quantity: 1,
|
|
||||||
taxStatus: findProductVariation().taxStatus,
|
|
||||||
shippingClassId:
|
|
||||||
findProductVariation().shippingClassId.toString(),
|
|
||||||
subtotal: findProductVariation().price,
|
|
||||||
stockQuantity: findProductVariation().stockQuantity,
|
|
||||||
isManagedStock: findProductVariation().manageStock,
|
|
||||||
taxClass: findProductVariation().taxClass,
|
|
||||||
imageSrc: (findProductVariation().image != null
|
|
||||||
? findProductVariation().image.src
|
|
||||||
: _product.images.first.src),
|
|
||||||
shippingIsTaxable: _product.shippingTaxable,
|
|
||||||
variationOptions: options.join(", "),
|
|
||||||
total: findProductVariation().price);
|
|
||||||
|
|
||||||
_itemAddToCart(cartLineItem: cartLineItem);
|
|
||||||
Navigator.of(context).pop();
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
margin: EdgeInsets.only(bottom: 10),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _modalBottomSheetMenu() {
|
void _modalBottomSheetMenu() {
|
||||||
wsModalBottom(context,
|
wsModalBottom(
|
||||||
title: trans(context, "Description"),
|
context,
|
||||||
bodyWidget: Expanded(
|
title: trans(context, "Description"),
|
||||||
child: SingleChildScrollView(
|
bodyWidget: Expanded(
|
||||||
child: Text(parseHtmlString(_product.description)),
|
child: SingleChildScrollView(
|
||||||
),
|
child: Text(parseHtmlString(_product.description)),
|
||||||
flex: 1,
|
),
|
||||||
));
|
flex: 1,
|
||||||
}
|
),
|
||||||
|
);
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
super.didChangeDependencies();
|
|
||||||
if (_isLoading) {
|
|
||||||
_product = ModalRoute.of(context).settings.arguments;
|
|
||||||
|
|
||||||
if (_product.type == "variable") {
|
|
||||||
WooSignal.getInstance(config: wsConfig).then((wcStore) {
|
|
||||||
wcStore.getProductVariations(_product.id).then((productVariations) {
|
|
||||||
_productVariations = productVariations;
|
|
||||||
_isLoading = false;
|
|
||||||
setState(() {});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
_isLoading = false;
|
|
||||||
setState(() {});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -254,170 +267,276 @@ class _ProductDetailState extends State<ProductDetailPage> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
backgroundColor: Colors.transparent,
|
backgroundColor: Colors.transparent,
|
||||||
actions: <Widget>[wsCartIcon(context)],
|
actions: <Widget>[
|
||||||
title: storeLogo(height: 50),
|
wsCartIcon(context),
|
||||||
|
],
|
||||||
|
title: storeLogo(height: 55),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
),
|
),
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
minimum: safeAreaDefault(),
|
|
||||||
child: _isLoading
|
child: _isLoading
|
||||||
? showAppLoader()
|
? showAppLoader()
|
||||||
: Column(
|
: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
Expanded(
|
||||||
flex: 3,
|
child: ListView(
|
||||||
child: SizedBox(
|
|
||||||
child: new Swiper(
|
|
||||||
itemBuilder: (BuildContext context, int index) {
|
|
||||||
return CachedNetworkImage(
|
|
||||||
imageUrl: _product.images[index].src,
|
|
||||||
placeholder: (context, url) =>
|
|
||||||
new CircularProgressIndicator(
|
|
||||||
strokeWidth: 2,
|
|
||||||
backgroundColor: Colors.black12),
|
|
||||||
errorWidget: (context, url, error) =>
|
|
||||||
new Icon(Icons.error),
|
|
||||||
fit: BoxFit.contain);
|
|
||||||
},
|
|
||||||
itemCount: _product.images.length,
|
|
||||||
viewportFraction: 0.8,
|
|
||||||
scale: 0.9,
|
|
||||||
onTap: (i) {
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(top: 10),
|
|
||||||
child: Row(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Flexible(
|
SizedBox(
|
||||||
child: Text(
|
height: MediaQuery.of(context).size.height * 0.40,
|
||||||
_product.name,
|
child: SizedBox(
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
child: new Swiper(
|
||||||
textAlign: TextAlign.left,
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
return CachedNetworkImage(
|
||||||
|
imageUrl: _product.images[index].src,
|
||||||
|
placeholder: (context, url) =>
|
||||||
|
new CircularProgressIndicator(
|
||||||
|
strokeWidth: 2,
|
||||||
|
backgroundColor: Colors.black12,
|
||||||
|
),
|
||||||
|
errorWidget: (context, url, error) =>
|
||||||
|
new Icon(Icons.error),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: _product.images.length,
|
||||||
|
viewportFraction: 0.85,
|
||||||
|
scale: 0.9,
|
||||||
|
onTap: (i) {
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
flex: 4,
|
|
||||||
),
|
),
|
||||||
Flexible(
|
Container(
|
||||||
child: Column(
|
height: 100,
|
||||||
crossAxisAlignment: CrossAxisAlignment.end,
|
padding: EdgeInsets.symmetric(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
vertical: 10, horizontal: 16),
|
||||||
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Flexible(
|
||||||
formatStringCurrency(total: _product.price),
|
child: Text(
|
||||||
style:
|
_product.name,
|
||||||
Theme.of(context).primaryTextTheme.subhead,
|
style:
|
||||||
textAlign: TextAlign.right,
|
Theme.of(context).primaryTextTheme.body2,
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 2,
|
||||||
|
),
|
||||||
|
flex: 4,
|
||||||
),
|
),
|
||||||
Text(
|
Flexible(
|
||||||
((_product.stockStatus != "instock"
|
child: Column(
|
||||||
? trans(context, "Out of stock")
|
crossAxisAlignment: CrossAxisAlignment.end,
|
||||||
: trans(context, "In Stock"))),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
style: Theme.of(context).primaryTextTheme.body1,
|
children: <Widget>[
|
||||||
textAlign: TextAlign.right,
|
Text(
|
||||||
|
formatStringCurrency(
|
||||||
|
total: _product.price),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.display1
|
||||||
|
.copyWith(
|
||||||
|
fontSize: 20,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
flex: 2,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
color: Colors.white,
|
||||||
|
padding:
|
||||||
|
EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||||
|
height: 180,
|
||||||
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
|
children: <Widget>[
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment:
|
||||||
|
MainAxisAlignment.spaceBetween,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
Text(
|
||||||
|
trans(context, "Description"),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.caption
|
||||||
|
.copyWith(fontSize: 18),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
MaterialButton(
|
||||||
|
child: Text(
|
||||||
|
trans(context, "Full description"),
|
||||||
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.body1
|
||||||
|
.copyWith(fontSize: 14),
|
||||||
|
textAlign: TextAlign.right,
|
||||||
|
),
|
||||||
|
height: 50,
|
||||||
|
minWidth: 60,
|
||||||
|
onPressed: () {
|
||||||
|
_modalBottomSheetMenu();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Text(
|
||||||
|
(_product.shortDescription != null &&
|
||||||
|
_product.shortDescription != ""
|
||||||
|
? parseHtmlString(
|
||||||
|
_product.shortDescription)
|
||||||
|
: parseHtmlString(_product.description)),
|
||||||
|
),
|
||||||
|
flex: 3,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
flex: 2,
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black12,
|
||||||
|
blurRadius: 15.0,
|
||||||
|
spreadRadius: -17,
|
||||||
|
offset: Offset(
|
||||||
|
0,
|
||||||
|
-10,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Divider(
|
|
||||||
color: Colors.black12,
|
|
||||||
thickness: 1,
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
trans(context, "Description"),
|
"Quantity",
|
||||||
style: Theme.of(context).primaryTextTheme.body1,
|
style: Theme.of(context).primaryTextTheme.body2,
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
),
|
||||||
MaterialButton(
|
Row(
|
||||||
|
children: <Widget>[
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.remove_circle_outline,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if ((_quantityIndicator - 1) >= 1) {
|
||||||
|
setState(() {
|
||||||
|
_quantityIndicator--;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
_quantityIndicator.toString(),
|
||||||
|
style:
|
||||||
|
Theme.of(context).primaryTextTheme.body2,
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
Icons.add_circle_outline,
|
||||||
|
size: 28,
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
if (_quantityIndicator != 0) {
|
||||||
|
setState(() {
|
||||||
|
_quantityIndicator++;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: <Widget>[
|
||||||
|
Flexible(
|
||||||
|
child: Align(
|
||||||
child: Text(
|
child: Text(
|
||||||
trans(context, "Full description"),
|
formatStringCurrency(
|
||||||
|
total: (double.parse(_product.price) *
|
||||||
|
_quantityIndicator)
|
||||||
|
.toString()),
|
||||||
style:
|
style:
|
||||||
Theme.of(context).primaryTextTheme.caption,
|
Theme.of(context).primaryTextTheme.display1,
|
||||||
textAlign: TextAlign.right,
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
)),
|
||||||
|
Flexible(
|
||||||
|
child: wsPrimaryButton(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Add to cart"),
|
||||||
|
action: () {
|
||||||
|
_addItemToCart();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
height: 50,
|
|
||||||
minWidth: 60,
|
|
||||||
onPressed: () {
|
|
||||||
_modalBottomSheetMenu();
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Flexible(
|
|
||||||
child: Text(
|
|
||||||
(_product.shortDescription != null &&
|
|
||||||
_product.shortDescription != ""
|
|
||||||
? parseHtmlString(_product.shortDescription)
|
|
||||||
: parseHtmlString(_product.description)),
|
|
||||||
),
|
|
||||||
flex: 3,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
flex: 1,
|
height: 140,
|
||||||
),
|
|
||||||
wsPrimaryButton(
|
|
||||||
context,
|
|
||||||
title: trans(context, "ADD TO CART"),
|
|
||||||
action: () {
|
|
||||||
CartLineItem cartLineItem = CartLineItem(
|
|
||||||
name: _product.name,
|
|
||||||
productId: _product.id,
|
|
||||||
quantity: 1,
|
|
||||||
taxStatus: _product.taxStatus,
|
|
||||||
shippingClassId: _product.shippingClassId.toString(),
|
|
||||||
subtotal: _product.price,
|
|
||||||
taxClass: _product.taxClass,
|
|
||||||
isManagedStock: _product.manageStock,
|
|
||||||
stockQuantity: _product.stockQuantity,
|
|
||||||
shippingIsTaxable: _product.shippingTaxable,
|
|
||||||
imageSrc: _product.images.length == 0 ? "" : _product.images.first.src,
|
|
||||||
total: _product.price);
|
|
||||||
|
|
||||||
if (_product.type != "simple") {
|
|
||||||
_modalBottomSheetAttributes();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_product.stockStatus == "instock") {
|
|
||||||
_itemAddToCart(cartLineItem: cartLineItem);
|
|
||||||
} else {
|
|
||||||
showEdgeAlertWith(context,
|
|
||||||
title: trans(context, "Sorry"),
|
|
||||||
desc: trans(context, "This item is out of stock"),
|
|
||||||
style: EdgeAlertStyle.WARNING,
|
|
||||||
icon: Icons.local_shipping);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class ProductDetailPage extends StatefulWidget {
|
_addItemToCart() {
|
||||||
ProductDetailPage();
|
CartLineItem cartLineItem = CartLineItem(
|
||||||
|
name: _product.name,
|
||||||
|
productId: _product.id,
|
||||||
|
quantity: _quantityIndicator,
|
||||||
|
taxStatus: _product.taxStatus,
|
||||||
|
shippingClassId: _product.shippingClassId.toString(),
|
||||||
|
subtotal: _product.price,
|
||||||
|
taxClass: _product.taxClass,
|
||||||
|
isManagedStock: _product.manageStock,
|
||||||
|
stockQuantity: _product.stockQuantity,
|
||||||
|
shippingIsTaxable: _product.shippingTaxable,
|
||||||
|
imageSrc: _product.images.first.src,
|
||||||
|
total: _product.price,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
if (_product.type != "simple") {
|
||||||
_ProductDetailState createState() => _ProductDetailState();
|
_modalBottomSheetAttributes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_product.stockStatus == "instock") {
|
||||||
|
_itemAddToCart(cartLineItem: cartLineItem);
|
||||||
|
} else {
|
||||||
|
showEdgeAlertWith(context,
|
||||||
|
title: trans(context, "Sorry"),
|
||||||
|
desc: trans(context, "This item is out of stock"),
|
||||||
|
style: EdgeAlertStyle.WARNING,
|
||||||
|
icon: Icons.local_shipping);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
106
LabelStoreMax/lib/providers/stripe_pay.dart
Normal file
106
LabelStoreMax/lib/providers/stripe_pay.dart
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
//
|
||||||
|
// LabelCore
|
||||||
|
// Label StoreMAX
|
||||||
|
//
|
||||||
|
// Created by Anthony Gordon.
|
||||||
|
// Copyright © 2020 WooSignal. 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/cupertino.dart';
|
||||||
|
import 'package:label_storemax/helpers/data/order_wc.dart';
|
||||||
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/pages/checkout_confirmation.dart';
|
||||||
|
import 'package:woosignal/models/payload/order_wc.dart';
|
||||||
|
import 'package:woosignal/models/response/order.dart';
|
||||||
|
import 'package:woosignal/models/response/tax_rate.dart';
|
||||||
|
import 'package:woosignal_stripe/woosignal_stripe.dart';
|
||||||
|
|
||||||
|
stripePay(context,
|
||||||
|
{@required CheckoutConfirmationPageState state,
|
||||||
|
TaxRate taxRate}) async {
|
||||||
|
|
||||||
|
// CONFIGURE STRIPE
|
||||||
|
FlutterStripePayment.setStripeSettings(
|
||||||
|
stripeAccount: app_stripe_account, liveMode: app_stripe_live_mode);
|
||||||
|
|
||||||
|
var paymentResponse = await FlutterStripePayment.addPaymentMethod();
|
||||||
|
|
||||||
|
// CHECK STATUS FROM STRIPE
|
||||||
|
if (paymentResponse.status == PaymentResponseStatus.succeeded) {
|
||||||
|
state.reloadState(showLoader: true);
|
||||||
|
|
||||||
|
// CHECKOUT HELPER
|
||||||
|
await checkout(taxRate, (total, billingDetails, cart) async {
|
||||||
|
|
||||||
|
Map<String, dynamic> address = {
|
||||||
|
"name": billingDetails.billingAddress.nameFull(),
|
||||||
|
"line1": billingDetails.shippingAddress.addressLine,
|
||||||
|
"city": billingDetails.shippingAddress.city,
|
||||||
|
"postal_code": billingDetails.shippingAddress.postalCode,
|
||||||
|
"country": billingDetails.shippingAddress.country
|
||||||
|
};
|
||||||
|
|
||||||
|
String cartShortDesc = await cart.cartShortDesc();
|
||||||
|
|
||||||
|
dynamic rsp = await appWooSignal((api) {
|
||||||
|
return api.stripePaymentIntent(
|
||||||
|
amount: total,
|
||||||
|
email: billingDetails.billingAddress.emailAddress,
|
||||||
|
desc: cartShortDesc,
|
||||||
|
shipping: address,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (rsp == null) {
|
||||||
|
showToastNetworkError();
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String clientSecret = rsp["client_secret"];
|
||||||
|
var intentResponse = await FlutterStripePayment.confirmPaymentIntent(
|
||||||
|
clientSecret,
|
||||||
|
paymentResponse.paymentMethodId,
|
||||||
|
(double.parse(total) * 100),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (intentResponse.status == PaymentResponseStatus.succeeded) {
|
||||||
|
OrderWC orderWC = await buildOrderWC(taxRate: taxRate);
|
||||||
|
Order order = await appWooSignal((api) {
|
||||||
|
return api.createOrder(orderWC);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (order != null) {
|
||||||
|
Cart.getInstance.clear();
|
||||||
|
Navigator.pushNamed(context, "/checkout-status", arguments: order);
|
||||||
|
} else {
|
||||||
|
showEdgeAlertWith(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
|
desc:
|
||||||
|
trans(context, "Something went wrong, please contact our store"),
|
||||||
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
}
|
||||||
|
} else if (intentResponse.status == PaymentResponseStatus.failed) {
|
||||||
|
if (app_debug) {
|
||||||
|
print(intentResponse.errorMessage);
|
||||||
|
}
|
||||||
|
showEdgeAlertWith(
|
||||||
|
context,
|
||||||
|
title: trans(context, "Error"),
|
||||||
|
desc: intentResponse.errorMessage,
|
||||||
|
);
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
} else {
|
||||||
|
state.reloadState(showLoader: false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
7
LabelStoreMax/lib/widgets/app_loader.dart
Normal file
7
LabelStoreMax/lib/widgets/app_loader.dart
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
import '../helpers/tools.dart';
|
||||||
|
|
||||||
|
Widget showAppLoader() {
|
||||||
|
return SpinKitDoubleBounce(color: HexColor("#393318"));
|
||||||
|
}
|
||||||
52
LabelStoreMax/lib/widgets/buttons.dart
Normal file
52
LabelStoreMax/lib/widgets/buttons.dart
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../helpers/tools.dart';
|
||||||
|
|
||||||
|
Widget wsPrimaryButton(BuildContext context,
|
||||||
|
{@required String title, void Function() action}) {
|
||||||
|
return Container(
|
||||||
|
height: 55,
|
||||||
|
child: RaisedButton(
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12.0)),
|
||||||
|
padding: EdgeInsets.all(8),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).primaryTextTheme.button.copyWith(fontSize: 16),
|
||||||
|
),
|
||||||
|
onPressed: action ?? null,
|
||||||
|
elevation: 0,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget wsSecondaryButton(BuildContext context,
|
||||||
|
{String title, void Function() action}) {
|
||||||
|
return Container(
|
||||||
|
height: 60,
|
||||||
|
margin: EdgeInsets.only(top: 10),
|
||||||
|
child: RaisedButton(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: Text(title,
|
||||||
|
style: Theme.of(context).primaryTextTheme.body2,
|
||||||
|
textAlign: TextAlign.center),
|
||||||
|
onPressed: action,
|
||||||
|
color: HexColor("#f6f6f9"),
|
||||||
|
elevation: 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget wsLinkButton(BuildContext context,
|
||||||
|
{String title, void Function() action}) {
|
||||||
|
return Container(
|
||||||
|
height: 60,
|
||||||
|
margin: EdgeInsets.only(top: 10),
|
||||||
|
child: MaterialButton(
|
||||||
|
padding: EdgeInsets.all(10),
|
||||||
|
child: Text(title,
|
||||||
|
style: Theme.of(context).primaryTextTheme.body2,
|
||||||
|
textAlign: TextAlign.left),
|
||||||
|
onPressed: action,
|
||||||
|
elevation: 0),
|
||||||
|
);
|
||||||
|
}
|
||||||
45
LabelStoreMax/lib/widgets/cart_icon.dart
Normal file
45
LabelStoreMax/lib/widgets/cart_icon.dart
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
|
||||||
|
Widget wsCartIcon(BuildContext context) {
|
||||||
|
return IconButton(
|
||||||
|
icon: Stack(
|
||||||
|
children: <Widget>[
|
||||||
|
Positioned.fill(
|
||||||
|
child: Align(
|
||||||
|
child: Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
),
|
||||||
|
bottom: 0),
|
||||||
|
Positioned.fill(
|
||||||
|
child: Align(
|
||||||
|
child: FutureBuilder<List<CartLineItem>>(
|
||||||
|
future: Cart.getInstance.getCart(),
|
||||||
|
builder: (BuildContext context,
|
||||||
|
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
||||||
|
switch (snapshot.connectionState) {
|
||||||
|
case ConnectionState.waiting:
|
||||||
|
return Text("");
|
||||||
|
default:
|
||||||
|
if (snapshot.hasError)
|
||||||
|
return Text("");
|
||||||
|
else
|
||||||
|
return new Text(
|
||||||
|
snapshot.data.length.toString(),
|
||||||
|
style: Theme.of(context).primaryTextTheme.body2,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
),
|
||||||
|
top: 0)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pushNamed(context, "/cart");
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
27
LabelStoreMax/lib/widgets/menu_item.dart
Normal file
27
LabelStoreMax/lib/widgets/menu_item.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
Widget wsMenuItem(BuildContext context,
|
||||||
|
{String title, Widget leading, void Function() action}) {
|
||||||
|
return Flexible(
|
||||||
|
child: InkWell(
|
||||||
|
child: Card(
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
|
children: <Widget>[
|
||||||
|
leading,
|
||||||
|
Text(" " + title,
|
||||||
|
style: Theme.of(context).primaryTextTheme.body1),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
elevation: 1,
|
||||||
|
margin: EdgeInsets.only(top: 8, bottom: 8, left: 8, right: 8),
|
||||||
|
),
|
||||||
|
onTap: action,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
// Label StoreMAX
|
// Label StoreMAX
|
||||||
//
|
//
|
||||||
// Created by Anthony Gordon.
|
// Created by Anthony Gordon.
|
||||||
// Copyright © 2019 WooSignal. All rights reserved.
|
// Copyright © 2020 WooSignal. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:label_storemax/labelconfig.dart';
|
import 'package:label_storemax/labelconfig.dart';
|
||||||
|
import 'package:label_storemax/models/cart.dart';
|
||||||
|
import 'package:label_storemax/models/cart_line_item.dart';
|
||||||
|
import 'package:label_storemax/models/checkout_session.dart';
|
||||||
|
import 'package:label_storemax/widgets/app_loader.dart';
|
||||||
import 'package:woosignal/models/response/products.dart';
|
import 'package:woosignal/models/response/products.dart';
|
||||||
import 'package:label_storemax/helpers/tools.dart';
|
import 'package:label_storemax/helpers/tools.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
@ -17,118 +21,6 @@ import 'package:woosignal/models/response/tax_rate.dart';
|
|||||||
|
|
||||||
const appFontFamily = "Overpass";
|
const appFontFamily = "Overpass";
|
||||||
|
|
||||||
Widget wsCartIcon(BuildContext context) {
|
|
||||||
return IconButton(
|
|
||||||
icon: Stack(
|
|
||||||
children: <Widget>[
|
|
||||||
Positioned.fill(
|
|
||||||
child: Align(
|
|
||||||
child: Icon(Icons.shopping_cart, size: 20, color: Colors.black87),
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
),
|
|
||||||
bottom: 0),
|
|
||||||
Positioned.fill(
|
|
||||||
child: Align(
|
|
||||||
child: FutureBuilder<List<CartLineItem>>(
|
|
||||||
future: Cart.getInstance.getCart(),
|
|
||||||
builder: (BuildContext context,
|
|
||||||
AsyncSnapshot<List<CartLineItem>> snapshot) {
|
|
||||||
switch (snapshot.connectionState) {
|
|
||||||
case ConnectionState.waiting:
|
|
||||||
return Text("");
|
|
||||||
default:
|
|
||||||
if (snapshot.hasError)
|
|
||||||
return Text("");
|
|
||||||
else
|
|
||||||
return new Text(
|
|
||||||
snapshot.data.length.toString(),
|
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
alignment: Alignment.topCenter,
|
|
||||||
),
|
|
||||||
top: 0)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pushNamed(context, "/cart");
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget wsMenuItem(BuildContext context,
|
|
||||||
{String title, Widget leading, void Function() action}) {
|
|
||||||
return Flexible(
|
|
||||||
child: InkWell(
|
|
||||||
child: Card(
|
|
||||||
child: Container(
|
|
||||||
width: double.infinity,
|
|
||||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
children: <Widget>[
|
|
||||||
leading,
|
|
||||||
Text(" " + title,
|
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
elevation: 1,
|
|
||||||
margin: EdgeInsets.only(top: 8, bottom: 8, left: 8, right: 8),
|
|
||||||
),
|
|
||||||
onTap: action,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget wsPrimaryButton(BuildContext context,
|
|
||||||
{String title, void Function() action}) {
|
|
||||||
return Container(
|
|
||||||
height: 60,
|
|
||||||
margin: EdgeInsets.only(top: 10),
|
|
||||||
child: RaisedButton(
|
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
child: Text(title, style: Theme.of(context).primaryTextTheme.button),
|
|
||||||
onPressed: action,
|
|
||||||
elevation: 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget wsSecondaryButton(BuildContext context,
|
|
||||||
{String title, void Function() action}) {
|
|
||||||
return Container(
|
|
||||||
height: 60,
|
|
||||||
margin: EdgeInsets.only(top: 10),
|
|
||||||
child: RaisedButton(
|
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
child: Text(title,
|
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
|
||||||
textAlign: TextAlign.center),
|
|
||||||
onPressed: action,
|
|
||||||
color: HexColor("#f6f6f9"),
|
|
||||||
elevation: 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget wsLinkButton(BuildContext context,
|
|
||||||
{String title, void Function() action}) {
|
|
||||||
return Container(
|
|
||||||
height: 60,
|
|
||||||
margin: EdgeInsets.only(top: 10),
|
|
||||||
child: MaterialButton(
|
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
child: Text(title,
|
|
||||||
style: Theme.of(context).primaryTextTheme.body2,
|
|
||||||
textAlign: TextAlign.left),
|
|
||||||
onPressed: action,
|
|
||||||
elevation: 0),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
@ -142,7 +34,11 @@ Widget wsRow2Text(BuildContext context, {String text1, String text2}) {
|
|||||||
),
|
),
|
||||||
Flexible(
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Text(text2, style: Theme.of(context).primaryTextTheme.body2),
|
child: Text(text2,
|
||||||
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.body2
|
||||||
|
.copyWith(fontSize: 16, color: Colors.black87)),
|
||||||
),
|
),
|
||||||
flex: 3,
|
flex: 3,
|
||||||
)
|
)
|
||||||
@ -168,45 +64,46 @@ Widget wsCheckoutRow(BuildContext context,
|
|||||||
return Flexible(
|
return Flexible(
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
child: Container(
|
child: Container(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Padding(
|
Padding(
|
||||||
child: Text(heading,
|
child: Text(heading,
|
||||||
style: Theme.of(context).primaryTextTheme.body1),
|
style: Theme.of(context).primaryTextTheme.body1),
|
||||||
padding: EdgeInsets.only(bottom: 8),
|
padding: EdgeInsets.only(bottom: 8),
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
leadImage,
|
leadImage,
|
||||||
Container(
|
Container(
|
||||||
child: Text(leadTitle,
|
child: Text(leadTitle,
|
||||||
style: Theme.of(context).primaryTextTheme.subhead,
|
style: Theme.of(context).primaryTextTheme.subhead,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
softWrap: false),
|
softWrap: false),
|
||||||
padding: EdgeInsets.only(left: 15),
|
padding: EdgeInsets.only(left: 15),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Icon(Icons.arrow_forward_ios)
|
Icon(Icons.arrow_forward_ios)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
decoration: showBorderBottom == true
|
decoration: showBorderBottom == true
|
||||||
? BoxDecoration(
|
? BoxDecoration(
|
||||||
border: Border(
|
border:
|
||||||
bottom: BorderSide(color: Colors.black12, width: 1)))
|
Border(bottom: BorderSide(color: Colors.black12, width: 1)))
|
||||||
: BoxDecoration()),
|
: BoxDecoration(),
|
||||||
|
),
|
||||||
onTap: action,
|
onTap: action,
|
||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
),
|
),
|
||||||
@ -335,14 +232,18 @@ void wsModalBottom(BuildContext context,
|
|||||||
child: new Container(
|
child: new Container(
|
||||||
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
padding: EdgeInsets.only(top: 25, left: 18, right: 18),
|
||||||
decoration: new BoxDecoration(
|
decoration: new BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: new BorderRadius.only(
|
borderRadius: new BorderRadius.only(
|
||||||
topLeft: const Radius.circular(10.0),
|
topLeft: const Radius.circular(10.0),
|
||||||
topRight: const Radius.circular(10.0))),
|
topRight: const Radius.circular(10.0)),
|
||||||
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(title,
|
Text(title,
|
||||||
style: Theme.of(context).primaryTextTheme.display1,
|
style: Theme.of(context)
|
||||||
|
.primaryTextTheme
|
||||||
|
.display1
|
||||||
|
.copyWith(fontSize: 20),
|
||||||
textAlign: TextAlign.left),
|
textAlign: TextAlign.left),
|
||||||
bodyWidget,
|
bodyWidget,
|
||||||
extraWidget ?? Container()
|
extraWidget ?? Container()
|
||||||
@ -481,12 +382,13 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
void Function() actionRemoveItem}) {
|
void Function() actionRemoveItem}) {
|
||||||
return Container(
|
return Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
border: Border(
|
border: Border(
|
||||||
bottom: BorderSide(
|
bottom: BorderSide(
|
||||||
color: Colors.black12,
|
color: Colors.black12,
|
||||||
width: 1,
|
width: 1,
|
||||||
))),
|
))),
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Row(
|
Row(
|
||||||
@ -508,8 +410,12 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(cartLineItem.name,
|
Text(
|
||||||
style: Theme.of(context).primaryTextTheme.subhead),
|
cartLineItem.name,
|
||||||
|
style: Theme.of(context).primaryTextTheme.subhead,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 3,
|
||||||
|
),
|
||||||
(cartLineItem.variationOptions != null
|
(cartLineItem.variationOptions != null
|
||||||
? Text(cartLineItem.variationOptions,
|
? Text(cartLineItem.variationOptions,
|
||||||
style: Theme.of(context).primaryTextTheme.body2)
|
style: Theme.of(context).primaryTextTheme.body2)
|
||||||
@ -575,9 +481,10 @@ Widget wsCardCartItem(BuildContext context,
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget storeLogo({double height}) {
|
Widget storeLogo({double height, double width}) {
|
||||||
return cachedImage(app_logo_url,
|
return cachedImage(app_logo_url,
|
||||||
height: height, placeholder: Container(height: height, width: height));
|
height: height,
|
||||||
|
placeholder: Container(height: height ?? 100, width: width ?? 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget cachedImage(image, {double height, Widget placeholder, BoxFit fit}) {
|
Widget cachedImage(image, {double height, Widget placeholder, BoxFit fit}) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ packages:
|
|||||||
name: archive
|
name: archive
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.10"
|
version: "2.0.11"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -21,7 +21,7 @@ packages:
|
|||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.0"
|
version: "2.4.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -35,7 +35,7 @@ packages:
|
|||||||
name: cached_network_image
|
name: cached_network_image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "2.0.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -50,13 +50,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.14.11"
|
version: "1.14.11"
|
||||||
connectivity:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: connectivity
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.4"
|
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -98,7 +91,7 @@ packages:
|
|||||||
name: dio
|
name: dio
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.4"
|
version: "3.0.9"
|
||||||
edge_alert:
|
edge_alert:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -106,6 +99,20 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
flare_dart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flare_dart
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.3"
|
||||||
|
flare_flutter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flare_flutter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.8.3"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -117,14 +124,14 @@ packages:
|
|||||||
name: flutter_cache_manager
|
name: flutter_cache_manager
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.3"
|
||||||
flutter_launcher_icons:
|
flutter_launcher_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_launcher_icons
|
name: flutter_launcher_icons
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3"
|
version: "0.7.4"
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -150,7 +157,7 @@ packages:
|
|||||||
name: flutter_spinkit
|
name: flutter_spinkit
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.0"
|
version: "4.1.2+1"
|
||||||
flutter_swiper:
|
flutter_swiper:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -170,13 +177,18 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.0"
|
version: "0.11.0"
|
||||||
|
flutter_web_plugins:
|
||||||
|
dependency: transitive
|
||||||
|
description: flutter
|
||||||
|
source: sdk
|
||||||
|
version: "0.0.0"
|
||||||
fluttertoast:
|
fluttertoast:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: fluttertoast
|
name: fluttertoast
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.3"
|
version: "4.0.1"
|
||||||
html:
|
html:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -204,49 +216,42 @@ packages:
|
|||||||
name: image
|
name: image
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "2.1.4"
|
||||||
intl:
|
intl:
|
||||||
dependency: transitive
|
dependency: "direct overridden"
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: intl
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.15.8"
|
version: "0.15.8"
|
||||||
json_annotation:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: json_annotation
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.0"
|
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.5"
|
version: "0.12.6"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.7"
|
version: "1.1.8"
|
||||||
package_info:
|
package_info:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: package_info
|
name: package_info
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.0+6"
|
version: "0.4.0+16"
|
||||||
page_transition:
|
page_transition:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: page_transition
|
name: page_transition
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.4"
|
version: "1.1.5"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -282,13 +287,6 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "2.2.1"
|
||||||
pref_dessert:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: pref_dessert
|
|
||||||
url: "https://pub.dartlang.org"
|
|
||||||
source: hosted
|
|
||||||
version: "0.4.0+1"
|
|
||||||
quiver:
|
quiver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -302,7 +300,28 @@ packages:
|
|||||||
name: shared_preferences
|
name: shared_preferences
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.5.4+3"
|
version: "0.5.6+3"
|
||||||
|
shared_preferences_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1+6"
|
||||||
|
shared_preferences_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.3"
|
||||||
|
shared_preferences_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2+4"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -329,6 +348,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.3"
|
version: "1.9.3"
|
||||||
|
status_alert:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: status_alert
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.1"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -363,7 +389,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.5"
|
version: "0.2.11"
|
||||||
transformer_page_view:
|
transformer_page_view:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -405,7 +431,7 @@ packages:
|
|||||||
name: woosignal_stripe
|
name: woosignal_stripe
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.2"
|
version: "0.0.4"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -421,5 +447,5 @@ packages:
|
|||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "2.2.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">2.4.0 <3.0.0"
|
dart: ">=2.5.0 <3.0.0"
|
||||||
flutter: ">=1.6.7 <2.0.0"
|
flutter: ">=1.12.13+hotfix.4 <2.0.0"
|
||||||
|
|||||||
@ -24,21 +24,20 @@ environment:
|
|||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
woosignal: ^1.0.2
|
woosignal: ^1.0.2
|
||||||
woosignal_stripe: ^0.0.2
|
woosignal_stripe: ^0.0.4
|
||||||
connectivity: ^0.4.4
|
shared_preferences: ^0.5.6+3
|
||||||
shared_preferences: ^0.5.3+4
|
|
||||||
cached_network_image: ^2.0.0
|
cached_network_image: ^2.0.0
|
||||||
page_transition: ^1.1.4
|
page_transition: ^1.1.5
|
||||||
package_info: ^0.4.0+6
|
package_info: ^0.4.0+16
|
||||||
flutter_money_formatter: ^0.8.2
|
flutter_money_formatter: ^0.8.3
|
||||||
flutter_web_browser: ^0.11.0
|
flutter_web_browser: ^0.11.0
|
||||||
dio: ^3.0.2
|
dio: ^3.0.9
|
||||||
flutter_swiper: ^1.1.6
|
flutter_swiper: ^1.1.6
|
||||||
edge_alert: ^0.0.1
|
edge_alert: ^0.0.1
|
||||||
fluttertoast: ^3.1.3
|
status_alert: ^0.1.1
|
||||||
flutter_spinkit: ^4.0.0
|
fluttertoast: ^4.0.1
|
||||||
pref_dessert: ^0.4.0+1
|
flutter_spinkit: ^4.1.2+1
|
||||||
flutter_launcher_icons: ^0.7.3
|
flutter_launcher_icons: ^0.7.4
|
||||||
html: ^0.14.0+3
|
html: ^0.14.0+3
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user