diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
index ce374496..50968a4c 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Guest.kt
@@ -1,22 +1,23 @@
package com.ejada.hmg.hmgwifi
+import android.annotation.SuppressLint
import android.content.Context
import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
import android.net.wifi.WifiConfiguration
-import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
+import android.net.wifi.WifiNetworkSpecifier
import android.os.Build
import android.util.Log
-import android.widget.Toast
+import androidx.annotation.RequiresApi
import com.ejada.hmg.MainActivity
-import com.ejada.hmg.utils.FlutterText
import com.ejada.hmg.utils.HMGUtils
-class HMG_Guest(context: MainActivity) {
+class HMG_Guest(private var context: MainActivity) {
private var wifiManager: WifiManager? = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager?
- private var connectivityManager: ConnectivityManager? = context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager?
- private var context = context
private val TAG = "HMG_Guest"
private val TEST = false
@@ -40,114 +41,69 @@ class HMG_Guest(context: MainActivity) {
wm.isWifiEnabled = true
HMGUtils.popFlutterText(context,"enablingWifi");
HMGUtils.timer(2000,false){
- connect()
+ connectWifi()
}
- }else{
- connect()
+ connectWifi()
}
}
}
+ private fun errorConnecting(){
+ completionOnUiThread(false, "errorConnectingHmgNetwork")
+ }
- private fun connect(){
- val security = "OPEN"
- val networkPass = ""
- Log.d(TAG, "Connecting to SSID \"$SSID\" with password \"$networkPass\" and with security \"$security\" ...")
-
- // You need to create WifiConfiguration instance like this:
- val conf = WifiConfiguration()
- conf.SSID = SSID
- conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
- conf.networkId = ssidToNetworkId(SSID)
-
- val wm = wifiManager!!
-
- if (conf.networkId == -1) {
- wm.addNetwork(conf)
- } else {
- Log.v(TAG, "WiFi found - updating it.\n")
- wm.updateNetwork(conf)
+ fun connectWifi(){
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
+ wifiManager?.let { connectApiGreaterThen28(it) }
+ }else {
+ connectApiLessThen29()
}
+ }
- conf.networkId = ssidToNetworkId(SSID)
- Log.d(TAG, "Network ID: ${conf.networkId}")
-
- val networkIdToConnect = conf.networkId
- if (networkIdToConnect >= 0) {
- Log.v(TAG, "Start connecting to $SSID Wifi...")
-
- // We disable the network before connecting, because if this was the last connection before
- // a disconnect(), this will not reconnect.
- wm.disableNetwork(networkIdToConnect)
- val result = wm.enableNetwork(networkIdToConnect, true)
- if(result){
- HMGUtils.timer(8000,false){
- if(wm.getConnectionInfo().getSSID() == SSID){
- completionOnUiThread(true, "successConnectingHmgNetwork")
-
- }else{
- errorConnecting()
- }
- }
+ // I }else{f CompileSDK is greater and equals to APILevel 29
+ @RequiresApi(Build.VERSION_CODES.Q)
+ private fun connectApiGreaterThen28(wm:WifiManager){
+ Log.e(TAG, "connection wifi with Android Q+")
+ val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
+// .setWpa2Passphrase(password)
+ .build()
+
+ val networkRequest: NetworkRequest = NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .setNetworkSpecifier(wifiNetworkSpecifier)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet
+ .build()
+
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val networkCallback = object : ConnectivityManager.NetworkCallback() {
+ override fun onAvailable(network: Network) {
+ super.onAvailable(network)
+ connectivityManager.bindProcessToNetwork(network)
+ Log.e(TAG, "onAvailable")
+ }
- }else{
- errorConnecting()
+ override fun onLosing(network: Network, maxMsToLive: Int) {
+ super.onLosing(network, maxMsToLive)
+ Log.e(TAG, "onLosing")
}
+ override fun onLost(network: Network) {
+ super.onLost(network)
+ Log.e(TAG, "onLosing")
+ Log.e(TAG, "losing active connection")
+ }
+ override fun onUnavailable() {
+ super.onUnavailable()
+ Log.e(TAG, "onUnavailable")
+ }
- }else{
- Log.v(TAG, "Cannot connect to $SSID network")
- errorConnecting()
}
- }
-
- private fun errorConnecting(){
- completionOnUiThread(false, "errorConnectingHmgNetwork")
- }
- // If CompileSDK is greater and equals to APILevel 29
- private fun connectNewer(wm:WifiManager){
-
-// Log.e(TAG, "connection wifi Q")
-//
-// val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
-// .setSsid(ssid)
-// .setWpa2Passphrase(password)
-// .build()
-//
-// val networkRequest: NetworkRequest = NetworkRequest.Builder()
-// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-// .setNetworkSpecifier(wifiNetworkSpecifier)
-// .build()
-//
-// var connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
-// var networkCallback = object : ConnectivityManager.NetworkCallback() {
-// override fun onAvailable(network: Network) {
-// super.onAvailable(network)
-// connectivityManager.bindProcessToNetwork(network)
-// Log.e(TAG, "onAvailable")
-// }
-//
-// override fun onLosing(network: Network, maxMsToLive: Int) {
-// super.onLosing(network, maxMsToLive)
-// Log.e(TAG, "onLosing")
-// }
-//
-// override fun onLost(network: Network) {
-// super.onLost(network)
-// Log.e(TAG, "onLosing")
-// Log.e(TAG, "losing active connection")
-// }
-//
-// override fun onUnavailable() {
-// super.onUnavailable()
-// Log.e(TAG, "onUnavailable")
-// }
-// }
-// connectivityManager.requestNetwork(networkRequest, networkCallback)
+ //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable
+ connectivityManager.requestNetwork(networkRequest, networkCallback, 30000)
}
@@ -156,6 +112,7 @@ class HMG_Guest(context: MainActivity) {
* networks, and returns the networkId for the network if the SSID matches. If not,
* it returns -1.
*/
+ @SuppressLint("MissingPermission")
private fun ssidToNetworkId(ssid: String): Int {
val currentNetworks = wifiManager!!.configuredNetworks
var networkId = -1
@@ -169,4 +126,130 @@ class HMG_Guest(context: MainActivity) {
}
return networkId
}
-}
\ No newline at end of file
+
+
+ fun connectApiLessThen29(){
+ if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){
+
+ // Initialize the WifiConfiguration object
+ val security = "OPEN"
+ val networkPass = ""
+ Log.d(TAG, "Connecting to SSID \"$SSID\" with password \"$networkPass\" and with security \"$security\" ...")
+
+ // You need to create WifiConfiguration instance like this:
+ val conf = WifiConfiguration()
+ conf.SSID = SSID
+ conf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE)
+ conf.networkId = ssidToNetworkId(SSID)
+
+ val wm = wifiManager!!
+
+ if (conf.networkId == -1) {
+ wm.addNetwork(conf)
+ } else {
+ Log.v(TAG, "WiFi found - updating it.\n")
+ wm.updateNetwork(conf)
+ }
+
+ conf.networkId = ssidToNetworkId(SSID)
+ Log.d(TAG, "Network ID: ${conf.networkId}")
+
+ val networkIdToConnect = conf.networkId
+ if (networkIdToConnect >= 0) {
+ Log.v(TAG, "Start connecting to $SSID Wifi...")
+
+ // We disable the network before connecting, because if this was the last connection before
+ // a disconnect(), this will not reconnect.
+ wm.disableNetwork(networkIdToConnect)
+ val result = wm.enableNetwork(networkIdToConnect, true)
+ if(result){
+ HMGUtils.timer(8000,false){
+ if(wm.getConnectionInfo().getSSID() == SSID){
+ completionOnUiThread(true, "successConnectingHmgNetwork")
+
+ }else{
+ errorConnecting()
+ }
+ }
+
+ }else{
+ errorConnecting()
+ }
+
+
+
+ }else{
+ Log.v(TAG, "Cannot connect to $SSID network")
+ errorConnecting()
+ }
+ }
+
+ /*val wifi = WifiConfiguration();
+ wifi.hiddenSSID = this.hiddenSSID;
+ wifi.SSID = newSSID;
+ wifi.preSharedKey = newPass;
+ wifi.status = WifiConfiguration.Status.ENABLED;
+ wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+ wifi.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
+ wifi.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ wifi.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ wifi.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
+
+ wifi.networkId = ssidToNetworkId(newSSID);
+
+ // Set network to highest priority (deprecated in API >= 26)
+ if(Build.VERSION.SDK_INT < 26) {
+ wifi.priority = getMaxWifiPriority(wifiManager) + 1;
+ }
+
+ // After processing authentication types, add or update network
+ if(wifi.networkId == -1) { // -1 means SSID configuration does not exist yet
+
+ int newNetId = wifiManager.addNetwork(wifi);
+ if( newNetId > -1 ){
+ callbackContext.success( newNetId );
+ } else {
+ callbackContext.error( "ERROR_ADDING_NETWORK" );
+ }
+
+ } else {
+
+ int updatedNetID = wifiManager.updateNetwork(wifi);
+
+ if(updatedNetID == -1)
+ updatedNetID = wifiManager.addNetwork(wifi);
+
+ if(updatedNetID > -1) {
+ callbackContext.success( updatedNetID );
+ } else {
+ callbackContext.error("ERROR_UPDATING_NETWORK");
+ }
+
+ }
+
+ // WifiManager configurations are presistent for API 26+
+ if(API_VERSION < 26) {
+ wifiManager.saveConfiguration(); // Call saveConfiguration for older < 26 API
+ }*/
+ }
+
+ companion object{
+
+ /**
+ * Figure out what the highest priority network in the network list is and return that priority
+ */
+ @RequiresApi(Build.VERSION_CODES.S)
+ fun getMaxWifiPriority(wifiManager:WifiManager) : Int {
+ val configurations = wifiManager.callerConfiguredNetworks
+ var maxPriority = 0
+ configurations.forEach {
+ if (it.priority > maxPriority) {
+ maxPriority = it.priority;
+ }
+ }
+ return maxPriority;
+ }
+ }
+}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
index 2eedef3a..c55040b3 100644
--- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/HMG_Internet.kt
@@ -3,7 +3,6 @@ package com.ejada.hmg.hmgwifi
import android.annotation.SuppressLint
import com.ejada.hmg.utils.API
import com.ejada.hmg.MainActivity
-import com.ejada.hmg.utils.FlutterText
import com.github.kittinunf.fuel.core.extensions.jsonBody
import com.github.kittinunf.fuel.httpGet
import com.github.kittinunf.fuel.httpPost
@@ -14,7 +13,7 @@ import java.util.*
@SuppressLint("MissingPermission")
class HMG_Internet(flutterMainActivity: MainActivity) {
private val TAG = "HMG_Wifi"
- private val TEST = false
+ private val TEST = true
private var context = flutterMainActivity;
@@ -41,7 +40,7 @@ class HMG_Internet(flutterMainActivity: MainActivity) {
fun connectToHMGGuestNetwork(patientId: String, completion: (status: Boolean, message: String) -> Unit): HMG_Internet {
completionListener = completion
getWifiCredentials(patientId) {
- WPA(context,SSID).connect(USER_NAME,PASSWORD) { status, message ->
+ WpaEnterprise(context,SSID).connect(USER_NAME,PASSWORD) { status, message ->
completionOnUiThread(status,message)
}
}
diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt
new file mode 100644
index 00000000..23871fd6
--- /dev/null
+++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/hmgwifi/WpaEnterprise.kt
@@ -0,0 +1,160 @@
+package com.ejada.hmg.hmgwifi
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkRequest
+import android.net.wifi.*
+import android.net.wifi.SupplicantState.ASSOCIATED
+import android.net.wifi.SupplicantState.COMPLETED
+import android.os.Build
+import android.util.Log
+import androidx.annotation.RequiresApi
+import com.ejada.hmg.MainActivity
+import com.ejada.hmg.utils.HMGUtils
+
+class WpaEnterprise(private val mainActivity: MainActivity, private var SSID: String) {
+ private var TAG = "WpaEnterprise"
+
+ private lateinit var identity:String
+ private lateinit var password:String
+ private lateinit var completion:((status: Boolean, message: String) -> Unit)
+
+ fun connect(identity:String, password:String, completion: (status: Boolean, message: String) -> Unit) {
+ this.password = password
+ this.identity = identity
+ this.completion = completion
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
+ apiGreaterThen28()
+ }else if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){
+ apiLessThen29()
+ }
+ }
+
+ @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+ fun apiLessThen29(){
+ val wifiManager = mainActivity.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
+
+ val wifi = WifiConfiguration()
+ wifi.SSID = """"$SSID""""
+ wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP)
+ wifi.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X)
+ wifi.enterpriseConfig = enterpriseConfig()
+ wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager)
+ if (wifi.networkId == -1) {
+ wifiManager.addNetwork(wifi)
+ } else {
+ Log.v(TAG, "WiFi found - updating it.\n")
+ wifiManager.updateNetwork(wifi)
+ }
+ Log.v(TAG, "saving config.\n")
+ wifiManager.saveConfiguration()
+ wifi.networkId = ssidToNetworkId(wifi.SSID, wifiManager)
+
+ Log.v(TAG, "wifi ID in device = " + wifi.networkId)
+
+ var supState: SupplicantState
+ val networkIdToConnect = wifi.networkId
+ if (networkIdToConnect >= 0) {
+ Log.v(TAG, "Start connecting...\n")
+
+ // We disable the network before connecting, because if this was the last connection before
+ // a disconnect(), this will not reconnect.
+ wifiManager.disableNetwork(networkIdToConnect)
+ wifiManager.enableNetwork(networkIdToConnect, true)
+
+ val wifiInfo: WifiInfo = wifiManager.connectionInfo
+
+ HMGUtils.timer(5000,false){
+ supState = wifiInfo.supplicantState
+ Log.i(TAG, "Done connect to network : status = $supState")
+ val successStates = listOf(COMPLETED, ASSOCIATED)
+ if (successStates.contains(supState))
+ completion(true,"Connected to internet Wifi")
+ else
+ completion(false,"errorConnectingHmgNetwork")
+ }
+
+ } else {
+ Log.v(TAG, "WifiWizard: cannot connect to network")
+ completion(false,"errorConnectingHmgNetwork")
+ }
+ }
+
+ /**
+ * This method takes a given String, searches the current list of configured WiFi
+ * networks, and returns the networkId for the network if the SSID matches. If not,
+ * it returns -1.
+ */
+ @SuppressLint("MissingPermission")
+ private fun ssidToNetworkId(ssid: String, wifiManager: WifiManager): Int {
+ val currentNetworks = wifiManager.configuredNetworks
+ var networkId = -1
+ // For each network in the list, compare the SSID with the given one
+ for (test in currentNetworks) {
+ if (test.SSID == ssid) {
+ networkId = test.networkId
+ break
+ }
+ }
+ return networkId
+ }
+
+
+ @RequiresApi(Build.VERSION_CODES.Q)
+ fun apiGreaterThen28(){
+ val connectivityManager = mainActivity.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+
+ Log.e(TAG, "connection wifi with Android Q+")
+ val wifiNetworkSpecifier: WifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
+ .setWpa2EnterpriseConfig(enterpriseConfig())
+ .build()
+
+ val networkRequest: NetworkRequest = NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ .setNetworkSpecifier(wifiNetworkSpecifier)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) //removeCapability added for hotspots without internet
+ .build()
+
+ val networkCallback = object : ConnectivityManager.NetworkCallback() {
+ override fun onAvailable(network: Network) {
+ super.onAvailable(network)
+ connectivityManager.bindProcessToNetwork(network)
+ Log.e(TAG, "onAvailable")
+ }
+
+ override fun onLosing(network: Network, maxMsToLive: Int) {
+ super.onLosing(network, maxMsToLive)
+ Log.e(TAG, "onLosing")
+ }
+
+ override fun onLost(network: Network) {
+ super.onLost(network)
+ Log.e(TAG, "onLosing")
+ Log.e(TAG, "losing active connection")
+ }
+
+ override fun onUnavailable() {
+ super.onUnavailable()
+ Log.e(TAG, "onUnavailable")
+ }
+
+ }
+
+ //timeout add because "No devices found" wasn't handled correct and doesn't throw Unavailable
+ connectivityManager.requestNetwork(networkRequest, networkCallback, 30000)
+ }
+
+ fun enterpriseConfig() : WifiEnterpriseConfig{
+ // Initialize the WifiConfiguration object
+ val enterpriseConfig = WifiEnterpriseConfig()
+ enterpriseConfig.eapMethod = WifiEnterpriseConfig.Eap.PEAP
+ enterpriseConfig.identity = identity
+ enterpriseConfig.password = password
+ return enterpriseConfig;
+ }
+
+}
\ No newline at end of file
diff --git a/assets/images/new/hmg_icon.svg b/assets/images/new/hmg_icon.svg
index e777d9ee..e09967e2 100644
--- a/assets/images/new/hmg_icon.svg
+++ b/assets/images/new/hmg_icon.svg
@@ -1,3 +1,6 @@
+
+
+
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index 9bf7caa5..14e77cd0 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -14,7 +14,6 @@
306FE6CB271D8B73002D6EFC /* OpenTok.swift in Sources */ = {isa = PBXBuildFile; fileRef = 306FE6CA271D8B73002D6EFC /* OpenTok.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
- 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
@@ -36,6 +35,7 @@
E9C8C136256BACDA00EFFB62 /* HMG_Guest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */; };
E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */; };
E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */; };
+ FA0839686861F9C0546E6F45 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C703B0BB1CDBBCA30693DBD3 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@@ -58,13 +58,12 @@
301C79AF27200DED0016307B /* OpenTokLocalVideoFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokLocalVideoFactory.swift; sourceTree = ""; };
306FE6C7271D790C002D6EFC /* OpenTokPlatformBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTokPlatformBridge.swift; sourceTree = ""; };
306FE6CA271D8B73002D6EFC /* OpenTok.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenTok.swift; sourceTree = ""; };
- 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 44DB2098C8C4B08C2F3B1329 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
- 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
+ 84A70B284E0DDF62ECE83D3B /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -72,7 +71,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
+ 9C2760F1A81999922ACAA9E6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
+ C703B0BB1CDBBCA30693DBD3 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E91B538D256AAA6500E96549 /* GlobalHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GlobalHelper.swift; sourceTree = ""; };
E91B538E256AAA6500E96549 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
E91B538F256AAA6500E96549 /* API.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = API.swift; sourceTree = ""; };
@@ -99,8 +99,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 813F9CBA7DD5ED63B28B8BB6 /* Pods_Runner.framework in Frameworks */,
E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */,
+ FA0839686861F9C0546E6F45 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -121,7 +121,7 @@
isa = PBXGroup;
children = (
E9620804255C2ED100D3A35D /* NetworkExtension.framework */,
- 767C165F7ABF3BF1F829B9BF /* Pods_Runner.framework */,
+ C703B0BB1CDBBCA30693DBD3 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -129,9 +129,9 @@
605039E5DDF72C245F9765FE /* Pods */ = {
isa = PBXGroup;
children = (
- DCFFD369041FFFFA94CF7B26 /* Pods-Runner.debug.xcconfig */,
- 969F0CEC868FD7C196987A3E /* Pods-Runner.release.xcconfig */,
- 308FEC658188F7D588BE7580 /* Pods-Runner.profile.xcconfig */,
+ 44DB2098C8C4B08C2F3B1329 /* Pods-Runner.debug.xcconfig */,
+ 9C2760F1A81999922ACAA9E6 /* Pods-Runner.release.xcconfig */,
+ 84A70B284E0DDF62ECE83D3B /* Pods-Runner.profile.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -232,15 +232,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
- 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */,
+ D74B98D9E413413D50043E1B /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */,
- 29B24CD65FDFD6111DD04897 /* [CP] Copy Pods Resources */,
+ 796644D4DF82E4D5FBECBF3B /* [CP] Embed Pods Frameworks */,
+ 0EF99525B5E50490BA0DF0A4 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -257,7 +257,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 1020;
+ LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
@@ -304,29 +304,7 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
- 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
- 29B24CD65FDFD6111DD04897 /* [CP] Copy Pods Resources */ = {
+ 0EF99525B5E50490BA0DF0A4 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -357,6 +335,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
+ 796644D4DF82E4D5FBECBF3B /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -371,21 +366,26 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
- EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */ = {
+ D74B98D9E413413D50043E1B /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
- name = "[CP] Embed Pods Frameworks";
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
@@ -520,6 +520,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
+ MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -659,6 +660,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
+ MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -692,6 +694,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
+ MARKETING_VERSION = 1;
PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
index fb2dffc4..c87d15a3 100644
--- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -1,6 +1,6 @@
????
CFBundleVersion
$(FLUTTER_BUILD_NUMBER)
+ LSApplicationQueriesSchemes
+
+ comgooglemaps
+ baidumap
+ iosamap
+
LSRequiresIPhoneOS
MinimumOSVersion
@@ -94,13 +100,5 @@
io.flutter.embedded_views_preview
- LSApplicationQueriesSchemes
-
- comgooglemaps
- baidumap
- iosamap
-
-
-
diff --git a/lib/config/config.dart b/lib/config/config.dart
index 3ed8d764..0e899c89 100644
--- a/lib/config/config.dart
+++ b/lib/config/config.dart
@@ -14,6 +14,7 @@ const PACKAGES_PRODUCTS = '/api/products';
const PACKAGES_CUSTOMER = '/api/customers';
const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items';
const PACKAGES_ORDERS = '/api/orders';
+const PACKAGES_ORDER_HISTORY = '/api/orders/items';
const PACKAGES_TAMARA_OPT = '/api/orders/paymentoptions/tamara';
const BASE_URL = 'https://uat.hmgwebservices.com/';
// const BASE_URL = 'https://hmgwebservices.com/';
diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart
index fefc9139..b339ed69 100644
--- a/lib/core/service/client/base_app_client.dart
+++ b/lib/core/service/client/base_app_client.dart
@@ -517,7 +517,8 @@ class BaseAppClient {
}
simpleGet(String fullUrl,
- {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async {
+ {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams, Map headers}) async {
+ headers = headers ?? {};
String url = fullUrl;
var haveParams = (queryParams != null);
diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart
index 6c4e0d24..978164bd 100644
--- a/lib/core/service/packages_offers/PackagesOffersServices.dart
+++ b/lib/core/service/packages_offers/PackagesOffersServices.dart
@@ -24,14 +24,15 @@ Map packagesAuthHeader = {};
class OffersAndPackagesServices extends BaseService {
AuthenticatedUser patientUser;
- List categoryList = List();
- List productList = List();
- List latestOffersList = List();
- List tamaraPaymentOptions = List();
- List bestSellerList = List();
- List bannersList = List();
- List cartItemList = List();
- List _hospitals = List();
+ List categoryList = [];
+ List productList = [];
+ List latestOffersList = [];
+ List tamaraPaymentOptions = [];
+ List bestSellerList = [];
+ List bannersList = [];
+ List ordersHistory = [];
+ List cartItemList = [];
+ List _hospitals = [];
List get hospitals => _hospitals;
String cartItemCount = "";
@@ -58,7 +59,7 @@ class OffersAndPackagesServices extends BaseService {
request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0;
- productList = List();
+ productList = [];
var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS;
await baseAppClient.simpleGet(url, headers: packagesAuthHeader, onSuccess: (dynamic stringResponse, int statusCode) {
if (statusCode == 200) {
@@ -349,6 +350,40 @@ class OffersAndPackagesServices extends BaseService {
return errorThrow ?? order_id;
}
+ // --------------------
+ // Order History
+ // --------------------
+ Future> orderHistory({@required BuildContext context, bool showLoading = true}) async {
+ // if(ordersHistory.isNotEmpty)
+ // return ordersHistory;
+
+ Future errorThrow;
+ // https://mdlaboratories.com/offersdiscounts/api/orders/items/0535256053?fields=id,product,utilize_by_vida,valid_until_date_utc,order_id&page=1&limit=100
+ Map queryParams ={};
+ queryParams['fields'] = 'id,product,utilize_by_vida,valid_until_date_utc,order_id';
+ queryParams['page'] = "1";
+ queryParams['limit'] = "100";
+ print(queryParams);
+
+ _showLoading(context, showLoading);
+ var url = EXA_CART_API_BASE_URL + PACKAGES_ORDER_HISTORY + "/${user.mobileNumber}";
+
+ await baseAppClient.simpleGet(url, headers: packagesAuthHeader, queryParams: queryParams, onSuccess: (dynamic stringResponse, int statusCode) {
+ _hideLoading(context, showLoading);
+ var jsonResponse = json.decode(stringResponse);
+ final order_items = jsonResponse["order_items"] as List;
+ ordersHistory = order_items.map((e) => PackagesResponseModel().fromJson(e['product'])).toList();
+ print(ordersHistory);
+
+ }, onFailure: (String error, int statusCode) {
+ _hideLoading(context, showLoading);
+ log(error);
+ errorThrow = Future.error(error);
+ });
+
+ return errorThrow ?? ordersHistory;
+ }
+
Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async {
Future errorThrow;
ResponseModel response;
diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart
index 75b9a473..2b8aa394 100644
--- a/lib/pages/landing/fragments/home_page_fragment2.dart
+++ b/lib/pages/landing/fragments/home_page_fragment2.dart
@@ -16,6 +16,7 @@ import 'package:diplomaticquarterapp/pages/landing/widgets/services_view.dart';
import 'package:diplomaticquarterapp/pages/landing/widgets/slider_view.dart';
import 'package:diplomaticquarterapp/pages/medical/medical_profile_page_new.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart';
+import 'package:diplomaticquarterapp/pages/packages_offers/packages_offers_tab_pager.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart';
@@ -284,7 +285,7 @@ class _HomePageFragment2State extends State {
child: InkWell(
onTap: () {
AuthenticatedUser user = projectViewModel.user;
- Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(user)));
+ Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesOfferTabPage(user)));
},
child: Container(
width: double.infinity,
diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart
index f3af7c74..18c1e4cd 100644
--- a/lib/pages/landing/home_page.dart
+++ b/lib/pages/landing/home_page.dart
@@ -13,6 +13,7 @@ import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart';
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart';
+import 'package:diplomaticquarterapp/pages/packages_offers/packages_offers_tab_pager.dart';
import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart';
import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
@@ -420,7 +421,7 @@ class _HomePageState extends State {
padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15),
child: InkWell(
onTap: () {
- Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage(projectViewModel.user)));
+ Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesOfferTabPage(projectViewModel.user)));
},
child: Container(
decoration: BoxDecoration(
diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart
index f73172b6..915c8e96 100644
--- a/lib/pages/landing/landing_page.dart
+++ b/lib/pages/landing/landing_page.dart
@@ -21,7 +21,9 @@ import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'
import 'package:diplomaticquarterapp/services/family_files/family_files_provider.dart' as family;
import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart';
import 'package:diplomaticquarterapp/theme/colors.dart';
+import 'package:diplomaticquarterapp/uitl/HMGNetworkConnectivity.dart';
import 'package:diplomaticquarterapp/uitl/LocalNotification.dart';
+import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart';
import 'package:diplomaticquarterapp/uitl/SignalRUtil.dart';
import 'package:diplomaticquarterapp/uitl/app_toast.dart';
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
@@ -232,10 +234,10 @@ class _LandingPageState extends State with WidgetsBindingObserver {
});
// HMG (Guest/Internet) Wifi Access [Zohaib Kambrani]
//for now commented to reduce this call will enable it when needed
- // HMGNetworkConnectivity(context, () {
- // GifLoaderDialogUtils.showMyDialog(context);
- // PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)});
- // }).checkAndConnectIfNoInternet();
+ HMGNetworkConnectivity(context, () {
+ GifLoaderDialogUtils.showMyDialog(context);
+ PlatformBridge.shared().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)});
+ }).checkAndConnectIfNoInternet();
requestPermissions().then((results) {
locationUtils.getCurrentLocation();
diff --git a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart
index c4d0ce6e..6b6f1a5a 100644
--- a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart
+++ b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart
@@ -15,8 +15,9 @@ import 'package:rating_bar/rating_bar.dart';
class OfferAndPackagesDetail extends StatefulWidget {
final PackagesResponseModel itemModel;
final Function(PackagesResponseModel product) onCartClick;
+ bool showAddToCartFooter = true;
- const OfferAndPackagesDetail({@required this.itemModel, @required this.onCartClick, Key key}) : super(key: key);
+ OfferAndPackagesDetail({@required this.itemModel, @required this.onCartClick, Key key}) : super(key: key);
@override
State createState() => OfferAndPackagesDetailState();
@@ -30,6 +31,11 @@ class OfferAndPackagesDetailState extends State {
@override
Widget build(BuildContext context) {
+ final images = widget.itemModel.images ?? [];
+ String image = "";
+ if(images.isNotEmpty)
+ image = widget.itemModel.images.first.src ?? "";
+
return BaseView(
onModelReady: (model) {
viewModel = model;
@@ -58,7 +64,11 @@ class OfferAndPackagesDetailState extends State {
aspectRatio: 333 / 333,
child: ClipRRect(
borderRadius: BorderRadius.circular(15.0),
- child: Image.network("https://mdlaboratories.com/offersdiscounts/images/thumbs/0000162_dermatology-testing.jpeg", fit: BoxFit.fill),
+ child: Image.network(
+ image,
+ fit: BoxFit.fill,
+ errorBuilder: (a1,a2,a3) => Container(color: Colors.grey.withOpacity(0.25),),
+ ),
),
),
),
@@ -181,7 +191,8 @@ class OfferAndPackagesDetailState extends State {
],
),
),
- Row(
+ if(widget.showAddToCartFooter && widget.onCartClick != null)
+ Row(
children: [
Expanded(
child: Column(
diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart
index 91f59c74..4a72aeb8 100644
--- a/lib/pages/packages_offers/OfferAndPackagesPage.dart
+++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart
@@ -14,9 +14,11 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting
import 'package:diplomaticquarterapp/pages/base/base_view.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart';
import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart';
+import 'package:diplomaticquarterapp/pages/packages_offers/packages_orders_history.dart';
import 'package:diplomaticquarterapp/routes.dart';
import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart' as auth;
import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart';
+import 'package:diplomaticquarterapp/uitl/navigation_service.dart';
import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
import 'package:diplomaticquarterapp/uitl/utils.dart' as utils;
import 'package:diplomaticquarterapp/uitl/utils_new.dart';
@@ -84,7 +86,6 @@ class _PackagesHomePageState extends State {
}
}
- AppScaffold appScaffold;
PackagesCategoriesResponseModel selectedClinic;
@override
@@ -94,87 +95,74 @@ class _PackagesHomePageState extends State {
allowAny: true,
onModelReady: (model) => viewModel = model,
builder: (_, model, wi) {
- return appScaffold = AppScaffold(
- description: TranslationBase.of(context).offerAndPackagesDetails,
- imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')],
- appBarTitle: TranslationBase.of(context).offerAndPackages,
- isShowAppBar: true,
- isPharmacy: false,
- backgroundColor: Color(0xfff7f7f7),
- showPharmacyCart: false,
- isOfferPackages: true,
- showOfferPackagesCart: false,
- isShowDecPage: false,
- showNewAppBar: true,
- showNewAppBarTitle: true,
- body: Column(
- children: [
- Expanded(
- child: ListView(
- padding: EdgeInsets.only(top: 21, bottom: 21),
- physics: BouncingScrollPhysics(),
- children: [
- inputWidget(TranslationBase.of(context).search, "", _searchTextController, isInputTypeNum: false),
- SizedBox(height: 12),
- Padding(
- padding: const EdgeInsets.only(left: 21, right: 21),
- child: CommonDropDownView(TranslationBase.of(context).browseOffers, selectedClinic?.name ?? TranslationBase.of(context).selectClinic, () => showClinicSelectionList())
- .withBorderedContainer,
- ),
- SizedBox(height: 12),
- Container(
- width: double.infinity,
- height: MediaQuery.of(context).size.width * 0.8,
- child: ListView.separated(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: BouncingScrollPhysics(),
- padding: EdgeInsets.only(left: 21, right: 21),
- itemCount: viewModel.bestSellerList.length,
- separatorBuilder: (context, index) {
- return mWidth(9.0);
- },
- itemBuilder: (BuildContext context, int index) {
- return PackagesItemCard(
- itemModel: viewModel.bestSellerList[index],
- onCartClick: onProductCartClick,
- );
- },
- ),
+ return Column(
+ children: [
+ Expanded(
+ child: ListView(
+ padding: EdgeInsets.only(top: 21, bottom: 21),
+ physics: BouncingScrollPhysics(),
+ children: [
+ inputWidget(TranslationBase.of(context).search, "", _searchTextController, isInputTypeNum: false),
+ SizedBox(height: 12),
+ Padding(
+ padding: const EdgeInsets.only(left: 21, right: 21),
+ child: CommonDropDownView(TranslationBase.of(context).browseOffers, selectedClinic?.name ?? TranslationBase.of(context).selectClinic, () => showClinicSelectionList())
+ .withBorderedContainer,
+ ),
+ SizedBox(height: 12),
+ Container(
+ width: double.infinity,
+ height: MediaQuery.of(context).size.width * 0.8,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ shrinkWrap: true,
+ physics: BouncingScrollPhysics(),
+ padding: EdgeInsets.only(left: 21, right: 21),
+ itemCount: viewModel.bestSellerList.length,
+ separatorBuilder: (context, index) {
+ return mWidth(9.0);
+ },
+ itemBuilder: (BuildContext context, int index) {
+ return PackagesItemCard(
+ itemModel: viewModel.bestSellerList[index],
+ onCartClick: onProductCartClick,
+ );
+ },
),
- SizedBox(height: 12),
- Container(
- width: double.infinity,
- height: MediaQuery.of(context).size.width * 0.8,
- child: ListView.separated(
- scrollDirection: Axis.horizontal,
- shrinkWrap: true,
- physics: BouncingScrollPhysics(),
- padding: EdgeInsets.only(left: 21, right: 21),
- itemCount: viewModel.latestOffersList.length,
- separatorBuilder: (context, index) {
- return mWidth(9.0);
- },
- itemBuilder: (BuildContext context, int index) {
- return PackagesItemCard(
- itemModel: viewModel.latestOffersList[index],
- onCartClick: onProductCartClick,
- );
- },
- ),
+ ),
+ SizedBox(height: 12),
+ Container(
+ width: double.infinity,
+ height: MediaQuery.of(context).size.width * 0.8,
+ child: ListView.separated(
+ scrollDirection: Axis.horizontal,
+ shrinkWrap: true,
+ physics: BouncingScrollPhysics(),
+ padding: EdgeInsets.only(left: 21, right: 21),
+ itemCount: viewModel.latestOffersList.length,
+ separatorBuilder: (context, index) {
+ return mWidth(9.0);
+ },
+ itemBuilder: (BuildContext context, int index) {
+ return PackagesItemCard(
+ itemModel: viewModel.latestOffersList[index],
+ onCartClick: onProductCartClick,
+ );
+ },
),
- ],
- ),
+ ),
+ ],
),
- DefaultButton(
- TranslationBase.of(context).myCart,
- onCartClick,
- svgIcon: "assets/images/new/cart.svg",
- isTextExpanded: false,
- count: viewModel?.service?.customer?.shoppingCartItems?.length ?? 0,
- ).insideContainer
- ],
- ),
+ ),
+
+ DefaultButton(
+ TranslationBase.of(context).myCart,
+ onCartClick,
+ svgIcon: "assets/images/new/cart.svg",
+ isTextExpanded: false,
+ count: viewModel?.service?.customer?.shoppingCartItems?.length ?? 0,
+ ).insideContainer
+ ],
);
},
);
diff --git a/lib/pages/packages_offers/packages_offers_tab_pager.dart b/lib/pages/packages_offers/packages_offers_tab_pager.dart
new file mode 100644
index 00000000..7042327d
--- /dev/null
+++ b/lib/pages/packages_offers/packages_offers_tab_pager.dart
@@ -0,0 +1,86 @@
+import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart';
+import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
+import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart';
+import 'package:diplomaticquarterapp/pages/base/base_view.dart';
+import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart';
+import 'package:diplomaticquarterapp/pages/packages_offers/packages_orders_history.dart';
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+class PackagesOfferTabPage extends StatefulWidget{
+
+ AuthenticatedUser user;
+ PackagesOfferTabPage(this.user);
+
+ @override
+ State createState() => PackagesOfferTabPageState();
+}
+
+class PackagesOfferTabPageState extends State with SingleTickerProviderStateMixin{
+ TabController _tabController;
+ ProjectViewModel _projectViewModel;
+
+ @override
+ void initState() {
+ _tabController = TabController(length: 2, vsync: this);
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ _projectViewModel = Provider.of(context);
+ return AppScaffold(
+ description: TranslationBase.of(context).offerAndPackagesDetails,
+ imagesInfo: [ImagesInfo(imageAr: 'https://hmgwebservices.com/Images/MobileApp/CMC/ar/0.png', imageEn: 'https://hmgwebservices.com/Images/MobileApp/CMC/en/0.png')],
+ appBarTitle: TranslationBase.of(context).offerAndPackages,
+ isShowAppBar: true,
+ isPharmacy: false,
+ backgroundColor: Color(0xfff7f7f7),
+ showPharmacyCart: false,
+ isOfferPackages: true,
+ showOfferPackagesCart: false,
+ isShowDecPage: false,
+ showNewAppBar: true,
+ showNewAppBarTitle: true,
+ body: Column(
+ children: [
+ TabBar(
+ controller: _tabController,
+ indicatorWeight: 3.0,
+ indicatorSize: TabBarIndicatorSize.tab,
+ labelColor: Color(0xff2B353E),
+ unselectedLabelColor: Color(0xff575757),
+ labelPadding: EdgeInsets.only(top: 15, bottom: 13, left: 20, right: 20),
+ labelStyle: TextStyle(
+ fontFamily: _projectViewModel.isArabic ? 'Cairo' : 'Poppins',
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ letterSpacing: -0.48,
+ ),
+ unselectedLabelStyle: TextStyle(
+ fontFamily: _projectViewModel.isArabic ? 'Cairo' : 'Poppins',
+ fontSize: 16,
+ fontWeight: FontWeight.w600,
+ letterSpacing: -0.48,
+ ),
+ tabs: [Text(TranslationBase.of(context).offerAndPackages), Text(TranslationBase.of(context).orderLog)],
+ ),
+ Expanded(
+ child: TabBarView(
+ physics: BouncingScrollPhysics(),
+ controller: _tabController,
+ children: [
+ PackagesHomePage(widget.user),
+ PackagesOrdersHistory()
+ ],
+ ),
+ )
+ ],
+ ),
+ );
+ }
+
+}
diff --git a/lib/pages/packages_offers/packages_orders_history.dart b/lib/pages/packages_offers/packages_orders_history.dart
new file mode 100644
index 00000000..bc9a44e8
--- /dev/null
+++ b/lib/pages/packages_offers/packages_orders_history.dart
@@ -0,0 +1,98 @@
+import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart';
+import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
+import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
+import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart';
+import 'package:diplomaticquarterapp/pages/base/base_view.dart';
+import 'package:diplomaticquarterapp/uitl/date_uitl.dart';
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils_new.dart';
+import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart';
+import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart';
+import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOrderHistoryItemCard.dart';
+import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+import 'OfferAndPackageDetailPage.dart';
+class PackagesOrdersHistory extends StatefulWidget{
+ @override
+ State createState() => PackagesOrdersHistorySatate();
+}
+
+class PackagesOrdersHistorySatate extends State{
+ ProjectViewModel projectViewModel;
+ PackagesViewModel packagesViewModel;
+
+ List orders;
+
+ @override
+ void initState() {
+ Future.delayed(Duration(milliseconds: 200)).then((value) async{
+ final orders_ = await packagesViewModel.service.orderHistory(context: context);
+ setState(() => orders = orders_ ?? []);
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ projectViewModel = Provider.of(context);
+ return BaseView(
+ allowAny: true,
+ onModelReady: (model) => packagesViewModel = model,
+ builder: (_, model, wi) {
+ return content(context);
+ }
+ );
+ }
+
+ Widget content(BuildContext context){
+ if(orders == null){
+ return SizedBox();
+ }else if(orders.isEmpty){
+ return getNoDataWidget(context);
+ }else {
+ return ListView.separated(
+ padding: EdgeInsets.all(20),
+ itemCount: orders.length,
+ itemBuilder: (ctx, idx) => item(ctx, order: orders[idx]),
+ separatorBuilder: (ctx, idx) => SizedBox(height: 10),
+ );
+ }
+ }
+
+ Widget item(BuildContext context, {@required PackagesResponseModel order}){
+ return InkWell(
+ child: PackagesOrderHistoryItemCard(itemModel: order, viewModel: packagesViewModel),
+ onTap: (){
+ final detailPage = OfferAndPackagesDetail(itemModel: order, onCartClick: null)..showAddToCartFooter = false;
+ Navigator.of(context).push(MaterialPageRoute(builder: (BuildContext context) => detailPage));
+ },
+ );
+ }
+
+ void showConfirmMessage(BuildContext context, {@required PackagesResponseModel order}){
+ showDialog(
+ context: context,
+ builder: (cxt) => ConfirmWithMessageDialog(
+ message: TranslationBase.of(context).cancelOrderMsg,
+ onTap: () {
+ },
+ ),
+ );
+ return;
+ }
+
+ Color color(int status){
+ if (status == 1) { //pending
+ return Color(0xffCC9B14);
+ } else if (status == 2) { //processing
+ return Color(0xff2E303A);
+ } else if (status == 3) { //completed
+ return Color(0xff359846);
+ } else if (status == 4 || status == 6 || status == 7) { //cancel // Rejected
+ return Color(0xffD02127);
+ }
+ return Colors.transparent;
+ }
+}
\ No newline at end of file
diff --git a/lib/pages/rateAppointment/rate_appointment_clinic.dart b/lib/pages/rateAppointment/rate_appointment_clinic.dart
index 94ee801a..aac0a4d6 100644
--- a/lib/pages/rateAppointment/rate_appointment_clinic.dart
+++ b/lib/pages/rateAppointment/rate_appointment_clinic.dart
@@ -70,7 +70,7 @@ class _RateAppointmentClinicState extends State {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
- model.appointmentDetails.projectName,
+ model.appointmentDetails.projectName ?? '',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w600, color: Color(0xff2E303A), letterSpacing: -0.64, height: 25 / 16),
),
Text(
diff --git a/lib/uitl/app_shared_preferences.dart b/lib/uitl/app_shared_preferences.dart
index f90a2f98..0a952cf3 100644
--- a/lib/uitl/app_shared_preferences.dart
+++ b/lib/uitl/app_shared_preferences.dart
@@ -6,7 +6,7 @@ class AppSharedPreferences {
Future _prefs = SharedPreferences.getInstance();
/// Save String [key] the key for save value [value] the value we need to save it
- setString(String key, String value) async {
+ Future setString(String key, String value) async {
final SharedPreferences prefs = await _prefs;
return prefs.setString(key, value);
}
@@ -42,7 +42,7 @@ class AppSharedPreferences {
}
/// Get String [key] the key was saved
- getString(String key) async {
+ Future getString(String key) async {
final SharedPreferences prefs = await _prefs;
return prefs.getString(key);
}
diff --git a/lib/uitl/navigation_service.dart b/lib/uitl/navigation_service.dart
index d394fa63..a589249c 100644
--- a/lib/uitl/navigation_service.dart
+++ b/lib/uitl/navigation_service.dart
@@ -1,6 +1,8 @@
import 'package:diplomaticquarterapp/locator.dart';
import 'package:flutter/material.dart';
+MaterialPageRoute _pageRoute(Widget page) => MaterialPageRoute(builder: (BuildContext context) => page);
+
class NavigationService {
final GlobalKey navigatorKey =
new GlobalKey();
@@ -18,4 +20,11 @@ class NavigationService {
}
}
+class Navigate{
+ static to({@required Widget page}){
+ final context = locator().navigatorKey.currentContext;
+ Navigator.of(context).push(_pageRoute(page));
+ }
+}
+
BuildContext get currentContext => locator().navigatorKey.currentContext;
diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart
index 5fdcbb01..e0f7e728 100644
--- a/lib/uitl/translations_delegate_base.dart
+++ b/lib/uitl/translations_delegate_base.dart
@@ -1472,6 +1472,7 @@ class TranslationBase {
String get enablingWifi => localizedValues['enablingWifi'][locale.languageCode];
String get offerAndPackages => localizedValues['offerAndPackages'][locale.languageCode];
+ String get orderHistory => localizedValues['orderHistory'][locale.languageCode];
String get offerAndPackagesDetails => localizedValues['offerAndPackagesDetails'][locale.languageCode];
diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart
index f20f4243..97ba5e25 100644
--- a/lib/uitl/utils.dart
+++ b/lib/uitl/utils.dart
@@ -546,7 +546,7 @@ class Utils {
medical.add(InkWell(
onTap: () {
userData().then((userData_) {
- if (projectViewModel.isLogin && userData_ != null) {
+ if (projectViewModel.isLogin && userData_ != null || true) {
String patientID = userData_.patientID.toString();
GifLoaderDialogUtils.showMyDialog(context);
projectViewModel
diff --git a/lib/widgets/buttons/defaultButton.dart b/lib/widgets/buttons/defaultButton.dart
index affd9a3e..e2ee35dc 100644
--- a/lib/widgets/buttons/defaultButton.dart
+++ b/lib/widgets/buttons/defaultButton.dart
@@ -3,6 +3,7 @@ import 'package:flutter_svg/svg.dart';
extension WithContainer on Widget {
Widget get insideContainer => Container(color: Colors.white, padding: EdgeInsets.only(top: 16, bottom: 16, right: 21, left: 21), child: this);
+ Widget get expand => Expanded(child: this);
}
class DefaultButton extends StatelessWidget {
diff --git a/lib/widgets/in_app_browser/InAppBrowser.dart b/lib/widgets/in_app_browser/InAppBrowser.dart
index 9e363e4d..e139f105 100644
--- a/lib/widgets/in_app_browser/InAppBrowser.dart
+++ b/lib/widgets/in_app_browser/InAppBrowser.dart
@@ -99,18 +99,19 @@ class MyInAppBrowser extends InAppBrowser {
if (onExitCallback != null) onExitCallback(appo, isPaymentDone);
}
- // @override
- // Future shouldOverrideUrlLoading(ShouldOverrideUrlLoadingRequest shouldOverrideUrlLoadingRequest) async {
- // var url = shouldOverrideUrlLoadingRequest.url;
- // debugPrint("redirecting/overriding to: $url");
- //
- // if (paymentType == _PAYMENT_TYPE.PACKAGES && [PACKAGES_PAYMENT_SUCCESS_URL, PACKAGES_PAYMENT_FAIL_URL].contains(url)) {
- // isPaymentDone = (url == PACKAGES_PAYMENT_SUCCESS_URL);
- // close();
- // }
- //
- // return ShouldOverrideUrlLoadingAction.ALLOW;
- // }
+ @override
+ Future shouldOverrideUrlLoading(NavigationAction navigationAction) {
+ var url = navigationAction.request.url.toString();
+ debugPrint("redirecting/overriding to: $url");
+
+ if (paymentType == _PAYMENT_TYPE.PACKAGES && [PACKAGES_PAYMENT_SUCCESS_URL, PACKAGES_PAYMENT_FAIL_URL].contains(url)) {
+ isPaymentDone = (url == PACKAGES_PAYMENT_SUCCESS_URL);
+ close();
+ }
+
+ return Future.value(NavigationActionPolicy.ALLOW);
+ }
+
getLanguageID() async {
return await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar');
@@ -135,7 +136,7 @@ class MyInAppBrowser extends InAppBrowser {
openPackagesPaymentBrowser({@required int customer_id, @required int order_id}) {
paymentType = _PAYMENT_TYPE.PACKAGES;
var full_url = '$PACKAGES_REQUEST_PAYMENT_URL?customer_id=$customer_id&order_id=$order_id';
- this.browser.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(full_url)), options: _InAppBrowserOptions);
+ this.openUrlRequest(urlRequest: URLRequest(url: Uri.parse(full_url)), options: _InAppBrowserOptions);
}
openPaymentBrowser(double amount, String orderDesc, String transactionID, String projId, String emailId, String paymentMethod, dynamic patientType, String patientName, dynamic patientID,
@@ -367,6 +368,8 @@ class MyChromeSafariBrowser extends ChromeSafariBrowser {
onLoadStartCallback("ApplePay");
}
+
+
@override
void onClosed() {
print("ChromeSafari browser closed");
diff --git a/lib/widgets/offers_packages/PackagesOrderHistoryItemCard.dart b/lib/widgets/offers_packages/PackagesOrderHistoryItemCard.dart
new file mode 100644
index 00000000..6ba6bb29
--- /dev/null
+++ b/lib/widgets/offers_packages/PackagesOrderHistoryItemCard.dart
@@ -0,0 +1,124 @@
+import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart';
+import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart';
+import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart';
+import 'package:diplomaticquarterapp/theme/colors.dart';
+import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart';
+import 'package:diplomaticquarterapp/uitl/utils.dart';
+import 'package:diplomaticquarterapp/uitl/utils_new.dart';
+import 'package:diplomaticquarterapp/widgets/CounterView.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+bool wide = true;
+
+class PackagesOrderHistoryItemCard extends StatefulWidget {
+ final PackagesResponseModel itemModel;
+ final PackagesViewModel viewModel;
+ final Function getCartItems;
+
+ const PackagesOrderHistoryItemCard({@required this.itemModel, @required this.viewModel, this.getCartItems, Key key}) : super(key: key);
+
+ @override
+ State createState() => PackagesOrderHistoryItemCardState();
+}
+
+class PackagesOrderHistoryItemCardState extends State {
+ @override
+ Widget build(BuildContext context) {
+ wide = !wide;
+ return Container(
+ decoration: cardRadius(15.0),
+ height: 95,
+ padding: EdgeInsets.all(9),
+ child: Row(
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ _image(widget.itemModel),
+ SizedBox(width: 7),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ _itemName(widget.itemModel.name),
+ Expanded(child: _itemDescription(widget.itemModel.shortDescription)),
+ Row(
+ mainAxisSize: MainAxisSize.max,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ _itemPrice(widget.itemModel.price, context: context),
+ _cancelButton(context, itemModel: widget.itemModel)
+ ],
+ ),
+ ],
+ ),
+ )
+ ],
+ ),
+ );
+ }
+}
+
+Widget _cancelButton(BuildContext context, {@required PackagesResponseModel itemModel, VoidCallback onClick}) => InkWell(
+ onTap:onClick,
+ child: Padding(
+ padding: const EdgeInsets.only(right: 3, bottom: 3),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ // Text(
+ // TranslationBase.of(context).removeMember,
+ // style: TextStyle(
+ // fontSize: 10,
+ // color: CustomColors.accentColor,
+ // fontWeight: FontWeight.w600,
+ // letterSpacing: -0.36,
+ // ),
+ // ),
+ // SizedBox(width: 2),
+ // SvgPicture.asset("assets/images/new-design/delete.svg", color: CustomColors.accentColor),
+ ],
+ ),
+ ),
+ );
+
+Widget _image(PackagesResponseModel model) => AspectRatio(
+ aspectRatio: 1 / 1,
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(15), child: ((model.images ?? []).isNotEmpty) ? Utils.loadNetworkImage(url: model.images.first.src, fitting: BoxFit.fill) : Container(color: Colors.grey[200])),
+ );
+
+Widget _itemName(String name) => Text(
+ name,
+ style: TextStyle(
+ fontSize: 14,
+ fontWeight: FontWeight.bold,
+ color: Color(0xff2B353E),
+ letterSpacing: -0.56,
+ ),
+ );
+
+Widget _itemDescription(String desc) => Text(
+ desc,
+ maxLines: 2,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontSize: 10,
+ fontWeight: FontWeight.w500,
+ color: Color(0xff535353),
+ letterSpacing: -0.4,
+ ),
+ );
+
+Widget _itemPrice(double price, {@required BuildContext context}) {
+ final prc = (price ?? 0.0).toStringAsFixed(2);
+ return Text(
+ '$prc ${TranslationBase.of(context).sar}',
+ style: TextStyle(
+ fontSize: 11,
+ fontWeight: FontWeight.w600,
+ color: Color(0xff5D5D5D),
+ letterSpacing: -0.44,
+ ),
+ );
+}