diff --git a/.gitignore b/.gitignore index fd4aca5a..cff0e374 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ .dart_tool/ .flutter-plugins pubspec.lock +/ios/Podfile.lock .flutter-plugins-dependencies .packages .pub-cache/ diff --git a/GoogleService-Info_DQ.plist b/GoogleService-Info_DQ.plist new file mode 100644 index 00000000..0c093a2a --- /dev/null +++ b/GoogleService-Info_DQ.plist @@ -0,0 +1,36 @@ + + + + + CLIENT_ID + 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r + API_KEY + AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs + GCM_SENDER_ID + 864393916058 + PLIST_VERSION + 1 + BUNDLE_ID + com.cloud.diplomaticquarterapp + PROJECT_ID + diplomaticquarter-d2385 + STORAGE_BUCKET + diplomaticquarter-d2385.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:864393916058:ios:13f787bbfe6051f8b97923 + DATABASE_URL + https://diplomaticquarter-d2385.firebaseio.com + + \ No newline at end of file diff --git a/GoogleService-Info_HMG.plist b/GoogleService-Info_HMG.plist new file mode 100644 index 00000000..153aa2c6 --- /dev/null +++ b/GoogleService-Info_HMG.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com + API_KEY + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA + GCM_SENDER_ID + 815750722565 + PLIST_VERSION + 1 + BUNDLE_ID + com.HMG.Smartphone + PROJECT_ID + api-project-815750722565 + STORAGE_BUCKET + api-project-815750722565.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:815750722565:ios:328ec247a81a2ca23c186c + DATABASE_URL + https://api-project-815750722565.firebaseio.com + + \ No newline at end of file diff --git a/agconnect-services_DQ.json b/agconnect-services_DQ.json new file mode 100644 index 00000000..563c412f --- /dev/null +++ b/agconnect-services_DQ.json @@ -0,0 +1,14 @@ +{ + "client":{ + "appType":"1", + "cp_id":"2640966000002322881", + "product_id":"736430079244816576", + "client_id":"563737844552565952", + "client_secret":"9C9A2C272576B8AE6E886C78AF944E8354B91F0AF3381129BB8369FB35E41C47", + "project_id":"736430079244816576", + "app_id":"103856487", + "api_key":"CgB6e3x90XxBrOCMun809w+DOzcFEettcBDUF3fqaLry1ViqTeJqoPwpfaOq/uGw//x0oYwucu9aWazs+Rdj0GUF", + "package_name":"com.cloud.diplomaticquarterapp" + }, + "configuration_version":"1.0" +} \ No newline at end of file diff --git a/agconnect-services_HMG.json b/agconnect-services_HMG.json new file mode 100644 index 00000000..cfdaf83b --- /dev/null +++ b/agconnect-services_HMG.json @@ -0,0 +1,14 @@ +{ + "client":{ + "appType":"1", + "cp_id":"2640966000002322881", + "product_id":"736430079244816567", + "client_id":"563735388191982656", + "client_secret":"650C7C799812AFFD53A10C7756CF05FB9F215A7E49032ABA8EBF3E14B77535CF", + "project_id":"736430079244816567", + "app_id":"102857389", + "api_key":"CgB6e3x9DJzMgRCmnT6dyUEkp6UsIfddb6l3w0ZEXzeiRMHEFi3400Z5fJ5qaHneU0OrAI/JRpk+DMGVs3QpUxlI", + "package_name":"com.ejada.hmg" + }, + "configuration_version":"1.0" +} \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index 19d22b13..11e99a2a 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -7,9 +7,9 @@ if (localPropertiesFile.exists()) { } def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} +//if (flutterRoot == null) { +// throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +//} def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { @@ -27,7 +27,7 @@ apply plugin: 'com.google.gms.google-services' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -41,7 +41,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.cloud.diplomaticquarterapp" minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName multiDexEnabled true @@ -78,6 +78,7 @@ dependencies { // exclude group: 'com.google.protobuf',module: 'protobuf-lite' // }) implementation 'pub.devrel:easypermissions:0.4.0' +// implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' // implementation 'com.google.firebase:firebase-inappmessaging-display:17.2.0' implementation 'com.google.guava:guava:27.0.1-android' // Dependency on local binaries @@ -93,6 +94,6 @@ dependencies { implementation 'com.github.kittinunf.fuel:fuel:2.3.0' //for JVM implementation 'com.github.kittinunf.fuel:fuel-android:2.3.0' implementation 'com.google.android.gms:play-services-location:17.1.0'//for Android - + implementation 'com.google.android.gms:play-services-basement:17.5.0' } diff --git a/android/app/google-services.json b/android/app/google-services.json index f86832ad..a4655794 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,39 +1,37 @@ { "project_info": { - "project_number": "815750722565", - "firebase_url": "https://api-project-815750722565.firebaseio.com", - "project_id": "api-project-815750722565", - "storage_bucket": "api-project-815750722565.appspot.com" + "project_number": "864393916058", + "firebase_url": "https://diplomaticquarter-d2385.firebaseio.com", + "project_id": "diplomaticquarter-d2385", + "storage_bucket": "diplomaticquarter-d2385.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:815750722565:android:62281cd3e5df4063", + "mobilesdk_app_id": "1:864393916058:android:5b5a65cd6d8c18b4b97923", "android_client_info": { "package_name": "com.cloud.diplomaticquarterapp" } }, "oauth_client": [ { - "client_id": "815750722565-3a0gc7neins0eoahdrimrfksk0sqice8.apps.googleusercontent.com", + "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDUfg6AKM1-00WyzpvLImUBC46wFrq9-qw" + "current_key": "AIzaSyBdV3mos1BPhUzNKCj2KANJtiO3o2zh9IM" } ], "services": { - "analytics_service": { - "status": 1 - }, "appinvite_service": { - "status": 1, - "other_platform_oauth_client": [] - }, - "ads_service": { - "status": 2 + "other_platform_oauth_client": [ + { + "client_id": "864393916058-tphjrn8j39ntevt32ekcvmll8aue7qql.apps.googleusercontent.com", + "client_type": 3 + } + ] } } } diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro new file mode 100644 index 00000000..4ace459d --- /dev/null +++ b/android/app/proguard-rules.pro @@ -0,0 +1,4 @@ +-keep class tvi.webrtc.** { *; } +-keep class com.twilio.video.** { *; } +-keep class com.twilio.common.** { *; } +-keepattributes InnerClasses \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1032b29b..1a3d4cfe 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -10,6 +10,7 @@ + @@ -76,13 +77,21 @@ - - - + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt index 8b73b0c7..e67f646f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/MainActivity.kt @@ -2,8 +2,7 @@ package com.cloud.diplomaticquarterapp import android.os.Bundle import android.util.Log import androidx.annotation.NonNull; -import com.cloud.diplomaticquarterapp.utils.FlutterText -import com.cloud.diplomaticquarterapp.utils.PlatformBridge +import com.cloud.diplomaticquarterapp.utils.* import io.flutter.embedding.android.FlutterFragmentActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel @@ -15,6 +14,16 @@ class MainActivity: FlutterFragmentActivity() { // Create Flutter Platform Bridge PlatformBridge(flutterEngine.dartExecutor.binaryMessenger, this).create() + val time = timeToMillis("04:00:00", "HH:mm:ss") + print(time) + +// val d1 = Logs.list(this) +// val d2 = Logs.raw(this) +// val d3 = Logs.RegisterGeofence.list(this) +// val d4 = Logs.RegisterGeofence.raw(this) +// val d5 = Logs.GeofenceEvent.list(this) +// val d6 = Logs.GeofenceEvent.raw(this) + print("") } override fun onResume() { diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt index 7eba1ead..b3fb4f56 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeoZoneModel.kt @@ -37,6 +37,7 @@ class GeoZoneModel { val rad = Radius.toFloat() if(lat != null && long != null){ + val loiteringDelayMinutes:Int = 2 // in Minutes return Geofence.Builder() .setRequestId(identifier()) .setCircularRegion( @@ -45,7 +46,8 @@ class GeoZoneModel { rad ) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) -// .setNotificationResponsiveness(0) + .setNotificationResponsiveness(0) + .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build() } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt deleted file mode 100644 index 8fc1faae..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt +++ /dev/null @@ -1,13 +0,0 @@ - - -package com.cloud.diplomaticquarterapp.geofence - -import android.content.BroadcastReceiver -import android.content.Context -import android.content.Intent - -class GeofenceBroadcastReceiver : BroadcastReceiver() { - override fun onReceive(context: Context, intent: Intent) { - GeofenceTransitionsJobIntentService.enqueueWork(context, intent) - } -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt index 4d2c48b3..840075eb 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/HMG_Geofence.kt @@ -6,7 +6,11 @@ import android.content.Context import android.content.Intent import android.content.SharedPreferences import android.content.pm.PackageManager +import android.location.Location import androidx.core.content.ContextCompat +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.GeofenceBroadcastReceiver +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService +import com.cloud.diplomaticquarterapp.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient import com.google.android.gms.location.GeofencingRequest @@ -17,8 +21,10 @@ import com.google.gson.reflect.TypeToken enum class GeofenceTransition(val value: Int) { ENTER(1), EXIT(2), + DWELL(4), + ENTER_EXIT((ENTER.value or EXIT.value)), - DWELL(4); + DWELL_EXIT((DWELL.value or EXIT.value)); companion object { fun fromInt(value: Int) = GeofenceTransition.values().first { it.value == value } @@ -27,17 +33,13 @@ enum class GeofenceTransition(val value: Int) { fun named():String{ if (value == 1)return "Enter" if (value == 2)return "Exit" - if (value == (ENTER.value or EXIT.value))return "Enter or Exit" if (value == 4)return "dWell" + if (value == (ENTER.value or EXIT.value))return "Enter or Exit" + if (value == (DWELL.value or EXIT.value))return "DWell or Exit" return "unknown" } } -const val PREFS_STORAGE = "FlutterSharedPreferences" -const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" -const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" -const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" - class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java @@ -69,13 +71,53 @@ class HMG_Geofence { } } - fun register(geoZones: List){ + fun limitize(zones: List):List{ + var geoZones_ = zones + if(zones.size > 100) + geoZones_ = zones.subList(0, 99) + return geoZones_ + } + + + fun register(completion:((Boolean, java.lang.Exception?)->Unit)){ + unRegisterAll { status, exception -> + val geoZones = getGeoZonesFromPreference(context) + doRegister(geoZones){ status_, error -> + completion.let { it(status_, error) } + } + } + } + + fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ + getActiveGeofences({ success -> + removeActiveGeofences() + if(success.isNotEmpty()) + geofencingClient + .removeGeofences(success) + .addOnSuccessListener { + completion(true, null) + } + .addOnFailureListener { + completion(false, it) + saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) + } + else + completion(true, null) + + }, { failed -> + // Nothing to do with failed geofences. + }) + } + + private fun doRegister(geoZones: List, completion:((Boolean, java.lang.Exception?)->Unit)? = null){ if (geoZones.isEmpty()) return + val geoZones_ = limitize(geoZones) + fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() - .setInitialTrigger(0) + .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) .addGeofences(geofences) .build() } @@ -83,9 +125,9 @@ class HMG_Geofence { getActiveGeofences({ active -> val geofences = mutableListOf() - geoZones.forEach { - it.toGeofence()?.let { geof -> - if(!active.contains(geof.requestId)){ // if not already registered then register + geoZones_.forEach { + it.toGeofence()?.let { geof -> + if (!active.contains(geof.requestId)) { // if not already registered then register geofences.add(geof) } } @@ -95,31 +137,29 @@ class HMG_Geofence { geofencingClient .addGeofences(buildGeofencingRequest(geofences), geofencePendingIntent) .addOnSuccessListener { + Logs.RegisterGeofence.save(context,"SUCCESS", "Successfuly registered the geofences", Logs.STATUS.SUCCESS) saveActiveGeofence(geofences.map { it.requestId }, listOf()) + completion?.let { it(true,null) } } - .addOnFailureListener { - print(it.localizedMessage) + .addOnFailureListener { exc -> + Logs.RegisterGeofence.save(context,"FAILED_TO_REGISTER", "Failed to register geofence",Logs.STATUS.ERROR) + completion?.let { it(false,exc) } } + + // Schedule the job to register after specified duration (due to: events not calling after long period.. days or days [Needs to register fences again]) + HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalDuration) } - },null) + + }, null) + } - fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ - getActiveGeofences({ success -> - val mList = success.toMutableList() - mList.add("12345") - geofencingClient - .removeGeofences(success) - .addOnSuccessListener { - completion(true, null) - } - .addOnFailureListener { - completion(false, it) - } - removeActiveGeofences() - }, { failed -> - // Nothing to do with failed geofences. - }) + fun getGeoZonesFromPreference(context: Context):List{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") + + val geoZones = GeoZoneModel().listFrom(json!!) + return geoZones } fun saveActiveGeofence(success: List, failed: List){ @@ -130,8 +170,8 @@ class HMG_Geofence { } fun removeActiveGeofences(){ - preferences.edit().putString(PREF_KEY_SUCCESS,"[]").apply() - preferences.edit().putString(PREF_KEY_FAILED,"[]").apply() + preferences.edit().putString(PREF_KEY_SUCCESS, "[]").apply() + preferences.edit().putString(PREF_KEY_FAILED, "[]").apply() } fun getActiveGeofences(success: (success: List) -> Unit, failure: ((failed: List) -> Unit)?){ @@ -154,12 +194,48 @@ class HMG_Geofence { } fun getPatientID():Int?{ - val profileJson = preferences.getString("flutter.imei-user-data", "{}") + var profileJson = preferences.getString("flutter.imei-user-data", null) + if (profileJson == null) + profileJson = preferences.getString("flutter.user-profile", null) + val type = object : TypeToken?>() {}.type - return gson.fromJson?>(profileJson,type) + return gson.fromJson?>(profileJson, type) ?.get("PatientID") .toString() .toDoubleOrNull() ?.toInt() } + + + fun handleEvent(triggerGeofences: List, location: Location, transition: GeofenceTransition) { + getPatientID()?.let { patientId -> + getActiveGeofences({ activeGeofences -> + + triggerGeofences.forEach { geofence -> + // Extract PointID from 'geofence.requestId' and find from active geofences + val pointID = activeGeofences.firstOrNull { it == geofence.requestId }?.split('_')?.first() + if (!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null) { + + val body = mutableMapOf( + "PointsID" to pointID.toIntOrNull(), + "GeoType" to transition.value, + "PatientID" to patientId + ) + body.putAll(HMGUtils.defaultHTTPParams(context)) + + httpPost>(API.LOG_GEOFENCE, body, { response -> + saveLog(context, "HMG_GEOFENCE_NOTIFY", "Success: Notified to server\uD83D\uDE0E.") + sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎") + }, { exception -> + val errorMessage = "${transition.named()}, ${geofence.requestId}" + saveLog(context, "HMG_GEOFENCE_NOTIFY", "failed: $errorMessage | error: ${exception.localizedMessage}") + sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server😔 -> ${exception.localizedMessage}") + }) + + } + } + + }, null) + } + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt new file mode 100644 index 00000000..77df1572 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -0,0 +1,49 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.util.Log +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.Logs +import com.google.android.gms.location.GeofenceStatusCodes +import com.google.android.gms.location.GeofencingEvent + +class GeofenceBroadcastReceiver : BroadcastReceiver() { + private val LOG_TAG = "GeofenceBroadcastReceiver" + override fun onReceive(context: Context, intent: Intent) { + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + + Logs.GeofenceEvent.save(context,LOG_TAG,"Error while triggering geofence event",Logs.STATUS.ERROR) + doReRegisterIfRequired(context,geofencingEvent.errorCode) + + return + } + + Logs.GeofenceEvent.save(context,LOG_TAG,"Geofence event triggered: ${GeofenceTransition.fromInt(geofencingEvent.geofenceTransition).value} for ${geofencingEvent.triggeringGeofences.map {it.requestId}}",Logs.STATUS.SUCCESS) + HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + + } + + fun doReRegisterIfRequired(context: Context, errorCode: Int){ + val errorRequiredReregister = listOf( + GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT + ) + + if(errorRequiredReregister.contains(errorCode)) + HMG_Geofence.shared(context).register(){ status, error -> + + } + + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt new file mode 100644 index 00000000..a9924ca1 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt @@ -0,0 +1,16 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.google.android.gms.location.GeofenceStatusCodes + +class GeofenceBroadcastReceiverWithJobService : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + GeofenceTransitionsJobIntentService.enqueueWork(context, intent) + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt old mode 100755 new mode 100644 similarity index 67% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 4890f7cb..01377d49 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -1,9 +1,10 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.GeofenceStatusCodes @@ -18,7 +19,7 @@ object GeofenceErrorMessages { fun getErrorString(context: Context, errorCode: Int): String { val resources = context.resources - return when (errorCode) { + val errorMessage = when (errorCode) { GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE -> resources.getString(R.string.geofence_not_available) @@ -28,7 +29,15 @@ object GeofenceErrorMessages { GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS -> resources.getString(R.string.geofence_too_many_pending_intents) + GeofenceStatusCodes.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION -> + resources.getString(R.string.GEOFENCE_INSUFFICIENT_LOCATION_PERMISSION) + + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT -> + resources.getString(R.string.GEOFENCE_REQUEST_TOO_FREQUENT) + else -> resources.getString(R.string.geofence_unknown_error) } + + return errorMessage } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt old mode 100755 new mode 100644 similarity index 53% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index f28e1720..214957cf --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -29,31 +29,27 @@ */ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import android.content.Intent -import android.location.Location import android.util.Log import androidx.core.app.JobIntentService -import com.cloud.diplomaticquarterapp.utils.API -import com.cloud.diplomaticquarterapp.utils.httpPost -import com.cloud.diplomaticquarterapp.utils.sendNotification -import com.github.kittinunf.fuel.core.extensions.jsonBody -import com.github.kittinunf.fuel.core.isSuccessful -import com.github.kittinunf.fuel.httpPost -import com.google.android.gms.location.Geofence +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent -import com.google.gson.Gson class GeofenceTransitionsJobIntentService : JobIntentService() { companion object { private const val LOG_TAG = "GeoTrIntentService" - private const val JOB_ID = 573 - + private const val JOB_ID = 95902 + var context_: Context? = null fun enqueueWork(context: Context, intent: Intent) { + context_ = context enqueueWork( context, GeofenceTransitionsJobIntentService::class.java, JOB_ID, @@ -64,43 +60,31 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { override fun onHandleWork(intent: Intent) { val geofencingEvent = GeofencingEvent.fromIntent(intent) if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) + val errorMessage = GeofenceErrorMessages.getErrorString(context_!!, geofencingEvent.errorCode) Log.e(LOG_TAG, errorMessage) - return - } - if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { - handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - } - } - private fun handleEvent(triggerGeofences: List, location:Location, transition:GeofenceTransition) { - val hmg = HMG_Geofence.shared(this) - hmg.getPatientID()?.let { patientId -> + saveLog(context_!!,LOG_TAG,errorMessage) + doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) - hmg.getActiveGeofences({ activeGeofences -> + return + } - triggerGeofences.forEach { geofence -> - // Extract PointID from 'geofence.requestId' and find from active geofences - val pointID = activeGeofences.firstOrNull {it == geofence.requestId}?.split('_')?.first() - if(!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null){ + HMG_Geofence.shared(context_!!).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - val body = mapOf( - "PointsID" to pointID.toIntOrNull(), - "GeoType" to transition.value, - "PatientID" to patientId - ) + } - httpPost>(API.LOG_GEOFENCE, body, { response -> - sendNotification(this, transition.named(), geofence.requestId, "Notified to server.😎") - },{ exception -> - sendNotification(this, transition.named(), geofence.requestId, "Failed to notify server.😔") - }) - } - } + fun doReRegisterIfRequired(context: Context, errorCode: Int){ + val errorRequiredReregister = listOf( + GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES, + GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS, + GeofenceStatusCodes.GEOFENCE_REQUEST_TOO_FREQUENT + ) + + if(errorRequiredReregister.contains(errorCode)) + HMG_Geofence.shared(context).register(){ status, exc -> } - },null) - } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt similarity index 58% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index 08a0c93f..6421b327 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -1,26 +1,22 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -import android.os.Handler -import android.os.Message import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.utils.HMGUtils +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { +// if (intent.action.equals("android.intent.action.BOOT_COMPLETE")) { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() - HMG_Geofence.shared(context).unRegisterAll { status, exception -> - val geoZones = HMGUtils.getGeoZonesFromPreference(context) - HMG_Geofence.shared(context).register(geoZones) - } + HMG_Geofence.shared(context).register(){ status, error -> } } } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt new file mode 100644 index 00000000..273ca8f5 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt @@ -0,0 +1,25 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.location.LocationManager +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.HMGUtils +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE + +class LocationProviderChangeReceiver : BroadcastReceiver() { + private val LOG_TAG = "LocationProviderChangeReceiver" + override fun onReceive(context: Context, intent: Intent) { + + if (LocationManager.PROVIDERS_CHANGED_ACTION.equals(intent.action)) { + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + pref.edit().putString("LOCATION_PROVIDER_CHANGE","YES").apply() + + HMG_Geofence.shared(context).register(){ s, e -> } + } + } + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt new file mode 100644 index 00000000..0bc496bc --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt @@ -0,0 +1,24 @@ +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.app.job.JobParameters +import android.app.job.JobService +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.utils.Logs + +class ReregisterGeofenceJobService : JobService(){ + companion object{ + val TriggerIntervalDuration:String = "06:00:00" + val JobID = 918273 + } + override fun onStartJob(params: JobParameters?): Boolean { + Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalDuration >> [HH:mm:ss]") + HMG_Geofence.shared(applicationContext).register(){ status, error -> + jobFinished(params, true) + } + return true + } + + override fun onStopJob(params: JobParameters?): Boolean { + return true + } +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt index 30f57dde..924bda91 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt @@ -2,7 +2,7 @@ package com.cloud.diplomaticquarterapp.utils class API { companion object{ - private val BASE = "https://uat.hmgwebservices.com" + private val BASE = "https://hmgwebservices.com" private val SERVICE = "Services/Patients.svc/REST" val WIFI_CREDENTIALS = "$BASE/$SERVICE/Hmg_SMS_Get_By_ProjectID_And_PatientID" diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt new file mode 100644 index 00000000..aa0f8ec2 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt @@ -0,0 +1,8 @@ +package com.cloud.diplomaticquarterapp.utils + + +const val PREFS_STORAGE = "FlutterSharedPreferences" +const val PREF_KEY_SUCCESS = "HMG_GEOFENCE_SUCCESS" +const val PREF_KEY_FAILED = "HMG_GEOFENCE_FAILED" +const val PREF_KEY_HMG_ZONES = "flutter.hmg-geo-fences" +const val PREF_KEY_LANGUAGE = "flutter.language" \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index bebd0101..94bf54e6 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt @@ -3,6 +3,9 @@ package com.cloud.diplomaticquarterapp.utils import android.app.NotificationChannel import android.app.NotificationManager import android.app.PendingIntent +import android.app.job.JobInfo +import android.app.job.JobScheduler +import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Build @@ -14,17 +17,16 @@ import com.cloud.diplomaticquarterapp.BuildConfig import com.cloud.diplomaticquarterapp.MainActivity import com.cloud.diplomaticquarterapp.R import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE -import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost -import com.google.android.gms.location.Geofence import com.google.gson.Gson import com.google.gson.reflect.TypeToken import io.flutter.plugin.common.MethodChannel +import org.jetbrains.anko.doAsyncResult import org.json.JSONArray import org.json.JSONException import org.json.JSONObject +import java.text.SimpleDateFormat import java.util.* import kotlin.concurrent.timerTask @@ -68,24 +70,65 @@ class HMGUtils { } } - fun getGeoZonesFromPreference(context: Context):List{ + fun getLanguageCode(context: Context) : Int { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val json = pref.getString(PREF_KEY_HMG_ZONES,"[]") + val lang = pref.getString(PREF_KEY_LANGUAGE, "ar") + return if (lang == "ar") 2 else 1 + } - val geoZones = GeoZoneModel().listFrom(json) - return geoZones + fun defaultHTTPParams(context: Context) : Map{ + return mapOf( + "ZipCode" to "966", + "VersionID" to 5.8, + "Channel" to 3, + "LanguageID" to getLanguageCode(context), + "IPAdress" to "10.20.10.20", + "generalid" to "Cs2020@2016$2958", + "PatientOutSA" to 0, + "SessionID" to null, + "isDentalAllowedBackend" to false, + "DeviceTypeID" to 2) + } + + + fun scheduleJob(context: Context, pendingIntentClassType:Class, jobId:Int, intervalDuration:String, deadlineMillis:Long = (30 * 1000)) { // default deadline: 30 Seconds + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + val jobScheduler: JobScheduler = context.getSystemService(JobScheduler::class.java) + + val serviceComponent = ComponentName(context, pendingIntentClassType) + val builder = JobInfo.Builder(jobId, serviceComponent) + builder.setPersisted(true) + builder.setBackoffCriteria(30000, JobInfo.BACKOFF_POLICY_LINEAR) + + val intervalMillis = timeToMillis(intervalDuration,"HH:mm:ss") + builder.setMinimumLatency(intervalMillis) // wait at least + builder.setOverrideDeadline((intervalMillis + deadlineMillis)) // maximum delay + if (jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_SUCCESS){ + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Job scheduled to trigger after duration $intervalDuration >> HH:mm:ss --('MinimumLatency:$intervalMillis Deadline:${(intervalMillis + deadlineMillis)}')--",Logs.STATUS.SUCCESS) + }else{ + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job",Logs.STATUS.ERROR) + } + + } else { + Logs.save(context,"ScheduleJob", "${pendingIntentClassType.simpleName}: Failed to scheduled Job on VERSION.SDK_INT < ${android.os.Build.VERSION_CODES.M}",Logs.STATUS.ERROR) + } } } } -private fun Timer.schedule(timerTask: TimerTask) { -} private const val NOTIFICATION_CHANNEL_ID = BuildConfig.APPLICATION_ID + ".channel" -fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, message:String?) { + +fun timeToMillis(time:String, format:String):Long{ + val sdf = SimpleDateFormat(format, Locale.US) + val millis = sdf.parse(time).time + TimeZone.getDefault().rawOffset + return millis +} + +fun sendNotification(context: Context, title: String, @Nullable subtitle: String?, message: String?) { val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O @@ -117,8 +160,18 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, notificationManager.notify(getUniqueId(), notification.build()) } +//------------------------- +// Open Helper Methods +//------------------------- +fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) -private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) +object DateUtils { + @JvmStatic + fun dateTimeNow() : String { + val format = SimpleDateFormat("dd-MMM-yyy hh:mm:ss") + return format.format(Date()) + } +} fun isJSONValid(jsonString: String?): Boolean { try { JSONObject(jsonString) } catch (ex: JSONException) { @@ -129,31 +182,43 @@ fun isJSONValid(jsonString: String?): Boolean { return true } +fun saveLog(context: Context, tag: String, message: String){ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + var logs = pref.getString("LOGS", "") + logs += "$tag -> $message \n" + pref.edit().putString("LOGS", logs).apply(); +} + +fun getLogs(context: Context) : String?{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + return pref.getString("LOGS", "") +} + class HTTPResponse(data: T){ final var data:T = data } -fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){ +fun httpPost(url: String, body: Map, onSuccess: (response: HTTPResponse) -> Unit, onError: (error: Exception) -> Unit){ val gson = Gson() val type = object : TypeToken() {}.type val jsonBody = gson.toJson(body) url.httpPost() .jsonBody(jsonBody, Charsets.UTF_8) .timeout(10000) - .header("Content-Type","application/json") - .header("Allow","*/*") + .header("Content-Type", "application/json") + .header("Allow", "*/*") .response { request, response, result -> + result.doAsyncResult { } result.fold({ data -> val dataString = String(data) - if(isJSONValid(dataString)){ - val responseData = gson.fromJson(dataString,type) + if (isJSONValid(dataString)) { + val responseData = gson.fromJson(dataString, type) onSuccess(HTTPResponse(responseData)) - }else{ + } else { onError(Exception("Invalid response from server (Not a valid JSON)")) } }, { onError(it) - it.localizedMessage }) } diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt new file mode 100644 index 00000000..e74f463e --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -0,0 +1,145 @@ +package com.cloud.diplomaticquarterapp.utils + +import android.content.Context +import android.content.SharedPreferences +import android.os.Build +import com.cloud.diplomaticquarterapp.BuildConfig +import com.google.gson.Gson + +class Logs { + + enum class STATUS{ + SUCCESS, + ERROR; + } + class GeofenceEvent{ + companion object{ + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"GeofenceEvent", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"GeofenceEvent", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"GeofenceEvent") + } + } + } + + class RegisterGeofence{ + companion object{ + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"RegisterGeofence", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"RegisterGeofence", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"RegisterGeofence"); + } + } + } + + + companion object{ + private var pref:SharedPreferences? = null + fun save(context: Context, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + Logs.Common.save(context,"Logs", tag, message, status) + } + + fun list(context: Context, tag:String? = null, status:Logs.STATUS? = null):List{ + return Logs.Common.list(context,"Logs", tag, status) + } + + fun raw(context: Context):String{ + return Logs.Common.raw(context,"Logs"); + } + + private fun storage(context: Context):SharedPreferences{ + if(pref == null) { + pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + } + return pref!! + } + } + + private class Common{ + companion object{ + private val gson = Gson() + + fun save(context: Context, key:String, tag:String, message:String, status:Logs.STATUS = STATUS.SUCCESS){ + if(!BuildConfig.DEBUG) + return + + val pref = Logs.storage(context) + + val string = pref.getString(key,"{}") + val json = gson.fromJson(string,LogsContainerModel::class.java) + json.add( + LogModel().apply { + this.TAG = tag + this.MESSAGE = message + this.STATUS = status.name + this.DATE = DateUtils.dateTimeNow() + } + ) + + pref.edit().putString(key,gson.toJson(json)).apply() + } + + fun list(context: Context, key:String, tag:String? = null, status:Logs.STATUS? = null):List{ + val pref = Logs.storage(context) + val string = pref.getString(key,"{}") + val json = gson.fromJson(string,LogsContainerModel::class.java) + if(tag == null && status == null) { + return json.LOGS + }else if(tag != null && status != null){ + return json.LOGS.filter { (it.TAG == tag && it.STATUS == status.name) } + }else if(tag != null){ + return json.LOGS.filter { (it.TAG == tag) } + }else if(status != null){ + return json.LOGS.filter { (it.STATUS == status.name) } + } + return listOf() + } + + fun raw(context: Context, key:String):String{ + val pref = Logs.storage(context) + val string = pref.getString(key,"{}") + return string!! + } + + } + } + + class LogModel{ + lateinit var TAG:String + lateinit var MESSAGE:String + lateinit var STATUS:String + lateinit var DATE:String + + companion object{ + fun with(tag:String, message:String, status:String):LogModel{ + return LogModel().apply { + this.TAG = tag + this.MESSAGE = message + this.STATUS = status + this.DATE = DateUtils.dateTimeNow() + } + } + } + } + + class LogsContainerModel{ + var LOGS = mutableListOf() + fun add(log:LogModel){ + LOGS.add(log) + } + } + + +} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt index ed1a62c8..eb2fff08 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/PlatformBridge.kt @@ -105,7 +105,7 @@ class PlatformBridge(binaryMessenger: BinaryMessenger, flutterMainActivity: Main override fun success(result: Any?) { if(result is String) { val geoZones = GeoZoneModel().listFrom(result) - HMG_Geofence.shared(mainActivity).register(geoZones) + HMG_Geofence.shared(mainActivity).register(){ s, e -> } } } diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml old mode 100755 new mode 100644 index 8acc0c12..4e107030 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -13,4 +13,10 @@ You have provided too many PendingIntents to the addGeofences() call. + + App do not have permission to access location service. + + + Geofence requests happened too frequently. + diff --git a/android/build.gradle b/android/build.gradle index 433bc8ad..32bda0b1 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -3,6 +3,9 @@ buildscript { repositories { google() jcenter() +// maven { +// url "https://dl.bintray.com/kotlin/kotlin-eap/" +// } } dependencies { diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index c935be88..1f9de82f 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip diff --git a/assets/app_icons/config.json b/assets/app_icons/config.json index 0bedcb06..e2e1afdb 100644 --- a/assets/app_icons/config.json +++ b/assets/app_icons/config.json @@ -257,6 +257,20 @@ "search": [ "calendar-(2)" ] + }, + { + "uid": "ad42aa33b55d1a7b2edcf4ed976435d9", + "css": "roboticon", + "code": 59410, + "src": "custom_icons", + "selected": true, + "svg": { + "path": "M546.9 33.2C546.1 35.3 544.8 37.2 544.1 37.7 542.9 38.3 542.9 38.9 543.8 40.6 544.5 42.2 546.7 43.5 550.4 44.7L555.8 46.6 557.5 44.4C560.3 40.7 562.1 36.4 561.5 34.8 561.2 34 559.3 32.9 557.3 32.3 555.4 31.7 553.7 30.8 553.7 30.4 553.7 30 552.5 29.6 551 29.6 548.8 29.6 548.1 30.2 546.9 33.2ZM453.8 33.9C452.7 35.3 451.9 37.6 451.9 39 451.9 41 451.4 41.7 450 41.7 447.2 41.7 447.8 43.1 452 46.8 458.9 52.5 461.7 52.1 464.4 45 466.7 39.1 466 36.9 461.7 35.6 459.7 35.1 457.6 33.9 456.9 33.1 455.8 31.5 455.6 31.6 453.8 33.9ZM500.2 34.4C499.4 36 498 38.1 497.1 39 495.6 40.5 495.7 40.7 499 43.8 503.9 48.7 506.6 49 509.6 45.2 510.9 43.5 512.8 41.4 513.6 40.6 515 39 514.9 38.7 511.2 35.2 506.2 30.4 502.5 30.1 500.2 34.4ZM523.1 36L518.8 40.5 523.3 45.2C525.7 47.8 527.8 50.6 527.8 51.7 527.8 52.7 525.9 55.6 523.6 58.1L519.4 62.9 523 66.6C528 71.9 530.9 71.8 536.2 66 539.9 62 540 61.7 538.4 60.7 534.1 58.3 531.5 54.8 531.5 51.5 531.5 47.3 535.7 38.9 537.9 38.9 538.9 38.9 538.1 37.7 535.5 35.2 530.3 30.3 528.3 30.5 523.1 36ZM477.4 34.4C476.7 35.6 475.4 38.2 474.5 40.3 473 43.8 473.1 44 475 45.6 476.1 46.5 477.9 47.2 478.8 47.2 479.7 47.2 481 48.1 481.7 49.1 482.3 50.1 483.1 50.9 483.6 50.9 484.8 50.9 488 45 488 42.8 488 41.3 488.5 40.7 490 40.7 491.9 40.7 491.9 40.6 489.3 37.9 486.3 34.8 482.4 32.4 480.2 32.4 479.4 32.4 478.1 33.3 477.4 34.4ZM568.7 36.6L566.8 39.7 569.5 42C575.1 46.8 581.6 46.9 583.2 42.3 585.6 36 585.8 36.4 578.8 34.8 570.4 32.9 570.8 32.8 568.7 36.6ZM428.6 38C428 40.2 426.8 41.9 425.6 42.2 424.1 42.7 424.2 43.1 426.9 46 433.4 52.7 436.5 52.8 439.8 46.2 440.8 44.3 442.3 42.6 443.1 42.6 446.6 42.6 442.2 37.5 437.9 36.6 436.4 36.2 435 35.6 434.7 35.1 434.4 34.6 433.1 34.3 431.9 34.3 430.1 34.3 429.4 35 428.6 38ZM408.4 38.8C404 40.2 403.2 40.7 402.5 43.4 401.4 47.9 402 48.8 407.7 50.6 413.7 52.4 415.6 51.9 416.4 48.1 416.7 46.6 417.9 44.5 419.1 43.6L421.3 41.9 419.4 39.4C417.2 36.7 415.5 36.6 408.4 38.8ZM619.7 52C617 54.9 615.3 61.8 616.8 63.5 617.3 64.3 618.3 64.8 618.9 64.8 619.5 64.8 621.5 65.6 623.4 66.6 626.8 68.2 626.9 68.2 629.1 66.6 631.3 64.8 633.9 57.2 632.9 55.6 632.3 54.7 623.1 50 622 50 621.9 50 620.7 50.9 619.7 52ZM572.2 54.3C571.7 55.6 571.3 56.9 571.3 57.3 571.3 57.8 570.5 59.2 569.4 60.5 567.6 62.8 567.6 62.8 569.5 65.2 571.6 67.8 577 69.8 580.6 69.3 582.4 69.1 583.1 68.1 584.5 64 585.5 61.3 585.9 58.2 585.6 57.2 585 55.3 581.2 53.4 576.1 52.5 573.5 51.9 573 52.2 572.2 54.3ZM595.2 53.4C594.4 54.4 593.2 56.9 592.8 59.1 591.6 64.3 593.2 66.4 599.4 67.5 605.4 68.6 606.3 68.1 607 64.1 607.4 62.1 608.1 59.9 608.5 58.9 610.9 54.4 598.8 49.4 595.2 53.4ZM548.7 54.7C547.9 55.9 547.2 57.4 547.2 58 547.2 58.5 546.6 59.5 545.8 60.2 545.1 60.8 544.4 62.3 544.4 63.6 544.4 65.5 545.3 66.2 549.1 67.8 551.7 68.8 553.7 70.1 553.7 70.5 553.7 72 556.2 71.3 558.1 69.2 560.4 66.8 562.5 60 561.7 57.9 561.1 56.4 557.2 54.4 552.6 53.2 550.7 52.8 549.9 53.1 548.7 54.7ZM480 55.4C479.4 55.7 477.8 58.1 476.4 60.8 473.3 66.3 473.7 67.3 479.7 70.5 485.6 73.3 487.9 72.7 489.4 67.6 489.7 66.3 490.6 64.5 491.5 63.6 493.2 61.7 492.5 60.8 487.7 59.3 485.7 58.7 483.7 57.4 483.1 56.4 481.9 54.4 481.5 54.4 480 55.4ZM500.1 57C499 58.4 497.9 60.6 497.6 61.8 496.5 65.8 502.6 72 506.6 70.8 509 70 515.7 64.1 515.7 62.6 515.7 61.3 507.7 55.8 504.5 55.1 502.6 54.6 501.7 55 500.1 57ZM429.7 59.8C427.7 62.3 426.5 67.1 427 70 427.7 73.6 438.2 76.1 439.8 73.1 444.9 63.8 444.7 62 438.5 59.2 433.4 56.9 431.9 56.9 429.7 59.8ZM453.2 59.5C452.5 60.7 451.6 63.6 451.3 65.8 450.7 70 450.8 70.1 453.8 71.3 455.6 71.9 457.7 73.1 458.5 73.9 460.7 75.8 462.9 74.6 464.4 70.6 465.2 68.7 466.3 66.2 466.9 65.1 468.2 62.4 465.9 59.6 461.2 58.3 456.2 56.9 454.8 57.2 453.2 59.5ZM407.2 59.9C405 62.5 401.8 69.4 402.3 70.4 402.6 70.8 404.4 71.5 406.3 71.9 408.1 72.1 410.8 73.2 412.2 74.2L414.8 75.9 417.1 71.3C418.4 68.8 419.4 65.7 419.4 64.4 419.4 59.5 410.5 56.3 407.2 59.9ZM382.4 60.6C380.8 62.5 378.7 70.2 379.3 71.8 379.5 72.5 381.3 73.5 383.1 74.2 385.1 74.7 386.9 75.6 387.5 76 390.3 78.7 394.8 74.6 395.8 68.4 396.7 63.6 394.9 61.6 388.8 60.3 383.1 59.1 383.8 59 382.4 60.6ZM358.9 61.9C357.3 63.7 355.6 68.7 355.6 71.5 355.6 73.8 358 75.7 362.1 76.9 367.1 78.2 369 77.4 370.7 73.1 373.4 66.5 372.9 65.1 367 62.5 360.7 59.7 360.8 59.7 358.9 61.9ZM339.3 65.2C332 69 331 70.1 332 72.9 333.1 75.8 336 77.5 341.2 78 344.4 78.2 345 78 346 75.9 346.7 74.6 347.4 71.9 347.8 69.7 348.3 66.2 348.1 65.8 345.7 64.5 343.2 63.2 342.8 63.3 339.3 65.2ZM645.2 73.8C644.4 74.7 643 77.7 642 80.4 640.4 85.3 640.4 85.4 642.1 86.7 643.1 87.4 644.5 88 645.5 88 646.3 88 647.5 88.6 648.1 89.4 650.7 92.5 655.6 89 657 83.1 657.6 80.8 657 79.9 653.3 76.3 648.6 71.9 647.3 71.4 645.2 73.8ZM666.4 77.7C663.8 85 664.4 87 669.5 87 670.5 87 672.1 87.9 673.2 89 675.5 91.2 677.2 90.3 678.2 86.3 678.6 84.9 679.4 83.1 680.2 82.3 681.4 81 681 80.5 676.6 77.6 668.8 72.4 668.2 72.4 666.4 77.7ZM622.2 75C621.4 75.5 619.7 78 618.5 80.6L616.3 85.4 618.8 87.6C621.2 89.6 623.3 90.3 626.9 89.9 628.5 89.7 635.2 82.7 635.2 81.1 635.1 80 626.1 74.1 624.5 74.1 624.1 74.1 623 74.5 622.2 75ZM597.8 76.4C595.7 78.5 592.6 85.9 593.1 87.5 593.7 88.8 599.9 91.7 602.2 91.7 604.1 91.7 608.5 87.8 610.4 84.4L611.9 81.8 607 78.3C601.7 74.6 599.9 74.3 597.8 76.4ZM550.1 78.3C547.8 81.3 545.8 87.3 546.6 89.3 547.2 90.9 556.7 94 558.7 93.2 559.5 92.9 560.2 91.9 560.2 90.9 560.2 90 561.2 87.9 562.5 86.1 563.8 84.4 564.8 82.9 564.8 82.7 564.8 82.5 562.9 81.5 560.5 80.5 558 79.4 555.6 78 555.3 77.2 554.2 75.3 552.2 75.6 550.1 78.3ZM574.4 77C573 78.8 569.4 86.6 569.4 87.7 569.4 89.4 575.5 92.6 578.4 92.6 581.4 92.6 584.1 90.3 586.4 85.6L587.9 82.7 583.4 79.4C578.8 75.8 575.8 75.1 574.4 77ZM525.5 79.3C524.7 80 523.9 81.7 523.6 83 523.3 84.2 523 86.1 522.7 87.3 522.1 90.1 523.1 91.2 526.4 92 528 92.4 529.9 93.3 530.7 94.2 534.2 97.2 538.9 91.9 538.9 84.7 538.9 81.9 538.5 81.2 535.9 80.2 530.6 78.1 527 77.7 525.5 79.3ZM501.7 80.3C499.5 82.6 498.1 89.7 499.2 91.9 499.6 92.7 502.1 94.1 504.7 94.8 509.4 96.2 512 96 512 94.2 512 93.6 512.9 91.4 514 89.2 516.2 84.5 515.9 83.1 512.3 81.1 507.6 78.7 503.3 78.3 501.7 80.3ZM478.5 80.6C476.9 81.6 475 86.9 475 90.6 475 91.9 475.8 93 477.6 93.6 479 94.2 481.4 95.2 482.9 95.9 484.4 96.7 486.4 97 487.2 96.8 489.4 95.9 491.7 90.6 491.7 86.7 491.7 84 491.2 83.1 489.2 82.1 485.5 80.3 480.4 79.5 478.5 80.6ZM455.1 82.1C454.4 82.9 453.7 84.4 453.7 85.6 453.7 86.8 453.1 88.2 452.3 88.9 448.9 91.8 451.7 95.6 458.5 97.3 462.4 98.4 463.1 98.3 464.7 96.9 466.9 94.8 468.7 87.3 467.5 85.1 466.8 83.6 463.9 82.4 458.5 81.2 457.3 80.9 455.8 81.3 455.1 82.1ZM430.8 82.6C429.4 84.4 427.8 89.7 427.8 92.3 427.8 93.6 428.4 94.7 429.4 95.1 430.3 95.4 432.8 96.4 434.9 97.4 437 98.4 439.4 98.9 439.9 98.6 441.5 97.6 444.4 90.6 444.4 87.7 444.4 85.6 443.8 84.8 441.5 83.8 436.4 81.8 431.9 81.2 430.8 82.6ZM407.6 83.5C406.9 84.2 406.5 85.4 406.5 86.3 406.5 87.3 405.5 89.1 404.2 90.4 401.9 92.6 401.9 92.7 403.7 94.4 404.7 95.5 406.1 96.3 406.9 96.3 407.5 96.3 409.2 97.1 410.5 98.1 413.1 100.3 416 100.6 417.5 98.7 419 96.9 421.5 88.1 420.8 87 420.4 86.3 410.9 82.4 409.4 82.4 409 82.4 408.2 82.9 407.6 83.5ZM386.6 84.3C385.6 84.6 383.3 86.8 381.6 88.9L378.5 92.8 382.4 96.8C387.1 101.6 389.1 102.2 392 99.9 394.6 97.9 397.5 91.2 396.8 88.9 395.7 85.6 389.7 83 386.6 84.3ZM360.3 86.7C359.2 88.1 357.9 90.8 357.2 92.9 356.2 96.1 356.3 96.7 357.9 97.8 358.8 98.5 360.6 99.1 361.7 99.1 362.9 99.1 364.4 99.9 365.1 100.9 366.3 102.7 366.4 102.7 368.9 100.1 370.3 98.7 371.3 97.1 371.2 96.7 370.8 94.6 371.4 93.5 372.7 93.5 375.6 93.5 373 89.2 368.1 86.2 364.1 83.6 362.6 83.8 360.3 86.7ZM336.9 85.9C334.5 86.4 332.9 91.8 333.2 97.5 333.3 99.5 338.5 101.9 343 101.9 345.8 101.9 346.3 101.5 347.2 98.3 347.9 96.5 348.7 94.5 349.2 94 350.6 92.5 350.1 89.9 348 88.5 345.5 86.9 339.1 85.4 336.9 85.9ZM311.6 88.2C310.8 89.4 309.9 92.3 309.6 94.7 309 99.4 308.7 99.2 317 101.9 320.6 103 320.8 102.9 322.8 100.6 325.8 97.1 326.6 92.1 324.5 89.8 322.9 88.1 317.8 86.1 314.6 86.1 313.7 86.1 312.4 87 311.6 88.2ZM671.6 95.5C670.5 95.8 668.5 98.4 666.9 101.8L664.3 107.3 668.1 110.2C670.3 111.7 673.1 113 674.4 113 676.9 113 680.8 109 681.9 105.5 683.6 100.3 676.7 93.5 671.6 95.5ZM691.9 96.5C690.8 97.8 688.9 104.3 688.9 106.5 688.9 107.4 691.2 109 694.5 110.6 699.8 113 700.3 113.1 701.9 111.6 702.8 110.7 704.2 108.1 705 105.7L706.5 101.4 703 98.4C699.3 95.2 693.7 94.3 691.9 96.5ZM647.5 98.9C645.9 99.7 643.5 101.8 642.2 103.3L639.8 106.3 644.4 110.6C646.9 112.9 649.5 114.8 650.3 114.8 652.8 114.8 658.3 106.7 658.3 103.1 658.2 101.3 655.5 98.8 652.3 97.8 651.2 97.5 649.2 97.9 647.5 98.9ZM596.4 103.2C592.5 109.6 593.1 112 599 113.8 601.1 114.4 603.1 115.5 603.3 116.2 604.3 118.5 606.7 116.5 608.9 111.4 611.9 104.6 611.8 102.9 608.4 102.2 606.9 101.9 604.9 100.8 604.1 99.9 601.5 97 599.6 97.9 596.4 103.2ZM622.4 99.3C621.9 99.9 620.5 102.4 619.2 104.8 617 108.8 616.9 109.3 618.4 110.5 623.5 115 628.6 115.1 633 110.7 634.7 109 636.1 106.9 636.1 106.2 636.1 105.4 634.4 103.2 632.2 101.5 628.2 98.1 624.2 97.1 622.4 99.3ZM574.6 101.1C571.9 105.4 570.1 110.1 570.6 111.5 571 112.3 573.1 113.8 575.5 114.8 578.6 116.2 579.6 117.1 579.6 118.7 579.6 120.5 579.8 120.6 580.9 119.4 582.8 117.5 588 107.6 588 106 588 105.3 586.6 104.1 585 103.4 583.3 102.7 581.4 101.5 580.6 100.6 578.9 98.4 576.2 98.7 574.6 101.1ZM549.3 103C546.1 108.9 546.2 114.8 549.4 114.8 550 114.8 552 115.6 553.9 116.5 558.7 119 560.7 117.9 562.5 111.6 564.4 105.4 564 104.1 559.7 102.3 554.8 100.2 550.6 100.6 549.3 103ZM502.9 104.3C500.2 107.7 498.6 113.6 500.1 115.4 500.6 116.1 501.7 116.7 502.2 116.7 502.9 116.7 504.9 117.5 506.9 118.5L510.6 120.4 512.6 118.4C516.6 114.7 517.1 105.6 513.5 105.6 512.9 105.6 510.8 104.7 508.8 103.7 506.8 102.7 505.1 101.9 505 101.9 504.8 101.9 503.9 103 502.9 104.3ZM525.9 105.3C525.3 107.2 524.2 109.5 523.4 110.4 520.6 113.5 526.8 118.5 533.2 118.5 535.6 118.5 536.4 118 537.1 115.9 537.7 114.5 538.7 112.1 539.4 110.6 540.9 106.9 539.9 105.3 535 103.2 529.2 100.9 527.1 101.3 525.9 105.3ZM480.3 103.8C478.1 105.1 475.9 110.2 475.9 113.8 475.9 117.3 478.6 119.2 484.4 120L488.7 120.6 490.3 115.8C491.1 113.2 492.2 110.9 492.7 110.6 494 109.7 491.9 106.6 488.6 104.6 485.3 102.6 482.8 102.3 480.3 103.8ZM408.3 108.4C404.9 113.2 404.4 114.9 405.5 117.8 406.7 120.9 414 124.5 416.5 123.2 418.4 122.2 421.3 116.9 421.3 114.3 421.3 112.6 413.6 104.6 412 104.6 411.6 104.6 409.9 106.3 408.3 108.4ZM433.1 107.4C431.8 108.9 430.2 111.7 429.5 113.6 428.5 116.8 428.6 117.1 430.6 118.7 431.7 119.6 433.4 120.4 434.4 120.4 435.4 120.4 436.4 121 436.7 121.8 438 125.1 442.6 121.5 442.6 117.2 442.6 115.5 443.1 114.5 444.4 114.2 445.5 113.9 446.3 113.3 446.3 113 446.3 111.8 438.1 104.6 436.7 104.6 435.9 104.6 434.4 105.8 433.1 107.4ZM455.7 106.2C455.3 107.1 454.6 109 454.3 110.4 453.9 111.9 453 113 451.6 113.1L449.5 113.4 451.9 115.7C456.3 119.8 461.2 122.4 463.6 121.8 466.2 121.1 468.2 117 468.7 111.6L469 108.1 463.4 106.3C456.6 104.3 456.8 104.3 455.7 106.2ZM363.6 107.5C362.8 108.1 361 110.5 359.7 113 358.4 115.5 357 117.7 356.5 118.1 355.9 118.3 357.7 120.1 360.2 121.9 366.6 126.2 369.1 125.9 371.9 120.4 373.1 118.1 374.1 115.3 374.1 114.2 374.1 111.9 371.7 110.2 368.5 110.2 367.5 110.2 366.3 109.4 365.9 108.4 365.5 107 364.9 106.9 363.6 107.5ZM384.2 109.8C383.6 111.3 382.5 113.9 381.7 115.5 380.4 118.2 380.4 118.6 381.9 120.3 384.2 122.8 388.1 124.3 391.8 123.9 395.3 123.6 397 120.9 397.9 114.8 398.3 111.8 398.1 111.1 395.9 109.7 394.6 108.8 391.7 107.9 389.4 107.6 385.6 107.2 385.2 107.3 384.2 109.8ZM313.7 110.8C311.7 113.1 310.2 117.1 310.2 120.5 310.2 122.6 310.7 123.4 312.8 124.1 314.2 124.5 316.5 125.6 318.1 126.5 320.7 127.9 320.8 127.9 323.2 125.2 324.6 123.6 326 120.6 326.4 118.6 327.3 113.2 325.6 111.5 318 109.8 315.9 109.4 314.8 109.6 313.7 110.8ZM336.1 112.2C335.1 113.9 334.3 116.9 334.3 118.8 334.3 122 334.5 122.4 338.2 124.1 344.7 127 346 126.7 348.7 120.6 350.2 117.3 350.7 114.8 350.3 114 349.5 112.8 341.3 109.3 339.1 109.3 338.4 109.3 337.1 110.6 336.1 112.2ZM291 111.3C288.7 112.4 286.9 116.2 286.8 120.6 286.6 123.4 286.9 123.8 291.7 126 295.2 127.7 297.2 128.2 298.3 127.7 299.9 126.9 303.9 115.9 303.1 114.6 302.4 113.5 295.6 110.2 294.3 110.3 293.6 110.3 292.1 110.7 291 111.3ZM268 117.7L262.5 123.3 266.1 126.5C268.1 128.2 270.2 129.6 270.6 129.6 271.1 129.6 273.1 128 275.2 125.9 279.3 121.9 279.3 120.6 275.5 115.1L273.5 112.1 268 117.7ZM718.3 118.1C717.4 119.3 716.7 120.6 716.7 121 716.7 121.5 715.8 122.8 714.8 123.9 711.4 127.5 714.1 132.3 720.4 134.1 723.1 134.8 721.8 135 713.2 135.1L702.8 135.2 704.7 131.6C705.7 129.6 706.7 126.8 706.8 125.4 706.9 123.1 706.5 122.6 702.1 121 698 119.5 697 119.4 694.7 120.6 693.3 121.2 691.4 123.3 690.5 125.3 688.9 128.4 688.9 129 690.1 130.9 690.8 132 692.9 133.4 694.6 134 697.2 134.8 696.3 135 688.2 135.1L678.7 135.2 680.6 132.1C683.1 128.1 682.9 126.9 679.5 122.9 675.5 118 672.2 118.1 669.1 123.5 667.8 125.7 666 127.8 665.2 128.1 664.3 128.5 661.6 127.3 658.1 125 651.6 120.6 648 120.4 645.3 124.1 642.8 127.6 642.2 131.9 644 133.7 645.4 135.1 645 135.2 639.4 135.2 636.1 135.2 633.3 134.9 633.3 134.6 633.3 133.6 635.5 130.1 636.5 129.4 638.1 128.4 632.5 123.2 628.5 122 623.6 120.6 620.9 122.5 619.4 128.6 618.9 131.2 618.6 133.7 619 134.3 619.4 134.8 617.8 135.2 614.5 135.2L609.4 135.2 610.4 132C611.7 127.9 610.9 126.3 606.9 124.6 605.2 123.9 603.7 122.8 603.7 122.3 603.7 120.2 600.7 121.5 599.3 124.2 598.4 125.7 596.8 128.4 595.6 130.2 593.8 133.1 593.7 133.3 595.2 134.2 596.4 134.9 595.6 135.1 591.8 135.2 587.6 135.2 586.9 135 588 133.9 590 131.4 588.7 128.3 584.6 126.4 582.5 125.4 580.2 124 579.4 123.4 577.2 121.5 572.7 126.9 572.7 131.5L572.7 135.2 567.9 135.2C564 135.2 563.1 134.9 563.5 133.8 563.9 133.1 564.4 132.4 564.8 132.4 566.2 132.4 564.5 128.6 562.6 127.3 561.6 126.6 558.8 125.6 556.7 125.1 551.7 124 549.6 125.6 548.6 131.4L548 135.2 543.4 135.2C539.1 135.2 538.9 135.1 539.8 133.2 541.1 130.9 539.4 128.7 534.7 126.5 530.4 124.4 529.9 124.5 527.3 128.7 526 130.8 524.3 132.8 523.4 133.1 521.9 133.7 512.7 129.4 509.5 126.6 507.8 125 507.2 124.9 505.9 126 505.1 126.7 503.6 129.1 502.7 131.2 501 135.1 500.9 135.2 496.4 135.2 492.4 135.2 491.9 135 492.3 133.4 493 131 489.7 128.1 485.6 127.2 481.8 126.6 480.6 127.3 479.1 131.8 478.2 134.4 477.7 134.7 474.2 135 471.1 135.3 469.9 134.9 469 133.6 468.2 132.6 466 130.6 463.9 129.2L460.1 126.6 457.4 129.2C455.9 130.6 454.4 132.6 454.1 133.5 453.3 136 447.9 135.7 443.7 132.9 441.9 131.6 439.8 130.6 439.3 130.6 438.7 130.6 438 129.7 437.7 128.7 436.9 126 434.8 127.3 432.9 131.6 431.2 135.1 431.1 135.2 426.2 135.2 423.5 135.2 421.3 134.8 421.3 134.4 421.3 133.9 419.5 132.9 417.4 131.9 415.2 131.1 413.1 129.9 412.9 129.4 412.5 128.8 411 129.8 409.3 131.9 406.8 134.7 405.7 135.2 402.4 135.2 400.3 135.2 396.6 134.2 394 133 389.3 130.6 387.7 130.8 385.2 133.7 383.6 135.6 373 135.7 371.4 133.9 369.4 131.4 365.6 131.2 362.7 133.3 360.4 135.1 359.2 135.3 353.3 134.8 349.7 134.5 345.2 134.1 343.2 133.7 341 133.3 339.3 133.5 338.4 134.3 337.4 135.1 321.6 135.3 268.3 135.1L199.5 134.7 193.5 137.6C178.4 144.7 170.9 160.9 175.4 176.3 177.2 182.6 178.8 185.3 183.1 189.9L186.3 193.3 181.6 194.4C171.5 196.5 163 203.3 158.5 212.8 156.4 217.3 156 219.3 156 226.4 156 233.6 156.4 235.5 158.7 240.5 161.8 247.2 168.3 253.8 174.8 256.8 178.1 258.2 181.6 258.8 189 259.1L198.8 259.4 198.3 263.4C198 267.1 198.2 267.8 201.8 271.5L205.6 275.5 209.3 271.6C213.4 267.1 213.9 264.5 210.9 261.4L209 259.3 215.5 259.3 221.9 259.3 221.5 264.3C221.1 269.1 221.2 269.4 223.9 270.7 227.3 272.5 232.8 272.7 234 271 235.2 269.5 237.4 261.9 237.1 260.4 237 259.6 238.3 259.3 241.1 259.3L245.4 259.3 244.8 263.2C244.4 266.3 244.6 267.6 245.7 268.8 247.6 270.6 254.3 272.6 256.1 271.9 257.7 271.3 262.2 261.3 261.5 260.1 261.2 259.6 263.1 259.3 265.8 259.3L270.6 259.3 269 261.7C267.6 263.8 267.6 264.2 269 266.3 270.7 269 273.9 270.4 278.3 270.4 281.1 270.4 281.8 269.9 283 267.1 283.6 265.4 284.3 262.9 284.3 261.6 284.3 259.4 284.6 259.3 288.2 259.3 292.1 259.3 292.1 259.3 292.1 262.7 292.1 265.9 292.3 266.1 297.6 268.2 302.8 270.2 303.2 270.3 304.8 268.8 305.7 268 307 265.5 307.6 263.2 308.5 259.3 308.6 259.3 312.7 259.3 316.2 259.3 316.7 259.4 315.9 260.8 314.5 263.5 315.6 264.8 320.9 267.1 326.7 269.7 328.6 269.4 329.4 265.6 330.1 262 333 259.3 336.1 259.3 338.1 259.3 338.8 259.7 339.1 261.2 339.4 264 343.8 266.9 347.3 266.9 349.6 266.9 351.1 266.1 353.9 263.1 358.4 258.2 361.1 258.1 364.9 262.5 366.9 264.7 368.6 265.7 370.3 265.7 371.9 265.7 374.3 264.4 376.6 262.5 380.6 259.1 386.1 258 386.1 260.6 386.1 262.3 390.1 264.4 395.3 265.6 398.7 266.4 399.3 266.3 400.5 264.5 401.2 263.4 401.9 261.9 401.9 260.9 401.9 259.5 402.7 259.3 406.5 259.3 409.1 259.3 411.1 259.7 411.1 260.3 411.1 260.7 412.9 261.9 415.1 262.9 422.4 266.1 422.7 266.1 424 262.5 425.1 259.4 425.3 259.3 429.7 259.3 432.2 259.3 434.3 259.6 434.3 260.1 434.3 260.6 435.8 261.5 437.8 262 439.6 262.7 441.9 263.8 442.9 264.6 444.3 265.9 444.6 265.8 446.3 264.4 447.3 263.4 448.3 261.9 448.6 261 449.5 258.2 457.3 258.6 461.7 261.6 463.5 262.9 465.8 263.9 466.9 263.9 467.8 263.9 469.6 262.9 470.9 261.6 472.9 259.6 474.2 259.3 478.3 259.3 481.6 259.3 484.7 259.9 487 261.1 491.7 263.4 493.1 263.4 494.7 261 496 259.3 496.8 259.2 503.4 259.6 512 260.3 512.5 260.3 525.2 259.6 530.6 259.4 536.6 259.5 538.3 260.1 540.4 260.6 541.7 260.6 541.7 260.1 541.7 259.6 578.1 259.3 632.9 259.3L724.2 259.3 722.7 262C721.9 263.5 721.3 265.6 721.3 266.7 721.3 267.9 720.6 268.9 719.4 269.2 716.8 269.9 717.1 270.9 721.5 274.1 726.1 277.5 729.8 277.7 732.9 274.6 737.4 270.1 736.7 264.2 731.3 261.9 726.3 259.9 727.7 259.3 737.6 259.3 745.4 259.3 747.2 259.5 746.6 260.4 746 261 744.9 263.7 744 266.4 741.9 272.3 742.6 273.5 749.7 275.6 755.8 277.3 756.9 276.8 758.9 269.7 760.3 265 760.3 264.5 758.7 262.9 757.9 261.9 755.8 260.7 754.3 260.3 752 259.6 753.6 259.4 760.8 259.4L770.2 259.3 769.2 262.7C768.6 264.6 767.6 266.9 766.8 267.9 765.6 269.4 765.6 269.7 767.7 271.8 770.6 274.7 777 276.2 779.4 274.4 781.4 273.1 783.9 264.7 783 262.5 782.7 261.7 781.5 260.6 780.4 260.2 778.7 259.5 779.2 259.4 783.1 259.4 788.3 259.3 788.2 259.2 789.4 266.4 790.1 271.3 791 271.4 799.7 267.2 807.2 263.6 813.9 258 817.8 251.9 821.4 246.2 821.2 245.4 816.1 245.4 813.8 245.4 812 245.1 812.2 244.6 820.6 228.4 818.3 213.3 806 201.9 801.8 198.1 799.4 196.8 794 195.2L787.2 193.2 791.2 188.3C804.6 171.9 799.2 147.2 779.8 137.8L773.6 134.7 750.3 134.7C737.4 134.7 726.9 134.5 726.9 134.4 726.9 134.2 727.8 132.4 728.9 130.5L730.8 126.9 726.3 121.6C723.7 118.7 721.3 116.2 720.7 116 720.3 115.9 719.2 116.8 718.3 118.1ZM675.6 263.1C674.4 264.4 672.9 267.2 672.2 269.9 671.3 273.9 671.4 274.6 672.8 275.6 674.7 277 684.1 279.3 684.8 278.4 685.2 278.1 685.6 276.5 686 274.8 686.4 273 687.4 271.4 688.7 270.8 689.8 270.4 690.7 269.7 690.7 269.4 690.7 268.1 686.8 264.8 685.2 264.8 684.2 264.8 682.6 264 681.8 263 679.7 260.6 678.4 260.6 675.6 263.1ZM699.9 263.8C698.4 265.3 697.2 267.1 697.2 267.9 697.2 268.6 696.3 269.4 695.2 269.7L693.1 270.3 695.4 272.7C696.9 274.3 698.2 274.9 699.5 274.6 700.6 274.4 702.5 273.9 704 273.6 705.9 273.1 706.5 273.2 706.5 274.4 706.5 276.7 707.7 276.3 710.6 273.1 713.2 270.5 713.3 270.2 712 267.8 710.6 265.4 705.2 261.1 703.5 261.1 703.1 261.1 701.4 262.3 699.9 263.8ZM605.2 265.1C604.4 266.2 602.9 269.1 601.8 271.5 599.4 276.5 600 278.1 604.8 279.2 606.3 279.5 608.4 280.6 609.4 281.7 611.7 283.9 613.4 282.8 614.4 278.6 614.7 277.1 616 275.1 617.3 274.1L619.7 272.2 617.6 269.9C616.4 268.6 614.9 267.6 614.4 267.6 613.7 267.6 611.7 266.6 609.8 265.3L606.5 263.1 605.2 265.1ZM650.9 266.3C650.3 268.3 649.2 270.9 648.3 272.1 647 274.3 647.1 274.5 649.4 276.5 650.7 277.7 653.4 279.1 655.3 279.5 659.8 280.8 662.5 279.1 663.9 274 665.7 267.1 663.7 264.4 656.1 263.3 652 262.8 652 262.8 650.9 266.3ZM627.8 266.3C627.2 267.6 626.9 269.1 626.9 269.5 626.9 270 626 271.2 624.9 272.3 623.1 274.2 623.1 274.3 624.7 276.1 628.6 280.5 634.7 281.8 637.3 278.9 639.6 276.4 641.9 270.5 641.2 268.4 640.8 267.3 639 266.2 635.9 265.3 629.5 263.4 628.8 263.5 627.8 266.3ZM580.6 268.1C579.6 269.5 578.3 272.1 577.8 274 576.9 276.9 577 277.5 578.8 278.9 579.9 279.8 581.6 280.6 582.5 280.6 583.4 280.6 584.7 281.4 585.4 282.3 587 285 589.3 283.3 592.3 276.9L594.9 271.6 590.6 268.7C585.6 265.1 583.1 265 580.6 268.1ZM555.6 268.4C552.8 273.6 553 280.6 555.8 280.6 556.5 280.6 558.7 281.4 560.6 282.4L564.4 284.4 566.8 281.6C569.3 278.9 571.1 272.2 569.9 270.3 567.8 266.9 557.2 265.5 555.6 268.4ZM487.1 268.9C486.7 269.4 485.6 271.7 484.7 273.8 483.9 275.9 482.6 277.9 481.9 278.1 479.6 279 481.9 282.1 485.6 283.3 487.4 283.9 489.6 285.4 490.6 286.7 492.2 288.7 492.6 288.8 493.8 287.5 494.6 286.8 495.5 284.9 495.8 283.3 496.2 281.9 497.5 279.7 498.8 278.7 501.1 276.9 501.1 276.8 499.5 275 496.7 271.9 488.1 267.6 487.1 268.9ZM532.3 271.4C531.7 273.4 530.3 275.7 529.3 276.5 527.3 277.9 527.3 277.9 529.9 280.1 532.5 282.4 538.8 284.6 541.5 284.1 543.3 283.7 547.2 277.1 547.2 274.4 547.2 272.8 546.1 271.7 542.6 269.9 535.8 266.5 533.7 266.8 532.3 271.4ZM511.2 271.2C504 279 504.2 278.5 506.1 280.7 507.1 281.8 509.3 283.2 510.9 284 513.4 285 514.4 285 517 283.9 518.7 283.2 521 281.3 522.1 279.8L524.2 276.9 520.8 273.3C516.5 268.4 514.3 268 511.2 271.2ZM439.4 271.5C435.9 273.4 433.4 282.9 436.1 284.3 436.9 284.7 439.4 285.9 441.7 286.9L445.7 288.9 447.9 286.9C449.9 284.9 451.9 280 451.9 276.7 451.9 273.5 442.7 269.6 439.4 271.5ZM460.2 276.4C459.1 279.8 458.5 282.9 458.9 283.3 459.4 283.7 461.3 284.5 463.2 285.2 465.1 285.7 466.7 286.9 466.7 287.6 466.7 288.3 467.2 288.9 467.9 288.9 469.5 288.9 471.7 286.4 473.1 282.6 473.8 281 474.7 279.6 475.2 279.6 475.6 279.6 475.9 278.5 475.7 277.1 475.4 274 471.9 271.6 466.6 270.8L462.2 270.2 460.2 276.4ZM414.5 273.9C412.5 276.1 411 280.6 411.6 282.5 411.9 283.4 414.2 285.6 416.7 287.4L421.2 290.6 424.9 286.4C429.2 281.6 429.6 279 426.7 276.1 422.5 272.2 416.9 271.2 414.5 273.9ZM278.4 273.8C277.9 274.7 266.1 322.5 265.2 327.1 264.6 330.3 264.4 330.5 263.1 329.3 262.2 328.5 259.2 327.2 256.1 326.4 251.6 325.1 250.6 325 249.5 326 248.1 327.5 246.3 336.5 247.1 337.8 247.4 338.2 249.6 339.5 252.1 340.6 254.5 341.7 256.5 343.1 256.5 343.9 256.5 346.4 259 344.4 260.6 340.6 261.6 338.7 262.4 337.1 262.6 337.3 263.2 337.9 259.9 350.6 258.9 351.1 258.3 351.5 257.5 350.9 256.9 349.9 256 348.2 255.8 348.2 253.1 351.1 248.6 355.9 247.8 358.1 249.4 360.6 250.3 361.9 252.1 363.6 253.7 364.5 256.2 365.9 256.6 366.6 256.1 369 255.7 370.5 254.7 372.6 253.7 373.6 252.7 374.7 251.9 376 251.9 376.5 251.9 376.9 250.8 378.9 249.5 380.7L247.2 384.2 250 385.6C251.9 386.7 252.7 387.6 252.4 388.7 252.1 389.5 251.3 394.3 250.5 399.1 249.6 403.9 248.6 408.7 248.1 409.7 247.7 410.7 247 413.9 246.8 416.7 246.5 419.4 245.4 427.5 244.3 434.4L242.4 447.1 237.9 446.6C233.5 446.1 233.2 446.2 229.6 449.8 226.2 453.2 226 453.7 226.9 455.9 228.4 459.1 231.4 460.9 236 461.7 239.2 462.1 239.8 462.6 239.8 464.4 239.8 468.1 238.9 469.4 236.5 468.9 233.5 468.1 230 471.9 229.2 476.8 228.4 481.5 229.3 482.8 234.6 484.3 238.5 485.4 238.8 485.6 240.2 490.6 243.2 501.7 244.3 509.3 247.2 544 249.6 572.4 255.3 618.1 257.1 624.4 257.5 625.9 257.2 626.1 255 625.6 250.6 624.4 242.8 618.8 234.5 610.6 230.4 606.5 226.7 603.3 226.4 603.5 226.1 603.8 225.9 606.5 225.9 609.4 225.9 615.6 225.5 615.8 220 613 218 612 216.1 611.4 215.6 611.6 214.4 612.4 211.1 620 211.1 622.3 211.1 624.2 212 625.1 216.3 627.1 219.2 628.6 221.6 629.6 221.8 629.4 221.9 629.3 222.6 628.1 223.4 626.9 225 624.6 225 624.7 225 631.3 225 634.9 224.8 638 224.5 638 224.3 638 222.5 637.3 220.6 636.6 216.7 634.9 214.8 635.3 214.8 637.9 214.8 638.9 213.6 641.2 212 642.9L209.3 646 214.7 649.4C217.8 651.3 221 652.8 222.1 652.8 223.8 652.8 224.1 653.3 224.1 656.6 224.1 659.9 223.9 660.3 222.2 659.7 221.2 659.4 219.5 659.4 218.5 659.7 216.2 660.5 213 666.6 213 670.3 213 672.6 213.4 673.2 215.6 673.7 220.6 674.8 221.3 675.2 221.3 676.6 221.3 677.4 221.9 677.8 222.6 677.5 224 676.9 225 679.4 225 683.1 225 685.6 223.6 685.7 221.6 683.3 219.3 680.6 218.7 680.9 216.6 685.8 215.6 688.3 214 690.8 213.1 691.5 211.8 692.6 211.9 693.1 215.7 696.4 219.1 699.4 220.5 700 223 699.7 225.6 699.4 225.9 699.7 225.9 701.9 225.9 703.1 226.2 705.2 226.6 706.4 227 708.1 226.9 708.4 225.4 708.1 219.4 706.3 218.7 706.3 217.2 708.5 216.5 709.6 215.6 712.8 215.2 715.4L214.6 720.2 219.4 721.8C222 722.6 224.4 724 224.7 724.7 225.2 726 225.5 725.9 226.5 724.5 228 722.6 228.3 723.2 229 729.4 229.5 734 228.3 734.5 223.9 731.4 220.6 729 219.6 729.7 217.2 735.9 215.1 741.5 215.3 744.4 217.7 744.4 218.7 744.4 220.8 745.3 222.3 746.4 225.6 748.7 227.5 748.1 228.9 744.4 229.4 742.9 230 741.8 230.3 742 230.6 742.2 231.1 745.5 231.6 749.3 232 753 232.6 756.9 232.9 758.1 233.3 760.2 233.2 760.1 229.5 757.4 227.4 755.9 224.7 754.6 223.5 754.6 221.2 754.6 218.5 757.8 218.5 760.4 218.5 761.4 217.8 762 216.7 762 214.1 762 214.4 763 218.1 766.9 222.6 771.5 225.6 771.5 230 767.1 231.9 765.4 233.4 763.9 233.6 763.9 233.8 763.9 234.3 766.3 234.6 769.2 235 772 237.3 786.2 239.8 800.6 244 824.3 244.4 827.1 243.3 831.4 242.2 836.2 243.1 838.9 245.8 838.9 246.5 838.9 247.3 840.6 247.6 843.1 248.1 846.4 247.9 847.7 246.4 849.7 245.4 851.1 244.4 854.2 244.3 856.5 244 860.7 244.6 861.5 251 864.1 251.3 864.3 251.9 865.9 252.2 867.8 252.8 871.1 252.7 871.3 250.6 871.3 247.7 871.3 245.8 873.9 244.5 879.6 243.3 884.9 244.5 886.4 251.3 887.9 256.4 889 257.3 890.1 257.4 894.7 257.4 896.1 256.8 896.4 253.1 896.1 249.2 895.8 248.5 896.1 247.5 898.2 246.9 899.5 246.3 902.4 246.1 904.6 245.8 908.7 245.9 908.8 249.5 910 251.6 910.6 253.8 911.9 254.4 912.7 255.5 914.1 255.6 914.1 257.4 912.5 258.4 911.6 259.3 910.2 259.3 909.4 259.3 906.3 260.3 909.4 261.5 916L262.7 923 260.1 922C258.7 921.6 257 920.6 256.4 919.8 255.8 919.1 254.4 918.5 253.1 918.5 251.3 918.5 250.5 919.4 249.1 922.4 248.1 924.5 246.5 926.9 245.4 927.8 243.3 929.4 243.3 929.4 247.8 931.9 250.3 933.3 253.8 935.4 255.6 936.4 257.3 937.4 258.5 938 258.1 937.6 257.8 937.1 258.1 936.2 258.8 935.5 259.5 934.8 260.6 932.5 261.1 930.6 261.7 928.5 262.5 926.9 262.9 926.9 263.3 926.9 264.3 930.4 264.8 934.5L266 942.3 272.8 945.6C276.6 947.5 279.5 948.6 279.4 948.1 279.3 947.7 281.5 945.8 284.3 944.2 288.7 941.5 293 936.4 319.3 902.8 335.6 881.7 349.7 863.8 350.5 863.1 351.5 862 352 861.9 353.1 862.9 353.9 863.5 354.6 863.6 354.9 863.2 355.8 861.9 360.2 833.9 361.4 822.5L362.5 811.3 372.7 818.6C400.6 838.7 426.3 851 452 856.7 463 859.1 504.3 860.1 518.2 858.3 549.7 854.4 579.4 840.8 614.2 814.6 621.4 809.3 627.6 805.1 627.9 805.4 628.1 805.7 628.9 809.7 629.5 814.4 631.9 832.5 636.4 854.7 637.6 854.3 638.2 854 649.4 870.2 666.2 895.6 681.3 918.5 693.9 937.8 694.1 938.3 694.4 938.9 698.7 941.6 703.8 944.4 711 948.3 713 949.8 712.7 951 712 953.3 727.6 945.6 728.3 943.2 728.7 942 729.5 941.6 731 941.9 732.8 942.2 733.5 941.6 735 938.5 738 932.5 738.3 930.2 736.4 928.5 735.5 927.7 733.9 926.9 732.9 926.7 731.3 926.4 731.1 925.7 731.3 922.2 731.5 920 732.4 917.1 733.4 915.9 734.4 914.6 735.2 912.9 735.2 912 735.2 911.1 735.8 909.9 736.6 909.3 738.5 907.7 738.3 905.8 736.1 905.1 733.8 904.4 733.8 902.9 736 887.5 737 880.8 738.1 872.7 738.4 869.2 738.8 865.7 739.4 863 739.7 863 740 863 742.1 864.4 744.4 866.2 751.6 871.9 754.3 871.6 756.9 864.4 759.3 858.3 758.6 856.3 753.8 854.5 751.5 853.7 749.4 852.3 749.1 851.4 748.5 849.9 748.4 849.9 746.9 851.3 746.1 852.1 745 854.5 744.4 856.6 743.5 859.9 741.4 862 740.2 860.8 739.7 860.5 741.4 845.2 742.1 842.9 742.3 842.2 743.6 842.8 745.5 844.5 747 846 748.6 847.2 749 847.2 749.4 847.2 751.4 845.7 753.5 843.9 759.3 839 758.9 835.3 752 830 747.9 826.9 747.9 826.9 745.9 828.6L744 830.5 744.3 825.8C744.6 821.2 745.2 820.6 746.9 822.3 749.2 824.5 752.8 822.4 754.7 817.8 755.7 815.5 757 813.1 757.6 812.8 759.3 811.9 756.9 809.4 751.7 806.9 747.7 804.8 747.2 804.3 747.2 801.5 747.2 798.9 747.5 798.4 749 798.8 751.2 799.4 754.4 796 755.6 791.8 756.9 786.6 756.7 785.4 753.8 783.8L751.1 782.4 752.9 777.8C754.5 773.2 756.6 753.6 756.4 742.6L756.3 738.4 755.1 741.7 753.9 744.9 753.8 742.1C753.7 740.6 754.2 733.3 754.7 725.9 755.2 718.6 755.9 704.4 756.4 694.3 756.8 684.2 757.3 675.7 757.6 675.5 758.1 674.8 764.9 677.6 766.7 679.3 767.9 680.3 768.6 679.9 771.6 676.2 776.1 670.6 775.9 668 770.8 665.1 765.4 661.9 762.2 662.2 760.7 665.9 758 673 757.9 672.9 757.4 662.5 757.1 656.9 756.9 652.2 757 652 757 651.9 759.7 652.7 763 653.8 766.1 654.8 769.3 655.5 769.9 655.2 770.6 655 771.4 653.2 771.7 651.4 772.1 649.1 773 647.8 774.2 647.5 777.8 646.6 775.5 643.1 769.7 640.8 768.1 640.2 766.6 639.1 766.3 638.4 765.7 636.9 762.7 637.6 760.7 639.7 759.9 640.6 758.7 643 758 645 756.7 648.5 756.6 648.4 756.5 638.4 756.3 627.5 755.4 612.2 753.8 593.5 753.2 587.1 751.9 571.3 750.8 558.3 749.8 545.4 748.6 533.5 748.2 532L747.6 529.4 743.7 534.4C741.6 537.2 738.4 542.6 736.7 546.4L733.4 553.2 734 542.6C734.3 536.5 735 530.8 735.7 529.3 736.5 527.7 737.7 520.6 738.4 513.5 739.3 506.3 740.6 497.5 741.4 494 742.2 490.4 743 484 743.1 479.7 743.1 475.3 743.6 471.8 744.1 471.6 745 471.3 744.8 421.6 744 418.7 743.7 418.1 742.7 417.6 741.6 417.6 740.2 417.6 739.8 417.2 740.2 416.1 742.8 409.3 741.9 405.9 737 404.6 735 404.1 732.9 403.9 732.4 404.2 731.9 404.4 731.5 403.9 731.5 402.9 731.5 397 718.8 337.1 709.6 299.8L703.5 275 701.1 275.6C699.7 275.8 698.1 276.2 697.6 276.4 696.9 276.6 697 278.6 698.3 283.1 701.4 293.8 702.6 301.6 704.6 323.1 706.8 345.6 707.7 350.9 714.2 376 718 390.6 722.2 411.6 722.2 415.6 722.2 417.1 718.1 417.2 667.4 416.9 637.2 416.8 603 416.9 591.2 417.5 572.3 418.2 569.1 418.6 562.3 420.7 553.1 423.7 544.4 429.4 540 435.3L536.7 439.7 520.9 439.3C506.9 438.8 494.4 439.4 475.5 441.3L469.9 441.9 467.2 436.7C462.1 426.7 449.6 418.2 435.5 415.3 423.2 412.8 381.6 411 323.1 410.5 292.3 410.2 266.9 409.8 266.8 409.6 266 408.9 287.1 285.8 289 280.2 290.4 275.8 290.5 274.4 289.5 273.9 288.1 273 279 273 278.4 273.8ZM360.2 425.9C395.7 427 421.9 428.5 429.6 429.7 441.2 431.6 449.9 436.9 454.3 444.6 456.9 449.4 456.9 449.8 456.9 463 456.8 474.8 456.4 477.7 453.9 487 445.2 520.2 433 538.3 411.2 550.6 398.9 557.6 386.2 561 369 561.8 326.8 563.7 291.5 544.1 280.5 512.4 276.1 499.8 274.4 469.8 277.2 456.4 278.7 449.4 282.1 442.1 285.4 439.2 292.4 432.7 305.6 427.2 317.9 425.9 327.5 424.9 329.1 424.9 360.2 425.9ZM679.9 434.5C694 438.6 702.2 445.2 705.4 454.7 711.5 473.2 709.9 504.4 702.2 520.2 685.6 554.4 631.8 569.7 594 550.9 575 541.6 562.6 525.9 554.4 500.8 549.4 485.7 547.8 476.9 547.7 464.4 547.7 454.2 547.9 452.8 550.1 448.6 553 443 559.3 438 566.5 435.6 574 433.2 589.4 432.6 635.2 432.9 668.9 433 675.3 433.2 679.9 434.5ZM528.4 455.2L531.2 455.7 531.8 466C533.4 498.9 548.1 534.4 566.9 551.5 590.3 572.4 623.7 579.7 657.5 571.2 692.3 562.4 716.9 538.3 722.7 507.3 723.4 503 724.3 493.4 724.4 486.3 724.5 475.7 724.8 473.1 725.8 473.1 726.9 473.1 727 477.2 726.5 499.7L725.9 526.4 717.7 543.1C698.8 581.8 680.4 608.8 657 631.9 639.3 649.6 622.8 660.6 604 667.6L596.9 670.2 589.4 663.9C550.6 631.5 501.6 619.6 455 631.5 432 637.4 408.7 649.5 391.8 664.4 384.7 670.6 384.4 670.6 371.6 665 333.1 648.4 296.2 605.8 264.9 541.7L256.9 525.5 256.6 516.2C256.2 506.3 258.1 471.9 259.2 467.8 259.6 466.3 260.1 470.8 260.5 479.6 261.9 514.2 268.7 532.1 286.9 549.2 294.7 556.7 299.2 559.7 309 564.7 344.5 582.5 390.5 581.4 422.2 561.9 431.2 556.4 444.8 543.3 450.4 534.9 462 517 470.9 489.4 472.8 465.1L473.4 456.7 481.9 455.7C491.5 454.8 524.4 454.4 528.4 455.2ZM740.5 604.6L744.4 614.4 740.6 618C736.8 621.3 730.6 625 726.3 626.3 724.4 626.9 724.4 626.9 725.5 620.2 726.1 616.5 727.3 607.8 728.2 600.9 730.6 582.2 730.2 582.8 733.6 589.4 735.2 592.4 738.2 599.3 740.5 604.6ZM555.6 685.7C555.6 686 554 689.3 552.1 693 545.4 705.9 532.8 715.7 517.5 720.1 508.8 722.5 476.4 722.5 467.1 720.1 456.7 717.3 444.8 711.1 438 704.8 432.7 700 425 689.2 425 686.6 425 685.9 446.6 685.6 490.3 685.4 526.2 685.2 555.6 685.4 555.6 685.7ZM602.7 692.1C612.2 694.4 620.8 699.5 629.3 707.9 637.6 716.1 639.8 720.2 642 730.9 644.6 743.6 643.7 749.6 638.1 755.7 630.7 764 619.2 768.1 605.6 767.4 598.7 767.1 596.6 766.6 590.4 763.6 571.3 754.5 559.9 739.1 559.9 722.2 559.9 699.6 578.6 686.5 602.7 692.1ZM363 462.2C355.6 465.9 351.6 471 349.9 478.2 347.7 488.3 352.1 498.3 361.5 504.2 365 506.3 367.3 506.9 372.2 507.2 380.1 507.7 383.9 506.5 389.2 501.8 399.1 493.1 400.8 479.2 393.2 469.3 388.6 463.1 382.8 460 375.3 459.5 369.5 459.2 368.4 459.4 363 462.2ZM389.3 466.8C394.2 470.6 391.4 478.1 385 478.1 379.1 478.1 376.5 470.4 381.1 466.8 382.5 465.6 384.3 464.8 385.2 464.8 386.1 464.8 387.9 465.6 389.3 466.8ZM602.5 460.6C594.4 463.6 587.8 471.9 586.6 480.6 584.6 494.4 596.3 507.4 610.6 507.4 620.3 507.3 627.8 502.4 632 493.1 637.4 481.7 632.4 467.8 620.8 461.9 616.2 459.4 607.2 458.8 602.5 460.6ZM626.3 466.8C631.2 470.6 628.4 478.1 622 478.1 616.3 478.1 613.8 471.3 618.1 467.1 620.8 464.4 623.1 464.3 626.3 466.8ZM390.1 274.3C389.4 275 388.5 277.5 388 279.9 386.8 285.6 387.8 287.6 392.4 288.8 399.4 290.6 399.4 290.6 402.1 285 403.6 282 404.6 279.1 404.4 278.3 403 274.6 392.2 271.7 390.1 274.3ZM366.2 276.3C365.3 277.6 364.4 280.6 364.2 282.8L363.7 286.9 368.4 288.4C371 289.3 373.3 290.4 373.6 290.8 374.5 292.2 377.6 290.1 379.2 287 379.9 285.6 380.6 282.9 380.6 281.1 380.6 277.1 377.9 275 371.9 274.4 368.2 273.9 367.6 274.2 366.2 276.3ZM342.6 278.4C341.9 280.4 340.9 282.9 340.2 283.9 339.2 285.6 339.3 286.1 341.1 287.9 343.5 290.1 348.7 291.3 352.2 290.4 353.8 290 354.9 288.6 356 285.6 357.5 281.8 357.6 281.4 356.1 279.2 354.3 276.4 351.2 275 346.8 275 344 275 343.5 275.4 342.6 278.4ZM202.1 281.7C198.6 285.6 198 287.3 199.2 290.6 200.3 293.5 204.5 298.1 206.1 298.1 207.6 298.1 213 292.8 213.9 290.4 214.8 287.8 213 284.4 208.9 281.2 207.1 279.8 205.5 278.7 205.3 278.7 205.2 278.7 203.7 280.1 202.1 281.7ZM249.2 281.1C248.1 282.4 246.9 284.9 246.3 286.7 245 290.5 245.9 292 249.7 293.1 251.1 293.3 253.2 294.4 254.4 295.5L256.8 297.2 258.5 294.7C259.4 293.2 260.2 291.3 260.2 290.2 260.2 289.1 261 287.9 262 287.4 263.8 286.6 263.9 286.5 262.4 284.4 260.9 282.3 254.5 278.8 252.1 278.7 251.6 278.7 250.2 279.8 249.2 281.1ZM224.3 280.8C222.6 282.8 221.3 290 222.3 291.8 222.8 292.7 224.4 293.6 226.1 294 227.8 294.4 229.9 295.3 230.8 296.1 232.3 297.4 232.6 297.3 234.6 295.5 237.4 292.9 239.4 285.9 238 283.4 236.3 280.1 226.4 278.2 224.3 280.8ZM770 284C769.4 285.5 768.2 288.1 767.8 290.1 766.9 293.3 766.9 293.9 768.9 295.8 771.4 298.3 777.4 299.8 779.5 298.4 780.3 298 781.3 296.3 781.8 294.8 782.2 293.3 783.2 291.4 784.1 290.6 786.3 288 783.5 284.7 777.4 283 771.1 281.1 771.6 281 770 284ZM748.5 283.1C746.9 284.2 743.2 293.3 743.8 294.8 744.7 297.1 749.1 299.4 752.9 299.4 756.5 299.5 756.6 299.4 758.8 294.1 760.6 289.8 760.8 288.2 760 287.2 757.8 284.6 750.4 281.9 748.5 283.1ZM723.1 285.5C723.1 286.1 722.3 288.2 721.3 290.3 720.3 292.3 719.4 294.4 719.4 295 719.4 298.1 730.1 302.3 733.1 300.4 735.2 299.1 737.2 290.1 736 287.9 734.5 285 723.1 282.9 723.1 285.5ZM606.6 289.9C604.5 291.5 602.5 293.8 602.2 295.1 601.6 297.5 603.2 301.5 605.1 302.2 606.5 302.8 616.9 299.1 617.8 297.7 618.8 296.4 617.7 293.4 615.4 290.9 611.9 287 610.7 286.9 606.6 289.9ZM582.1 290.6C580.7 291.9 579.2 294.4 578.6 296.2 577.7 298.8 577.8 299.5 579.4 301.7 580.3 303 582.8 304.5 584.7 305.3 591 307.5 593.6 305 593.9 296.5 594 293.5 593.7 293.1 590.3 292 588.2 291.3 586.1 290.1 585.6 289.4 584.7 288.2 584.2 288.4 582.1 290.6ZM535 293.2C533.7 294.7 532.4 296.7 532.2 297.7 532 298.7 531.3 299.5 530.6 299.5 528.1 299.5 528.7 301.7 532.1 304.4 538.1 309.2 539.2 309.1 544.7 303.8L549.5 299.1 545.2 294.9C542.8 292.6 540.1 290.7 539.1 290.7 538.1 290.7 536.3 291.9 535 293.2ZM557.5 293.1C552.6 297.2 552.4 298.3 556.1 302.7 560.9 308.2 563.9 307.9 569.1 300.8 570.8 298.3 572 295.8 571.7 295.3 570.9 294 564 290.8 561.9 290.7 561 290.7 559.1 291.9 557.5 293.1ZM488.2 293.1C486.3 294.4 485 297.5 483.8 303.3 483.3 305.9 483.5 306.3 486.9 307.8 492.3 310.3 495.4 309.5 497.9 305.1 501 299.6 500.5 297 495.6 295.6 493.4 294.8 491.7 293.7 491.7 293 491.7 291.3 490.7 291.3 488.2 293.1ZM509.2 295.8C508.1 298.1 507.4 301.4 507.6 303.1 507.9 305.6 508.4 306.2 512.1 307.6 517.6 309.5 519.9 309 521.3 305.3 521.9 303.6 522.9 301.2 523.6 299.8 524.9 297.2 524.9 297.2 519.3 294.4 516.2 293 513.1 291.7 512.3 291.7 511.6 291.7 510.2 293.5 509.2 295.8ZM464.1 293.8C463.5 294.4 462.8 296.1 462.5 297.5 462.1 298.9 460.7 300.8 459.5 301.9 456.6 304.2 457.4 305.4 464.7 309.3L469.9 312.1 471.9 309.6C473.1 308.2 474.6 305.5 475.6 303.5 477.5 299.3 476.6 297.7 471.3 296.3 469.4 295.7 467.5 294.7 467.2 294 466.6 292.3 465.4 292.2 464.1 293.8ZM417.9 295.4C414.6 296.7 411.3 305.3 412.6 308.8 413 309.5 415.5 310.8 418.3 311.7 423.4 313.1 423.5 313.1 425.2 311.1 426.1 310 426.9 308.3 426.9 307.3 426.9 306.4 427.7 305.1 428.7 304.4 431.3 302.6 430.4 300.6 425.2 297.2 420.6 294.2 420.7 294.3 417.9 295.4ZM439.4 296.5C438.6 297.6 438 299.3 438 300.2 438 301 437.2 302.1 436.4 302.6 434.9 303.4 434.9 303.6 436.4 305.9 438.7 309.4 442.2 311.4 444.8 310.7 446.8 310.3 454.5 301.3 453.6 300.6 449.4 297.6 443.8 294.4 442.5 294.4 441.6 294.4 440.2 295.4 439.4 296.5ZM391.2 298.5C389.9 300.6 388 305.9 388 307.7 388 308.1 390.7 309.6 394.1 311.2 399.7 313.7 400.4 313.8 401.9 312.5 402.8 311.7 404 309.2 404.6 307 406.1 301.5 404.9 299.5 398.9 297.7 392.8 295.9 392.9 295.9 391.2 298.5ZM251.4 300.8C247.7 302.4 245.9 305.5 245.8 310.4L245.8 315.2 251.8 317.3C258.5 319.7 259.4 319.4 261 313.9 261.7 311.5 262.7 310.2 263.6 310.2 265.8 310.2 260.6 304.8 258 304.4 256.9 304.3 255.6 303.2 255.1 302 254.1 299.8 254.1 299.8 251.4 300.8ZM203.3 305.6C198.1 311.8 198.5 315.7 204.5 320.1L207.3 322.2 211.1 318.7C216 314 216 311.2 211.4 307.7 209.4 306.3 207.4 304.5 206.9 303.8 206.1 302.8 205.4 303.1 203.3 305.6ZM226 304.4C225 305.3 223.6 308 223 310.5 221.6 315.7 222.2 316.6 229.1 318.9 233.5 320.4 233.7 320.3 235.7 318.4 238.1 316.3 239.9 310.2 239.2 307.3 238.1 303.2 229.6 301.4 226 304.4ZM181.6 310.9C181 313.8 180.3 317.1 180 318.2 179.2 321.3 183.5 322.9 186.8 320.7 189.3 319.2 191.7 314.3 191.7 310.7 191.7 308.8 191 308.2 187.8 307.3 185.6 306.8 183.5 306.1 183.2 305.9 182.9 305.7 182.1 308 181.6 310.9ZM748.4 307C747.8 307.3 746.6 309.8 745.7 312.6 743.8 319.4 745.1 321.6 751.9 323.1 754.6 323.6 756.9 324 756.9 323.9 757 323.7 758.3 321.1 759.7 318.1 762.5 312.2 762.3 310.6 758.2 308.6 755.5 307.3 749.9 306.4 748.4 307ZM770.8 308.3C770 309.3 769 311.9 768.8 314.3L768.2 318.4 773.7 320.8C776.7 322.1 779.6 323 780.2 322.8 782.2 321.9 784.3 318.1 784.8 313.6 785.5 309.4 785.4 309.3 782.1 307.9 777.4 305.9 772.9 306.1 770.8 308.3ZM723.6 310.4C723.2 311.6 722.3 313.9 721.6 315.6 720.1 318.8 721 321.3 723.8 321.3 724.5 321.3 726.2 322.4 727.5 323.7 730.7 326.9 732.4 325.8 734.3 319.6 735 317 735.9 314.6 736.4 314.3 737.8 312.9 736.9 311.9 732.8 310.2 727.1 307.7 724.4 307.8 723.6 310.4ZM513 314.8C513 315.5 511.9 317.4 510.6 319.2 509.3 320.9 507.9 323.4 507.5 324.8L506.9 327.2 501.1 321.9C495.8 317.1 494.4 316 494.4 317 494.4 317.9 510.6 330.9 511.9 331.2 521.3 332.9 522.2 332.6 522.2 328 522.2 326.9 522.9 325.6 523.6 325.4 524.4 325 525 323.8 525 322.5 525 320.7 524.2 319.9 520.6 318.3 518.1 317.3 515.5 315.8 514.6 315 513.3 314 513 313.9 513 314.8ZM534.3 318.1C533.7 319.4 533.3 320.8 533.3 321.3 533.3 321.8 532.7 322.8 531.9 323.6 530.5 325 530.5 325.3 532.5 327.4 538.5 333.9 543.8 333.4 547.3 326.1 549.2 322.3 549.3 321.7 548.1 319.5 546.6 317 544.1 316 538.6 315.8 535.6 315.7 535 316.1 534.3 318.1ZM464.5 319C463.7 319.7 462.9 321.6 462.5 323.1 462.2 324.5 461.3 326.3 460.6 326.9 458.5 328.6 459 329.6 462.8 331.2 464.6 331.9 466.9 333.1 467.7 333.9 468.9 335 469.4 334.8 471.5 332.6 472.8 331.2 474.1 328.8 474.4 327.3 474.8 325.7 475.3 323.9 475.6 323.1 475.8 321.9 474.7 321 471.4 319.5 465.9 317.2 466.2 317.2 464.5 319ZM440.2 322.9C438.7 324.8 436.9 326.9 436.2 327.6 434.9 328.7 435.1 329.2 437.8 331.6 441.4 334.8 446.1 335.2 450.1 332.3 454.9 328.9 455.1 327.4 451.3 323.1 446.8 318.1 443.7 318.1 440.2 322.9ZM228.5 326.6C227.1 326.9 223.1 335.4 223.1 337.9 223.1 339 235 343.5 236.5 343 239.3 341.9 241.5 332.9 239.6 330.3 238.3 328.5 231 326 228.5 326.6ZM203.3 329.5C199.2 333.9 199.8 338.6 205.6 344L208.4 346.8 212.1 342.9C217 337.6 216.9 334.6 212 330.2 210 328.3 207.8 326.9 207.1 326.9 206.5 326.9 204.7 328.1 203.3 329.5ZM178.2 331.9C177.4 333.7 176.7 336.8 176.6 338.6 176.4 341.9 176.5 342 180.8 343.2 183.2 344 185.2 344.9 185.2 345.5 185.2 347 187.6 346.3 189.6 344.2 191.6 342 193.7 334.9 193 332.9 192.3 331.3 188.4 329.6 183.7 329 179.7 328.4 179.6 328.5 178.2 331.9ZM773.1 330.6C772.7 331.5 772.2 333 772.2 333.8 772.2 334.6 771.2 336.2 769.9 337.4L767.6 339.6 770.8 342.4C774 345.3 779.5 347 781.4 345.8 783.1 344.8 786.2 338 785.9 335.9 785.7 334.6 783.9 333.2 779.9 331.5 774.4 328.9 774.1 328.9 773.1 330.6ZM725 333.9C721.1 340.1 721.5 343.2 726.4 346 732.6 349.5 735.5 348.6 736.7 342.8 737.1 340.7 737.8 339.8 739 339.8 742.6 339.8 740.6 336.7 735.6 334.6 733.6 333.8 731 332.3 729.9 331.3L727.9 329.4 725 333.9ZM796.8 331.3C795.3 332.2 793.3 334.2 792.6 335.6 791.3 338.1 791.3 338.2 794.4 340.9 799.2 344.9 801.7 345.7 804.3 344 806.7 342.4 806.8 341.5 805.3 334.7 804.4 330.8 803.8 330.1 801.9 329.8 800.6 329.7 798.3 330.4 796.8 331.3ZM747.1 335.3L743.3 339.1 745.6 341.5C749.3 345.7 751.3 347.2 753.7 347.2 757.1 347.2 760.2 344.7 760.2 341.9 760.2 340.5 760.8 339.4 762 339.2 764.5 338.5 764.4 337.9 760.8 334.4 756.3 330 752.1 330.3 747.1 335.3ZM205.3 351.7C204.4 352.6 203.4 354.6 203.1 356.2 202.8 358.2 201.9 359.3 200.4 359.6 198.2 360.2 198.1 360.3 199.6 362.5 200.5 363.8 201.9 364.8 202.7 364.8 203.5 364.8 205.2 365.6 206.5 366.7 209.9 369.4 212.5 369.1 213.9 365.7 214.5 364.2 216.1 362 217.4 361 220.5 358.6 219.4 356.7 214.3 354.9 212.3 354.3 210 352.9 209.1 351.9 207.2 349.6 207.1 349.6 205.3 351.7ZM227.8 351.8C227.3 352.8 226.9 354.2 226.9 354.9 226.9 355.6 225.8 357.1 224.5 358.3L222.3 360.5 226.7 364.1C230.4 367.1 231.6 367.6 234.7 367.4 238.1 367.1 238.5 366.9 239.6 363.5 240.3 361.6 240.8 358.8 241 357.3 241.2 354.8 240.7 354.4 235.6 352.3 229 349.5 229 349.5 227.8 351.8ZM181.7 353.7C178.9 356.3 176.7 360.8 177 363.2 177.2 364.7 178.4 365.6 180.9 366.5 183 367.1 185 368.2 185.6 369.1 186.5 370.3 186.9 370.3 189.2 368.5 190.6 367.4 191.7 365.6 191.7 364.6 191.7 363.5 192.3 361.9 193.1 361.1 194.4 359.6 194.1 359.2 190.3 355.6 185.6 351.3 184.5 351.1 181.7 353.7ZM796.9 353.9C796.1 355.1 795.2 358.1 794.9 360.6L794.3 365.3 799.4 367.4C806.7 370.5 808.2 369.5 809.7 361 810.6 356 809.2 354.1 803.7 352.9 801.1 352.3 798.8 351.9 798.6 351.9 798.3 351.9 797.6 352.8 796.9 353.9ZM774.2 354C773.7 354.6 773 356.3 772.7 357.7 772.3 359.1 771.2 360.8 770.1 361.6 768.4 362.7 768.4 363.1 769.5 364.4 770.3 365.3 772.1 366.6 773.6 367.3 775.2 368 777.1 369.1 778.1 369.7 780.4 371.4 782.6 369.5 784 364.8 784.6 362.7 785.6 360.3 786.2 359.5 787.7 357.8 786.7 356.9 780.4 354.7 776.4 353.3 774.9 353.1 774.2 354ZM726 356.7C725.5 358.3 725.3 361.5 725.6 364.2 726.1 368.1 726.7 369 729.7 370.9 731.7 372.1 733.5 373.1 733.7 373.1 735 373.1 738.9 365.8 738.9 363.4 738.9 360 737.6 358.1 733.3 355.6 728.8 353 727.2 353.1 726 356.7ZM749.1 357.4C748 358.9 746.9 361.7 746.6 363.4 746 366.6 746.1 366.7 751.4 369 754.4 370.3 757.4 371.3 758.1 371.1 758.9 370.9 760.2 369.1 760.9 366.9 761.7 364.6 762.8 362.6 763.5 362.3 765.7 361.5 765 360.3 760.5 357.4 754.8 353.8 751.7 353.8 749.1 357.4ZM591.7 373.2C576.1 374.3 558.8 377.6 554.8 380.2 546.9 385.4 547.4 397.6 555.7 402.9 559.3 405 563.5 404.9 575 402.3 596 397.6 623.9 399.2 647 406.3 651.5 407.6 656.9 408.8 659.3 408.8 669.7 408.8 675.7 396.8 669.5 388.1 666.9 384.4 661.2 381.9 646.9 378.2 628.7 373.6 610 371.9 591.7 373.2ZM227.5 378.2C225.6 381.2 224.4 384.2 224.7 385.1 225.2 386.8 228.6 388.9 230.7 388.9 231.4 388.9 232.8 389.7 233.9 390.8L235.9 392.7 237.7 390.5C238.6 389.2 240 386.4 240.7 384.3 242.2 379.7 241.5 377.9 237.4 376.6 235.9 376.1 234.1 375.1 233.2 374.4 232.5 373.7 231.6 373.1 231.2 373.1 230.9 373.1 229.3 375.5 227.5 378.2ZM362 373.8C332.4 378.2 318.1 382.8 314.5 388.8 312.1 393 312.4 399.6 315.4 403.4 318.1 407 322 409.3 325.7 409.3 327.2 409.3 331.4 408.2 335.1 406.9 358 399.2 388.1 397.5 412 402.7 416.9 403.8 421.8 404.6 423 404.6 426.4 404.6 431.3 401.9 433.4 398.9 437.2 393.6 435.3 383.2 429.7 379.9 427.3 378.4 417.3 376.1 406 374.5 397.6 373.3 368.2 372.8 362 373.8ZM182.6 376.4C179.7 378.8 177.1 385.8 178.1 388.4 178.7 390.1 181.9 391.4 187 392.2 190.6 392.8 190.7 392.8 192.5 388.6 193.5 386.3 195 384 195.9 383.5 197.4 382.7 197.2 382.4 194.4 380.6 192.6 379.6 190.7 378.7 190.1 378.7 189.5 378.7 188.2 377.7 187.2 376.4L185.4 374.1 182.6 376.4ZM776.1 375.2C775.6 375.8 774.7 378.1 774.2 380.3 773.5 382.4 772.2 384.8 771.1 385.6 768.4 387.4 769.4 389.3 774 390.6 776 391.2 778.3 392.6 779.1 393.7 780.9 396.3 783 395.4 784.7 391 785.6 389.1 786.9 386.9 787.7 386.4 790 384.6 788 381 783.3 378.7 781.2 377.6 779.4 376.2 779 375.5 778.4 373.8 777.4 373.7 776.1 375.2ZM797.7 376.6C797.4 378.1 796.4 380.7 795.5 382.6 794 385.6 793.9 386.2 795 387.9 795.7 388.9 797.5 389.9 799 390.3 800.5 390.6 802.2 391.5 802.9 392.2 804.7 394.4 806.1 393.7 809.6 388.2 814.6 380.3 814.4 379.4 805.6 376 799 373.5 798.2 373.6 797.7 376.6ZM206 377.7C204.5 378.6 202.4 380.3 201.5 381.4 199.6 383.3 199.7 383.4 203.2 387 208.1 392 210.8 391.9 216.5 386.7L220.8 382.6 219 380.6C216.8 378.1 212.8 375.9 210.5 375.9 209.5 375.9 207.6 376.7 206 377.7ZM750.3 381.3C748.6 383.7 747.2 386.6 747.2 387.7 747.2 390.3 752.9 393.8 757.2 393.9 760.5 394 760.7 393.8 761.9 390 762.6 387.9 763.7 386.1 764.4 386.1 765.8 386.1 766.1 385.3 765 383.6 764.5 383 754 376.8 753.2 376.9 753.2 376.9 751.9 378.8 750.3 381.3ZM728.8 380.7C728.8 381.9 729.4 385.6 730 388.9 731.1 394.6 731.3 394.9 733.7 394.7 736.9 394.4 738.9 392.9 740.5 389.1 742.3 384.6 741.3 382.9 735.9 380.6 730 378.1 728.7 378.1 728.8 380.7ZM230.2 398.7C229.4 399.4 228.7 400.9 228.7 401.8 228.7 402.7 227.9 404.5 226.8 405.9 224.9 408.3 224.9 408.5 226.4 410.2 227.2 411.1 229.3 412.2 230.9 412.6 232.5 412.9 234.4 413.6 234.9 414.1 236.6 415.4 240.3 412.8 242.2 409.2 244.2 405.3 242.7 401.9 238.1 399.3 233.8 396.9 232.1 396.8 230.2 398.7ZM181.9 400.2C181.5 400.7 180.6 403.6 180 406.4 178.6 412.2 179.2 413.3 183.5 414.3 185.1 414.5 187.1 415.5 188 416.2 190.5 418.4 194 415.1 195.4 409.3 196.8 403.5 196 402.4 189.5 400.5 183.9 398.8 182.7 398.7 181.9 400.2ZM205.6 401.1C201.9 411.1 202 413 206 413 207.4 413 209.4 414 210.6 415.4 213.2 418.1 214.2 417.9 215.7 413.7 216.4 412 217.8 409.7 218.8 408.6 221.4 405.6 220.2 403.3 214.6 401 208.6 398.5 206.7 398.5 205.6 401.1ZM775.2 403.4C773.1 405.5 771.3 408.1 771.3 409.1 771.3 411 776.2 415.7 778.2 415.7 778.9 415.7 779.7 416.5 780 417.3 780.6 418.6 781.2 418.2 784.3 415.3 788.6 411 789 408.2 785.5 405.3 784.1 404.2 782.1 402.4 781.1 401.4L779.2 399.5 775.2 403.4ZM799.5 402.3C796.7 405 796.2 405.9 796.7 408.1 797.5 411.5 804 418.1 805.9 417.3 808.1 416.5 812.3 409.5 812.3 406.8 812.3 403.9 807.5 399.1 804.7 399.1 803.7 399.1 801.4 400.6 799.5 402.3ZM162.5 404C162.2 405.6 161.7 409 161.2 411.4 160.5 415.5 160.6 415.9 162.5 417.2 166 419.5 169 417.6 171.2 411.5 172.3 408.6 172.9 405.8 172.5 405.5 172.1 405.1 169.8 403.9 167.4 402.9L163.1 401 162.5 404ZM751.1 403.2C749.1 405.8 747.8 410.6 748.3 413.5 748.7 415.8 752.8 417.7 757.6 417.9 761.4 418.1 761.5 418 762.7 414 763.3 411.7 764.4 409.5 765 409.1 767.6 407.5 762 403 755.5 401.4 753.5 400.9 752.6 401.3 751.1 403.2ZM231.5 422.1C229.3 425.4 226.9 430.8 226.9 432.9 226.9 434.6 233.6 437.9 237.1 438 240.1 438 241.7 436.2 241.9 432.9 242 431.6 242.7 430.1 243.4 429.7 245.5 428.4 244.2 425.6 241 424.6 239.4 424.1 237.2 422.7 236.1 421.5 235.1 420.4 234 419.4 233.8 419.4 233.6 419.4 232.6 420.6 231.5 422.1ZM208.1 422.4C206.7 423.5 203.8 430.2 203.4 433.3 203.3 434.1 204.8 435.5 206.9 436.4 209 437.4 211.4 438.8 212.3 439.6 213.1 440.4 214 440.8 214.2 440.6 216.9 437 220.4 430.5 220.4 429 220.4 426.7 218.1 424.5 213.6 422.7 209.5 421 210 421 208.1 422.4ZM777.3 424.6C776.1 425.9 774.6 429 774.1 431.6 772.8 436.9 773.2 437.9 778.1 440.2 783.5 442.7 784.9 442.2 787.5 436.8 788.8 434 789.8 431.2 789.8 430.5 789.8 428.5 788 426.9 785.9 426.9 784.9 426.9 783.1 425.8 781.9 424.5L779.5 422.2 777.3 424.6ZM801.1 424.3C799.2 426.4 798 429 796.9 433.4 796.4 435.5 796.9 436 801.4 438.4L806.4 441.2 808.6 439.1C813.4 434.5 813.7 426.9 809.1 423.7 806.2 421.7 803.4 421.9 801.1 424.3ZM159.4 425.7C157.9 429.5 157.1 434.8 157.9 436.9 158.1 438 159.8 439.6 161.5 440.7 165.5 443.1 169.1 442 170 438.2 170.4 436.9 171.2 434.4 171.9 433 173.6 429.6 173 428.8 165.6 425.6L160.4 423.3 159.4 425.7ZM181.5 427C179.2 432.1 179.1 436 181.3 436.8 182.1 437 184.6 438.1 186.9 439.1 190.6 440.8 190.9 440.9 192.7 439.3 195.1 437.1 197.5 428.8 196.2 427.2 195.1 425.9 187.6 423.1 185 423.1 183.8 423.1 182.6 424.5 181.5 427ZM751.5 427.2C748.1 432.4 748.7 439.8 752.5 439.8 753.2 439.8 755.4 440.5 757.1 441.4 760.3 442.9 760.4 442.8 762.5 440.6 765.1 438.1 766.9 431.6 765.6 429.2 764.4 427.2 759.3 425 755.6 425 753.9 425 752.5 425.7 751.5 427.2ZM160.2 449.7C155.8 458.9 156 459.9 162.1 463.1 167.7 465.8 169.3 465.2 171.8 459.3 174.4 453.2 173.8 451.8 168.5 449.6 166.5 448.8 164.5 447.5 164.3 446.8 163.3 444.4 162.3 445.2 160.2 449.7ZM207.9 448.8C207.6 450.2 206.5 452.4 205.5 453.8 203.2 457 203.8 458.4 208.4 461 213.3 463.8 215.5 463.1 219.6 457.5L223 453 221 451.1C218.7 449 212.6 446.3 210.2 446.3 209.2 446.3 208.3 447.2 207.9 448.8ZM801.7 447.9C800.9 448.8 799.6 451.4 798.8 453.6 796.9 458.5 797.8 460.6 801.9 461.6 803.5 461.9 805.6 463 806.4 463.8 807.9 465.3 808.2 465 812.8 458.1 816.2 453.1 817.2 450.9 816.2 450.9 815.4 450.9 812.8 449.9 810.4 448.6 805.3 445.8 803.5 445.7 801.7 447.9ZM182.9 449.4C182 450.6 181.3 453.7 181.2 456L181 460.3 186.2 462.4C192.3 464.9 194 464.4 195.9 459.6 199 452.3 196.8 448.4 189.1 447.5 184.8 447 184.4 447.2 182.9 449.4ZM779.4 448.2C776.9 449.6 773.1 458.3 774.1 460.2 775.4 462.6 781.3 465.1 783.9 464.4 785.8 463.9 791.7 456.6 791.7 454.5 791.7 453.9 782.3 447.2 781.5 447.2 781.2 447.2 780.3 447.7 779.4 448.2ZM754.4 449.7C751.9 452.7 749.9 457.5 750.2 460 750.4 461.9 751.2 462.7 753.2 463.2 754.8 463.7 757.2 464.6 758.7 465.4 761.7 466.9 763.9 465.8 763.9 463 763.9 462 765 459.9 766.3 458.3 767.7 456.8 768.6 455.4 768.4 455.2 766 453.1 757.9 448.1 756.9 448.1 756.4 448.1 755.2 448.9 754.4 449.7ZM803 470.8C800.7 472.5 797.5 482.1 798.8 483.4 799.3 483.9 801.9 485 804.9 486 809.6 487.7 810.3 487.7 811.6 486.5 812.3 485.6 813 484.3 813 483.4 813 482.5 813.8 480.6 814.9 479.3 817.1 476.4 816.9 475.9 811.6 472.2 806.9 469.1 805.8 468.9 803 470.8ZM185.5 471.5C184.9 472.1 183.8 474.8 182.9 477.5 180.8 483.1 181.6 484.6 186.6 485.6 188.3 485.9 190.2 486.9 190.6 487.8 191.5 489.2 191.8 489.2 193.9 487.1 195.2 485.8 196.3 483.9 196.3 482.6 196.3 481.2 196.9 480.2 198.1 479.9 200.5 479.3 200.5 478.6 198.1 475.6 196.9 474.2 194.3 472.6 191.5 471.8 185.7 470.1 186.5 470.1 185.5 471.5ZM208.4 472C207.9 473.1 207.4 474.6 207.4 475.4 207.4 476.2 206.5 477.8 205.4 478.9 203.5 480.7 203.5 480.9 205.1 482.1 206.1 482.8 207.3 483.3 208 483.3 208.6 483.3 210.5 484.4 212 485.8 214.4 487.7 215.4 488.1 216.6 487.3 218.7 486 221 481.6 221.8 477.5 222.4 474.2 222.3 474 218.9 472.6 212.9 470.1 209.5 469.9 208.4 472ZM161.4 472.7C159.8 473.8 157.4 480.1 157.4 483.3 157.4 484.3 166.9 488.9 169 488.9 170.9 488.9 173 485.8 174.2 481.2 175.1 477.3 175 476.6 173.6 475 172.8 474.1 170.7 473 169.1 472.7 167.5 472.3 165.6 471.9 164.8 471.7 164 471.5 162.5 471.9 161.4 472.7ZM756.3 473.1C753.5 475.3 750.6 481.9 751.4 484.4 751.8 485.4 753.4 486.5 755.6 487 757.6 487.6 759.5 488.6 760 489.4 761.6 492.3 765.7 488 765.7 483.4 765.7 482.4 766.7 481.5 767.9 481.1 769.8 480.6 769.6 480.3 765.1 475.9 762.5 473.3 759.9 471.3 759.4 471.3 759 471.3 757.5 472.1 756.3 473.1ZM778.9 472.5C778.3 473.1 777.6 474.8 777.3 476.2 776.9 477.6 775.7 479.4 774.7 480.1 772.9 481.4 772.9 481.5 774.5 483.2 775.4 484.3 777 485.4 778.1 485.7 779.2 486 781 487.1 782.1 488.2 784.1 489.9 784.4 490 786.5 488.6 788.9 487 792.4 477.1 791 475.9 790.6 475.6 787.9 474.4 785 473.3 781 471.9 779.5 471.7 778.9 472.5ZM210.7 493.7C209.9 494.8 209.3 496.3 209.3 497 209.3 497.7 208.2 499.3 206.9 500.6 205.7 501.8 204.9 503.3 205.2 504 205.4 504.6 208.1 506.5 211.3 508.1 216.8 511 217.1 511 218.6 509.5 219.4 508.6 220.8 505.8 221.7 503.3 223.4 498 222.8 496.8 218 495.8 215.7 495.5 214.4 494.6 214.2 493.4 213.5 491.1 212.5 491.2 210.7 493.7ZM185.8 496.3C183.5 499 181.8 505.6 182.8 507.3 183.6 508.6 193.2 511.4 194.8 510.8 195.6 510.6 196.5 508.8 196.9 506.9 197.1 505.2 198.3 503.1 199.4 502.3 200.8 501.3 201 500.7 200.1 499.6 199.4 498.9 197.8 498 196.3 497.7 194.9 497.4 193 496.3 192 495.3 189.8 492.9 188.5 493.1 185.8 496.3ZM804 494.6C803.4 495.3 802.3 497.5 801.5 499.5 800.6 501.5 799.5 503.4 799 503.7 797 504.9 799.4 507.4 804.4 509.3 811.8 512 811.9 511.9 815.2 504.7 817.3 500.3 817.1 499.7 812.9 496.9 808.1 493.8 805.3 493.1 804 494.6ZM827 494.6C826.6 495.3 825.8 496.9 825.5 498.1 825.1 499.4 824.3 501.4 823.5 502.5 822.4 504.2 822.5 504.7 824.1 506.8 825.1 508.1 827 509.4 828.4 509.6 829.9 510 831.8 510.5 832.8 510.8 834.4 511.3 834.4 510.9 833.9 505 832.9 494.5 832.5 493.5 830.1 493.5 829 493.5 827.6 494.1 827 494.6ZM161.8 496C160.2 497.8 158 506.1 158.8 507.3 159 507.8 161.6 509.3 164.4 510.6L169.6 513.1 171.9 510.8C173.5 509.4 174.4 507.1 174.7 504.3 175.5 498.4 173.8 496.7 166.1 495 164.1 494.5 163 494.8 161.8 496ZM757.8 495.2C757.2 495.6 755.6 498.1 754.3 500.6 753 503.3 751.4 505.6 750.9 505.6 748.9 505.6 751.4 508.3 755.6 510.6 761.9 514.1 763.6 513.5 767 507.3 769.4 502.9 769.7 501.9 768.6 500.6 768 499.7 766.6 499.1 765.6 499.1 764.6 499.1 762.8 498.1 761.5 496.8 758.9 494.2 759.2 494.3 757.8 495.2ZM779.4 498.1C775.4 502.8 774.8 504.8 776.6 507.4 778.2 509.7 783.1 512 786.5 512 788.1 512 789 511.3 789.7 509.1 790.3 507.5 791.4 505.4 792.2 504.5 794.4 502.2 793.2 500.2 789.2 498.5 787.2 497.7 785 496.4 784.2 495.7 782.8 494.5 782.3 494.7 779.4 498.1ZM210.7 518.7C209.9 519.8 209.3 521.4 209.3 522.2 209.3 523 208.6 524.7 207.9 526.2 206.4 529 205.8 528.3 214.4 533.6L218.1 535.9 220.7 531.9C225.6 524 224.9 520.1 217.7 517.7 213.2 516.2 212.3 516.4 210.7 518.7ZM804.4 518.7C801.9 522.8 799.8 528.6 800.3 530 800.6 530.7 802.5 531.9 804.6 532.5 806.8 533.1 809 534.4 809.6 535.4 810.7 536.9 810.9 536.9 812.2 535.5 813.9 533.5 817.6 525.8 817.6 524.4 817.6 523.5 810.4 518.7 806.4 516.9 806.1 516.8 805.2 517.6 804.4 518.7ZM187.8 519.7C186.6 521 184.7 523.5 183.6 525.3L181.7 528.5 183.6 530.4C186 532.5 192 535.2 194.6 535.2 195.6 535.2 196.6 534.4 196.9 533.5 197.2 532.7 198.2 530.2 199.3 528 200.3 525.7 201 523.8 200.7 523.6 200.6 523.4 198.9 522.2 197 521 191.8 517.4 190.1 517.1 187.8 519.7ZM829.3 519.5C828 520.6 826 522.9 824.9 524.6L822.9 528.1 825.1 529.7C832.8 535.6 836.1 535.5 836.1 529.4 836.1 519.1 833.9 515.9 829.3 519.5ZM780.5 520.6C779.9 521.7 779.1 523.6 778.7 524.9 778.4 526.2 777.6 527.3 776.9 527.3 774.4 527.3 775.2 529.3 778.9 532.1 784.2 536.5 787.1 536.2 790.6 531.2 792 529.1 793.5 526.9 793.8 526.3 794.5 525 785.6 518.5 783.1 518.5 782.2 518.5 781 519.4 780.5 520.6ZM163.1 520.6C162.7 521.2 161.9 523.1 161.6 524.8 161.2 526.5 160.4 528.1 159.6 528.4 158.5 528.8 158.6 529.4 160.4 531.3 163.5 534.6 167.9 536.3 170.8 535.2 175.3 533.5 178.6 524.8 175.7 522.5 174.6 521.7 166.9 519.4 165 519.4 164.5 519.4 163.7 520 163.1 520.6ZM755.2 524.1C753.3 526.1 751.9 528.3 751.9 529.1 751.9 529.8 753.1 531.7 754.7 533.2 758.8 537.3 762.5 537.1 767.6 532.6 772.3 528.4 772.2 527.2 766.6 523.1 761.4 519.4 759.3 519.6 755.2 524.1ZM187 545.5C185.1 548.7 184.3 551.1 184.4 553.1 184.7 555.8 185.1 556.1 190.6 557.5 197 559.2 196.7 559.4 199.6 552.1 201.6 547.4 201.3 545.4 198.6 545.4 198.1 545.4 196.1 544.4 194.3 543.1 192.4 541.8 190.6 540.7 190.4 540.7 190.2 540.7 188.7 542.9 187 545.5ZM211.1 543.1C210.6 544.4 210.2 546 210.2 546.6 210.2 547.2 209.5 548.7 208.7 549.8 207.5 551.6 207.5 552.2 208.4 553.3 209.9 555.2 213.6 557 217.3 557.8 220.1 558.4 220.3 558.3 223 552.7L225.7 546.9 223.6 544.8C221.8 543 216.2 540.7 213.1 540.7 212.5 540.7 211.6 541.9 211.1 543.1ZM805.7 542.1C803.6 543.7 800.4 553 801.4 554.5 802.2 555.9 811.7 558.7 813.2 558.1 814.1 557.8 815.2 555.8 815.7 553.7 816.3 551.6 817.3 549.7 818.1 549.4 820 548.6 818.3 545.9 814.1 543.1 810.1 540.4 808.6 540.2 805.7 542.1ZM827.6 542.3C823.3 547.2 823.4 550 827.7 554.1 830.6 556.9 834.3 557.5 836.6 555.6 838.8 553.7 838.4 544.9 836.1 542.6 833.8 540.3 829.4 540.2 827.6 542.3ZM164.5 544.2C163.8 545.1 162.9 546.9 162.5 548.2 162.1 549.6 161.1 551.1 160.1 551.5 158.4 552.2 158.6 552.6 162.2 555.4 166.9 559 169.9 559.9 171.9 558.2 173.5 556.9 179.1 549.1 178.5 548.8 178.4 548.7 176.3 547.2 173.9 545.6 169.1 542.2 166.7 541.9 164.5 544.2ZM780.3 544.3C779.4 545.3 778.4 548.1 778.1 550.6 777.4 556.3 779.4 558.4 785.8 559L790.3 559.4 792.7 554.2C795 549.1 795 548.9 793.4 546.9 792.5 545.6 790.5 544.4 789 544.2 787.5 543.9 785.3 543.3 784.1 543.1 782.6 542.7 781.4 543.1 780.3 544.3ZM757.7 544.6C755.4 547.5 753.1 554.4 753.9 555.8 755.2 558.2 759.7 560.2 763.8 560.2 766.9 560.2 767.8 559.8 768.9 557.6 769.6 556.1 770.4 553.3 770.6 551.5 770.7 548.6 770.4 547.6 768.5 546.2 765.4 543.9 759.1 543 757.7 544.6ZM211.9 567.2C211.4 568.7 210.3 571.3 209.5 572.9 207.8 576.5 208.8 578.2 213.6 580.3 220.8 583.2 224.4 581.1 225.6 573 226.1 569.2 225.9 568.5 223.9 567.2 222.7 566.4 219.7 565.5 217.3 565.2 213.2 564.6 213 564.7 211.9 567.2ZM828.1 567.1C827.2 568.6 826.5 571.5 826.5 573.9 826.4 578 826.5 578.1 829.6 579 831.4 579.4 833.6 580.5 834.5 581.3 835.8 582.4 836.6 582.6 837.8 581.8 839.1 580.9 839.4 579.4 839.3 573.7 839.2 569.8 838.9 566.4 838.7 566.2 838.4 565.9 836.4 565.5 834.1 565.2 830.2 564.6 829.7 564.8 828.1 567.1ZM164.9 567.8C164.4 569 163.3 571.7 162.5 573.9 160.9 577.6 160.9 577.9 162.4 579.5 164.4 581.7 171.4 583.7 173.9 583 176.3 582.1 178.2 576.5 177.9 571 177.8 570 176.2 568.6 173.9 567.6 168.5 565.2 165.9 565.3 164.9 567.8ZM187.5 567.9C186.8 569.1 185.8 571.9 185.6 574.3L184.9 578.5 188.8 579.7C190.9 580.4 193.1 581.4 193.6 582.1 196.1 585 199.4 582.2 201.5 575.5 203.1 570 202.1 568.1 197.4 566.7 191.9 565.2 189.1 565.5 187.5 567.9ZM804.6 567.1C803 569.1 801.9 576 802.9 578 803.5 579.2 810.6 581.5 813.9 581.5 815.5 581.5 817.5 578.6 818.4 575.3 819.7 570.8 818 568.1 813.2 566.8 808.4 565.4 806 565.5 804.6 567.1ZM780.2 569.2C778.2 573.1 777.6 577.5 778.6 579.4 779.7 581.6 784.2 583.3 788.4 583.3 791.2 583.3 791.6 583 793.4 577.7 795.1 573.1 795.3 571.9 794.4 570.7 792.5 568.4 788.2 566.7 784.8 566.7 782.1 566.7 781.3 567.1 780.2 569.2ZM756.9 569.7C756.1 571 755.4 574.1 755.3 576.5L755.1 580.7 759.1 581.9C761.2 582.6 763.7 583.7 764.4 584.4 765.7 585.4 766.3 585.2 768.1 583.1 769.3 581.7 770.6 578.7 770.9 576.3 771.8 570.7 769.6 568.4 763.1 567.8 759 567.4 758.3 567.6 756.9 569.7ZM212.6 590C211.9 591.2 210.7 594 210.2 596.2 209.3 599.9 209.3 600.5 210.7 601.6 211.7 602.2 213.1 602.8 214 602.8 214.8 602.8 216.6 603.6 218 604.7L220.4 606.6 223.1 603.9C226 600.9 227.7 595.1 226.2 592.7 225.1 590.8 221.8 589.3 217.4 588.5 214.4 588 213.8 588.2 212.6 590ZM829 590.4C828.1 591.8 827.4 594.7 827.4 597 827.3 601.2 827.4 601.3 831.2 602.8 833.4 603.6 835.6 604.7 836.3 605.4 837.1 606.2 837.8 606.1 839.1 604.9 840.4 603.7 840.7 602 840.7 596.8L840.7 590 836.7 589C831 587.6 830.8 587.6 829 590.4ZM189.4 590.9C188.6 592 188 593.4 188 594 188 594.4 187.3 596.1 186.6 597.6 185.3 600.1 185.3 600.5 187.1 602.4 188.8 604.2 195 606.5 198.1 606.5 199.8 606.5 202.8 600.6 202.8 597 202.8 593.1 201.1 591.1 196.5 589.8 191.7 588.5 191 588.6 189.4 590.9ZM806.1 590.3C804.6 591.8 802.8 597.3 802.8 600.3 802.8 601.2 803.9 602.3 805.4 602.9 806.8 603.4 809.1 604.4 810.5 605.2 811.9 605.9 813.7 606.5 814.4 606.5 817.4 606.5 821.1 596.6 819.4 593.3 817.6 590.1 808.4 588 806.1 590.3ZM782.4 592.2C781.9 593.5 781.5 595.2 781.5 595.9 781.5 596.6 780.6 597.7 779.6 598.3 778.6 599 777.8 599.8 777.8 600.2 777.8 601.7 781.9 604.6 784.1 604.6 785.5 604.6 786.5 605.3 786.8 606.5 787.4 608.8 790 608.9 791.9 606.7 792.7 605.8 794.2 602.9 795.3 600.2L797.1 595.2 791.2 592.5C783.9 589.3 783.5 589.2 782.4 592.2ZM164.4 594.6C163.5 596.8 162.1 599 161.4 599.6 160 600.6 160.2 600.8 162.6 602.3 164.1 603.2 166.4 604.7 167.8 605.6 173.1 609.4 176.8 607.2 178.5 599.4 179.6 594.6 179.2 593.9 174.2 592.1 167.6 589.8 166.1 590.2 164.4 594.6ZM760 592.3C757.6 595.1 755.5 600 755.7 602.1 755.9 603.6 757.1 604.5 759.7 605.4 761.8 606 763.9 607.1 764.4 608 766.5 610.6 770.4 606.6 770.4 601.9 770.4 600.6 771 600 772.2 600 775.1 600 774.4 598.6 769.8 594.5 765.2 590.5 762.2 589.8 760 592.3ZM168.3 613.6C166.4 615.8 163 622.8 163 624.4 163 625.3 165.4 627.1 168.4 628.6 174.6 631.9 175.5 631.6 178.7 625.3 181 620.6 180.3 618.4 175.6 616.1 174 615.3 172 614 171.2 613.3 169.9 612.2 169.5 612.2 168.3 613.6ZM784.4 614.2C783.3 615.4 781.9 617.6 781.4 619.2 780.2 622.9 782.2 627.8 786.4 630.7L789.2 632.8 792.8 628.8C796.7 624.4 797.2 621.2 794.5 618.7 792.3 616.7 786.9 612 786.7 612 786.5 612 785.6 613 784.4 614.2ZM830 614.4C829.2 615.6 828.2 618.5 828 620.8 827.6 624.7 827.7 625 830.2 625.9 831.7 626.4 834.1 627.4 835.5 628.2 837.4 629.3 838.6 629.4 839.9 628.7 841.4 627.9 841.7 626.7 841.7 620.5 841.7 613.7 841.5 613.1 839.6 612.6 834.9 611.4 831.6 611.9 830 614.4ZM189.8 615.4C189.4 616.9 188.2 619.3 187.5 620.7 186.1 623.2 186.1 623.6 187.7 625.1 188.6 625.9 191.3 627.5 193.7 628.5L198.1 630.5 201.4 626.1C205.3 621.1 205.4 618.1 201.8 615.5 200.4 614.5 197.4 613.4 195 613.2 191 612.8 190.7 612.9 189.8 615.4ZM760.8 616.5C756.1 621.3 756.2 624.2 761.3 629.4 763.4 631.6 765.7 633.3 766.3 633.3 766.9 633.3 768.5 632 769.8 630.5 773.4 626.2 773.1 621.4 768.9 616.7 767 614.6 765.3 613 764.9 613 764.5 613 762.7 614.5 760.8 616.5ZM807.8 614.1C807.3 614.7 806 617.1 804.9 619.4L802.8 623.6 804.7 625.3C805.8 626.1 807.8 627.1 809.2 627.4 810.5 627.7 812.6 628.3 813.8 628.8 815.3 629.4 816.4 629.4 817.1 628.7 818.3 627.8 820.4 620.2 820.4 617.1 820.4 614 809.4 611.4 807.8 614.1ZM146.5 622.9C146.8 630.9 146.8 631 149.2 631.3 151.3 631.6 152 630.9 154.5 626.3 156.1 623.3 157.4 620.6 157.4 620.4 157.4 619.7 148.1 614.8 146.9 614.8 146.6 614.8 146.4 618.4 146.5 622.9ZM191.4 637.8C189.7 639.7 188 644.9 188 647.8 188 649.4 188.7 650.2 191.8 651.1 193.9 651.7 196 653 196.6 653.8 198.1 656.1 200 654.9 201.9 650.4 202.9 648.1 204.1 646.3 204.6 646.3 206.1 646.3 205.7 641.9 204.2 640.4 203.3 639.5 200.9 638.5 198.8 638 196.7 637.4 194.4 636.8 193.8 636.6 193.2 636.4 192.1 636.9 191.4 637.8ZM785.3 638.5C783.5 640.7 783.1 641.9 783.4 644.2 783.4 644.5 782.6 645.2 781.5 645.6 778.3 646.8 779.6 649.2 784.8 651.8 787.4 653.1 790.3 654.7 791.1 655.5 792.4 656.6 792.8 656.2 794.5 652.2 795.6 649.7 797 647.3 797.8 646.9 800.7 645.3 799.2 642.5 794 640.3 791.2 639 788.9 637.6 788.9 637 788.9 635.4 787.2 636 785.3 638.5ZM834.5 637.5C833.4 638.2 831.3 640.9 829.7 643.4L826.9 648.1 830.9 649.9C835.3 652 838.1 652.3 840.8 650.9 842.2 650.1 842.6 648.9 842.6 644.4 842.6 639.3 842.4 638.9 839.8 637.5 836.6 635.8 836.9 635.8 834.5 637.5ZM168.1 638.5C167.3 639.3 166.7 640.4 166.7 640.9 166.7 641.4 165.9 643.3 165.1 645.1 162.8 650 165.3 652.7 173.2 654.2 177.5 654.9 179.3 653.2 180.1 647.8 180.9 642.5 180.1 640.2 177 639.1 172 637.1 169.6 637 168.1 638.5ZM807.2 640.9C805.3 643.1 803.7 645 803.7 645.4 803.7 645.6 805.6 647.7 807.8 649.9 813.1 655.1 816.3 655 819 649.5 820 647.5 821.4 645.5 822 645.1 824.4 643.6 816.5 637 812.4 637 811.6 637 809.3 638.8 807.2 640.9ZM147 647.1L147.3 655.6 150.5 655.6C154.1 655.6 155.8 653.1 156.9 646.8 157.7 642.1 155.9 640.2 150.5 639.4L146.8 638.7 147 647.1ZM193.1 662.3C188.1 666.6 188.3 669.4 193.8 674.8 197.9 678.9 198.1 679 200.3 677.5 202.6 676 205.6 670.7 205.6 668 205.6 666.5 198.8 659.3 197.4 659.3 197 659.3 195.2 660.6 193.1 662.3ZM833.1 660.9C832.1 661.9 831.5 663.7 831.5 665 831.5 666.7 830.8 667.5 829.5 667.9 826.6 668.6 828.8 671.8 833.8 674 836.1 675 838 676.3 838 676.8 838 677.3 838.7 677.8 839.6 677.8 842 677.8 843.5 674 843.5 667.7L843.5 662.2 839.8 660.7C835.1 658.9 834.9 658.9 833.1 660.9ZM807.9 665.4C804.9 671.9 805 673 808.1 674.3 813.9 676.8 815.6 678.6 815.6 681.9 815.5 684.7 815.3 685 813.7 684.2 811.6 683.1 809.6 684.3 808.7 687.3 808.4 688.4 807.5 690.1 806.8 690.9 805.6 692.2 805.6 692.9 806.7 695 807.6 696.9 809.3 698.1 813.6 699.5L819.3 701.6 820.4 697.3C820.9 695 821.8 692.4 822.1 691.7 822.7 690.7 821.9 689.2 819.8 686.8 818 684.8 816.7 682.3 816.7 681 816.7 677.8 820.3 670 822.6 668.4 823.1 668.1 823.1 666.8 822.8 665.4 822.3 663.5 821.2 662.8 817.4 661.6 814.8 660.8 812 660.2 811.4 660.2 810.7 660.2 809.2 662.5 807.9 665.4ZM168.2 662.8C166.2 665 164.7 672.1 165.8 674.3 166.3 675.2 166.9 675.9 167 675.9 167.2 675.9 169.5 676.3 172.1 676.9 178 678 180 677.1 181.4 673.1 183.4 667.2 182.9 665.9 177.2 663.4 171 660.6 170.2 660.6 168.2 662.8ZM784.4 664.3C781.8 668.3 781.9 672.3 784.5 674.7 787.6 677.6 792.9 680.1 793.3 678.9 793.5 678.3 794.9 676.4 796.4 674.4 797.9 672.5 799.1 669.9 799.1 668.4 799.1 666.2 798.3 665.6 794.1 663.5 787.5 660.5 786.7 660.5 784.4 664.3ZM147.9 669.6C148.3 675 148.9 677.6 150.1 678.8 151.6 680.3 151.8 680.3 154 678 156.7 675.1 158.3 671.3 158.3 668 158.3 665.6 155.8 664.1 149.8 662.6L147.4 662 147.9 669.6ZM194.5 683.9C192 685.7 189.8 690.6 189.8 694.4 189.8 697.5 191.2 698.5 197 699.8 201.9 700.9 204.2 699.4 205 694.4 205.4 692.2 206.2 690.5 207.1 690.1 208.4 689.5 208.4 689.4 206.9 688.2 205.9 687.6 204.4 687 203.5 687 202.5 687 200.7 686 199.4 684.7 196.7 681.9 197.2 682 194.5 683.9ZM833.7 686.5C829.8 690.4 829.6 693.5 833 696.2 834.4 697.3 836 698.1 836.7 698.1 837.3 698.1 838.2 698.8 838.7 699.6 839.2 700.5 840.4 700.9 841.3 700.7 842.8 700.5 843.1 699.4 843.3 693.3L843.6 686.3 840.6 684.8C839 684 837.5 683.3 837.2 683.3 837 683.3 835.5 684.7 833.7 686.5ZM169.9 685.7C169.2 686.6 168.5 687.8 168.5 688.5 168.5 689.3 167.5 690.9 166.2 692.2 165 693.4 164.2 695 164.4 695.6 164.9 697 174.5 702.8 176.3 702.8 178.7 702.8 180.8 700.2 182 695.6 183.8 688.5 183.6 688.2 174.4 685.3 171.9 684.5 171 684.6 169.9 685.7ZM764.1 686.7C761.7 688.3 759.3 692.6 759.3 695.2 759.3 696.2 760.3 697.7 761.6 698.5 765.8 701.3 766.1 704 763 711.8 758.9 721.9 759.1 722.8 765.3 724.5 771.8 726.5 773.3 726.1 774.3 722.6 774.6 721 775.6 719.2 776.4 718.5 779.1 716.3 778 714.3 773.1 712.2 767.7 709.9 767.3 708.2 771.2 703.4 777 695.9 777.1 691.2 771.4 687.3 767.7 684.8 766.9 684.7 764.1 686.7ZM786.4 686.3C785.7 687.4 783.8 692.2 782.8 695.4 782.2 696.9 790.3 702.8 792.8 702.8 794.4 702.8 797.2 699.9 797.2 698.4 797.2 697.9 798.2 696 799.4 694.2 802 690.4 801.9 690.1 795.3 687.1 790.6 684.9 787.5 684.7 786.4 686.3ZM148.5 690.9C148.8 693.6 149.1 697.2 149.1 698.8 149.1 701.5 149.4 701.9 151.6 701.9 153.2 701.9 155.2 700.6 157.7 698L161.4 694.1 157.1 690.1C154.3 687.4 152 686.1 150.4 686.1 148 686.1 147.9 686.2 148.5 690.9ZM811.8 708.1C810.8 709.1 810.2 710.4 810.2 711.1 810.2 711.8 809.4 713.7 808.2 715.5 805.7 719.4 806.7 720.6 813.6 722.9 819.2 724.6 821.6 724 822 720.5 822.2 719.4 823.3 717.9 824.5 717 827.3 715.2 826.7 713.3 822.3 711.1 820.4 710.2 818.3 708.7 817.7 708 816 706 813.6 706.1 811.8 708.1ZM835.4 707.7C834.7 708.4 834 710.3 833.7 711.9 833.3 713.5 832.6 714.8 831.9 714.8 827.6 714.8 830.6 719.6 836 721.4 837.9 721.9 840.1 723.1 840.9 723.8 843.4 726 844.8 722.3 844.1 715.4 843.5 710.5 843.1 709.5 840.9 708.5 836.7 706.4 836.5 706.4 835.4 707.7ZM169.6 711.9C166.2 715.5 165.4 715.9 162.7 715.5 160.9 715.2 157.6 713.7 155.1 712.1 152.6 710.6 150.2 709.3 149.8 709.3 149.4 709.3 149.1 712.8 149.1 717 149.1 725.4 150 727.2 153.8 726.7 155.8 726.4 156.4 725.7 158.5 720.8 160 717.4 162.8 716.8 164.7 719.4 165.6 720.4 167.9 721.8 169.9 722.4 174.5 723.9 175 726.2 171.9 731.7 167.6 739.2 167.9 743.9 172.9 748.5 175.3 750.7 175.5 750.8 177.8 749.4 186.6 743.8 187.5 739.3 181 733.1 178.7 731 176.9 728.8 176.9 728.4 176.9 728 178.1 726.1 179.6 724.4 183.7 719.7 183.4 715.6 178.8 711 176.9 709 174.8 707.5 174.4 707.5 174 707.6 171.9 709.5 169.6 711.9ZM192.5 712.6C189.3 718.4 189.4 719.7 194 722.2 198.5 724.7 198.8 726.1 195.5 731.1 191.9 736.6 191.3 738.7 192.5 741.9 193.3 744.2 200.9 750 203 750 203.3 750 204.3 748.7 205.1 747.2 205.9 745.6 206.3 744.4 205.9 744.4 205.6 744.4 206.3 743.1 207.3 741.3 209.8 737.3 209.7 736.5 206.9 735.7 203.4 734.8 199.9 731 200.6 729 200.9 728.1 202.9 724.4 204.8 721 206.9 717.5 208.2 714.2 208.1 713.5 207.4 711.9 199.4 707.4 197.1 707.4 196.1 707.4 194.4 709.4 192.5 712.6ZM787.7 709C787.5 709.4 786.8 711.4 786.1 713.4 785.5 715.5 784.5 717.6 784.2 718.1 782.1 720.6 786.3 724 793.2 725.5 796 726 796.2 725.9 798.9 720.3L801.7 714.5 799.5 712.4C796.8 709.6 788.7 707.3 787.7 709ZM811.8 731.9C810.1 733.5 808.3 739 808.3 742.3 808.3 745 811.6 747 816.9 747.8 821 748.3 821.3 748.2 822.3 745.7 822.9 744.3 823.9 741.8 824.5 740.2 825.9 736.9 825.1 734.8 821.5 733 817 730.7 813.3 730.3 811.8 731.9ZM836.8 731.6C834.6 732.9 832.4 738 832.4 741.7 832.4 744.8 833.7 745.6 840.6 746.8L844.6 747.4 844 741.1C842.9 730.8 841.4 728.9 836.8 731.6ZM787.9 734.8C787.3 736.3 786.5 738.4 786 739.5 785.6 740.7 784.8 741.7 784.3 741.7 783.7 741.7 783.7 742.5 784.4 743.9 785.6 746.5 791.1 749.1 795.3 749.1 797.6 749.1 798.1 748.5 799.2 745.6 799.7 743.7 800.6 741.6 801.1 741 801.7 740.4 801.9 738.9 801.5 737.6 800.9 735.3 798.1 733.8 792.4 732.8 789.3 732.2 788.9 732.4 787.9 734.8ZM149.2 735.4C149.2 737.4 149.3 737.4 150 735.6 150.5 734.5 150.6 736.4 150.3 740.6 149.8 746.9 149.9 747.3 152.2 749.5L154.6 751.8 156.9 749.7C158.2 748.6 159.9 745.7 160.6 743.4 162.2 737.9 161 735.8 155.2 734.4 149.5 733 149.1 733.1 149.2 735.4ZM763.6 735C762.8 735.8 761.8 738.4 761.2 740.6 760.5 744.1 760.6 744.8 762.1 746.4 763.1 747.3 764.6 748.1 765.6 748.1 766.5 748.1 768.1 748.8 769.3 749.6 772.6 751.9 775.5 749.5 776.9 743.1 778.3 736.9 777.8 735.6 773.4 734.4 768.3 732.9 765.3 733.1 763.6 735ZM197.4 755.1C195.7 756.5 194 759.4 193.1 762.1 191.1 767.8 191.6 768.4 199 770.8 204 772.5 204.1 772.5 205.7 770.4 206.7 769.3 207.4 767.7 207.4 766.9 207.4 766 208.3 764.4 209.4 763.2 211.9 760.7 211.2 759.8 206 758.1 204 757.3 201.9 755.8 201.3 754.7L200.3 752.7 197.4 755.1ZM172.8 755.7C171.9 756.9 171.3 758.2 171.3 758.8 171.3 759.4 170.5 761.4 169.4 763.3 167.4 766.9 167.5 769.4 169.7 769.4 170.4 769.4 172.5 770.3 174.5 771.3 179.5 773.9 181.2 773.6 183.3 770.1 186.3 765.3 185.7 762.9 180.6 758.1 178.1 755.6 175.6 753.7 175.1 753.7 174.6 753.7 173.5 754.6 172.8 755.7ZM835.6 758.8C833.9 761.7 832.4 764.5 832.4 765.2 832.4 767.3 838.4 770.5 842.8 770.6L846.8 770.8 846.5 764.4C846.1 757.6 845.6 756.6 841.5 754.8 839 753.8 838.8 754 835.6 758.8ZM811.1 757.4C810.6 758.3 809.9 761 809.6 763.1 808.9 768.6 811.2 770.7 817.8 770.8 822.8 770.8 822.8 770.8 825.6 764.5 826.8 761.7 826.9 760.8 825.8 759.6 822.4 755.5 813 754 811.1 757.4ZM150.1 757.3C149.4 757.8 148.7 760.6 148.4 764.4 148 770.1 148.1 771 149.8 772.6 152.9 775.3 155.8 773.9 159.6 767.9L162.9 762.7 158.1 759.6C152.9 756.3 152 756.1 150.1 757.3ZM766.9 758.5C765.2 760.5 761.1 767.8 761.1 769 761.1 770.1 767.6 772.2 770.8 772.2 773.2 772.2 775 771.4 777.5 769.1L780.9 766 778.3 762.9C775.6 759.5 771.5 756.5 769.8 756.5 769.3 756.5 768 757.4 766.9 758.5ZM789.1 757.6C788.6 758.2 787.9 760.2 787.5 761.9 787.1 763.8 786.2 765.2 785.2 765.5 782.6 766.1 784 768.3 787.8 769.4 789.7 770.1 792.1 771.6 793.2 773L795.2 775.3 798 772.5C800.7 769.8 803.3 763 802.5 760.6 802 759.5 794 756.5 791.4 756.5 790.6 756.5 789.6 757 789.1 757.6ZM220.1 779.4C218.4 781.3 216.7 786.2 216.7 789.2 216.7 790.3 218.1 791.5 221.1 792.7 223.5 793.7 226.1 795.2 226.9 795.9 228.1 797 228.7 796.5 231.4 791.3 233.1 788 234.3 784.6 234.1 783.7 233.6 781.4 229.7 778.9 225.5 778.2 222.4 777.8 221.4 778.1 220.1 779.4ZM790.9 781C789.3 782.8 787.9 785 787.9 785.9 787.5 791 789.4 794.4 793.9 796.8 797.8 798.9 799.4 798 801 792.8 801.7 790.9 802.8 788.9 803.5 788.3 805.7 786.8 804.2 784.4 799.6 782.4 797.4 781.5 795.2 780 794.7 779.2 794 777.9 793.4 778.1 790.9 781ZM838.2 778.9C837.7 779.5 836.9 781.1 836.6 782.4 836.2 783.7 835.3 785.5 834.4 786.4 833.1 787.9 833.2 788.2 836.1 791.2 839.8 795 841.9 795.8 844.4 794.5 848.1 792.5 849.1 790.6 849.1 786.1 849.1 782.4 848.7 781.5 846.8 780.2 843.4 778 839.4 777.4 838.2 778.9ZM196.9 780.7C196 781.9 195.4 783.2 195.4 783.7 195.4 784.2 194.4 785.6 193.4 786.8 191.7 788.5 191.6 789.1 192.7 790.4 193.8 791.8 203 796.3 204.6 796.3 205.4 796.3 211.1 785.6 211.1 784.3 211.1 783.2 201.9 778.7 200 778.7 199 778.7 197.6 779.6 196.9 780.7ZM815.6 779.6C814.7 780.2 812.8 782.4 811.2 784.7L808.4 788.8 812.1 792C816.1 795.7 819.5 796.3 823 793.9 824.2 793.1 825 791.5 825 790.1 825 788.5 825.6 787.6 826.9 787.3 829.4 786.7 828.9 785.5 824.9 782.3 821.2 779.4 817.8 778.3 815.6 779.6ZM173.3 780.7C172.9 781.4 171.6 783.7 170.6 785.9L168.7 789.8 171.5 792.6C176.4 797.6 181.9 797.4 185.1 792.2 188.9 786.1 187.1 782.3 179.6 780.6 174.4 779.4 174.4 779.4 173.3 780.7ZM764.8 783.3C764.2 785 763.5 788.1 763.5 790.1 763.4 793.7 763.6 794 766.8 794.9 768.6 795.4 770.7 796.4 771.6 797 775 799.9 778.4 795.9 779.4 787.8 779.8 783.6 779.7 783.3 777.2 782.4 775.7 781.8 772.6 781.1 770.3 780.8 766.2 780.4 766 780.5 764.8 783.3ZM149.1 785.5C144.8 789.4 144.8 792.3 149 795.1 150.7 796.3 153 797.2 154.1 797.2 156.9 797.2 161.4 794.3 162.9 791.3 164.2 789 164.1 788.7 161.1 785.6 156.9 781.4 153.5 781.4 149.1 785.5ZM840.2 800.7C839.6 801.1 838.2 803.3 837.2 805.7 834.7 811.5 832.7 811.5 826.8 806 821.7 801.3 818 800.6 814.7 803.8 813.2 805.3 813 806.6 813.1 810.5 813.4 814.7 813.8 815.5 816.7 817.4 821 820.3 824.1 819.8 825.4 816 825.9 814.4 827.1 812.3 828 811.4 829.5 809.9 829.7 809.9 832.1 811.9 835.4 814.4 844.1 818.5 846.4 818.5 847.4 818.5 848.1 818 848.1 817.3 848.1 816.7 849 814.6 850 812.7 852.3 808.4 852.4 805.6 850.3 805 848.4 804.4 845.8 803.1 843.1 801.3 842 800.6 840.7 800.4 840.2 800.7ZM196.9 806.2C195 809.2 193.5 811.9 193.5 812.3 193.5 815 203.1 820.2 206 819.1 206.8 818.8 208.5 816.2 209.8 813.4 212.3 808 211.9 805.6 208.4 805.6 207.5 805.6 205.5 804.5 203.7 803.2 201.9 801.9 200.5 800.9 200.4 800.9 200.3 800.9 198.6 803.3 196.9 806.2ZM221.5 803.4C220.7 804.8 218.5 813.8 218.5 815.3 218.5 815.6 220.2 816 222.2 816.3 224.4 816.7 225.9 817.4 225.9 818.1 225.9 819.8 229.2 819.8 230.8 818.1 231.6 817.4 232.9 814.6 233.7 811.9 235.6 806.2 235.2 805.6 228.3 803.3 222.6 801.5 222.5 801.5 221.5 803.4ZM792.4 803.4C790.3 805.8 786.8 814.5 787.4 815.6 788.2 816.9 796.1 820.4 798.2 820.4 800.6 820.4 803 816.5 803.4 811.8 804 807.3 803 805.9 798.7 805.2 797.3 804.9 795.6 804.1 795 803.2 794 801.9 793.8 801.9 792.4 803.4ZM172.4 808.3C170.7 811.4 169.4 814.1 169.4 814.4 169.4 814.6 170.8 815.4 172.5 816 174.1 816.8 176.3 818.2 177.2 819.4 179 821.3 179 821.4 176.1 826.9 172.2 834.1 172.2 838.1 175.9 841.8 180 845.8 183.1 845.2 185.8 839.8 188.7 833.9 188.5 831.8 185 829.6 178.8 826 178.6 825.5 181.9 821.6 184.3 818.7 188.1 809.4 187.5 808.3 186.9 807.4 177.4 802.8 176.2 802.8 175.7 802.8 174 805.3 172.4 808.3ZM149.6 805.7C148 808.4 146 815.5 146.8 816.7 147 817 148.8 818 150.7 818.6 152.6 819.2 154.8 820.3 155.6 821 158.8 823.7 162.5 819.4 163.5 811.8 164.1 807.8 164.1 807.7 160.6 806.3 153.4 803.5 151.2 803.3 149.6 805.7ZM766.2 807.8C765.5 809.5 764.4 811.2 763.9 811.6 763.4 811.9 763 813.1 763 814.4 763 816.3 763.8 817.1 767.3 818.6 769.7 819.6 772 821 772.5 821.6 773.4 823.1 780.6 815 780.6 812.4 780.6 810.2 778.7 808.3 774.4 806.1 769.7 803.8 767.7 804.2 766.2 807.8ZM223.7 824.5C223 825.3 222.1 827.1 221.8 828.7 221.4 830.2 220.3 832.1 219.2 832.9 215.1 835.7 220.9 841.3 228.9 841.9 231.8 842.1 231.9 841.9 234 836.4 235.8 831.2 235.9 830.5 234.6 829.2 233.8 828.4 232.4 827.8 231.4 827.8 230.4 827.8 228.5 826.8 227.3 825.6 225.3 823.5 224.8 823.4 223.7 824.5ZM840 826.9C838.9 828 838 829.5 838 830.6 838 831.5 837.3 832.7 836.5 833.1 835.4 833.8 835.1 834.7 835.6 836.4 836 838.2 837 839.1 840.1 839.9 842.2 840.6 844.5 841.5 845.3 842 846.7 843.1 846.9 842.8 851.4 835.8 852.7 833.9 853.7 831.9 853.7 831.5 853.7 830.4 845.4 825 843.5 825 842.7 825 841.1 825.8 840 826.9ZM198.2 828.3C195.9 831.3 194.8 836.8 196 838.8 197.1 840.6 205 843.6 206.9 843 207.6 842.7 209 840.4 210 837.9 211.1 835.4 212.4 833.3 213 833.3 214.8 833.3 212.9 831.5 208.1 828.7 202.1 825.3 200.6 825.3 198.2 828.3ZM814.4 830.7C811.4 837.2 811.5 838.3 815.2 840.6 818.3 842.6 820.9 843.1 823.6 842 825.1 841.5 830.6 834.1 830.6 832.7 830.5 831.2 821.6 825.9 819.1 825.9 816.9 825.9 816.2 826.7 814.4 830.7ZM768.7 830.4C766.6 832.4 764.8 834.6 764.8 835.4 764.8 838.6 771.9 846.3 774.9 846.3 776.6 846.3 781.5 838.8 781.5 836.3 781.5 834.2 775.2 826.9 773.2 826.9 772.9 826.9 770.8 828.4 768.7 830.4ZM793.9 827.6C791.8 828.9 788.9 834.8 788.9 837.7 788.9 840.4 789.3 840.7 792.6 841.7 794.5 842.2 796.7 843.3 797.1 844.3 798 845.7 798.1 845.7 799.9 844 801.6 842.3 806.8 833.1 806.2 832.8 797.8 826.7 796.2 826 793.9 827.6ZM150.7 829.4C149.1 831.2 146.9 839.4 147.7 840.7 148 841.2 149.7 842 151.7 842.7 153.5 843.2 155.8 844.4 156.8 845.2 158.1 846.5 158.5 846.4 160.2 844.9 162.5 842.9 165.1 836.1 164.6 833.2 164.4 830.7 161.6 829.2 156 828.2 153.1 827.8 151.9 828.1 150.7 829.4ZM840.5 849.5C839.6 850.3 838.2 853.2 837.4 856.1 835.6 861.5 836.2 863.3 839.9 864.1 841.9 864.4 853.1 854 852.4 852.3 852.1 851.6 850.3 850.6 848.1 850 846 849.4 843.8 848.8 843.1 848.5 842.4 848.2 841.2 848.7 840.5 849.5ZM198.4 854.5C196.8 857.6 195.4 860.5 195.4 860.9 195.4 861.5 197.7 863.1 200.6 864.8 205 867.3 206.2 867.6 208 866.8 210.2 865.8 210.6 864.9 210.3 861.8 210.1 860.8 211 859.8 212.4 859.3 215.4 858.1 215.4 857.3 212.8 854.9 210.9 853.3 203 849.1 201.8 849.1 201.6 849.1 200 851.6 198.4 854.5ZM223.3 850.2C222.7 850.8 222.2 852.2 222.2 853.3 222.2 855.5 220.5 857.9 218.3 858.5 216.6 859.2 218.4 861.1 222.3 862.7 224.4 863.4 226.6 864.9 227.2 865.9 229.1 868.6 231.4 866.9 234.5 860.7 237.7 854.4 237.1 852.7 230.8 850.6 225.6 848.8 224.8 848.7 223.3 850.2ZM793 852.3C792.3 854.1 791.7 855.9 791.7 856.4 791.7 856.9 790.8 857.9 789.7 858.7 788.3 859.6 788 860.6 788.4 861.9 789.1 864.2 795.8 867.6 799.7 867.6 802.4 867.6 802.7 867.2 804.5 861.9 806.8 855.4 806.4 854.5 801 853 799.1 852.3 797.1 851.2 796.9 850.5 796 848.1 794.4 848.9 793 852.3ZM816.3 851.1C814.4 852.7 813.7 854.4 813.2 858.1L812.7 863 816.3 864.4C818.3 865.2 820.8 866.3 821.9 866.9 824.8 868.2 826.3 866.8 828.7 860.4 830.9 854.5 830.7 853.4 827.1 851.6 821.9 848.9 819 848.8 816.3 851.1ZM770.6 852C768 855.1 765.7 859.7 765.7 862.5 765.7 864.4 766.5 865.2 769.3 866.4 771.1 867.2 774.1 867.9 775.8 868 778.7 868.1 779.1 867.8 779.8 864.8 780.3 863.1 781.5 860.8 782.5 860 784.9 858 784.2 856.8 779.1 854.5 776.8 853.6 774.7 852.2 774.4 851.4 773.7 849.5 772.9 849.6 770.6 852ZM174.6 853C173.8 854.2 172.9 857 172.6 859.4L172 863.4 177.7 866C182.1 868.1 183.7 868.4 185.2 867.6 187.1 866.6 190.2 857.7 189.4 855.5 188.5 853.3 185.4 851.8 180.6 851.2 176.6 850.7 175.9 850.9 174.6 853ZM150.7 854.3C149.6 856.6 149.9 857 155.4 862.1 158.5 865.2 161.5 867.6 161.9 867.6 163.1 867.6 166 860.6 166 857.8 166 855.1 164.9 854.2 160.2 852.8 154.5 851.2 151.9 851.6 150.7 854.3ZM225.2 872.4C224.5 873.1 224.1 874.3 224.1 875.1 224.1 876 223.1 878 221.8 879.4 220.4 881.1 219.6 882.9 220 883.7 220.9 886 230.5 890.3 232.3 889.2 234.3 888 236.1 884.2 236.8 880 237.3 876.4 236.3 875 232.7 875 231.5 875 230.1 874.2 229.4 873.1 228.1 871 226.8 870.8 225.2 872.4ZM176.1 875.2C173.8 877.5 175.1 880.1 181 885 186.7 889.6 186.9 889.7 187.5 887.8 187.9 886.6 189.1 884.7 190.1 883.5L191.9 881.5 189.7 879.1C185.8 874.8 178.6 872.7 176.1 875.2ZM200.1 876.4C198.6 877.7 197 879.5 196.8 880.6 196 882.9 198.6 886.8 201.9 888.5 205 890.1 207.2 889.3 212.9 884.5 215.6 882.2 215.8 881.6 215 879.9 213.5 877.3 208.2 874.1 205.3 874.1 204 874.1 201.7 875.1 200.1 876.4ZM770.2 876.1C768.1 877.7 766.7 881.7 766.7 885.6 766.7 888.5 767 888.9 770.2 889.7 772 890.3 774.5 891.3 775.6 892.1 777.4 893.3 777.8 893.3 780 891.1 784.3 886.8 784.4 879 780.2 877 776.2 875.3 771.9 874.8 770.2 876.1ZM792.2 879.3C791.3 881.8 790.6 884.5 790.5 885.6 790.2 887.9 794.4 890.7 798.8 891.4 801.9 891.8 802.8 891.6 804.4 889.4 805.4 888.1 806.5 885.4 806.9 883.2 807.7 877.9 805.6 875.7 798.8 875.2L793.8 874.8 792.2 879.3ZM745.4 879.3C744.7 880.7 743.7 883.1 743 884.5 741.3 887.9 741.7 888.4 747.2 891.2 749.7 892.5 752 894 752.4 894.5 753.3 896.1 759.3 886.3 759.3 883.1 759.3 879.9 756.1 877.7 750.5 877 746.7 876.7 746.3 876.8 745.4 879.3ZM225.6 897.7C224.8 898.4 223.9 900.4 223.6 902 223.2 903.7 222.5 905.6 221.9 906.3 220.8 907.7 220.6 907.4 226.6 911.1 232 914.4 234.1 914.3 236.3 910.5 238.1 907.3 239.1 901.8 238.1 900.4 236.2 897.4 227.7 895.6 225.6 897.7ZM747.9 900.4C746.2 902.1 743.2 910 743.8 911.4 744.1 912 746.7 913.7 749.5 915.3L754.8 918.1 757 915.5C761.8 910 761.1 904.9 755.3 901.4 750.6 898.7 749.7 898.6 747.9 900.4ZM769.4 901.9C768.2 904.1 767.6 906.3 767.8 908.7 768.1 912 768.3 912.3 772.6 914L777.2 915.6 780.3 913.3C783.4 910.9 784.6 908.2 784.1 904.5 783.8 902 780.3 900 774.9 899.4 771.7 898.9 771.2 899.1 769.4 901.9Z", + "width": 1000 + }, + "search": [ + "roboticon" + ] } ] } \ No newline at end of file diff --git a/assets/app_icons/fonts/DQIcons.ttf b/assets/app_icons/fonts/DQIcons.ttf index 3cff7aa3..bc92c83d 100644 Binary files a/assets/app_icons/fonts/DQIcons.ttf and b/assets/app_icons/fonts/DQIcons.ttf differ diff --git a/assets/images/BMI/BMIChart_AR.png b/assets/images/BMI/BMIChart_AR.png new file mode 100644 index 00000000..405574c0 Binary files /dev/null and b/assets/images/BMI/BMIChart_AR.png differ diff --git a/assets/images/BMI/BMIChart_EN.png b/assets/images/BMI/BMIChart_EN.png new file mode 100644 index 00000000..2432e888 Binary files /dev/null and b/assets/images/BMI/BMIChart_EN.png differ diff --git a/assets/images/BMI/bmi_blue_female_ar.png b/assets/images/BMI/bmi_blue_female_ar.png new file mode 100644 index 00000000..483cb664 Binary files /dev/null and b/assets/images/BMI/bmi_blue_female_ar.png differ diff --git a/assets/images/BMI/bmi_blue_female_en.png b/assets/images/BMI/bmi_blue_female_en.png new file mode 100644 index 00000000..9984736e Binary files /dev/null and b/assets/images/BMI/bmi_blue_female_en.png differ diff --git a/assets/images/BMI/bmi_blue_male_ar.png b/assets/images/BMI/bmi_blue_male_ar.png new file mode 100644 index 00000000..d4ff734c Binary files /dev/null and b/assets/images/BMI/bmi_blue_male_ar.png differ diff --git a/assets/images/BMI/bmi_blue_male_en.png b/assets/images/BMI/bmi_blue_male_en.png new file mode 100644 index 00000000..ec50a0c6 Binary files /dev/null and b/assets/images/BMI/bmi_blue_male_en.png differ diff --git a/assets/images/BMI/bmi_green_female_ar.png b/assets/images/BMI/bmi_green_female_ar.png new file mode 100644 index 00000000..f8dc4759 Binary files /dev/null and b/assets/images/BMI/bmi_green_female_ar.png differ diff --git a/assets/images/BMI/bmi_green_female_en.png b/assets/images/BMI/bmi_green_female_en.png new file mode 100644 index 00000000..b4eb32e0 Binary files /dev/null and b/assets/images/BMI/bmi_green_female_en.png differ diff --git a/assets/images/BMI/bmi_green_male_ar.png b/assets/images/BMI/bmi_green_male_ar.png new file mode 100644 index 00000000..380d8384 Binary files /dev/null and b/assets/images/BMI/bmi_green_male_ar.png differ diff --git a/assets/images/BMI/bmi_green_male_en.png b/assets/images/BMI/bmi_green_male_en.png new file mode 100644 index 00000000..78693310 Binary files /dev/null and b/assets/images/BMI/bmi_green_male_en.png differ diff --git a/assets/images/BMI/bmi_orange_female_ar.png b/assets/images/BMI/bmi_orange_female_ar.png new file mode 100644 index 00000000..b2437c14 Binary files /dev/null and b/assets/images/BMI/bmi_orange_female_ar.png differ diff --git a/assets/images/BMI/bmi_orange_female_en.png b/assets/images/BMI/bmi_orange_female_en.png new file mode 100644 index 00000000..31779cd3 Binary files /dev/null and b/assets/images/BMI/bmi_orange_female_en.png differ diff --git a/assets/images/BMI/bmi_orange_male_ar.png b/assets/images/BMI/bmi_orange_male_ar.png new file mode 100644 index 00000000..291b316e Binary files /dev/null and b/assets/images/BMI/bmi_orange_male_ar.png differ diff --git a/assets/images/BMI/bmi_orange_male_en.png b/assets/images/BMI/bmi_orange_male_en.png new file mode 100644 index 00000000..c6ebb5eb Binary files /dev/null and b/assets/images/BMI/bmi_orange_male_en.png differ diff --git a/assets/images/BMI/bmi_red_female_ar.png b/assets/images/BMI/bmi_red_female_ar.png new file mode 100644 index 00000000..0e4d7339 Binary files /dev/null and b/assets/images/BMI/bmi_red_female_ar.png differ diff --git a/assets/images/BMI/bmi_red_female_en.png b/assets/images/BMI/bmi_red_female_en.png new file mode 100644 index 00000000..0d5dfe80 Binary files /dev/null and b/assets/images/BMI/bmi_red_female_en.png differ diff --git a/assets/images/BMI/bmi_red_male_ar.png b/assets/images/BMI/bmi_red_male_ar.png new file mode 100644 index 00000000..86a47cb2 Binary files /dev/null and b/assets/images/BMI/bmi_red_male_ar.png differ diff --git a/assets/images/BMI/bmi_red_male_en.png b/assets/images/BMI/bmi_red_male_en.png new file mode 100644 index 00000000..452aa4f3 Binary files /dev/null and b/assets/images/BMI/bmi_red_male_en.png differ diff --git a/assets/images/BMI/bmi_yellow_female_ar.png b/assets/images/BMI/bmi_yellow_female_ar.png new file mode 100644 index 00000000..7453a642 Binary files /dev/null and b/assets/images/BMI/bmi_yellow_female_ar.png differ diff --git a/assets/images/BMI/bmi_yellow_female_en.png b/assets/images/BMI/bmi_yellow_female_en.png new file mode 100644 index 00000000..d2374c22 Binary files /dev/null and b/assets/images/BMI/bmi_yellow_female_en.png differ diff --git a/assets/images/BMI/bmi_yellow_male_ar.png b/assets/images/BMI/bmi_yellow_male_ar.png new file mode 100644 index 00000000..754cf6ea Binary files /dev/null and b/assets/images/BMI/bmi_yellow_male_ar.png differ diff --git a/assets/images/BMI/bmi_yellow_male_en.png b/assets/images/BMI/bmi_yellow_male_en.png new file mode 100644 index 00000000..f64decfe Binary files /dev/null and b/assets/images/BMI/bmi_yellow_male_en.png differ diff --git a/assets/images/BMI/default.png b/assets/images/BMI/default.png new file mode 100644 index 00000000..cef9f7d7 Binary files /dev/null and b/assets/images/BMI/default.png differ diff --git a/assets/images/DQ/logo.png b/assets/images/DQ/logo.png new file mode 100644 index 00000000..29719b35 Binary files /dev/null and b/assets/images/DQ/logo.png differ diff --git a/assets/images/DQ/logo_big.png b/assets/images/DQ/logo_big.png new file mode 100644 index 00000000..0d9e4a56 Binary files /dev/null and b/assets/images/DQ/logo_big.png differ diff --git a/assets/images/discount_ar.png b/assets/images/discount_ar.png new file mode 100644 index 00000000..854d1c1f Binary files /dev/null and b/assets/images/discount_ar.png differ diff --git a/assets/images/discount_en.png b/assets/images/discount_en.png new file mode 100644 index 00000000..2af52865 Binary files /dev/null and b/assets/images/discount_en.png differ diff --git a/assets/images/gif/robot-idle.gif b/assets/images/gif/robot-idle.gif new file mode 100644 index 00000000..89dee325 Binary files /dev/null and b/assets/images/gif/robot-idle.gif differ diff --git a/assets/images/gif/robot-speaking.gif b/assets/images/gif/robot-speaking.gif new file mode 100644 index 00000000..253d786b Binary files /dev/null and b/assets/images/gif/robot-speaking.gif differ diff --git a/assets/images/logo_HMG.png b/assets/images/logo_HMG.png new file mode 100644 index 00000000..0d9e4a56 Binary files /dev/null and b/assets/images/logo_HMG.png differ diff --git a/assets/images/map_markers/destination_map_marker.png b/assets/images/map_markers/destination_map_marker.png new file mode 100644 index 00000000..4f4eca35 Binary files /dev/null and b/assets/images/map_markers/destination_map_marker.png differ diff --git a/assets/images/map_markers/driver-pin.png b/assets/images/map_markers/driver-pin.png new file mode 100644 index 00000000..9d16ceca Binary files /dev/null and b/assets/images/map_markers/driver-pin.png differ diff --git a/assets/images/map_markers/source_map_marker.png b/assets/images/map_markers/source_map_marker.png new file mode 100644 index 00000000..4b493b09 Binary files /dev/null and b/assets/images/map_markers/source_map_marker.png differ diff --git a/assets/images/new-design/covid-19-car.svg b/assets/images/new-design/covid-19-car.svg new file mode 100644 index 00000000..b5c9cb85 --- /dev/null +++ b/assets/images/new-design/covid-19-car.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/new-design/video.png b/assets/images/new-design/video.png new file mode 100644 index 00000000..2962aade Binary files /dev/null and b/assets/images/new-design/video.png differ diff --git a/assets/images/new-design/view_more.png b/assets/images/new-design/view_more.png new file mode 100644 index 00000000..8b52a7e7 Binary files /dev/null and b/assets/images/new-design/view_more.png differ diff --git a/assets/images/new-design/walkin.png b/assets/images/new-design/walkin.png new file mode 100644 index 00000000..248c8788 Binary files /dev/null and b/assets/images/new-design/walkin.png differ diff --git a/assets/images/pharmacy/Redheart.svg b/assets/images/pharmacy/Redheart.svg new file mode 100644 index 00000000..3bba67fa --- /dev/null +++ b/assets/images/pharmacy/Redheart.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/images/pharmacy/heart-empty.svg b/assets/images/pharmacy/heart-empty.svg new file mode 100644 index 00000000..a682a44e --- /dev/null +++ b/assets/images/pharmacy/heart-empty.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/images/pharmacy/shipping_image.png b/assets/images/pharmacy/shipping_image.png new file mode 100644 index 00000000..ba16e92c Binary files /dev/null and b/assets/images/pharmacy/shipping_image.png differ diff --git a/assets/images/pharmacy/shipping_image_ar.png b/assets/images/pharmacy/shipping_image_ar.png new file mode 100644 index 00000000..cb623a62 Binary files /dev/null and b/assets/images/pharmacy/shipping_image_ar.png differ diff --git a/assets/images/pharmacy/sort.png b/assets/images/pharmacy/sort.png new file mode 100644 index 00000000..0143d915 Binary files /dev/null and b/assets/images/pharmacy/sort.png differ diff --git a/assets/images/roboticon.png b/assets/images/roboticon.png new file mode 100644 index 00000000..5b04e287 Binary files /dev/null and b/assets/images/roboticon.png differ diff --git a/assets/images/soundWaveAnimation.gif b/assets/images/soundWaveAnimation.gif new file mode 100644 index 00000000..730e27eb Binary files /dev/null and b/assets/images/soundWaveAnimation.gif differ diff --git a/assets/images/svg/discount_ar.svg b/assets/images/svg/discount_ar.svg new file mode 100644 index 00000000..d9d6ec27 --- /dev/null +++ b/assets/images/svg/discount_ar.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + مصخ + + + + diff --git a/assets/images/svg/discount_en.svg b/assets/images/svg/discount_en.svg new file mode 100644 index 00000000..294cf19c --- /dev/null +++ b/assets/images/svg/discount_en.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/images/svg/robort_svg.svg b/assets/images/svg/robort_svg.svg index 07d3d4b4..8b4875a1 100644 --- a/assets/images/svg/robort_svg.svg +++ b/assets/images/svg/robort_svg.svg @@ -1,3 +1,4 @@ + diff --git a/assets/images/svg/success.svg b/assets/images/svg/success.svg new file mode 100644 index 00000000..343589bd --- /dev/null +++ b/assets/images/svg/success.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..614a6708 --- /dev/null +++ b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug report +about: Create a report to help us improve + +--- + +## 🐛 Bug Report + + + +### Expected behavior + +### Reproduction steps + +### Configuration + +**Version:** 0.1.x + +**Platform:** +- [ ] :iphone: iOS +- [ ] :robot: Android diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..35a881a3 --- /dev/null +++ b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project + +--- + +## 🚀 Feature Requests + + + +### Contextualize the feature + + +### Describe the feature + + +### Platforms affected (mark all that apply) +- [ ] :iphone: iOS +- [ ] :robot: Android diff --git a/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md new file mode 100644 index 00000000..ba501f3c --- /dev/null +++ b/flutter_tts-voice_enhancement/.github/ISSUE_TEMPLATE/questions-and-help.md @@ -0,0 +1,9 @@ +--- +name: Questions and Help +about: If you have questions, please use this for support + +--- + +## 💬 Questions and Help + +Provide question related to this flutter plugin. diff --git a/flutter_tts-voice_enhancement/.github/workflows/main.yml b/flutter_tts-voice_enhancement/.github/workflows/main.yml new file mode 100644 index 00000000..832dd069 --- /dev/null +++ b/flutter_tts-voice_enhancement/.github/workflows/main.yml @@ -0,0 +1,34 @@ +name: github pages + +on: + push: + branches: + - master + +jobs: + deploy: + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + + - name: Setup Flutter + run: | + git clone https://github.com/flutter/flutter.git --depth 1 -b beta _flutter + echo "::add-path::${GITHUB_WORKSPACE}/_flutter/bin" + + - name: Install + run: | + cd example + flutter config --enable-web + flutter pub get + + - name: Build + run: | + cd example + flutter build web + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./example/build/web diff --git a/flutter_tts-voice_enhancement/.gitignore b/flutter_tts-voice_enhancement/.gitignore new file mode 100644 index 00000000..bc0883df --- /dev/null +++ b/flutter_tts-voice_enhancement/.gitignore @@ -0,0 +1,94 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.project +.svn/ +bin/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# Android Studio related +android/.classpath +android/.settings/ + +# Visual Studio Code related +.vscode/ + +# Flutter repo-specific +/bin/cache/ +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/docs/doc/ +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/packages/flutter/coverage/ +version + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +example/ios/Flutter/flutter_export_environment.sh diff --git a/flutter_tts-voice_enhancement/CHANGELOG.md b/flutter_tts-voice_enhancement/CHANGELOG.md new file mode 100644 index 00000000..bff8b759 --- /dev/null +++ b/flutter_tts-voice_enhancement/CHANGELOG.md @@ -0,0 +1,197 @@ +# ChangeLog + +## 1.3.0 + +- All: Adding await speak completion + +## 1.2.7 + +- iOS: Adding utterance settings to synthesizeToFile +- Android: Fix crash when utterance completes after Engine is detached + +## 1.2.6 + +- Android: Fixing new API onAttachedToEngine call + +## 1.2.5 + +- macOS: Adding support + +## 1.2.4 + +- iOS: Deactivate audio session only when needed +- Android: Better exception handling for getLanguages +- Android: Adding getEngines +- Android: Adding new Android plugin APIs + +## 1.2.3 + +- iOS: Adding synthesize to file +- iOS: Fix set category ios + +## 1.2.2 + +- Web: Adding pause and continue + +## 1.2.1 + +- iOS: Fix setting iOS Category +- iOS/Android: Adding additional platform calls + +## 1.2.0 + +- iOS: Adding Set Audio Session Category +- Android: Bug fixes + +## 1.1.0 + +- iOS: Adding Pause +- iOS: Adding set Shared Instance + +## 1.0.0 + +- iOS/Android: Feature - Speech marks +- iOS/Android: Breaking changes to Speech rate + +## 0.9.2 + +- iOS: Changing audio session to playAndRecord + +## 0.9.1 + +- Android: Fixing method call error + +## 0.9.0 + +- Android: Adding synthesize to file + +## 0.8.7 + +- Android: Fix sporadic ANR on initialization + +## 0.8.6 + +- iOS: Reducing volume of other sessions while TTS is playing + +## 0.8.5 + +- Android: Fix Android async platform initialization +- Android: Removing initHandler + +## 0.8.2 + +- Web: Adding isLanguageAvailable method +- All: Fixing isLanguageAvailable platform channel and making it case insensitive + +## 0.8.0 + +- Web: Adding Web Support + +## 0.7.0 + +- iOS: Adding Swift version 4.2 to podspec and correct audio playback category + +## 0.6.0 + +- Android: AndroidX support + +## 0.5.2 + +- Android: Bug Fix on isLanguageAvailable + +## 0.5.1 + +- Applying flutter format to fix health suggestion + +## 0.5.0 + +- Android: Adding silence before speak +- Android: Removing deprecated API + +## 0.2.6 + +- IOS: Add voice selection implementation + +## 0.2.5 + +- Android: Ensure invokeMethod runs on main thread + +## 0.2.4 + +- Android: setting minSDK back to 21 and adding instructions to readme +- Android: Adding fallback for getLanguages and defaultLanguage + +## 0.2.3 + +- IOS: Audio continues with the Ring/Silent switch set to silent + +## 0.2.2 + +- Android: Fixing Locale bug + +## 0.2.1 + +- IOS: Fixing getLanguages bug + +## 0.2.0 + +- Android: Adding exception catch for samsung devices +- Android: Using default com.google.android.tts engine +- Android: Get and Set Voice +- Android: InitHandler +- Cleaning up the example + +## 0.1.2 + +- Support for Android background execution +- Updating Android build gradle version to 3.2.1 + +## 0.1.1 + +- Fixing TTS bound error in the example +- Fixing default voice language not found error on Android + +## 0.1.0 + +- Updating version for improved maintenance score +- Updating package description for improved maintenance score + +## 0.0.8 + +- Adding analysis_options.yaml for improved health score +- Fixing info/errors from flutter analyze + +## 0.0.7 + +- Updating SDK version in pubspec.yaml +- Adding package link to README +- Fixing language string warning received from xcode + +## 0.0.6 + +- Android: Upgrading Gradle 4.1 to 4.4 +- Android: Setting minSdk version to 21 +- Android: Adding try/catch to getAvailableLanguages & getDefaultVoice methods (Issues with API 21 & 22) + +## 0.0.5 + +- Adding IOS/Android isLanguageAvailable +- Rename setRate to setSpeechRate + +## 0.0.4 + +- Simplify podspec for Cocoapods 1.5.0 + +## 0.0.3 + +- Adding IOS/Android speech pitch and volume + +## 0.0.2 + +- Flutter formatting and fixing pubspec sdk versioning + +## 0.0.1 + +- first POC : + - methods : speak, stop, setRate, setLangauge, getLanguages + - a globalHandler for completion diff --git a/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md b/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..43989576 --- /dev/null +++ b/flutter_tts-voice_enhancement/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at eyedea32@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/flutter_tts-voice_enhancement/LICENSE b/flutter_tts-voice_enhancement/LICENSE new file mode 100644 index 00000000..56dcdf22 --- /dev/null +++ b/flutter_tts-voice_enhancement/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Daniel Lutton + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/flutter_tts-voice_enhancement/README.md b/flutter_tts-voice_enhancement/README.md new file mode 100644 index 00000000..4e32d45d --- /dev/null +++ b/flutter_tts-voice_enhancement/README.md @@ -0,0 +1,194 @@ +# Text To Speech + +[![pub package](https://img.shields.io/pub/v/flutter_tts.svg?style=for-the-badge&colorB=green)](https://pub.dartlang.org/packages/flutter_tts) + +A flutter text to speech plugin (Swift,Java) + +## Features + +- [x] Android, iOS, Web, & macOS + - [x] speak + - [x] stop + - [x] get languages + - [x] set language + - [x] set speech rate + - [x] set speech volume + - [x] set speech pitch + - [x] is language available +- [x] Android, iOS + - [x] get voices + - [x] set voice + - [x] speech marks (requires iOS 7+ and Android 26+) + - [x] synthesize to file (requires iOS 13+) +- [x] iOS, Web + - [x] pause +- [x] Android + - [x] set Silence +- [x] iOS + - [x] set shared instance + - [x] set audio session category + +## Usage + +## macOS + +```bash +OSX version: 10.15 +``` + +[Example App](https://github.com/dlutton/flutter_tts/tree/macOS_app) from the macOS_app branch + +## Web + +[Website](https://dlutton.github.io/flutter_tts) from the example directory. + +## Android + +Change the minimum Android sdk version to 21 (or higher) in your `android/app/build.gradle` file. + +```java +minSdkVersion 21 +``` + +## iOS + +There's a known issue with integrating plugins that use Swift into a Flutter project created with the Objective-C template. [Flutter#16049](https://github.com/flutter/flutter/issues/16049) + +[Example](https://github.com/dlutton/flutter_tts/blob/master/example/lib/main.dart) + +To use this plugin : + +- add the dependency to your [pubspec.yaml](https://github.com/dlutton/flutter_tts/blob/master/example/pubspec.yaml) file. + +```yaml + dependencies: + flutter: + sdk: flutter + flutter_tts: +``` + +- instantiate FlutterTts + +```dart +FlutterTts flutterTts = FlutterTts(); + +``` + +To set shared audio [instance](https://developer.apple.com/documentation/avfoundation/avaudiosession/1616504-sharedinstance) (iOS only): + +```dart +await flutterTts.setSharedInstance(true); +``` + +To set audio [category and options](https://developer.apple.com/documentation/avfoundation/avaudiosession) (iOS only): + +```dart +await flutterTts + .setIosAudioCategory(IosTextToSpeechAudioCategory.playAndRecord, [ + IosTextToSpeechAudioCategoryOptions.allowBluetooth, + IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP, + IosTextToSpeechAudioCategoryOptions.mixWithOthers + ]); +``` + +To await speak completion. + +```dart +await flutterTts.awaitSpeakCompletion(true); +``` + +### speak, stop, getLanguages, setLanguage, setSpeechRate, setVoice, setVolume, setPitch, isLanguageAvailable, setSharedInstance + +```dart +Future _speak() async{ + var result = await flutterTts.speak("Hello World"); + if (result == 1) setState(() => ttsState = TtsState.playing); +} + +Future _stop() async{ + var result = await flutterTts.stop(); + if (result == 1) setState(() => ttsState = TtsState.stopped); +} + +List languages = await flutterTts.getLanguages; + +await flutterTts.setLanguage("en-US"); + +await flutterTts.setSpeechRate(1.0); + +await flutterTts.setVolume(1.0); + +await flutterTts.setPitch(1.0); + +await flutterTts.isLanguageAvailable("en-US"); + +// iOS and Web only +await flutterTts.pause(); + +// iOS, macOS, and Android only +await flutterTts.synthesizeToFile("Hello World", Platform.isAndroid ? "tts.wav" : "tts.caf"); + +await flutterTts.setVoice({"name": "Karen", "locale": "en-AU"}); + +// iOS only +await flutterTts.setSharedInstance(true); + +// Android only +await flutterTts.setSilence(2); + +await flutterTts.getEngines(); +``` + +### Listening for platform calls + +```dart +flutterTts.setStartHandler(() { + setState(() { + ttsState = TtsState.playing; + }); +}); + +flutterTts.setCompletionHandler(() { + setState(() { + ttsState = TtsState.stopped; + }); +}); + +flutterTts.setProgressHandler((String text, int startOffset, int endOffset, String word) { + setState(() { + _currentWord = word; + }); +}); + +flutterTts.setErrorHandler((msg) { + setState(() { + ttsState = TtsState.stopped; + }); +}); + +flutterTts.setCancelHandler((msg) { + setState(() { + ttsState = TtsState.stopped; + }); +}); + +// iOS and Web +flutterTts.setPauseHandler((msg) { + setState(() { + ttsState = TtsState.paused; + }); +}); + +flutterTts.setContinueHandler((msg) { + setState(() { + ttsState = TtsState.continued; + }); +}); +``` + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.dev/). + +For help on editing plugin code, view the [documentation](https://flutter.dev/platform-plugins/#edit-code). diff --git a/flutter_tts-voice_enhancement/analysis_options.yaml b/flutter_tts-voice_enhancement/analysis_options.yaml new file mode 100644 index 00000000..e8779c50 --- /dev/null +++ b/flutter_tts-voice_enhancement/analysis_options.yaml @@ -0,0 +1,35 @@ +analyzer: + strong-mode: + implicit-casts: false + errors: + unused_import: error + unused_local_variable: error + dead_code: error +linter: + rules: + - avoid_empty_else + - comment_references + - control_flow_in_finally + - empty_statements + - hash_and_equals + - only_throw_errors + - test_types_in_equals + - throw_in_finally + - unrelated_type_equality_checks + - valid_regexps + - avoid_init_to_null + - avoid_return_types_on_setters + - await_only_futures + - camel_case_types + - directives_ordering + - empty_catches + - empty_constructor_bodies + - library_names + - library_prefixes + - non_constant_identifier_names + - omit_local_variable_types + - prefer_final_fields + - prefer_is_not_empty + - prefer_typing_uninitialized_variables + - slash_for_doc_comments + - type_init_formals \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/android/.gitignore b/flutter_tts-voice_enhancement/android/.gitignore new file mode 100644 index 00000000..c6cbe562 --- /dev/null +++ b/flutter_tts-voice_enhancement/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/flutter_tts-voice_enhancement/android/build.gradle b/flutter_tts-voice_enhancement/android/build.gradle new file mode 100644 index 00000000..1308c920 --- /dev/null +++ b/flutter_tts-voice_enhancement/android/build.gradle @@ -0,0 +1,48 @@ +def PLUGIN = "flutter_tts"; +def ANDROIDX_WARNING = "flutterPluginsAndroidXWarning"; +gradle.buildFinished { buildResult -> + if (buildResult.failure && !rootProject.ext.has(ANDROIDX_WARNING)) { + println ' *********************************************************' + println 'WARNING: This version of ' + PLUGIN + ' will break your Android build if it or its dependencies aren\'t compatible with AndroidX.' + println ' See https://goo.gl/CP92wY for more information on the problem and how to fix it.' + println ' This warning prints for all Android build failures. The real root cause of the error may be unrelated.' + println ' *********************************************************' + rootProject.ext.set(ANDROIDX_WARNING, true); + } +} + +group 'com.tundralabs.fluttertts' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.4.2' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 21 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + targetSdkVersion 27 + } + lintOptions { + disable 'InvalidPackage' + } +} diff --git a/flutter_tts-voice_enhancement/android/gradle.properties b/flutter_tts-voice_enhancement/android/gradle.properties new file mode 100644 index 00000000..a6738207 --- /dev/null +++ b/flutter_tts-voice_enhancement/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties b/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..8d9c8a3f --- /dev/null +++ b/flutter_tts-voice_enhancement/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Sep 27 12:18:40 PDT 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip diff --git a/flutter_tts-voice_enhancement/android/settings.gradle b/flutter_tts-voice_enhancement/android/settings.gradle new file mode 100644 index 00000000..26aeb433 --- /dev/null +++ b/flutter_tts-voice_enhancement/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'flutter_tts' diff --git a/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml b/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..9cad3a1b --- /dev/null +++ b/flutter_tts-voice_enhancement/android/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + diff --git a/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java b/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java new file mode 100644 index 00000000..92e6a092 --- /dev/null +++ b/flutter_tts-voice_enhancement/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java @@ -0,0 +1,454 @@ +package com.tundralabs.fluttertts; + +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.speech.tts.TextToSpeech; +import android.speech.tts.UtteranceProgressListener; +import android.speech.tts.Voice; +import android.util.Log; +import androidx.annotation.NonNull; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry.Registrar; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.UUID; + +/** FlutterTtsPlugin */ +public class FlutterTtsPlugin implements MethodCallHandler, FlutterPlugin { + private Handler handler; + private MethodChannel methodChannel; + private MethodChannel.Result speakResult; + private boolean awaitSpeakCompletion = false; + private boolean speaking = false; + private Context context; + private TextToSpeech tts; + private final String tag = "TTS"; + private final String googleTtsEngine = "com.google.android.tts"; + private boolean isTtsInitialized = false; + private ArrayList pendingMethodCalls = new ArrayList<>(); + private final HashMap utterances = new HashMap<>(); + Bundle bundle; + private int silencems; + private static final String SILENCE_PREFIX = "SIL_"; + private static final String SYNTHESIZE_TO_FILE_PREFIX = "STF_"; + + /** Plugin registration. */ + public static void registerWith(Registrar registrar) { + FlutterTtsPlugin instance = new FlutterTtsPlugin(); + instance.initInstance(registrar.messenger(), registrar.activeContext()); + } + + private void initInstance(BinaryMessenger messenger, Context context) { + this.context = context; + methodChannel = new MethodChannel(messenger, "flutter_tts"); + methodChannel.setMethodCallHandler(this); + handler = new Handler(Looper.getMainLooper()); + bundle = new Bundle(); + tts = new TextToSpeech(context, onInitListener, googleTtsEngine); + } + + /** Android Plugin APIs */ + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + initInstance(binding.getBinaryMessenger(), binding.getApplicationContext()); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + stop(); + tts.shutdown(); + context = null; + methodChannel.setMethodCallHandler(null); + methodChannel = null; + } + + private UtteranceProgressListener utteranceProgressListener = + new UtteranceProgressListener() { + @Override + public void onStart(String utteranceId) { + if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + invokeMethod("synth.onStart", true); + } else { + Log.d(tag, "Utterance ID has started: " + utteranceId); + invokeMethod("speak.onStart", true); + } + if (Build.VERSION.SDK_INT < 26) { + this.onProgress(utteranceId, 0, utterances.get(utteranceId).length()); + } + } + + @Override + public void onDone(String utteranceId) { + if (utteranceId != null && utteranceId.startsWith(SILENCE_PREFIX)) return; + if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + invokeMethod("synth.onComplete", true); + } else { + Log.d(tag, "Utterance ID has completed: " + utteranceId); + if (awaitSpeakCompletion) { + speakCompletion(1); + } + invokeMethod("speak.onComplete", true); + } + utterances.remove(utteranceId); + } + + @Override + public void onStop(String utteranceId, boolean interrupted) { + Log.d( + tag, + "Utterance ID has been stopped: " + utteranceId + ". Interrupted: " + interrupted); + if (awaitSpeakCompletion) { + speaking = false; + } + invokeMethod("speak.onCancel", true); + } + + private void onProgress(String utteranceId, int startAt, int endAt) { + if (utteranceId != null && !utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + final String text = utterances.get(utteranceId); + final HashMap data = new HashMap<>(); + data.put("text", text); + data.put("start", Integer.toString(startAt)); + data.put("end", Integer.toString(endAt)); + data.put("word", text.substring(startAt, endAt)); + invokeMethod("speak.onProgress", data); + } + } + + // Requires Android 26 or later + @Override + public void onRangeStart(String utteranceId, int startAt, int endAt, int frame) { + if (utteranceId != null && !utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + super.onRangeStart(utteranceId, startAt, endAt, frame); + this.onProgress(utteranceId, startAt, endAt); + } + } + + @Override + @Deprecated + public void onError(String utteranceId) { + if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + invokeMethod("synth.onError", "Error from TextToSpeech (synth)"); + } else { + if (awaitSpeakCompletion) { + speaking = false; + } + invokeMethod("speak.onError", "Error from TextToSpeech (speak)"); + } + } + + @Override + public void onError(String utteranceId, int errorCode) { + if (utteranceId != null && utteranceId.startsWith(SYNTHESIZE_TO_FILE_PREFIX)) { + invokeMethod("synth.onError", "Error from TextToSpeech (synth) - " + errorCode); + } else { + if (awaitSpeakCompletion) { + speaking = false; + } + invokeMethod("speak.onError", "Error from TextToSpeech (speak) - " + errorCode); + } + } + }; + + void speakCompletion(final int success) { + speaking = false; + handler.post( + new Runnable() { + @Override + public void run() { + speakResult.success(success); + } + }); + } + + private TextToSpeech.OnInitListener onInitListener = + new TextToSpeech.OnInitListener() { + @Override + public void onInit(int status) { + if (status == TextToSpeech.SUCCESS) { + tts.setOnUtteranceProgressListener(utteranceProgressListener); + + try { + Locale locale = tts.getDefaultVoice().getLocale(); + if (isLanguageAvailable(locale)) { + tts.setLanguage(locale); + } + } catch (NullPointerException | IllegalArgumentException e) { + Log.e(tag, "getDefaultLocale: " + e.getMessage()); + } + + // Handle pending method calls (sent while TTS was initializing) + isTtsInitialized = true; + for (Runnable call : pendingMethodCalls) { + call.run(); + } + } else { + Log.e(tag, "Failed to initialize TextToSpeech"); + } + } + }; + + @Override + public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { + // If TTS is still loading + if (!isTtsInitialized) { + // Suspend method call until the TTS engine is ready + final Runnable suspendedCall = + new Runnable() { + public void run() { + onMethodCall(call, result); + } + }; + pendingMethodCalls.add(suspendedCall); + return; + } + switch (call.method) { + case "speak": + { + String text = call.arguments.toString(); + if (this.speaking) { + result.success(0); + break; + } + speak(text); + if (this.awaitSpeakCompletion) { + this.speaking = true; + this.speakResult = result; + } else { + result.success(1); + } + break; + } + case "awaitSpeakCompletion": + { + this.awaitSpeakCompletion = Boolean.parseBoolean(call.arguments.toString()); + result.success(1); + break; + } + case "synthesizeToFile": + { + String text = call.argument("text"); + String fileName = call.argument("fileName"); + synthesizeToFile(text, fileName); + result.success(1); + break; + } + case "stop": + stop(); + result.success(1); + break; + case "setSpeechRate": + String rate = call.arguments.toString(); + setSpeechRate(Float.parseFloat(rate)); + result.success(1); + break; + case "setVolume": + String volume = call.arguments.toString(); + setVolume(Float.parseFloat(volume), result); + break; + case "setPitch": + String pitch = call.arguments.toString(); + setPitch(Float.parseFloat(pitch), result); + break; + case "setLanguage": + { + String language = call.arguments.toString(); + setLanguage(language, result); + break; + } + case "getLanguages": + getLanguages(result); + break; + case "getVoices": + getVoices(result); + break; + case "getSpeechRateValidRange": + getSpeechRateValidRange(result); + break; + case "getEngines": + getEngines(result); + break; + case "setVoice": + HashMap voice = call.arguments(); + setVoice(voice, result); + break; + case "isLanguageAvailable": + { + String language = call.arguments().toString(); + Locale locale = Locale.forLanguageTag(language); + result.success(isLanguageAvailable(locale)); + break; + } + case "setSilence": + String silencems = call.arguments.toString(); + this.silencems = Integer.parseInt(silencems); + break; + case "setSharedInstance": + result.success(1); + break; + default: + result.notImplemented(); + break; + } + } + + void setSpeechRate(float rate) { + tts.setSpeechRate(rate); + } + + Boolean isLanguageAvailable(Locale locale) { + return tts.isLanguageAvailable(locale) >= TextToSpeech.LANG_AVAILABLE; + } + + void setLanguage(String language, Result result) { + Locale locale = Locale.forLanguageTag(language); + if (isLanguageAvailable(locale)) { + tts.setLanguage(locale); + result.success(1); + } else { + result.success(0); + } + } + + void setVoice(HashMap voice, Result result) { + for (Voice ttsVoice : tts.getVoices()) { + if (ttsVoice.getName().equals(voice.get("name")) && ttsVoice.getLocale().toLanguageTag().equals(voice.get("locale"))) { + tts.setVoice(ttsVoice); + result.success(1); + return; + } + } + Log.d(tag, "Voice name not found: " + voice); + result.success(0); + } + + void setVolume(float volume, Result result) { + if (volume >= 0.0F && volume <= 1.0F) { + bundle.putFloat(TextToSpeech.Engine.KEY_PARAM_VOLUME, volume); + result.success(1); + } else { + Log.d(tag, "Invalid volume " + volume + " value - Range is from 0.0 to 1.0"); + result.success(0); + } + } + + void setPitch(float pitch, Result result) { + if (pitch >= 0.5F && pitch <= 2.0F) { + tts.setPitch(pitch); + result.success(1); + } else { + Log.d(tag, "Invalid pitch " + pitch + " value - Range is from 0.5 to 2.0"); + result.success(0); + } + } + + void getVoices(Result result) { + ArrayList> voices = new ArrayList<>(); + try { + for (Voice voice : tts.getVoices()) { + HashMap voiceMap = new HashMap<>(); + voiceMap.put("name", voice.getName()); + voiceMap.put("locale", voice.getLocale().toLanguageTag()); + voices.add(voiceMap); + } + result.success(voices); + } catch (NullPointerException e) { + Log.d(tag, "getVoices: " + e.getMessage()); + result.success(null); + } + } + + void getLanguages(Result result) { + ArrayList locales = new ArrayList<>(); + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + // While this method was introduced in API level 21, it seems that it + // has not been implemented in the speech service side until API Level 23. + for (Locale locale : tts.getAvailableLanguages()) { + locales.add(locale.toLanguageTag()); + } + } else { + for (Locale locale : Locale.getAvailableLocales()) { + if (locale.getVariant().isEmpty() && isLanguageAvailable(locale)) { + locales.add(locale.toLanguageTag()); + } + } + } + } catch (MissingResourceException | NullPointerException e) { + Log.d(tag, "getLanguages: " + e.getMessage()); + } + result.success(locales); + } + + void getEngines(Result result) { + ArrayList engines = new ArrayList<>(); + try { + for (TextToSpeech.EngineInfo engineInfo : tts.getEngines()) { + engines.add(engineInfo.name); + } + } catch (Exception e) { + Log.d(tag, "getEngines: " + e.getMessage()); + } + result.success(engines); + } + + void getSpeechRateValidRange(Result result) { + // Valid values available in the android documentation. + // https://developer.android.com/reference/android/speech/tts/TextToSpeech#setSpeechRate(float) + final HashMap data = new HashMap(); + data.put("min", "0"); + data.put("normal", "1"); + data.put("max", "3"); + data.put("platform", "android"); + result.success(data); + } + + private void speak(String text) { + String uuid = UUID.randomUUID().toString(); + utterances.put(uuid, text); + if (silencems > 0) { + tts.playSilentUtterance(silencems, TextToSpeech.QUEUE_FLUSH, SILENCE_PREFIX + uuid); + tts.speak(text, TextToSpeech.QUEUE_ADD, bundle, uuid); + } else { + tts.speak(text, TextToSpeech.QUEUE_FLUSH, bundle, uuid); + } + } + + private void stop() { + tts.stop(); + } + + private void synthesizeToFile(String text, String fileName) { + File file = new File(context.getExternalFilesDir(null), fileName); + String uuid = UUID.randomUUID().toString(); + bundle.putString(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, SYNTHESIZE_TO_FILE_PREFIX + uuid); + + int result = tts.synthesizeToFile(text, bundle, file, SYNTHESIZE_TO_FILE_PREFIX + uuid); + if (result == TextToSpeech.SUCCESS) { + Log.d(tag, "Successfully created file : " + file.getPath()); + } else { + Log.d(tag, "Failed creating file : " + file.getPath()); + } + } + + private void invokeMethod(final String method, final Object arguments) { + handler.post( + new Runnable() { + @Override + public void run() { + if (methodChannel != null) methodChannel.invokeMethod(method, arguments); + } + }); + } +} diff --git a/flutter_tts-voice_enhancement/example/.gitignore b/flutter_tts-voice_enhancement/example/.gitignore new file mode 100644 index 00000000..7e6bbd47 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/.gitignore @@ -0,0 +1,11 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ + +.flutter-plugins +.flutter-plugins-dependencies +lib/generated_plugin_registrant.dart \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/.metadata b/flutter_tts-voice_enhancement/example/.metadata new file mode 100644 index 00000000..3c0dd2c8 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/.metadata @@ -0,0 +1,8 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: b397406561f5e7a9c94e28f58d9e49fca0dd58b7 + channel: beta diff --git a/flutter_tts-voice_enhancement/example/README.md b/flutter_tts-voice_enhancement/example/README.md new file mode 100644 index 00000000..a1356260 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/flutter_tts-voice_enhancement/example/android/.gitignore b/flutter_tts-voice_enhancement/example/android/.gitignore new file mode 100644 index 00000000..65b7315a --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/.gitignore @@ -0,0 +1,10 @@ +*.iml +*.class +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +GeneratedPluginRegistrant.java diff --git a/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs b/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..9f105273 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +#Sat Apr 14 11:55:40 PDT 2018 +connection.project.dir= diff --git a/flutter_tts-voice_enhancement/example/android/app/.classpath b/flutter_tts-voice_enhancement/example/android/app/.classpath new file mode 100644 index 00000000..8d8d85f1 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs b/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 00000000..0601ea50 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +#Sat Apr 14 11:55:40 PDT 2018 +connection.project.dir=.. diff --git a/flutter_tts-voice_enhancement/example/android/app/build.gradle b/flutter_tts-voice_enhancement/example/android/app/build.gradle new file mode 100644 index 00000000..563b8f89 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/build.gradle @@ -0,0 +1,50 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + applicationId "com.tundralabs.flutterttsexample" + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' +} diff --git a/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..49f10e46 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..1caca009 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/flutter_tts-voice_enhancement/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml b/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..1f83a33f --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml b/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..49f10e46 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/flutter_tts-voice_enhancement/example/android/build.gradle b/flutter_tts-voice_enhancement/example/android/build.gradle new file mode 100644 index 00000000..cd23eff8 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.0.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/flutter_tts-voice_enhancement/example/android/gradle.properties b/flutter_tts-voice_enhancement/example/android/gradle.properties new file mode 100644 index 00000000..b6e61b62 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/gradle.properties @@ -0,0 +1,4 @@ +android.enableJetifier=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true diff --git a/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties b/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..495eba36 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Jul 07 01:11:38 PDT 2020 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip diff --git a/flutter_tts-voice_enhancement/example/android/settings.gradle b/flutter_tts-voice_enhancement/example/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/flutter_tts-voice_enhancement/example/android/settings_aar.gradle b/flutter_tts-voice_enhancement/example/android/settings_aar.gradle new file mode 100644 index 00000000..e7b4def4 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/flutter_tts-voice_enhancement/example/ios/.gitignore b/flutter_tts-voice_enhancement/example/ios/.gitignore new file mode 100644 index 00000000..1e1aafd6 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/.gitignore @@ -0,0 +1,42 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/flutter_assets/ +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id b/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id new file mode 100644 index 00000000..bfaaeba1 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Flutter/.last_build_id @@ -0,0 +1 @@ +b443c2d1b6b1e4df6c6fcc277a981410 \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist b/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..6c2de808 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig b/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..e8efba11 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec b/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec new file mode 100644 index 00000000..5ca30416 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Flutter/Flutter.podspec @@ -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 diff --git a/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig b/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..399e9340 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/ios/Podfile b/flutter_tts-voice_enhancement/example/ios/Podfile new file mode 100644 index 00000000..1e8c3c90 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Podfile @@ -0,0 +1,41 @@ +# 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 flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..28d4b795 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,488 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 72BCD356E80F9F5F32A2B586 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.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; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 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 = ""; }; + BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CED86603210BC43D753C699B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + CF068A80D9BD19FC43D3FE99 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 72BCD356E80F9F5F32A2B586 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 04223708A30129901099FE16 /* Frameworks */ = { + isa = PBXGroup; + children = ( + BE3436CECE15DEA290DCD6B6 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 1ED2DC2A248FC04D7FB5EA8C /* Pods */ = { + isa = PBXGroup; + children = ( + CF068A80D9BD19FC43D3FE99 /* Pods-Runner.debug.xcconfig */, + CED86603210BC43D753C699B /* Pods-Runner.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 1ED2DC2A248FC04D7FB5EA8C /* Pods */, + 04223708A30129901099FE16 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 3B0CA933DCDA45D4F71410D4 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 46F7EA90EF3F4667EDB9E562 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0940; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0910; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 3B0CA933DCDA45D4F71410D4 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + 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; + }; + 46F7EA90EF3F4667EDB9E562 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", + "${PODS_ROOT}/../Flutter/Flutter.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", + ); + 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; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.flutterTtsExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.flutterTtsExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_SWIFT3_OBJC_INFERENCE = On; + SWIFT_VERSION = 4.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..4bafc458 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..21a3cc14 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..f9b0d7c5 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift b/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift new file mode 100644 index 00000000..71cc41e3 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist b/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist new file mode 100644 index 00000000..dd2d9263 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_tts_example + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h b/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 00000000..7335fdf9 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/example/lib/main.dart b/flutter_tts-voice_enhancement/example/lib/main.dart new file mode 100644 index 00000000..97530bbb --- /dev/null +++ b/flutter_tts-voice_enhancement/example/lib/main.dart @@ -0,0 +1,292 @@ +import 'dart:async'; +import 'dart:io' show Platform; +import 'package:flutter/foundation.dart' show kIsWeb; + +import 'package:flutter/material.dart'; +import 'package:flutter_tts/flutter_tts.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatefulWidget { + @override + _MyAppState createState() => _MyAppState(); +} + +enum TtsState { playing, stopped, paused, continued } + +class _MyAppState extends State { + FlutterTts flutterTts; + dynamic languages; + String language; + double volume = 0.5; + double pitch = 1.0; + double rate = 0.5; + + String _newVoiceText; + + TtsState ttsState = TtsState.stopped; + + get isPlaying => ttsState == TtsState.playing; + + get isStopped => ttsState == TtsState.stopped; + + get isPaused => ttsState == TtsState.paused; + + get isContinued => ttsState == TtsState.continued; + + @override + initState() { + super.initState(); + initTts(); + } + + initTts() { + flutterTts = FlutterTts(); + + _getLanguages(); + + if (!kIsWeb) { + if (Platform.isAndroid) { + _getEngines(); + } + } + + flutterTts.setStartHandler(() { + setState(() { + print("Playing"); + ttsState = TtsState.playing; + }); + }); + + flutterTts.setCompletionHandler(() { + setState(() { + print("Complete"); + ttsState = TtsState.stopped; + }); + }); + + flutterTts.setCancelHandler(() { + setState(() { + print("Cancel"); + ttsState = TtsState.stopped; + }); + }); + + if (kIsWeb || Platform.isIOS) { + flutterTts.setPauseHandler(() { + setState(() { + print("Paused"); + ttsState = TtsState.paused; + }); + }); + + flutterTts.setContinueHandler(() { + setState(() { + print("Continued"); + ttsState = TtsState.continued; + }); + }); + } + + flutterTts.setErrorHandler((msg) { + setState(() { + print("error: $msg"); + ttsState = TtsState.stopped; + }); + }); + } + + Future _getLanguages() async { + languages = await flutterTts.getLanguages; + if (languages != null) setState(() => languages); + } + + Future _getEngines() async { + var engines = await flutterTts.getEngines; + if (engines != null) { + for (dynamic engine in engines) { + print(engine); + } + } + } + + Future _speak() async { + await flutterTts.setVolume(volume); + await flutterTts.setSpeechRate(rate); + await flutterTts.setPitch(pitch); + + if (_newVoiceText != null) { + if (_newVoiceText.isNotEmpty) { + await flutterTts.awaitSpeakCompletion(true); + await flutterTts.speak(_newVoiceText); + } + } + } + + Future _stop() async { + var result = await flutterTts.stop(); + if (result == 1) setState(() => ttsState = TtsState.stopped); + } + + Future _pause() async { + var result = await flutterTts.pause(); + if (result == 1) setState(() => ttsState = TtsState.paused); + } + + @override + void dispose() { + super.dispose(); + flutterTts.stop(); + } + + List> getLanguageDropDownMenuItems() { + var items = List>(); + for (dynamic type in languages) { + items.add( + DropdownMenuItem(value: type as String, child: Text(type as String))); + } + return items; + } + + void changedLanguageDropDownItem(String selectedType) { + setState(() { + language = selectedType; + flutterTts.setLanguage(language); + }); + } + + void _onChange(String text) { + setState(() { + _newVoiceText = text; + }); + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + appBar: AppBar( + title: Text('Flutter TTS'), + ), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Column(children: [ + _inputSection(), + _btnSection(), + languages != null ? _languageDropDownSection() : Text(""), + _buildSliders() + ])))); + } + + Widget _inputSection() => Container( + alignment: Alignment.topCenter, + padding: EdgeInsets.only(top: 25.0, left: 25.0, right: 25.0), + child: TextField( + onChanged: (String value) { + _onChange(value); + }, + )); + + Widget _btnSection() { + if (!kIsWeb && Platform.isAndroid) { + return Container( + padding: EdgeInsets.only(top: 50.0), + child: + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + _buildButtonColumn(Colors.green, Colors.greenAccent, + Icons.play_arrow, 'PLAY', _speak), + _buildButtonColumn( + Colors.red, Colors.redAccent, Icons.stop, 'STOP', _stop), + ])); + } else { + return Container( + padding: EdgeInsets.only(top: 50.0), + child: + Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + _buildButtonColumn(Colors.green, Colors.greenAccent, + Icons.play_arrow, 'PLAY', _speak), + _buildButtonColumn( + Colors.red, Colors.redAccent, Icons.stop, 'STOP', _stop), + _buildButtonColumn( + Colors.blue, Colors.blueAccent, Icons.pause, 'PAUSE', _pause), + ])); + } + } + + Widget _languageDropDownSection() => Container( + padding: EdgeInsets.only(top: 50.0), + child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ + DropdownButton( + value: language, + items: getLanguageDropDownMenuItems(), + onChanged: changedLanguageDropDownItem, + ) + ])); + + Column _buildButtonColumn(Color color, Color splashColor, IconData icon, + String label, Function func) { + return Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + IconButton( + icon: Icon(icon), + color: color, + splashColor: splashColor, + onPressed: () => func()), + Container( + margin: const EdgeInsets.only(top: 8.0), + child: Text(label, + style: TextStyle( + fontSize: 12.0, + fontWeight: FontWeight.w400, + color: color))) + ]); + } + + Widget _buildSliders() { + return Column( + children: [_volume(), _pitch(), _rate()], + ); + } + + Widget _volume() { + return Slider( + value: volume, + onChanged: (newVolume) { + setState(() => volume = newVolume); + }, + min: 0.0, + max: 1.0, + divisions: 10, + label: "Volume: $volume"); + } + + Widget _pitch() { + return Slider( + value: pitch, + onChanged: (newPitch) { + setState(() => pitch = newPitch); + }, + min: 0.5, + max: 2.0, + divisions: 15, + label: "Pitch: $pitch", + activeColor: Colors.red, + ); + } + + Widget _rate() { + return Slider( + value: rate, + onChanged: (newRate) { + setState(() => rate = newRate); + }, + min: 0.0, + max: 1.0, + divisions: 10, + label: "Rate: $rate", + activeColor: Colors.green, + ); + } +} diff --git a/flutter_tts-voice_enhancement/example/macos/.gitignore b/flutter_tts-voice_enhancement/example/macos/.gitignore new file mode 100644 index 00000000..d2fd3772 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/.gitignore @@ -0,0 +1,6 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/xcuserdata/ diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 00000000..785633d3 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 00000000..5fba960c --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift b/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 00000000..1e6ac53b --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import flutter_tts + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FlutterTtsPlugin.register(with: registry.registrar(forPlugin: "FlutterTtsPlugin")) +} diff --git a/flutter_tts-voice_enhancement/example/macos/Podfile b/flutter_tts-voice_enhancement/example/macos/Podfile new file mode 100644 index 00000000..5bf4307c --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Podfile @@ -0,0 +1,82 @@ +platform :osx, '10.15' + +# 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 + pods_ary = [] + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) { |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) + pods_ary.push({:name => podname, :path => podpath}); + else + puts "Invalid plugin specification: #{line}" + end + } + return pods_ary +end + +def pubspec_supports_macos(file) + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return false; + end + File.foreach(file_abs_path) { |line| + return true if line =~ /^\s*macos:/ + } + return false +end + +target 'Runner' do + use_frameworks! + use_modular_headers! + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + ephemeral_dir = File.join('Flutter', 'ephemeral') + symlink_dir = File.join(ephemeral_dir, '.symlinks') + symlink_plugins_dir = File.join(symlink_dir, 'plugins') + system("rm -rf #{symlink_dir}") + system("mkdir -p #{symlink_plugins_dir}") + + # Flutter Pods + generated_xcconfig = parse_KV_file(File.join(ephemeral_dir, 'Flutter-Generated.xcconfig')) + if generated_xcconfig.empty? + puts "Flutter-Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." + end + generated_xcconfig.map { |p| + if p[:name] == 'FLUTTER_FRAMEWORK_DIR' + symlink = File.join(symlink_dir, 'flutter') + File.symlink(File.dirname(p[:path]), symlink) + pod 'FlutterMacOS', :path => File.join(symlink, File.basename(p[:path])) + end + } + + # Plugin Pods + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.map { |p| + symlink = File.join(symlink_plugins_dir, p[:name]) + File.symlink(p[:path], symlink) + if pubspec_supports_macos(File.join(symlink, 'pubspec.yaml')) + pod p[:name], :path => File.join(symlink, 'macos') + 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 diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..39fbd18c --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,656 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 51; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 3640FC23D5951A8FB0D6ECA0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A470206CCCE0007DE0E2807A /* Pods_Runner.framework */; }; + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, + 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 517AA5C8DE31A9B49D27971F /* 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 = ""; }; + 66FE8AA741C2B7FC12BF1304 /* 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + A470206CCCE0007DE0E2807A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C15A67B64555E7FFE7AD8B76 /* 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 = ""; }; + D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, + 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, + 3640FC23D5951A8FB0D6ECA0 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + 5F9F48FBDE9334256A3D8D1C /* Pods */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* example.app */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + D73912EF22F37F9E000D13A0 /* App.framework */, + 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + 5F9F48FBDE9334256A3D8D1C /* Pods */ = { + isa = PBXGroup; + children = ( + 66FE8AA741C2B7FC12BF1304 /* Pods-Runner.debug.xcconfig */, + 517AA5C8DE31A9B49D27971F /* Pods-Runner.release.xcconfig */, + C15A67B64555E7FFE7AD8B76 /* Pods-Runner.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A470206CCCE0007DE0E2807A /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9A62F257D3FF7C7C94E365B2 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + F7AADAC6A864E8BF8890B1EC /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1150; + ORGANIZATIONNAME = "The Flutter Authors"; + TargetAttributes = { + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + }; + 9A62F257D3FF7C7C94E365B2 /* [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; + }; + F7AADAC6A864E8BF8890B1EC /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter/ephemeral", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..6111bd0a --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..21a3cc14 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift b/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift new file mode 100644 index 00000000..d53ef643 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/AppDelegate.swift @@ -0,0 +1,9 @@ +import Cocoa +import FlutterMacOS + +@NSApplicationMain +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } +} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..a2ec33f1 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_16.png", + "scale" : "1x" + }, + { + "size" : "16x16", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "2x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_32.png", + "scale" : "1x" + }, + { + "size" : "32x32", + "idiom" : "mac", + "filename" : "app_icon_64.png", + "scale" : "2x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_128.png", + "scale" : "1x" + }, + { + "size" : "128x128", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "2x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_256.png", + "scale" : "1x" + }, + { + "size" : "256x256", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "2x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_512.png", + "scale" : "1x" + }, + { + "size" : "512x512", + "idiom" : "mac", + "filename" : "app_icon_1024.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 00000000..3c4935a7 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 00000000..ed4cc164 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 00000000..483be613 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 00000000..bcbf36df Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 00000000..9c0a6528 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 00000000..e71a7261 Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 00000000..8a31fe2d Binary files /dev/null and b/flutter_tts-voice_enhancement/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib b/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 00000000..537341ab --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,339 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 00000000..f960fd48 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.tundralabs.example + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2020 com.tundralabs. All rights reserved. diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 00000000..36b0fd94 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 00000000..dff4f495 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 00000000..42bcbf47 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements b/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 00000000..dddb8a30 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist b/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist new file mode 100644 index 00000000..4789daa6 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift b/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 00000000..2722837e --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements b/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements new file mode 100644 index 00000000..852fa1a4 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/flutter_tts-voice_enhancement/example/pubspec.yaml b/flutter_tts-voice_enhancement/example/pubspec.yaml new file mode 100644 index 00000000..54cbe6ed --- /dev/null +++ b/flutter_tts-voice_enhancement/example/pubspec.yaml @@ -0,0 +1,59 @@ +name: flutter_tts_example +description: Demonstrates how to use the flutter_tts plugin. + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + flutter_tts: + path: ../ + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/flutter_tts-voice_enhancement/example/test/widget_test.dart b/flutter_tts-voice_enhancement/example/test/widget_test.dart new file mode 100644 index 00000000..6db856cd --- /dev/null +++ b/flutter_tts-voice_enhancement/example/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../lib/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/flutter_tts-voice_enhancement/example/web/favicon.png b/flutter_tts-voice_enhancement/example/web/favicon.png new file mode 100644 index 00000000..8aaa46ac Binary files /dev/null and b/flutter_tts-voice_enhancement/example/web/favicon.png differ diff --git a/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png b/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png new file mode 100644 index 00000000..b749bfef Binary files /dev/null and b/flutter_tts-voice_enhancement/example/web/icons/Icon-192.png differ diff --git a/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png b/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png new file mode 100644 index 00000000..88cfd48d Binary files /dev/null and b/flutter_tts-voice_enhancement/example/web/icons/Icon-512.png differ diff --git a/flutter_tts-voice_enhancement/example/web/index.html b/flutter_tts-voice_enhancement/example/web/index.html new file mode 100644 index 00000000..20b0c00a --- /dev/null +++ b/flutter_tts-voice_enhancement/example/web/index.html @@ -0,0 +1,10 @@ + + + + + Flutter TTS example + + + + + diff --git a/flutter_tts-voice_enhancement/example/web/manifest.json b/flutter_tts-voice_enhancement/example/web/manifest.json new file mode 100644 index 00000000..8c012917 --- /dev/null +++ b/flutter_tts-voice_enhancement/example/web/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + } + ] +} diff --git a/flutter_tts-voice_enhancement/ios/.gitignore b/flutter_tts-voice_enhancement/ios/.gitignore new file mode 100644 index 00000000..956c87f3 --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/.gitignore @@ -0,0 +1,31 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + diff --git a/flutter_tts-voice_enhancement/ios/Assets/.gitkeep b/flutter_tts-voice_enhancement/ios/Assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift b/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift new file mode 100644 index 00000000..74e8ea0b --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/Classes/AudioCategory.swift @@ -0,0 +1,21 @@ +import AVFoundation + +enum AudioCategory: String { + case iosAudioCategoryAmbientSolo + case iosAudioCategoryAmbient + case iosAudioCategoryPlayback + case iosAudioCategoryPlaybackAndRecord + + func toAVAudioSessionCategory() -> AVAudioSession.Category { + switch self { + case .iosAudioCategoryAmbientSolo: + return .soloAmbient + case .iosAudioCategoryAmbient: + return .ambient + case .iosAudioCategoryPlayback: + return .playback + case .iosAudioCategoryPlaybackAndRecord: + return .playAndRecord + } + } +} diff --git a/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift b/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift new file mode 100644 index 00000000..f593bfdb --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/Classes/AudioCategoryOptions.swift @@ -0,0 +1,42 @@ +import AVFoundation + +enum AudioCategoryOptions: String { + case iosAudioCategoryOptionsMixWithOthers + case iosAudioCategoryOptionsDuckOthers + case iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers + case iosAudioCategoryOptionsAllowBluetooth + case iosAudioCategoryOptionsAllowBluetoothA2DP + case iosAudioCategoryOptionsAllowAirPlay + case iosAudioCategoryOptionsDefaultToSpeaker + + func toAVAudioSessionCategoryOptions() -> AVAudioSession.CategoryOptions? { + switch self { + case .iosAudioCategoryOptionsMixWithOthers: + return .mixWithOthers + case .iosAudioCategoryOptionsDuckOthers: + return .duckOthers + case .iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers: + if #available(iOS 9.0, *) { + return .interruptSpokenAudioAndMixWithOthers + } else { + return nil + } + case .iosAudioCategoryOptionsAllowBluetooth: + return .allowBluetooth + case .iosAudioCategoryOptionsAllowBluetoothA2DP: + if #available(iOS 10.0, *) { + return .allowBluetoothA2DP + } else { + return nil + } + case .iosAudioCategoryOptionsAllowAirPlay: + if #available(iOS 10.0, *) { + return .allowAirPlay + } else { + return nil + } + case .iosAudioCategoryOptionsDefaultToSpeaker: + return .defaultToSpeaker + } + } +} diff --git a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h new file mode 100644 index 00000000..13e3a21a --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface FlutterTtsPlugin : NSObject +@end diff --git a/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m new file mode 100644 index 00000000..3a1f187c --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/Classes/FlutterTtsPlugin.m @@ -0,0 +1,8 @@ +#import "FlutterTtsPlugin.h" +#import + +@implementation FlutterTtsPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + [SwiftFlutterTtsPlugin registerWithRegistrar:registrar]; +} +@end diff --git a/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift b/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift new file mode 100644 index 00000000..5c78c135 --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/Classes/SwiftFlutterTtsPlugin.swift @@ -0,0 +1,386 @@ +import Flutter +import UIKit +import AVFoundation + +public class SwiftFlutterTtsPlugin: NSObject, FlutterPlugin, AVSpeechSynthesizerDelegate { + final var iosAudioCategoryKey = "iosAudioCategoryKey" + final var iosAudioCategoryOptionsKey = "iosAudioCategoryOptionsKey" + + let synthesizer = AVSpeechSynthesizer() + var language: String = AVSpeechSynthesisVoice.currentLanguageCode() + var rate: Float = AVSpeechUtteranceDefaultSpeechRate + var languages = Set() + var volume: Float = 1.0 + var pitch: Float = 1.0 + var voice: AVSpeechSynthesisVoice? + var awaitSpeakCompletion: Bool = false + var speakResult: FlutterResult! + + var channel = FlutterMethodChannel() + lazy var audioSession = AVAudioSession.sharedInstance() + init(channel: FlutterMethodChannel) { + super.init() + self.channel = channel + synthesizer.delegate = self + setLanguages() + + // Allow audio playback when the Ring/Silent switch is set to silent + do { + try audioSession.setCategory(.playAndRecord, options: [.defaultToSpeaker]) + } catch { + print(error) + } + } + + private func setLanguages() { + for voice in AVSpeechSynthesisVoice.speechVoices(){ + self.languages.insert(voice.language) + } + } + + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "flutter_tts", binaryMessenger: registrar.messenger()) + let instance = SwiftFlutterTtsPlugin(channel: channel) + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "speak": + let text: String = call.arguments as! String + self.speak(text: text, result: result) + break + case "awaitSpeakCompletion": + self.awaitSpeakCompletion = call.arguments as! Bool + result(1) + break + case "synthesizeToFile": + guard let args = call.arguments as? [String: Any] else { + result("iOS could not recognize flutter arguments in method: (sendParams)") + return + } + let text = args["text"] as! String + let fileName = args["fileName"] as! String + self.synthesizeToFile(text: text, fileName: fileName, result: result) + break + case "pause": + self.pause(result: result) + break + case "setLanguage": + let language: String = call.arguments as! String + self.setLanguage(language: language, result: result) + break + case "setSpeechRate": + let rate: Double = call.arguments as! Double + self.setRate(rate: Float(rate)) + result(1) + break + case "setVolume": + let volume: Double = call.arguments as! Double + self.setVolume(volume: Float(volume), result: result) + break + case "setPitch": + let pitch: Double = call.arguments as! Double + self.setPitch(pitch: Float(pitch), result: result) + break + case "stop": + self.stop() + result(1) + break + case "getLanguages": + self.getLanguages(result: result) + break + case "getSpeechRateValidRange": + self.getSpeechRateValidRange(result: result) + break + case "isLanguageAvailable": + let language: String = call.arguments as! String + self.isLanguageAvailable(language: language, result: result) + break + case "getVoices": + self.getVoices(result: result) + break + case "setVoice": + guard let args = call.arguments as? [String: String] else { + result("iOS could not recognize flutter arguments in method: (sendParams)") + return + } + self.setVoice(voice: args, result: result) + break + case "setSharedInstance": + let sharedInstance = call.arguments as! Bool + self.setSharedInstance(sharedInstance: sharedInstance, result: result) + break + case "setIosAudioCategory": + guard let args = call.arguments as? [String: Any] else { + result("iOS could not recognize flutter arguments in method: (sendParams)") + return + } + let audioCategory = args["iosAudioCategoryKey"] as? String + let audioOptions = args[iosAudioCategoryOptionsKey] as? Array + self.setAudioCategory(audioCategory: audioCategory, audioOptions: audioOptions, result: result) + break + default: + result(FlutterMethodNotImplemented) + } + } + + private func speak(text: String, result: @escaping FlutterResult) { + if (self.synthesizer.isPaused) { + if (self.synthesizer.continueSpeaking()) { + if self.awaitSpeakCompletion { + self.speakResult = result + } else { + result(1) + } + } else { + result(0) + } + } else { + let utterance = AVSpeechUtterance(string: text) + if self.voice != nil { + utterance.voice = self.voice! + } else { + utterance.voice = AVSpeechSynthesisVoice(language: self.language) + } + utterance.rate = self.rate + utterance.volume = self.volume + utterance.pitchMultiplier = self.pitch + + self.synthesizer.speak(utterance) + if self.awaitSpeakCompletion { + self.speakResult = result + } else { + result(1) + } + } + } + + private func synthesizeToFile(text: String, fileName: String, result: FlutterResult) { + var output: AVAudioFile? + var failed = false + let utterance = AVSpeechUtterance(string: text) + + if self.voice != nil { + utterance.voice = self.voice! + } else { + utterance.voice = AVSpeechSynthesisVoice(language: self.language) + } + utterance.rate = self.rate + utterance.volume = self.volume + utterance.pitchMultiplier = self.pitch + + if #available(iOS 13.0, *) { + self.synthesizer.write(utterance) { (buffer: AVAudioBuffer) in + guard let pcmBuffer = buffer as? AVAudioPCMBuffer else { + NSLog("unknow buffer type: \(buffer)") + failed = true + return + } + print(pcmBuffer.format) + if pcmBuffer.frameLength == 0 { + // finished + } else { + // append buffer to file + let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fileName) + NSLog("Saving utterance to file: \(fileURL.absoluteString)") + + if output == nil { + do { + output = try AVAudioFile( + forWriting: fileURL, + settings: pcmBuffer.format.settings, + commonFormat: .pcmFormatInt16, + interleaved: false) + } catch { + NSLog(error.localizedDescription) + failed = true + return + } + } + + try! output!.write(from: pcmBuffer) + } + } + } else { + result("Unsupported iOS version") + } + if failed { + result(0) + } + result(1) + } + + private func pause(result: FlutterResult) { + if (self.synthesizer.pauseSpeaking(at: AVSpeechBoundary.word)) { + result(1) + } else { + result(0) + } + } + + private func setLanguage(language: String, result: FlutterResult) { + if !(self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { + result(0) + } else { + self.language = language + self.voice = nil + result(1) + } + } + + private func setRate(rate: Float) { + self.rate = rate + } + + private func setVolume(volume: Float, result: FlutterResult) { + if (volume >= 0.0 && volume <= 1.0) { + self.volume = volume + result(1) + } else { + result(0) + } + } + + private func setPitch(pitch: Float, result: FlutterResult) { + if (volume >= 0.5 && volume <= 2.0) { + self.pitch = pitch + result(1) + } else { + result(0) + } + } + + private func setSharedInstance(sharedInstance: Bool, result: FlutterResult) { + do { + try AVAudioSession.sharedInstance().setActive(sharedInstance) + result(1) + } catch { + result(0) + } + } + + private func setAudioCategory(audioCategory: String?, audioOptions: Array?, result: FlutterResult){ + let category: AVAudioSession.Category = AudioCategory(rawValue: audioCategory ?? "")?.toAVAudioSessionCategory() ?? audioSession.category + let options: AVAudioSession.CategoryOptions = audioOptions?.reduce([], { (result, option) -> AVAudioSession.CategoryOptions in + return result.union(AudioCategoryOptions(rawValue: option)?.toAVAudioSessionCategoryOptions() ?? []) + }) ?? [] + + do { + try audioSession.setCategory(category, options: options) + result(1) + } catch { + print(error) + result(0) + } + } + + private func stop() { + self.synthesizer.stopSpeaking(at: AVSpeechBoundary.immediate) + } + + private func getLanguages(result: FlutterResult) { + result(Array(self.languages)) + } + + private func getSpeechRateValidRange(result: FlutterResult) { + let validSpeechRateRange: [String:String] = [ + "min": String(AVSpeechUtteranceMinimumSpeechRate), + "normal": String(AVSpeechUtteranceDefaultSpeechRate), + "max": String(AVSpeechUtteranceMaximumSpeechRate), + "platform": "ios" + ] + result(validSpeechRateRange) + } + + private func isLanguageAvailable(language: String, result: FlutterResult) { + var isAvailable: Bool = false + if (self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { + isAvailable = true + } + result(isAvailable); + } + + private func getVoices(result: FlutterResult) { + if #available(iOS 9.0, *) { + let voices = NSMutableArray() + var voiceDict: [String: String] = [:] + for voice in AVSpeechSynthesisVoice.speechVoices() { + voiceDict["name"] = voice.name + voiceDict["locale"] = voice.language + voices.add(voiceDict) + } + result(voices) + } else { + // Since voice selection is not supported below iOS 9, make voice getter and setter + // have the same bahavior as language selection. + getLanguages(result: result) + } + } + + private func setVoice(voice: [String:String], result: FlutterResult) { + if #available(iOS 9.0, *) { + if let voice = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.name == voice["name"]! && $0.language == voice["locale"]! }) { + self.voice = voice + self.language = voice.language + result(1) + return + } + result(0) + } else { + setLanguage(language: voice["name"]!, result: result) + } + } + + private func shouldDeactivateAndNotifyOthers(_ session: AVAudioSession) -> Bool { + var options: AVAudioSession.CategoryOptions = .duckOthers + if #available(iOS 9.0, *) { + options.insert(.interruptSpokenAudioAndMixWithOthers) + } + options.remove(.mixWithOthers) + + return !options.isDisjoint(with: session.categoryOptions) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { + if shouldDeactivateAndNotifyOthers(audioSession) { + do { + try audioSession.setActive(false, options: .notifyOthersOnDeactivation) + } catch { + print(error) + } + } + if self.awaitSpeakCompletion { + self.speakResult(1) + } + self.channel.invokeMethod("speak.onComplete", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onStart", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onPause", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onContinue", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onCancel", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) { + let nsWord = utterance.speechString as NSString + let data: [String:String] = [ + "text": utterance.speechString, + "start": String(characterRange.location), + "end": String(characterRange.location + characterRange.length), + "word": nsWord.substring(with: characterRange) + ] + self.channel.invokeMethod("speak.onProgress", arguments: data) + } + +} diff --git a/flutter_tts-voice_enhancement/ios/flutter_tts.podspec b/flutter_tts-voice_enhancement/ios/flutter_tts.podspec new file mode 100644 index 00000000..03099f45 --- /dev/null +++ b/flutter_tts-voice_enhancement/ios/flutter_tts.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'flutter_tts' + s.version = '0.0.1' + s.summary = 'A flutter text to speech plugin.' + s.description = <<-DESC +A flutter text to speech plugin + DESC + s.homepage = 'https://github.com/dlutton/flutter_tts' + s.license = { :file => '../LICENSE' } + s.author = { 'tundralabs' => 'eyedea32@gmail.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.ios.deployment_target = '8.0' + s.swift_version = '4.2' + s.static_framework = true +end + diff --git a/flutter_tts-voice_enhancement/lib/flutter_tts.dart b/flutter_tts-voice_enhancement/lib/flutter_tts.dart new file mode 100644 index 00000000..c823a91d --- /dev/null +++ b/flutter_tts-voice_enhancement/lib/flutter_tts.dart @@ -0,0 +1,342 @@ +import 'dart:async'; +import 'dart:io' show Platform; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +typedef void ErrorHandler(dynamic message); +typedef ProgressHandler = void Function( + String text, int start, int end, String word); + +const String iosAudioCategoryOptionsKey = 'iosAudioCategoryOptionsKey'; +const String iosAudioCategoryKey = 'iosAudioCategoryKey'; +const String iosAudioCategoryAmbientSolo = 'iosAudioCategoryAmbientSolo'; +const String iosAudioCategoryAmbient = 'iosAudioCategoryAmbient'; +const String iosAudioCategoryPlayback = 'iosAudioCategoryPlayback'; +const String iosAudioCategoryPlaybackAndRecord = + 'iosAudioCategoryPlaybackAndRecord'; + +const String iosAudioCategoryOptionsMixWithOthers = + 'iosAudioCategoryOptionsMixWithOthers'; +const String iosAudioCategoryOptionsDuckOthers = + 'iosAudioCategoryOptionsDuckOthers'; +const String iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers = + 'iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers'; +const String iosAudioCategoryOptionsAllowBluetooth = + 'iosAudioCategoryOptionsAllowBluetooth'; +const String iosAudioCategoryOptionsAllowBluetoothA2DP = + 'iosAudioCategoryOptionsAllowBluetoothA2DP'; +const String iosAudioCategoryOptionsAllowAirPlay = + 'iosAudioCategoryOptionsAllowAirPlay'; +const String iosAudioCategoryOptionsDefaultToSpeaker = + 'iosAudioCategoryOptionsDefaultToSpeaker'; + +enum TextToSpeechPlatform { android, ios } + +enum IosTextToSpeechAudioCategory { + /// Audio is silenced by screen lock and the silent switch; audio will not mix + /// with other apps' audio. + ambientSolo, + + /// Audio is silenced by screen lock and the silent switch; audio will mix + /// with other apps' (mixable) audio. + ambient, + + /// Audio is not silenced by screen lock or silent switch; audio will not mix + /// with other apps' audio. + /// + playback, + + /// The category for recording (input) and playback (output) of audio, + /// such as for a Voice over Internet Protocol (VoIP) app. + /// The default value. + playAndRecord, +} + +enum IosTextToSpeechAudioCategoryOptions { + /// An option that indicates whether audio from this session mixes with audio + /// from active sessions in other audio apps. + mixWithOthers, + + /// An option that reduces the volume of other audio session while audio + /// from this session plays. + duckOthers, + + /// An option that determines whether to pause spoken audio content + /// from other sessions when your app plays its audio. + interruptSpokenAudioAndMixWithOthers, + + ///An option that determines whether Bluetooth hands-free devices + /// appear as available input routes. + allowBluetooth, + + ///An option that determines whether you can stream audio + /// from this session to Bluetooth devices that support the Advanced Audio Distribution Profile (A2DP). + allowBluetoothA2DP, + + ///An option that determines whether you can stream audio + /// from this session to AirPlay devices. + allowAirPlay, + + ///An option that determines whether audio + /// from the session defaults to the built-in speaker instead of the receiver. + /// The default value. + defaultToSpeaker, +} + +class SpeechRateValidRange { + final double min; + final double normal; + final double max; + final TextToSpeechPlatform platform; + + SpeechRateValidRange(this.min, this.normal, this.max, this.platform); +} + +// Provides Platform specific TTS services (Android: TextToSpeech, IOS: AVSpeechSynthesizer) +class FlutterTts { + static const MethodChannel _channel = const MethodChannel('flutter_tts'); + + VoidCallback startHandler; + VoidCallback completionHandler; + VoidCallback pauseHandler; + VoidCallback continueHandler; + VoidCallback cancelHandler; + ProgressHandler progressHandler; + ErrorHandler errorHandler; + + FlutterTts() { + _channel.setMethodCallHandler(platformCallHandler); + } + + /// [Future] which sets speak's future to return on completion of the utterance + Future awaitSpeakCompletion(bool awaitCompletion) async => + _channel.invokeMethod('awaitSpeakCompletion', awaitCompletion); + + /// [Future] which invokes the platform specific method for speaking + Future speak(String text) async => + _channel.invokeMethod('speak', text); + + /// [Future] which invokes the platform specific method for pause + /// ***iOS supported only*** + Future pause() async => _channel.invokeMethod('pause'); + + /// [Future] which invokes the platform specific method for synthesizeToFile + /// ***Android and iOS supported only*** + Future synthesizeToFile(String text, String fileName) async => + _channel.invokeMethod('synthesizeToFile', { + "text": text, + "fileName": fileName, + }); + + /// [Future] which invokes the platform specific method for setLanguage + Future setLanguage(String language) async => + _channel.invokeMethod('setLanguage', language); + + /// [Future] which invokes the platform specific method for setSpeechRate + /// Allowed values are in the range from 0.0 (slowest) to 1.0 (fastest) + Future setSpeechRate(double rate) async => + _channel.invokeMethod('setSpeechRate', rate); + + /// [Future] which invokes the platform specific method for setVolume + /// Allowed values are in the range from 0.0 (silent) to 1.0 (loudest) + Future setVolume(double volume) async => + _channel.invokeMethod('setVolume', volume); + + /// [Future] which invokes the platform specific method for shared instance + /// ***iOS supported only*** + Future setSharedInstance(bool sharedSession) async => + _channel.invokeMethod('setSharedInstance', sharedSession); + + /// [Future] which invokes the platform specific method for setting audio category + /// ***Ios supported only*** + Future setIosAudioCategory(IosTextToSpeechAudioCategory category, + List options) async { + const categoryToString = { + IosTextToSpeechAudioCategory.ambientSolo: iosAudioCategoryAmbientSolo, + IosTextToSpeechAudioCategory.ambient: iosAudioCategoryAmbient, + IosTextToSpeechAudioCategory.playback: iosAudioCategoryPlayback + }; + const optionsToString = { + IosTextToSpeechAudioCategoryOptions.mixWithOthers: + 'iosAudioCategoryOptionsMixWithOthers', + IosTextToSpeechAudioCategoryOptions.duckOthers: + 'iosAudioCategoryOptionsDuckOthers', + IosTextToSpeechAudioCategoryOptions.interruptSpokenAudioAndMixWithOthers: + 'iosAudioCategoryOptionsInterruptSpokenAudioAndMixWithOthers', + IosTextToSpeechAudioCategoryOptions.allowBluetooth: + 'iosAudioCategoryOptionsAllowBluetooth', + IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP: + 'iosAudioCategoryOptionsAllowBluetoothA2DP', + IosTextToSpeechAudioCategoryOptions.allowAirPlay: + 'iosAudioCategoryOptionsAllowAirPlay', + IosTextToSpeechAudioCategoryOptions.defaultToSpeaker: + 'iosAudioCategoryOptionsDefaultToSpeaker', + }; + if (!Platform.isIOS) return; + try { + return _channel + .invokeMethod('setIosAudioCategory', { + iosAudioCategoryKey: categoryToString[category], + iosAudioCategoryOptionsKey: + options.map((o) => optionsToString[o]).toList(), + }); + } on PlatformException catch (e) { + print( + 'setIosAudioCategory error, category: $category, error: ${e.message}'); + } + } + + /// [Future] which invokes the platform specific method for setPitch + /// 1.0 is default and ranges from .5 to 2.0 + Future setPitch(double pitch) async => + _channel.invokeMethod('setPitch', pitch); + + /// [Future] which invokes the platform specific method for setVoice + /// ***Android, iOS, and macOS supported only*** + Future setVoice(Map voice) async => + _channel.invokeMethod('setVoice', voice); + + /// [Future] which invokes the platform specific method for stop + Future stop() async => _channel.invokeMethod('stop'); + + /// [Future] which invokes the platform specific method for getLanguages + /// Android issues with API 21 & 22 + /// Returns a list of available languages + Future get getLanguages async { + final languages = await _channel.invokeMethod('getLanguages'); + return languages; + } + + /// [Future] which invokes the platform specific method for getEngines + /// Returns a list of installed TTS engines + /// ***Android supported only*** + Future get getEngines async { + final engines = await _channel.invokeMethod('getEngines'); + return engines; + } + + /// [Future] which invokes the platform specific method for getVoices + /// Returns a `List` of `Maps` containing a voice name and locale + /// ***Android, iOS, and macOS supported only*** + Future get getVoices async { + final voices = await _channel.invokeMethod('getVoices'); + return voices; + } + + /// [Future] which invokes the platform specific method for isLanguageAvailable + /// Returns `true` or `false` + Future isLanguageAvailable(String language) async => + _channel.invokeMethod('isLanguageAvailable', language); + + Future get getSpeechRateValidRange async { + final validRange = await _channel.invokeMethod('getSpeechRateValidRange') + as Map; + final min = double.parse(validRange['min'].toString()); + final normal = double.parse(validRange['normal'].toString()); + final max = double.parse(validRange['max'].toString()); + final platformStr = validRange['platform'].toString(); + final platform = TextToSpeechPlatform.values + .firstWhere((e) => describeEnum(e) == platformStr); + + return SpeechRateValidRange(min, normal, max, platform); + } + + /// [Future] which invokes the platform specific method for setSilence + /// 0 means start the utterance immediately. If the value is greater than zero a silence period in milliseconds is set according to the parameter + /// ***Android supported only*** + Future setSilence(int timems) async => + _channel.invokeMethod('setSilence', timems ?? 0); + + void setStartHandler(VoidCallback callback) { + startHandler = callback; + } + + void setCompletionHandler(VoidCallback callback) { + completionHandler = callback; + } + + void setContinueHandler(VoidCallback callback) { + continueHandler = callback; + } + + void setPauseHandler(VoidCallback callback) { + pauseHandler = callback; + } + + void setCancelHandler(VoidCallback callback) { + cancelHandler = callback; + } + + void setProgressHandler(ProgressHandler callback) { + progressHandler = callback; + } + + void setErrorHandler(ErrorHandler handler) { + errorHandler = handler; + } + + /// Platform listeners + Future platformCallHandler(MethodCall call) async { + switch (call.method) { + case "speak.onStart": + if (startHandler != null) { + startHandler(); + } + break; + case "synth.onStart": + if (startHandler != null) { + startHandler(); + } + break; + case "speak.onComplete": + if (completionHandler != null) { + completionHandler(); + } + break; + case "synth.onComplete": + if (completionHandler != null) { + completionHandler(); + } + break; + case "speak.onPause": + if (pauseHandler != null) { + pauseHandler(); + } + break; + case "speak.onContinue": + if (continueHandler != null) { + continueHandler(); + } + break; + case "speak.onCancel": + if (cancelHandler != null) { + cancelHandler(); + } + break; + case "speak.onError": + if (errorHandler != null) { + errorHandler(call.arguments); + } + break; + case 'speak.onProgress': + if (progressHandler != null) { + final args = call.arguments as Map; + progressHandler( + args['text'].toString(), + int.parse(args['start'].toString()), + int.parse(args['end'].toString()), + args['word'].toString(), + ); + } + break; + case "synth.onError": + if (errorHandler != null) { + errorHandler(call.arguments); + } + break; + default: + print('Unknowm method ${call.method}'); + } + } +} diff --git a/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart b/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart new file mode 100644 index 00000000..182e9dfa --- /dev/null +++ b/flutter_tts-voice_enhancement/lib/flutter_tts_web.dart @@ -0,0 +1,184 @@ +import 'dart:async'; +import 'dart:html' as html; +import 'dart:js'; + +import 'package:flutter/services.dart'; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +enum TtsState { playing, stopped, paused, continued } + +class FlutterTtsPlugin { + static const String PLATFORM_CHANNEL = "flutter_tts"; + static MethodChannel channel; + bool awaitSpeakCompletion = false; + + TtsState ttsState = TtsState.stopped; + + get isPlaying => ttsState == TtsState.playing; + + get isStopped => ttsState == TtsState.stopped; + + get isPaused => ttsState == TtsState.paused; + + get isContinued => ttsState == TtsState.continued; + + static void registerWith(Registrar registrar) { + channel = MethodChannel( + PLATFORM_CHANNEL, const StandardMethodCodec(), registrar.messenger); + final instance = FlutterTtsPlugin(); + channel.setMethodCallHandler(instance.handleMethodCall); + } + + html.SpeechSynthesis synth; + html.SpeechSynthesisUtterance utterance; + List voices; + List languages; + + FlutterTtsPlugin() { + utterance = html.SpeechSynthesisUtterance(); + synth = html.window.speechSynthesis; + + _listeners(); + } + + void _listeners() { + utterance.onStart.listen((e) { + ttsState = TtsState.playing; + channel.invokeMethod("speak.onStart", null); + }); + utterance.onEnd.listen((e) { + ttsState = TtsState.stopped; + channel.invokeMethod("speak.onComplete", null); + if (awaitSpeakCompletion) { + return 1; + } + }); + utterance.onPause.listen((e) { + ttsState = TtsState.paused; + channel.invokeMethod("speak.onPause", null); + }); + utterance.onResume.listen((e) { + ttsState = TtsState.continued; + channel.invokeMethod("speak.onContinue", null); + }); + utterance.onError.listen((e) { + channel.invokeMethod("speak.onError", e); + if (awaitSpeakCompletion) { + return 0; + } + }); + } + + Future handleMethodCall(MethodCall call) async { + switch (call.method) { + case 'speak': + final text = call.arguments as String; + _speak(text); + if (!awaitSpeakCompletion) { + return 1; + } + break; + case 'awaitSpeakCompletion': + awaitSpeakCompletion = call.arguments as bool; + return 1; + break; + case 'stop': + _stop(); + return 1; + break; + case 'pause': + _pause(); + return 1; + break; + case 'setLanguage': + final language = call.arguments as String; + _setLanguage(language); + return 1; + break; + case 'getLanguages': + return _getLanguages(); + break; + case 'setSpeechRate': + final rate = call.arguments as num; + _setRate(rate); + return 1; + break; + case 'setVolume': + final volume = call.arguments as num; + _setVolume(volume); + return 1; + break; + case 'setPitch': + final pitch = call.arguments as num; + _setPitch(pitch); + return 1; + break; + case 'isLanguageAvailable': + final lang = call.arguments as String; + return _isLanguageAvailable(lang); + break; + default: + throw PlatformException( + code: 'Unimplemented', + details: "The flutter_tts plugin for web doesn't implement " + "the method '${call.method}'"); + } + } + + void _speak(String text) { + if (ttsState == TtsState.stopped || ttsState == TtsState.paused) { + utterance.text = text; + if (ttsState == TtsState.paused) { + synth.resume(); + } else { + synth.speak(utterance); + } + } + } + + void _stop() { + if (ttsState != TtsState.stopped) { + synth.cancel(); + } + } + + void _pause() { + if (ttsState == TtsState.playing || ttsState == TtsState.continued) { + synth.pause(); + } + } + + void _setRate(num rate) => utterance.rate = rate * 2.0; + void _setVolume(num volume) => utterance.volume = volume; + void _setPitch(num pitch) => utterance.pitch = pitch; + void _setLanguage(String language) => utterance.lang = language; + + bool _isLanguageAvailable(String language) { + if (voices?.isEmpty ?? true) _setVoices(); + if (languages?.isEmpty ?? true) _setLanguages(); + for (var lang in languages) { + if (lang.toLowerCase() == language.toLowerCase()) return true; + } + return false; + } + + List _getLanguages() { + if (voices?.isEmpty ?? true) _setVoices(); + if (languages?.isEmpty ?? true) _setLanguages(); + return languages; + } + + void _setVoices() { + voices = + context['speechSynthesis'].callMethod('getVoices') as JsArray; + } + + void _setLanguages() { + var langs = Set(); + for (var v in voices) { + langs.add(v['lang'] as String); + } + + languages = langs.toList(); + } +} diff --git a/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift b/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift new file mode 100644 index 00000000..ec4bffa1 --- /dev/null +++ b/flutter_tts-voice_enhancement/macos/Classes/FlutterTtsPlugin.swift @@ -0,0 +1,315 @@ +import FlutterMacOS +import Foundation +import AVFoundation + +public class FlutterTtsPlugin: NSObject, FlutterPlugin, AVSpeechSynthesizerDelegate { + final var iosAudioCategoryKey = "iosAudioCategoryKey" + final var iosAudioCategoryOptionsKey = "iosAudioCategoryOptionsKey" + + let synthesizer = AVSpeechSynthesizer() + var language: String = AVSpeechSynthesisVoice.currentLanguageCode() + var rate: Float = AVSpeechUtteranceDefaultSpeechRate + var languages = Set() + var volume: Float = 1.0 + var pitch: Float = 1.0 + var voice: AVSpeechSynthesisVoice? + var awaitSpeakCompletion: Bool = false + var speakResult: FlutterResult! + + var channel = FlutterMethodChannel() + init(channel: FlutterMethodChannel) { + super.init() + self.channel = channel + synthesizer.delegate = self + setLanguages() + } + + private func setLanguages() { + for voice in AVSpeechSynthesisVoice.speechVoices(){ + self.languages.insert(voice.language) + } + } + + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "flutter_tts", binaryMessenger: registrar.messenger) + let instance = FlutterTtsPlugin(channel: channel) + registrar.addMethodCallDelegate(instance, channel: channel) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "speak": + let text: String = call.arguments as! String + self.speak(text: text, result: result) + break + case "awaitSpeakCompletion": + self.awaitSpeakCompletion = call.arguments as! Bool + result(1) + break + case "synthesizeToFile": + guard let args = call.arguments as? [String: Any] else { + result("iOS could not recognize flutter arguments in method: (sendParams)") + return + } + let text = args["text"] as! String + let fileName = args["fileName"] as! String + self.synthesizeToFile(text: text, fileName: fileName, result: result) + break + case "pause": + self.pause(result: result) + break + case "setLanguage": + let language: String = call.arguments as! String + self.setLanguage(language: language, result: result) + break + case "setSpeechRate": + let rate: Double = call.arguments as! Double + self.setRate(rate: Float(rate)) + result(1) + break + case "setVolume": + let volume: Double = call.arguments as! Double + self.setVolume(volume: Float(volume), result: result) + break + case "setPitch": + let pitch: Double = call.arguments as! Double + self.setPitch(pitch: Float(pitch), result: result) + break + case "stop": + self.stop() + result(1) + break + case "getLanguages": + self.getLanguages(result: result) + break + case "getSpeechRateValidRange": + self.getSpeechRateValidRange(result: result) + break + case "isLanguageAvailable": + let language: String = call.arguments as! String + self.isLanguageAvailable(language: language, result: result) + break + case "getVoices": + self.getVoices(result: result) + break + case "setVoice": + guard let args = call.arguments as? [String: String] else { + result("iOS could not recognize flutter arguments in method: (sendParams)") + return + } + self.setVoice(voice: args, result: result) + break + default: + result(FlutterMethodNotImplemented) + } + } + + private func speak(text: String, result: @escaping FlutterResult) { + if (self.synthesizer.isPaused) { + if (self.synthesizer.continueSpeaking()) { + if self.awaitSpeakCompletion { + self.speakResult = result + } else { + result(1) + } + } else { + result(0) + } + } else { + let utterance = AVSpeechUtterance(string: text) + if self.voice != nil { + utterance.voice = self.voice! + } else { + utterance.voice = AVSpeechSynthesisVoice(language: self.language) + } + utterance.rate = self.rate + utterance.volume = self.volume + utterance.pitchMultiplier = self.pitch + + self.synthesizer.speak(utterance) + if self.awaitSpeakCompletion { + self.speakResult = result + } else { + result(1) + } + } + } + + private func synthesizeToFile(text: String, fileName: String, result: FlutterResult) { + var output: AVAudioFile? + var failed = false + let utterance = AVSpeechUtterance(string: text) + + if #available(iOS 13.0, *) { + self.synthesizer.write(utterance) { (buffer: AVAudioBuffer) in + guard let pcmBuffer = buffer as? AVAudioPCMBuffer else { + NSLog("unknow buffer type: \(buffer)") + failed = true + return + } + print(pcmBuffer.format) + if pcmBuffer.frameLength == 0 { + // finished + } else { + // append buffer to file + let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent(fileName) + NSLog("Saving utterance to file: \(fileURL.absoluteString)") + + if output == nil { + do { + output = try AVAudioFile( + forWriting: fileURL, + settings: pcmBuffer.format.settings, + commonFormat: .pcmFormatInt16, + interleaved: false) + } catch { + NSLog(error.localizedDescription) + failed = true + return + } + } + + try! output!.write(from: pcmBuffer) + } + } + } else { + result("Unsupported iOS version") + } + if failed { + result(0) + } + result(1) + } + + private func pause(result: FlutterResult) { + if (self.synthesizer.pauseSpeaking(at: AVSpeechBoundary.word)) { + result(1) + } else { + result(0) + } + } + + private func setLanguage(language: String, result: FlutterResult) { + if !(self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { + result(0) + } else { + self.language = language + self.voice = nil + result(1) + } + } + + private func setRate(rate: Float) { + self.rate = rate + } + + private func setVolume(volume: Float, result: FlutterResult) { + if (volume >= 0.0 && volume <= 1.0) { + self.volume = volume + result(1) + } else { + result(0) + } + } + + private func setPitch(pitch: Float, result: FlutterResult) { + if (volume >= 0.5 && volume <= 2.0) { + self.pitch = pitch + result(1) + } else { + result(0) + } + } + + private func stop() { + self.synthesizer.stopSpeaking(at: AVSpeechBoundary.immediate) + } + + private func getLanguages(result: FlutterResult) { + result(Array(self.languages)) + } + + private func getSpeechRateValidRange(result: FlutterResult) { + let validSpeechRateRange: [String:String] = [ + "min": String(AVSpeechUtteranceMinimumSpeechRate), + "normal": String(AVSpeechUtteranceDefaultSpeechRate), + "max": String(AVSpeechUtteranceMaximumSpeechRate), + "platform": "ios" + ] + result(validSpeechRateRange) + } + + private func isLanguageAvailable(language: String, result: FlutterResult) { + var isAvailable: Bool = false + if (self.languages.contains(where: {$0.range(of: language, options: [.caseInsensitive, .anchored]) != nil})) { + isAvailable = true + } + result(isAvailable); + } + + private func getVoices(result: FlutterResult) { + if #available(iOS 9.0, *) { + let voices = NSMutableArray() + var voiceDict: [String: String] = [:] + for voice in AVSpeechSynthesisVoice.speechVoices() { + voiceDict["name"] = voice.name + voiceDict["locale"] = voice.language + voices.add(voiceDict) + } + result(voices) + } else { + // Since voice selection is not supported below iOS 9, make voice getter and setter + // have the same bahavior as language selection. + getLanguages(result: result) + } + } + + private func setVoice(voice: [String:String], result: FlutterResult) { + if #available(iOS 9.0, *) { + if let voice = AVSpeechSynthesisVoice.speechVoices().first(where: { $0.name == voice["name"]! && $0.language == voice["locale"]! }) { + self.voice = voice + self.language = voice.language + result(1) + return + } + result(0) + } else { + setLanguage(language: voice["name"]!, result: result) + } + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) { + if self.awaitSpeakCompletion { + self.speakResult(1) + } + self.channel.invokeMethod("speak.onComplete", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didStart utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onStart", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didPause utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onPause", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didContinue utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onContinue", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didCancel utterance: AVSpeechUtterance) { + self.channel.invokeMethod("speak.onCancel", arguments: nil) + } + + public func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, willSpeakRangeOfSpeechString characterRange: NSRange, utterance: AVSpeechUtterance) { + let nsWord = utterance.speechString as NSString + let data: [String:String] = [ + "text": utterance.speechString, + "start": String(characterRange.location), + "end": String(characterRange.location + characterRange.length), + "word": nsWord.substring(with: characterRange) + ] + self.channel.invokeMethod("speak.onProgress", arguments: data) + } + +} diff --git a/flutter_tts-voice_enhancement/macos/flutter_tts.podspec b/flutter_tts-voice_enhancement/macos/flutter_tts.podspec new file mode 100644 index 00000000..2838eb07 --- /dev/null +++ b/flutter_tts-voice_enhancement/macos/flutter_tts.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'flutter_tts' + s.version = '0.0.1' + s.summary = 'macOS implementation of the flutter_tts plugin.' + s.description = <<-DESC + A flutter text to speech plugin + DESC + s.homepage = 'https://github.com/dlutton/flutter_tts' + s.license = { :file => '../LICENSE' } + s.author = { 'Daniel Lutton' => 'eyedea32@gmail.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'FlutterMacOS' + + s.platform = :osx, '10.15' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } + s.swift_version = '5.0' + + end \ No newline at end of file diff --git a/flutter_tts-voice_enhancement/pubspec.yaml b/flutter_tts-voice_enhancement/pubspec.yaml new file mode 100644 index 00000000..06e93f33 --- /dev/null +++ b/flutter_tts-voice_enhancement/pubspec.yaml @@ -0,0 +1,28 @@ +name: flutter_tts +description: A flutter plugin for Text to Speech. This plugin is supported on iOS, Android, Web, & macOS. +version: 1.3.0 +homepage: https://github.com/dlutton/flutter_tts + +dependencies: + flutter: + sdk: flutter + flutter_web_plugins: + sdk: flutter + +flutter: + plugin: + platforms: + android: + package: com.tundralabs.fluttertts + pluginClass: FlutterTtsPlugin + ios: + pluginClass: FlutterTtsPlugin + macos: + pluginClass: FlutterTtsPlugin + web: + pluginClass: FlutterTtsPlugin + fileName: flutter_tts_web.dart + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/help/ios/Runner/Info.plist b/help/ios/Runner/Info.plist index fe4c8174..71ce57cb 100644 --- a/help/ios/Runner/Info.plist +++ b/help/ios/Runner/Info.plist @@ -41,5 +41,8 @@ UIViewControllerBasedStatusBarAppearance + + < key >NSCameraUsageDescription< /key > + < string >Camera permission is required for barcode scanning.< /string > diff --git a/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg b/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg new file mode 100644 index 00000000..abfc5b99 Binary files /dev/null and b/hms-plugins/flutter-hms-location/.docs/images/homeScreen.jpg differ diff --git a/hms-plugins/flutter-hms-location/CHANGELOG.md b/hms-plugins/flutter-hms-location/CHANGELOG.md new file mode 100644 index 00000000..8c43b7b8 --- /dev/null +++ b/hms-plugins/flutter-hms-location/CHANGELOG.md @@ -0,0 +1,12 @@ +## 5.0.0+301 + +* Added the getNavigationContextState function. +* Added the enableLogger and disableLogger methods. + +## 4.0.4+1/4.0.4+300 + +* Fix minor issues. + +## 4.0.4 + +* Initial release. diff --git a/hms-plugins/flutter-hms-location/LICENSE b/hms-plugins/flutter-hms-location/LICENSE new file mode 100644 index 00000000..7783de53 --- /dev/null +++ b/hms-plugins/flutter-hms-location/LICENSE @@ -0,0 +1,53 @@ +Apache License + +Version 2.0, January 2004 + +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS diff --git a/hms-plugins/flutter-hms-location/README.md b/hms-plugins/flutter-hms-location/README.md new file mode 100644 index 00000000..cb69c34a --- /dev/null +++ b/hms-plugins/flutter-hms-location/README.md @@ -0,0 +1,1737 @@ +# Huawei Location Kit Flutter Plugin + +## Table of Contents +* [Introduction](#introduction) +* [Installation Guide](#installation-guide) + * [Creating Project in App Gallery Connect](#creating-project-in-app-gallery-connect) + * [Configuring the Signing Certificate Fingerprint](#configuring-the-signing-certificate-fingerprint) + * [Integrating the Flutter Location Plugin](#integrating-the-flutter-location-plugin) +* [API Reference](#api-reference) + * [Overview](#overview) + * [FusedLocationProviderClient](#fusedlocationproviderclient) + * [Location](#location) + * [HWLocation](#hwlocation) + * [LocationAvailability](#locationavailability) + * [LocationCallback](#locationcallback) + * [LocationRequest](#locationrequest) + * [LocationResult](#locationresult) + * [LocationSettingsRequest](#locationsettingsrequest) + * [LocationSettingsStates](#locationsettingsstates) + * [NavigationResult](#navigationresult) + * [NavigationRequest](#navigationrequest) + * [ActivityIdentificationService](#activityidentificationservice) + * [ActivityConversionData](#activityconversiondata) + * [ActivityConversionInfo](#activityconversioninfo) + * [ActivityConversionResponse](#activityconversionresponse) + * [ActivityIdentificationData](#activityidentificationdata) + * [ActivityIdentificationResponse](#activityidentificationresponse) + * [Geofence Service](#geofence-service) + * [GeofenceData](#geofencedata) + * [GeofenceRequest](#geofencerequest) + * [PermissionHandler](#permissionhandler) + * [HMSLogger](#hmslogger) + +* [Configuration Description](#configuration-description) +* [Sample Project](#sample-project) +* [Questions or Issues](#questions-or-issues) +* [Licensing and Terms](#licensing-and-terms) + +## Introduction + +This plugin enables communication between Huawei Location SDK and Flutter platform. Huawei Location Kit combines the GPS, Wi-Fi, and base station locations to help you quickly obtain precise user locations, build up global positioning capabilities, and reach a wide range of users around the globe.Currently, it provides the four main capabilities: fused location, location semantics, activity identification, and geofence. You can call relevant capabilities as needed. + +Huawei Location Kit provides the following core capabilities: +- **Fused location**: Provides a set of simple and easy-to-use APIs for you to quickly obtain the device location based on the GPS, Wi-Fi, and base station location data. +- **Activity identification**: Identifies user motion status through the acceleration sensor, cellular network information, and magnetometer, helping you adjust your app based on user behavior. +- **Geofence**: Allows you to set an interested area through an API so that your app can receive a notification when a specified action (such as leaving, entering, or lingering in the area) occurs. + +## Installation Guide + +- Before you get started, you must register as a HUAWEI developer and complete identity verification on the [HUAWEI Developer](https://developer.huawei.com/consumer/en/) website. For details, please refer to [Register a HUAWEI ID](https://developer.huawei.com/consumer/en/doc/10104). + +- Create an app in your project is required in AppGallery Connect in order to communicate with Huawei services. To create an app, perform the following steps: + +### Creating Project in App Gallery Connect + +**Step 1.** Sign in to [AppGallery Connect](https://developer.huawei.com/consumer/en) and select My projects. + +**Step 2.** Click your project from the project list. + +**Step 3.** Go to **Project Setting** > **General information**, and click **Add app**. +If an app exists in the project, and you need to add a new one, expand the app selection area on the top of the page and click **Add app**. + +**Step 4.** On the **Add app** page, enter app information, and click **OK**. + +- A signing certificate fingerprint is used to verify the authenticity of an app when it attempts to access an HMS Core service through the HMS Core SDK. Before using HMS Core (APK), you must locally generate a signing certificate fingerprint and configure it in AppGallery Connect. Ensure that the JDK has been installed on your computer. + +### Configuring the Signing Certificate Fingerprint +**Step 1:** Go to **Project Setting** > **General information**. In the **App information** field, click the icon next to SHA-256 certificate fingerprint, and enter the obtained **SHA256 certificate fingerprint**. + +**Step 2:** After completing the configuration, click **OK**. (Check mark icon) + +### Integrating Flutter Location Plugin + +**Step 1:** Sign in [AppGallery Connect](https://developer.huawei.com/consumer/en/service/josp/agc/index.html) to AppGallery Connect and select **My projects**. + +**Step 2:** Find your app project, and click the desired app name. + +**Step 3:** Go to **Project Setting > > General information**. In the **App information** field, click **agconnect-service.json** to download configuration file. + +**Step 4:** Create a Flutter project if you do not have one. + +**Step 5:** Copy the **agconnect-service.json** file to the **android/app** directory of your Flutter project. + +**Step 6:** Copy the signature file that is generated in **Generating a Signature File** to the android/app directory of your Flutter project. + +**Step 7:** Check whether the **agconnect-services.json** file and signature file are successfully added to the **android/app** directory of the Flutter project. + + + +**Step 8:** Open the **build.gradle** file in the **android** directory of your Flutter project. + - Go to **buildscript** then configure the Maven repository address and agconnect plugin for the HMS SDK. + + ```gradle + buildscript { + repositories { + google() + jcenter() + maven { url 'https://developer.huawei.com/repo/' } + } + + dependencies { + /* + * + */ + classpath 'com.huawei.agconnect:agcp:1.4.1.300' + } + } + ``` + + - Go to **allprojects** then configure the Maven repository address for the HMS SDK. + + ```gradle + allprojects { + repositories { + google() + jcenter() + maven { url 'https://developer.huawei.com/repo/' } + } + } + ``` + +**Step 9:** Open the **build.gradle** file in the **android/app** directory. +- Add `apply plugin: 'com.huawei.agconnect'` line after other `apply` entries. + + ```gradle + apply plugin: 'com.android.application' + apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + apply plugin: 'com.huawei.agconnect' + ``` + + - Set your package name in **defaultConfig** > **applicationId** and set **minSdkVersion** to **19** or **higher**. + Package name must match with the **package_name** entry in **agconnect-services.json** file. + + ```gradle + defaultConfig { + applicationId "" + minSdkVersion 17 + /* + * + */ + } + ``` + - Copy the signature file that generated in [Generating a Signing Certificate](https://developer.huawei.com/consumer/en/codelab/HMSPreparation/index.html#3) to **android/app** directory. + + - Configure the signature in **android** according to the signature file information. + +```gradle +signingConfigs { + config { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword keystoreProperties['storePassword'] + } +} +buildTypes { + debug { + signingConfig signingConfigs.config + } + release { + signingConfig signingConfigs.config + } +} +``` + +**Step 10:** On your Flutter project directory find and open your **pubspec.yaml** file and add library to dependencies. For more details please refer the [Using packages](https://flutter.dev/docs/development/packages-and-plugins/using-packages#dependencies-on-unpublished-packages) document. + + ```yaml + dependencies: + huawei_location: + # Replace {library path} with actual library path of Huawei Push Kit Location for Flutter. + path: {library path} + ``` + +-**Step 11:** Run following command to update package info. + +``` +[project_path]> flutter pub get +``` + +**Step 12:** Run following command to start the app. + +``` +[project_path]> flutter run +``` + +## API Reference + +### Overview + +| Module | Description | +|----------------------------------|------------------------------------------------------------------------------------------------| +| FusedLocationProviderClient | With this module you can check the device location settings, get the last known location information once or continuously, set mock location and others. | +| ActivityIdentificationService | If your app needs to obtain the activity status of the user's device (for example, walking, running, or bicycling) or your app needs to detect activity status change of a user, you can use this module. | +| GeofenceService | If you are interested in a place, you can create a geofence based on the place. When the device enters the geofence or stays for a duration of time, a notification can be sent to your app. | + +### FusedLocationProviderClient + +#### Public Constructor Summary + +| Constructor | Description | +|----------------------------------|------------------------------------------------------------------------------------------------ +| FusedLocationProviderClient() | Default constructor. | + +#### Public Method Summary + +| Method | Return Type | Description | +|------------------------------------------------------------------------------------------------|-----------------------------------|-------------| +| checkLocationSettings(LocationSettingsRequest locationSettingsRequest) | Future\ | This API is used to check location settings of the device. | +| getLastLocation() | Future\ | This API is used to obtain the last requested available location. This API does not proactively request the location. Instead, it uses the location cached for the last request. | +| getLastLocationWithAddress(LocationRequest locationRequest) | Future\ | This API is used to obtain the available location of the last request, including the detailed address information. | +| getLocationAvailability() | Future\ | This API is used to check whether the location data is available. | +| setMockMode(bool mockMode) | Future\ | This API is used to specify whether the location provider uses the location mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation (Location) is directly returned. | +| setMockLocation(Location location) | Future\ | This API is used to set the specific mock location. You must call the setMockMode(boolean) method and set the flag to true before calling this method. | +| requestLocationUpdates(LocationRequest locationRequest) | Future\ | This API is used to continuously request location updates. | +| requestLocationUpdatesCb(LocationRequest locationRequest, LocationCallback locationCallback) | Future\ | This API is used to request location updates using the callback. | +| requestLocationUpdatesExCb(LocationRequest locationRequest, LocationCallback locationCallback) | Future\ | This API is an extended location information service API. It supports high-precision location and is compatible with common location APIs. If the device does not support high-precision location or the app does not request the high-precision location permission, this API returns common location information similar to that returned by the requestLocationUpdates API. | +| removeLocationUpdates(int requestCode) | Future\ | This API is used to remove location updates from the specified requestCode. | +| removeLocationUpdatesCb(int callbackId) | Future\ | This API is used to remove location updates of the specified callbackId. | +| onLocationData | Future\Location\> | This API is used to listen location updates that comes from requestLocationUpdates API method. | +| getNavigationContextState(int type) | Future\ | Obtains the requested navigation type. | + +#### Public Constructors + +##### FusedLocationProviderClient() + +Constructor for *FusedLocationProviderClient* object. + +#### Public Methods + +##### Future\ checkLocationSettings(LocationSettingsRequest locationSettingsRequest) *async* + +Checks location settings of the device. + +| Parameter | Description | +|-------------------------|-------------| +| locationSettingsRequest | Location setting request object. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | LocationSettingsStates object if the operation is successful; PlatformException otherwise. | + +##### Future\ getLastLocation() *async* + +Obtains the available location of the last request. Instead of proactively requesting a location, this method uses the location cached during the last request. + +The value null may be returned in the following scenarios: +- The location function has never been used. +- The location function is disabled. +- The device is restored to factory settings. + +If real-time location is required, you are advised to proactively call requestLocationUpdates instead of this method. To receive a location once only, you can set numUpdates in LocationRequest to 1. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Location object if the operation is successful; PlatformException otherwise. | + +##### Future\ getLastLocationWithAddress(LocationRequest locationRequest) *async* + +Obtains the available location of the last request, including the detailed address information. If no location is available, null is returned. + +| Parameter | Description | +|-------------------------|-------------| +| locationRequest | Location request object. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | HWLocation object if the operation is successful; PlatformException otherwise. | + +##### Future\ getLocationAvailability() *async* + +Checks whether the location data is available. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | LocationAvailability object if the operation is successful; PlatformException otherwise. | + +##### Future\ setMockMode(bool mockMode) *async* + +Sets whether the location provider uses the mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation is directly returned. + +| Parameter | Description | +|-------------------------|-------------| +| mockMode | Indicates whether the location provider uses the mock mode. true: yes; false: no. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Future\ setMockLocation(Location location) *async* + +Sets whether the location provider uses the mock mode. If yes, the GPS or network location is not used and the location set through setMockLocation is directly returned. + +| Parameter | Description | +|-------------------------|-------------| +| location | Mock location. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Future\ requestLocationUpdates(LocationRequest locationRequest) *async* + +Continuously requests location updates. You can call the onLocationData API method to listen for location updates. + +| Parameter | Description | +|-------------------------|-------------| +| locationRequest | Location update request. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the removeLocationUpdates method. | + +##### Future\ requestLocationUpdatesCb(LocationRequest locationRequest, LocationCallback locationCallback) *async* + +Requests location updates using the callback. + +| Parameter | Description | +|-------------------------|-------------| +| locationRequest | Location update request. | +| locationCallback | Location update callback.| + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Callback ID if the operation is successful; PlatformException otherwise. The callback ID can be used to call the removeLocationUpdatesCb method. | + +##### Future\ requestLocationUpdatesExCb(LocationRequest locationRequest, LocationCallback locationCallback) *async* + +Continuously requests location updates. This method is an extended location information service API. It supports high-precision location and is compatible with common location APIs. If the device does not support high-precision location or the app does not request the high-precision location, this method returns common location information similar to that returned by the requestLocationUpdatesCb method. + +| Parameter | Description | +|-------------------------|-------------| +| locationRequest | Location update request. | +| locationCallback | Location update callback.| + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Callback ID if the operation is successful; PlatformException otherwise. The callback ID can be used to call the removeLocationUpdatesCb method. | + +##### Future\ removeLocationUpdates(int requestCode) *async* + +Removes location updates based on the specified request code. + +| Parameter | Description | +|-------------------------|-------------| +| requestCode | Request code returned by the requestLocationUpdates method. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Future\ removeLocationUpdatesCb(int callbackId) *async* + +Removes location updates based on the specified callback ID. + +| Parameter | Description | +|-------------------------|-------------| +| callbackId | Callback ID returned by the requestLocationUpdatesCb or requestLocationUpdatesExCb method. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Stream\ onLocationData + +Listens for location updates that come from the requestLocationUpdates method. + +| Return Type | Description | +|----------------------------------|-------------| +| Stream\ | Stream of Location object. You can call the .listen() method to subscribe to this stream and listen for updates. | + +##### Future\ getNavigationContextState(int type) *async* + +Removes location updates based on the specified callback ID. + +| Parameter | Description | +|-------------------------|-------------| +| type | Requested navigation type. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | NavigationResult object if the operation is successful; PlatformException otherwise. | + +### Location + +#### Public Properties + +| Properties | Type | Description | +|------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------| +| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | +| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | +| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | +| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | +| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | +| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | +| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | +| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | +| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | +| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | +| time | int | Current timestamp, in milliseconds. | +| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | + +#### Public Constructor Summary + +| Constructor | Description | +|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| Location({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) | Default constructor. | +| Location.fromMap(Map\ map) | Creates a Location object from a map. | +| Location.fromJson(String source) | Creates a Location object from a JSON string. | + +#### Public Constructors + +##### Location({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) + +Constructor for Location object. + +| Parameter | Type | Description | +|------------------------------|--------|-------------------------------------------------------------------------------------------------------------------------| +| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | +| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | +| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | +| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | +| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | +| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | +| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | +| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | +| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | +| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | +| time | int | Current timestamp, in milliseconds. | +| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | + +##### Location.fromMap(Map\ map) + +Creates a Location object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### Location.fromJson(String source) + +Creates a Location object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + + +### HWLocation + +#### Public Properties + +| Properties | Type | Description | +|------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------| +| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | +| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | +| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | +| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | +| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | +| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | +| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | +| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | +| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | +| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | +| time | int | Current timestamp, in milliseconds. | +| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | +| countryCode | String | Country code. The value is a two-letter code complying with the ISO 3166-1 standard. | +| countryName | String | Country name. | +| state | String | Administrative region. | +| city | String | City of the current location. | +| county | String | County of the current location. | +| street | String | Street of the current location. | +| featureName | String | Landmark building at the current location. | +| postalCode | String | Postal code of the current location. | +| phone | String | Phone number of the landmark building (such as a store or company) at the current location. | +| url | String | Website of the landmark building (such as a store or company) at the current location. | +| extraInfo | Map\ | Additional information, which is a key-value pair. | + + +#### Public Constructor Summary + +| Constructor | Description | +|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| HWLocation({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos, String countryCode, String countryName, String state, String city, String county, String street, String featureName, String postalCode, String phone, String url, Map extraInfo}) | Default constructor. | +| HWLocation.fromMap(Map\ map) | Creates a HWLocation object from a map. | +| HWLocation.fromJson(String source) | Creates a HWLocation object from a JSON string. | + +#### Public Constructors + +##### HwLocation({String provider, double latitude, double longitude, double altitude, double speed, double bearing, double horizontalAccuracyMeters, double verticalAccuracyMeters, double speedAccuracyMetersPerSecond, double bearingAccuracyDegrees, int time, int elapsedRealtimeNanos}) + +Constructor for Location object. + +| Parameter | Type | Description | +|------------------------------|------------------------|-------------------------------------------------------------------------------------------------------------------------| +| provider | String | Location provider, such as network location, GPS, Wi-Fi, and Bluetooth. | +| latitude | double | Latitude of a location. If no latitude is available, 0.0 is returned. | +| longitude | double | Longitude of a location. If no longitude is available, 0.0 is returned. | +| altitude | double | Altitude of a location. If no altitude is available, 0.0 is returned. | +| speed | double | Speed of a device at the current location, in meters per second. If no speed is available, 0.0 is returned. | +| bearing | double | Bearing of a device at the current location, in degrees. If no bearing is available, 0.0 is returned. | +| horizontalAccuracyMeters | double | Horizontal error of a location, in meters. If no horizontal error is available, 0.0 is returned. | +| verticalAccuracyMeters | double | Vertical error of a location, in meters. If no vertical error is available, 0.0 is returned. | +| speedAccuracyMetersPerSecond | double | Speed error of a device at the current location, in meters per second. If no speed error is available, 0.0 is returned. | +| bearingAccuracyDegrees | double | Bearing error of the current location, in degrees. If no bearing error is available, 0.0 is returned. | +| time | int | Current timestamp, in milliseconds. | +| elapsedRealtimeNanos | int | Time elapsed since the system was started, in nanoseconds | +| countryCode | String | Country code. The value is a two-letter code complying with the ISO 3166-1 standard. | +| countryName | String | Country name. | +| state | String | Administrative region. | +| city | String | City of the current location. | +| county | String | County of the current location. | +| street | String | Street of the current location. | +| featureName | String | Landmark building at the current location. | +| postalCode | String | Postal code of the current location. | +| phone | String | Phone number of the landmark building (such as a store or company) at the current location. | +| url | String | Website of the landmark building (such as a store or company) at the current location. | +| extraInfo | Map\ | Additional information, which is a key-value pair. | + +##### HWLocation.fromMap(Map map) + +Creates a HWLocation object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### HWLocation.fromJson(String source) + +Creates a HWLocation object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### LocationAvailability + +Device location availability. + +#### Public Properties + +| Properties | Type | Description | +|-------------------|------|-----------------------------------------------------------------------------------------------------------| +| cellStatus | int | Availability status code of cell location. Currently not provided. Value is always **0**. | +| wifiStatus | int | Availability status code of wifi location. Currently not provided. Value is always **0**. | +| elapsedRealtimeNs | int | Time elapsed since the system was started, in nanoseconds. Currently not provided. Value is always **0**. | +| locationStatus | int | Location status code. If the value of smaller than 1000, then device location is available. | + +**NOTE:** + +Currently, cellStatus, wifiStatus and elapsedRealtimeNs are not provided and have a fixed value of 0. + +#### Public Constructor Summary + +| Constructor | Description | +|---------------------------------------------------------------------------------------------------|----------------------| +| LocationAvailability({int cellStatus, int wifiStatus, int elapsedRealtimeNs, int locationStatus}) | Default constructor. | +| LocationAvailability.fromMap(Map\ map) | Creates a LocationAvailability object from a map. | +| LocationAvailability.fromJson(String source) | Creates a LocationAvailability object from a JSON string. | + +#### Public Method Summary + +| Methods | Return Type | Description | +|---------------------|-------------|------------------------------------------------| +| isLocationAvailable | bool | Indicates if the location is available or not. | + +#### Public Constructors + +##### LocationAvailability({int cellStatus, int wifiStatus, int elapsedRealtimeNs, int locationStatus}) + +Constructor for LocationAvailability object. + +| Parameter | Type | Description | +|-------------------|------|-----------------------------------------------------------------------------------------------------------| +| cellStatus | int | Availability status code of cell location. Currently not provided. Value is always **0**. | +| wifiStatus | int | Availability status code of wifi location. Currently not provided. Value is always **0**. | +| elapsedRealtimeNs | int | Time elapsed since the system was started, in nanoseconds. Currently not provided. Value is always **0**. | +| locationStatus | int | Location status code. If the value of smaller than 1000, then device location is available. | + +##### LocationAvailability.fromMap(Map\ map) + +Creates a LocationAvailability object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### LocationAvailability.fromJson(String source) + +Creates a LocationAvailability object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +#### Public Methods + +##### bool isLocationAvaible + +Checks whether the device location is available. If yes, the value true is returned. A number of causes may result in failure to determine the location, such as that the location function is disabled or sensor data cannot be obtained from the device. + +| Return Type | Description | +|------------------------------|----------------------| +| String | JSON string as a source. | + +### LocationCallback + +#### Public Properties + +| Properties | Type | Description | +|------------------------|----------------------------------------------------------|------------------------------------------------------------| +| onLocationAvailability | void Function(LocationAvailability locationAvailability) | Callback function to listen location availability changes. | +| onLocationResult | void Function(LocationResult locationResult) | Callback function to listen location updates. | + +#### Public Constructor Summary + +| Constructor | Description | +|------------------------------------------------------------------------------------------|----------------------| +| LocationCallback({void Function onLocationResult, void Function onLocationAvailability}) | Default constructor. | + +#### Public Constructors + +##### LocationCallback({void Function onLocationResult, void Function onLocationAvailability}) + +Constructor for LocationCallback object. + +| Parameter | Type | Description | +|------------------------------|---------------|-------------------------------------------------------------------------------------------------------------------------| +| onLocationResult | void Function | Callback function to trigger when the device location is available. | +| onLocationAvailability | void Function | Callback function to trigger when the device location availability changes. | + +### LocationRequest + +Location request class. + +#### Public Properties + +| Properties | Type | Description | +|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| priority | int | Request priority. The default value is 100. | +| interval | int | Request interval, in milliseconds. The default value is 3600000. | +| fastestInterval | int | Shortest request interval, in milliseconds. The default value is 600000. If another app initiates a location request, the location is also reported to the app at the interval specified in fastestInterval. | +| expirationTime | int | Request expiration time, in milliseconds. | +| numUpdates | int | Number of requested location updates. | +| smallestDisplacement | double | Minimum displacement between location updates, in meters. | +| maxWaitTime | int | Maximum waiting timeIndicates whether to return the address information. The default value is false. | +| needAddress | bool | Indicates whether to return the address information. The default value is false. | +| language | String | Language. The value consists of two letters and complies with the ISO 639-1 international standard. By default, the value is empty. | +| countryCode | String | Country code. The value consists of two letters and complies with the ISO 3166-1 international standard. By default, the value is empty. | + +#### Public Constants + +| Constants | Type | Value | Description | +|----------------------------------|------|-------|----------------------------------------------------------------------------------------------------------------------------------------------| +| PRIORITY_HIGH_ACCURACY | int | 100 | Used to request the most accurate location. | +| PRIORITY_BALANCED_POWER_ACCURACY | int | 102 | Used to request the block-level location. | +| PRIORITY_LOW_POWER | int | 104 | Used to request the city-level location. | +| PRIORITY_NO_POWER | int | 105 | Used to request the location with the optimal accuracy without additional power consumption. | +| PRIORITY_HD_ACCURACY | int | 200 | Used to request the high-precision location information. Currently, this parameter is available only for the requestLocationUpdatesExCb API. | + +#### Public Constructor Summary + +| Constructor | Description | +|-------------------------------------------------------|----------------------| +| LocationRequest() | Default constructor. | +| LocationRequest.fromMap(Map\ map) | Creates a Location object from a map. | +| LocationRequest.fromJson(String source) | Creates a Location object from a JSON string. | + +#### Public Method Summary + +| Return Type | Method | Description | +|-----------------|--------------------------------|-------------| +| bool | isFastestIntervalExplicitlySet | Indicates whether the fastest interval explicitly set or default value is being used. | + + +#### Public Constructors + +##### LocationRequest() + +Constructor for Location object. + +##### LocationRequest.fromMap(Map\ map) + +Creates a Location object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### LocationRequest.fromJson(String source) + +Creates a Location object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +#### Public Methods + +##### bool isFastestIntervalExplicitlySet + +Checks whether the shortest interval is used. + +| Methods | Return Type | Description | +|--------------------------------|-------------|---------------------------------------------------------------------------------------| +| isFastestIntervalExplicitlySet | bool | Indicates whether the fastest interval explicitly set or default value is being used. | + +### LocationResult + +Location data information class. + +#### Public Properties + +| Properties | Type | Description | +|----------------|--------------------|-------------------------------------------------------------------------------------------------------| +| locations | List\ | Available locations, which are ordered from oldest to newest. | +| hwLocations | List\ | List of available locations sorted from oldest to newest, including the detailed address information. | +| lastLocation | Location | Available location of the last request. | +| lastHWLocation | HWLocation | Available location of the last request, including the detailed address information. | + +#### Public Constructor Summary + +| Constructor | Description | +|----------------------------------------------------------------------------------------------------------------------------|----------------------| +| LocationResult({List locations, List hwLocations, Location lastLocation, HWLocation lastHWLocation}) | Default constructor. | +| LocationResult.fromMap(Map\ map) | Creates a Location object from a map. | +| LocationResult.fromJson(String source) | Creates a Location object from a JSON string. | + +#### Public Constructors + +##### LocationResult({List locations, List hwLocations, Location lastLocation, HWLocation lastHWLocation}) + +Constructor for LocationResult object. + +| Parameter | Type | Description | +|------------------------------|--------------------|-------------------------------------------------------------------------------------------------------------------------| +| locations | List\ | Available locations, which are sorted from oldest to newest. | +| hwLocations | List\ | List of available locations sorted from oldest to newest, including the detailed address. | +| lastLocation | Location | Available location of the last request. | +| lastHWLocation | HWLocation | Available location of the last request, including the detailed address. | + + +##### LocationResult.fromMap(Map\ map) + +Creates a LocationResult object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### LocationResult.fromJson(String source) + +Creates a LocationResult object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + + + + +### LocationSettingsRequest + +Class for specifying the location service types and checking the location settings to obtain optimal functionality of all requested services. + +#### Public Properties + +| Properties | Type | Description | +|------------|-------------------------|--------------------------------------------------------------------------------------------------------------| +| requests | List\ | Collection of LocationRequest object. | +| alwaysShow | bool | Indicates whether BLE scanning needs to be enabled. The options are true (yes) and false (no). | +| needBle | bool | Indicates whether a location is required for the app to continue. The options are true (yes) and false (no). | + +#### Public Constructor Summary + +| Constructor | Description | +|--------------------------------------------------------------------------------------------|----------------------| +| LocationSettingsRequest({List\ requests, bool alwaysShow, bool needBle}) | Default constructor. | +| LocationSettingsRequest.fromMap(Map\ map) | Creates a LocationSettingsRequest object from a map. | +| LocationSettingsRequest.fromJson(String source) | Creates a LocationSettingsRequest object from a JSON string. | + +#### Public Constructors + +##### LocationSettingsRequest({List\ requests, bool alwaysShow, bool needBle}) + +Constructor for LocationSettingsRequest object. + +| Parameter | Type | Description | +|-----------------------------|-------------------------|-------------------------------------------------------------------------------------------------------------------------| +| requests | List\ | Collection of LocationRequest objects. | +| alwaysShow | bool | Indicates whether BLE scanning needs to be enabled. The options are true (yes) and false (no). | +| needBle | bool | Indicates whether a location is required for the app to continue. The options are true (yes) and false (no). | + +##### LocationSettingsRequest.fromMap(Map\ map) + +Creates a LocationSettingsRequest object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### LocationSettingsRequest.fromJson(String source) + +Creates a LocationSettingsRequest object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### LocationSettingsStates + +Current location-related setting status. + +#### Public Properties + +| Properties | Type | Description | +|------------------------|------|----------------------------------------------------------------------------------------| +| blePresent | bool | Indicates whether the BLE exists on the device. | +| bleUsable | bool | Indicates whether the BLE is enabled and can be used by the app. | +| gpsPresent | bool | Indicates whether the GPS provider exists on the device. | +| gpsUsable | bool | Indicates whether the GPS provider is enabled and can be used by the app. | +| locationPresent | bool | Indicates whether the location provider exists on the device. | +| locationUsable | bool | Indicates whether the location provider is enabled and can be used by the app. | +| networkLocationPresent | bool | Indicates whether the network location provider exists on the device. | +| networkLocationUsable | bool | Indicates whether the network location provider is enabled and can be used by the app. | + +#### Public Constructor Summary + +| Constructor | Description | +|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| LocationSettingsStates({bool blePresent, bool bleUsable, bool gpsPresent, bool gpsUsable, bool locationPresent, bool locationUsable, bool networkLocationPresent, bool networkLocationUsable}) | Default constructor. | +| LocationSettingsStates.fromMap(Map\ map) | Creates a LocationSettingsStates object from a map. | +| LocationSettingsStates.fromJson(String source) | Creates a LocationSettingsStates object from a JSON string. | + +#### Public Constructors + +##### LocationSettingsStates({bool blePresent, bool bleUsable, bool gpsPresent, bool gpsUsable, bool locationPresent, bool locationUsable, bool networkLocationPresent, bool networkLocationUsable}) + +Constructor for LocationSettingsStates object. + +| Parameter | Type | Description | +|------------------------|------|----------------------------------------------------------------------------------------| +| blePresent | bool | Indicates whether the BLE exists on the device. | +| bleUsable | bool | Indicates whether the BLE is enabled and can be used by the app. | +| gpsPresent | bool | Indicates whether the GPS provider exists on the device. | +| gpsUsable | bool | Indicates whether the GPS provider is enabled and can be used by the app. | +| locationPresent | bool | Indicates whether the location provider exists on the device. | +| locationUsable | bool | Indicates whether the location provider is enabled and can be used by the app. | +| networkLocationPresent | bool | Indicates whether the network location provider exists on the device. | +| networkLocationUsable | bool | Indicates whether the network location provider is enabled and can be used by the app. | + +##### LocationSettingsStates.fromMap(Map\ map) + +Creates a Location object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### LocationSettingsStates.fromJson(String source) + +Creates a Location object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### NavigationResult + +#### Public Properties + +| Methods | Return Type | Description | +|-------------------|-------------|----------------------------------------------------------------| +| possibility | int | Obtains the confidence of the status information. The value ranges from 0 to 100. A larger value indicates more reliable result authenticity. | +| state | int | Status information.If the navigation type is IS_SUPPORT_EX, the return values are described as follows: 11: The user device supports high-precision location.12: The user device does not support high-precision location. | + +#### Public Constructor Summary + +| Constructor | Description | +|-------------------------------------------------------|----------------------| +| NavigationResult({state, possibility}) | Default constructor. | +| NavigationResult.fromMap(Map\ map) | Creates a NavigationResult object from a map. | +| NavigationResult.fromJson(String source) | Creates a NavigationResult object from a JSON string. | + + +#### Public Constructors + +##### NavigationResult({state, possibility}) + +Constructor for NavigationResult object. + +| Parameter | Return Type | Description | +|-------------------|-------------|----------------------------------------------------------------| +| possibility | int | Obtains the confidence of the status information. The value ranges from 0 to 100. A larger value indicates more reliable result authenticity. | +| state | int | Status information.If the navigation type is IS_SUPPORT_EX, the return values are described as follows: 11: The user device supports high-precision location.12: The user device does not support high-precision location. | + + +##### NavigationResult.fromMap(Map\ map) + +Creates a NavigationResult object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### NavigationResult.fromJson(String source) + +Creates a NavigationResult object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### NavigationRequest + +#### Public Properties + +| Properties | Type | Description | +|--------------------------|----------------|--------------------------------------------| +| type | int | Requested navigation type. | + +#### Public Constants + +| Constants | Type | Value | Description | +|---------------------------|------|-------|----------------------------------------------------- | +| IS_SUPPORT_EX | int | 2 | Used to check whether the device supports high-precision location. | + +### ActivityIdentificationService + +Interaction access point of activity identification. + +#### Public Constructor Summary + +| Constructor | Description | +|------------------------------------------------|----------------------| +| ActivityIdentificationService() | Default constructor. | + +#### Public Method Summary + +| Return Type | Method | Description | +|------------------------------------------|-------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Future\ | createActivityIdentificationUpdates(int detectionIntervalMillis) | This API is used to register for activity identification updates. | +| Future\ | createActivityConversionUpdates(List\ activityConversions) | This API is used to activity conversions (entering and exit), for example, detecting user status change from walking to bicycling.The Conversion API supports the following activity parameters. | +| Future\ | deleteActivityIdentificationUpdates(int requestCode) | This API is used to remove all activity identification updates from the specified **requestCode**. | +| Future\ | deleteActivityConversionUpdates(int requestCode) | This API is used to remove all activity conversion updates from the specified **requestCode**. | +| Stream\ | onActivityIdentification | This API is used to listen activity identification updates that comes from createActivityIdentificationUpdates API method. | +| Stream\ | onActivityConversion | This API is used to listen activity conversion updates that comes from createActivityConversionUpdates API method. | + + +#### Public Constructors + +##### ActivityIdentificationService() + +Constructor for ActivityIdentificationService object. + +#### Public Methods + +##### Future\ createActivityIdentificationUpdates(int detectionIntervalMillis) *async* + +Registers for activity identification updates. + +| Parameter | Description | +|-------------------------|-------------| +| detectionIntervalMillis | Interval for activity identification updates, in milliseconds. A larger value will result in a lower activity identification frequency, while a smaller value will result in a higher activity identification frequency. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteActivityIdentificationUpdates method. | + +##### Future\ createActivityConversionUpdates(List\ activityConversions) *async* + +Registers for activity conversion updates (entering and exit), for example, detecting user status change from walking to bicycling. + +| Parameter | Description | +|---------------------|-------------| +| activityConversions | Activity conversion list. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteActivityConversionUpdates method. | + +##### Future\ deleteActivityIdentificationUpdates(int requestCode) *async* + +Removes activity identification updates based on the specified request code. + +| Parameter | Description | +|-------------|-------------| +| requestCode | Request code returned by the createActivityIdentificationUpdates method. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Future\ deleteActivityConversionUpdates(int requestCode) *async* + +Removes activity conversion updates based on the specified request code. + +| Parameter | Description | +|-------------|-------------| +| requestCode | Request code returned by the createActivityConversionUpdates method. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Stream\ onActivityIdentification + +Listens for activity identification updates that come from the createActivityIdentificationUpdates method. + +| Return Type | Description | +|------------------------------------------|-------------| +| Stream\ | Stream of ActivityIdentificationResponse object. You can call the .listen() method to subscribe to this stream and listen for updates. | + +##### Stream\ onActivityConversion + +Listens for activity conversion updates that come from the createActivityConversionUpdates method. + +| Return Type | Description | +|--------------------------------------|-------------| +| Stream\ | Stream of ActivityConversionResponse object. You can call the .listen() method to subscribe to this stream and listen for updates. | + +### ActivityConversionData + +Activity conversion event. + +#### Public Properties + +| Properties | Type | Description | +|-----------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | +| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | +| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this conversion since boot. | + +#### Public Constructor Summary + +| Constructor | Description | +|-------------------------------------------------------------------------------------------|----------------------| +| ActivityConversionData({int activityType, int conversionType, int elapsedTimeFromReboot}) | Default constructor. | +| ActivityConversionData.fromMap(Map\ map) | Creates a ActivityConversionData object from a map. | +| ActivityConversionData.fromJson(String source) | Creates a ActivityConversionData object from a JSON string. | + +#### Public Constructors + +##### ActivityConversionData({int activityType, int conversionType, int elapsedTimeFromReboot}) + +Constructor for ActivityConversionData object. + +| Parameter | Type | Description | +|-----------------------|------|--------------------------------------------------------------------------------------------------------------------------------------------------------| +| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | +| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | +| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this conversion since boot. | + +##### ActivityConversionData.fromMap(Map\ map) + +Creates a ActivityConversionData object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### ActivityConversionData.fromJson(String source) + +Creates a ActivityConversionData object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### ActivityConversionInfo + +Activity conversion information. + +#### Public Properties + +| Properties | Type | Description | +|----------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | +| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | + +#### Public Constants + +| Constants | Type | Value | Description | +|---------------------------|------|-------|-----------------------------------| +| ENTER_ACTIVITY_CONVERSION | int | 0 | A user enters the given activity. | +| EXIT_ACTIVITY_CONVERSION | int | 1 | A user exits the given activity. | + +#### Public Constructor Summary + +| Constructor | Description | +|----------------------------------------------------------------|----------------------| +| ActivityConversionInfo({int activityType, int conversionType}) | Default constructor. | +| ActivityConversionInfo.fromMap(Map\ map) | Creates a ActivityConversionInfo object from a map. | +| ActivityConversionInfo.fromJson(String source) | Creates a ActivityConversionInfo object from a JSON string. | + +#### Public Constructors + +##### ActivityConversionInfo({int activityType, int conversionType}) + +Constructor for ActivityConversionInfo object. + +| Properties | Type | Description | +|----------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| activityType | int | Activity type of the conversion. The value is one of the activity types defined in ActivityIdentificationData. | +| conversionType | int | Activity conversion information. The options are ActivityConversionInfo.ENTER_ACTIVITY_CONVERSION and ActivityConversionInfo.EXIT_ACTIVITY_CONVERSION. | + +##### ActivityConversionInfo.fromMap(Map\ map) + +Creates a ActivityConversionInfo object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### ActivityConversionInfo.fromJson(String source) + +Creates a ActivityConversionInfo object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### ActivityConversionResponse + +Activity conversion result. + +#### Public Properties + +| Properties | Type | Description | +|-------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------| +| activityConversionDatas | List\ | All activity conversion events in the result. The obtained activity events are sorted by time in ascending order. | + +#### Public Constructor Summary + +| Constructor | Description | +|--------------------------------------------------------------------------------------|----------------------| +| ActivityConversionResponse({List\ activityConversionDatas}) | Default constructor. | +| ActivityConversionResponse.fromMap(Map\ map) | Creates a ActivityConversionResponse object from a map. | +| ActivityConversionResponse.fromJson(String source) | Creates a ActivityConversionResponse object from a JSON string. | + +#### Public Constructors + +##### ActivityConversionResponse({List\ activityConversionDatas}) + +Constructor for ActivityConversionResponse object. + +| Parameter | Type | Description | +|------------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| activityConversionDatas | List\ | All activity conversion events in the result. The obtained activity events are sorted by time in ascending order. | + + +##### ActivityConversionResponse.fromMap(Map\ map) + +Creates a ActivityConversionResponse object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### ActivityConversionResponse.fromJson(String source) + +Creates a ActivityConversionResponse object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### ActivityIdentificationData + +Class for detecting the activity. + +#### Public Properties + +| Properties | Type | Description | +|------------------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| identificationActivity | int | Type of the detected activity. | +| possibility | int | The confidence for the user to execute the activity. The confidence ranges from 0 to 100. A larger value indicates more reliable activity authenticity. | + +#### Public Constants + +| Constants | Type | Value | Description | +|-----------|------|-------|-----------------------------------------------------------------| +| VEHICLE | int | 100 | The device is in a vehicle, such as a car. | +| BIKE | int | 101 | The device is on a bicycle. | +| FOOT | int | 102 | The device user is walking or running. | +| STILL | int | 103 | The device is still. | +| OTHERS | int | 104 | The current activity cannot be detected. | +| TILTING | int | 105 | The device has an obvious tilt change. | +| WALKING | int | 107 | The user of the device is walking,it is a sub-activity of FOOT. | +| RUNNING | int | 108 | The user of the device is running,it is a sub-activity of FOOT. | + +#### Public Constructor Summary + +| Constructor | Description | +|-----------------------------------------------------------------|----------------------| +| ActivityIdentificationData({int identificationActivity, int possibility}) | Default constructor. | +| ActivityIdentificationData.fromMap(Map\ map) | Creates a ActivityIdentificationData object from a map. | +| ActivityIdentificationData.fromJson(String source) | Creates a ActivityIdentificationData object from a JSON string. | + +#### Public Method Summary + +| Methods | Return Type | Description | +|------------------------------|-------------|----------------------------------------------------------------| +| static isValidType(int type) | bool | Checks that given activity type is one of the valid constants. | + +#### Public Constructors + +##### ActivityIdentificationData({int identificationActivity, int possibility}) + +Constructor for ActivityIdentificationData object. + +| Parameter | Type | Description | +|------------------------|------|---------------------------------------------------------------------------------------------------------------------------------------------------------| +| identificationActivity | int | Type of the detected activity. | +| possibility | int | The confidence for the user to execute the activity. The confidence ranges from 0 to 100. A larger value indicates more reliable activity authenticity. | + +##### ActivityIdentificationData.fromMap(Map\ map) + +Creates a ActivityIdentificationData object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### ActivityIdentificationData.fromJson(String source) + +Creates a ActivityIdentificationData object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +#### Public Methods + +##### bool isValidType + +Checks whether the specified activity type is a valid constant. + +| Return Type | Description | +|-----------------|-------------| +| bool | true if the specified activity type is a valid constant; false otherwise. | + +### ActivityIdentificationResponse + +Activity identification result. + +#### Public Properties + +| Properties | Type | Description | +|-----------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------| +| time | int | Time of this identification, which is in milliseconds since January 1, 1970. | +| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this identification since boot. | +| activityIdentificationDatas | List\ | List of activitiy identification list. The activity identifications are sorted by most probable activity first. | + +#### Public Constructor Summary + +| Constructor | Description | +|---------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| ActivityIdentificationResponse({int time, int elapsedTimeFromReboot, List\ activityIdentificationDatas}) | Default constructor. | +| ActivityIdentificationResponse.fromMap(Map\ map) | Creates a ActivityIdentificationResponse object from a map. | +| ActivityIdentificationResponse.fromJson(String source) | Creates a ActivityIdentificationResponse object from a JSON string. | + +#### Public Method Summary + +| Methods | Return Type | Description | +|------------------------------------------|----------------------------|-----------------------------------------------------------------------------------| +| mostActivityIdentification | ActivityIdentificationData | This API is used to obtain the most probable activity identification of the user. | +| getActivityPossibility(int activityType) | int | This API is used to obtain the confidence of an activity type. | + +#### Public Constructors + +##### ActivityIdentificationResponse({int time, int elapsedTimeFromReboot, List\ activityIdentificationDatas}) + +Constructor for ActivityIdentificationResponse object. + +| Parameter | Type | Description | +|-----------------------------|------------------------------------|-----------------------------------------------------------------------------------------------------------------| +| time | int | Time of this identification, which is in milliseconds since January 1, 1970. | +| elapsedTimeFromReboot | int | Elapsed real time (in milliseconds) of this identification since boot. | +| activityIdentificationDatas | List\ | List of activitiy identification list. The activity identifications are sorted by most probable activity first. | + +##### ActivityIdentificationResponse.fromMap(Map\ map) + +Creates a ActivityIdentificationResponse object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### ActivityIdentificationResponse.fromJson(String source) + +Creates a Location object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +#### Public Methods + +##### ActivityIdentificationData mostActivityIdentification + +Obtains the most possible activity of a user. + +| Return Type | Description | +|----------------------------------|-------------| +| ActivityIdentificationData | Identified activity. | + +##### int getActivityPossibility + +Obtains the confidence of an activity type. + +| Parameter | Description | +|-------------------------|-------------| +| activityType | Activity type. | + +| Return Type | Description | +|----------------------------------|-------------| +| int | Confidence of the activity type. | + +### Geofence Service + +Interaction access point of geofence. + +#### Public Constructor Summary + +| Constructor | Description | +|----------------------------------------|----------------------| +| GeofenceService() | Default constructor. | + +#### Public Method Summary + +| Return Type | Method | Description | +|------------------------|-------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------| +| Future\ | createGeofenceList(GeofenceRequest geofenceRequest) | This API is used to add geofences. When a geofence is triggered, a notification can be listened through **onGeofenceData** API method. | +| Future\ | deleteGeofenceList(int requestCode) | This API is used to remove geofences associated with a **requestCode**. | +| Future\ | deleteGeofenceListWithIds(List\ geofenceIds) | This API is used to remove geofences by their unique IDs. | +| Stream\ | onGeofenceData | This API is used to listen geofence updates that comes from createGeofenceList API method. | + +#### Public Constructors + +##### GeofenceService() + +Constructor for GeofenceService object. + +#### Public Methods + +##### Future\ createGeofenceList(GeofenceRequest geofenceRequest) *async* + +Adds geofences. When a geofence is triggered, the onGeofenceData method can listen for a notification. + +| Parameter | Description | +|-------------------------|-------------| +| geofenceRequest | Geofence request object. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Request code if the operation is successful; PlatformException otherwise. The request code can be used to call the deleteGeofenceList method. | + +##### Future\ deleteGeofenceList(int requestCode) *async* + +Removes geofences associated with a request code. + +| Parameter | Description | +|-------------------------|-------------| +| requestCode | Request code returned by the createGeofenceList method. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Future\ deleteGeofenceListWithIds(List\ geofenceIds) *async* + +Removes geofences by their unique IDs. + +| Parameter | Description | +|-------------------------|-------------| +| geofenceIds | Unique IDs of geofences to be removed. | + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | No return value if the operation is successful; PlatformException otherwise. | + +##### Stream\ onGeofenceData + +Listens for geofence updates that come from the createGeofenceList method. + +| Parameter | Description | +|-------------------------|-------------| +| geofenceIds | Unique IDs of geofences to be removed. | + +| Return Type | Description | +|----------------------------------|-------------| +| Stream\ | Stream of GeofenceData object. You can call the .listen() method to subscribe to this stream and listen for updates. | + +### Geofence + +Class that contains information about geofences. + +#### Public Properties + +| Properties | Type | Description | +|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| uniqueId | String | Unique ID. If the unique ID already exists, the new geofence will overwrite the old one. | +| conversions | int | Geofence conversions. The bitwise-OR operation is supported. | +| validDuration | int | Geofence timeout interval, in milliseconds. The geofence will be automatically deleted after this amount of time. | +| latitude | double | Latitude. The value range is [-90,90]. | +| longitude | double | Longitude. The value range is [-180,180]. | +| radius | double | Radius, in meters. | +| notificationInterval | int | Notification response capability. The default value is **0**. Setting it to a larger value can reduce power consumption accordingly. However, reporting of geofence events may be delayed. | +| dwellDelayTime | int | Lingering duration for converting a geofence event, in milliseconds. A geofence event is converted when a user lingers in a geofence for this amount of time. | + +#### Public Constants + +| Constants | Type | Value | Description | +|---------------------------|------|-------|-----------------------------------------------------| +| ENTER_GEOFENCE_CONVERSION | int | 1 | A user enters the geofence. | +| EXIT_GEOFENCE_CONVERSION | int | 2 | A user exits the geofence. | +| DWELL_GEOFENCE_CONVERSION | int | 4 | A user lingers in the geofence. | +| GEOFENCE_NEVER_EXPIRE | int | -1 | No timeout interval is configured for the geofence. | + +#### Public Constructor Summary + +| Constructor | Description | +|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------| +| Geofence({String uniqueId, int conversions, int validDuration, double latitude, double longitude, double radius, int notificationInterval, int dwellDelayTime}) | Default constructor. | +| Geofence.fromMap(Map\ map) | Creates a Geofence object from a map. | +| Geofence.fromJson(String source) | Creates a Geofence object from a JSON string. | + +### Public Constructors + +##### Geofence({String uniqueId, int conversions, int validDuration, double latitude, double longitude, double radius, int notificationInterval, int dwellDelayTime}) + +Constructor for Geofence object. + +| Parameter | Type | Description | +|----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| uniqueId | String | Unique ID. If the unique ID already exists, the new geofence will overwrite the old one. | +| conversions | int | Geofence conversions. The bitwise-OR operation is supported. | +| validDuration | int | Geofence timeout interval, in milliseconds. The geofence will be automatically deleted after this amount of time. | +| latitude | double | Latitude. The value range is [-90,90]. | +| longitude | double | Longitude. The value range is [-180,180]. | +| radius | double | Radius, in meters. | +| notificationInterval | int | Notification response capability. The default value is **0**. Setting it to a larger value can reduce power consumption accordingly. However, reporting of geofence events may be delayed. | +| dwellDelayTime | int | Lingering duration for converting a geofence event, in milliseconds. A geofence event is converted when a user lingers in a geofence for this amount of time. | + +##### Geofence.fromMap(Map\ map) + +Creates a Geofence object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### Geofence.fromJson(String source) + +Creates a Geofence object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### GeofenceData + +Geofence event. + +#### Public Properties + +| Properties | Type | Description | +|--------------------------|----------------|--------------------------------------------| +| errorCode | int | Error code. | +| conversion | int | Geofence convert type. | +| convertingGeofenceIdList | List\ | List of converted geofence unique IDs. | +| convertingLocation | Location | The location when a geofence is converted. | + +#### Public Constructor Summary + +| Constructor | Description | +|-------------------------------------------------------------------------------------------------------------------|----------------------| +| GeofenceData({int errorCode, int conversion, List convertingGeofenceIdList, Location convertingLocation}) | Default constructor. | +| GeofenceData.fromMap(Map\ map) | Creates a GeofenceData object from a map. | +| GeofenceData.fromJson(String source) | Creates a GeofenceData object from a JSON string. | + +#### Public Constructors + +##### GeofenceData({int errorCode, int conversion, List convertingGeofenceIdList, Location convertingLocation}) + +Constructor for GeofenceData object. + +| Properties | Type | Description | +|--------------------------|----------------|--------------------------------------------| +| errorCode | int | Error code. | +| conversion | int | Geofence convert type. | +| convertingGeofenceIdList | List\ | List of converted geofence unique IDs. | +| convertingLocation | Location | The location when a geofence is converted. | + +##### GeofenceData.fromMap(Map\ map) + +Creates a GeofenceData object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### GeofenceData.fromJson(String source) + +Creates a GeofenceData object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### GeofenceRequest + +Geofence request class. + +#### Public Properties + +| Properties | Type | Description | +|-----------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| geofenceList | List\ | List of geofences to be monitored. | +| initConversions | int | Initial conversion type. This parameter is invalid if it is set to 0. The default value is GeofenceRequest.ENTER_INIT_CONVERSION | GeofenceRequest.DWELL_INIT_CONVERSION. | +| coordinateType | int | Coordinate type of geofences. Defaults to GeofenceRequest.COORDINATE_TYPE_WGS_84. | + +#### Public Constants + +| Constants | Type | Value | Description | +|------------------------|------|-------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| ENTER_INIT_CONVERSION | int | 1 | ENTER_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already entered. | +| EXIT_INIT_CONVERSION | int | 2 | EXIT_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already exit. | +| DWELL_INIT_CONVERSION | int | 4 | DWELL_INIT_CONVERSION is converted immediately when a request is initiated to add the geofence where a user device has already entered and stayed for the specified duration. | +| COORDINATE_TYPE_WGS_84 | int | 1 | WGS_84 coordinate system. | +| COORDINATE_TYPE_GCJ_02 | int | 0 | GCJ-02 coordinate system. | + +#### Public Constructor Summary + +| Constructor | Description | +|-------------------------------------------------------------------------------------------|----------------------| +| GeofenceRequest({List\ geofenceList, int initConversions, int coordinateType}) | Default constructor. | +| GeofenceRequest.fromMap(Map\ map) | Creates a GeofenceRequest object from a map. | +| GeofenceRequest.fromJson(String source) | Creates a GeofenceRequest object from a JSON string. | + +#### Public Constructors + +##### GeofenceRequest({List\ geofenceList, int initConversions, int coordinateType}) + +Constructor for GeofenceRequest object. + +| Properties | Type | Description | +|-----------------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| geofenceList | List\ | List of geofences to be monitored. | +| initConversions | int | Initial conversion type. This parameter is invalid if it is set to 0. The default value is GeofenceRequest.ENTER_INIT_CONVERSION | GeofenceRequest.DWELL_INIT_CONVERSION. | +| coordinateType | int | Coordinate type of geofences. Defaults to GeofenceRequest.COORDINATE_TYPE_WGS_84. | + +##### GeofenceRequest.fromMap(Map\ map) + +Creates a GeofenceRequest object from a map. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| map | Map\| Map as a source. | + +##### GeofenceRequest.fromJson(String source) + +Creates a GeofenceRequest object from a JSON string. + +| Parameter | Type | Description | +|------------------------------|----------------------|-------------------------------------------------------------------------------------------------------------------------| +| source | String | JSON string as a source. | + +### PermissionHandler + +Checks or requests required permissions. + +#### Public Constructor Summary + +| Constructor | Description | +|------------------------------------------------|----------------------| +| PermissionHandler() | Default constructor. | + +#### Public Method Summary + +| Return Type | Method | Description | +|----------------|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| Future\ | hasLocationPermission() | This API is used to check location permission is available or not. | +| Future\ | hasBackgroundLocationPermission() | This API is used to check background location permission is available or not. | +| Future\ | hasActivityRecognitionPermission() | This API is used to check activity permission is available or not. | +| Future\ | requestLocationPermission() | This API is used to request location permission. Returns true if permission is granted, else returns false. | +| Future\ | requestBackgroundLocationPermission() | This API is used to request background location permission. Returns true if permission is granted, else returns false. | +| Future\ | requestActivityRecognitionPermission() | This API is used to request activity recognition permission. Returns true if permission is granted, else returns false. | + +#### Public Constructors + +##### PermissionHandler() + +Constructor for PermissionHandler object. + +#### Public Methods + +##### Future\ hasLocationPermission() *async* + +Checks whether the location permission is available. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +##### Future\ hasBackgroundLocationPermission() *async* + +Checks whether the background location permission is available. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +##### Future\ hasActivityRecognitionPermission() *async* + +Checks whether the activity permission is available. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +##### Future\ requestLocationPermission() *async* + +Requests the location permission. The value true is returned if the permission is granted. Otherwise, false is returned. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +##### Future\ requestBackgroundLocationPermission() *async* + +Requests the background location permission. The value true is returned if the permission is granted. Otherwise, false is returned + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +##### Future\ requestActivityRecognitionPermission() *async* + +Requests the activity permission. The value true is returned if the permission is granted. Otherwise, false is returned. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | true or false if the operation is successful; PlatformException otherwise. | + +### HMSLogger + +#### Public Method Summary + +| Return Type | Method | Description | +|----------------|----------------------------------------|-------------------------------------------------------------------------------------------------------------------------| +| Future\ | enableLogger() | This method enables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality.. | +| Future\ | disableLogger() | This method disables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. | + +#### Public Methods + +##### Future\ enableLogger() *async* + +This method enables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. HMSLogger is enabled by default, it can be disabled with the disableLogger method. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Future result of an execution that returns no value. | + +##### Future\ disableLogger() *async* + +This method disables the HMSLogger capability which is used for sending usage analytics of Location SDK's methods to improve the service quality. + +| Return Type | Description | +|----------------------------------|-------------| +| Future\ | Future result of an execution that returns no value. | + + +## Configuration Description + + +### Preparing for Release + +Before building a release version of your app you may need to customize the **proguard-rules.pro** obfuscation configuration file to prevent the HMS Core SDK from being obfuscated. Add the configurations below to exclude the HMS Core SDK from obfuscation. For more information on this topic refer to [this Android developer guide](https://developer.android.com/studio/build/shrink-code). + +**/android/app/proguard-rules. pro** + +``` +-ignorewarnings +-keepattributes *Annotation* +-keepattributes Exceptions +-keepattributes InnerClasses +-keepattributes Signature +-keepattributes SourceFile,LineNumberTable +-keep class com.hianalytics.android.**{*;} +-keep class com.huawei.updatesdk.**{*;} +-keep class com.huawei.hms.**{*;} + +``` + +**/android/app/build.gradle** + +```gradle +buildTypes { + debug { + signingConfig signingConfigs.config + } + release { + + // Enables code shrinking, obfuscation and optimization for release builds + minifyEnabled true + // Unused resources will be removed, resources defined in the res/raw/keep.xml will be kept. + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + + signingConfig signingConfigs.config + } +} +``` + + +## Sample Project +This plugin includes a demo project in the **example** folder, there you can find more usage examples. + + + +## Questions or Issues + +If you have questions about how to use HMS samples, try the following options: + +- [Stack Overflow](https://stackoverflow.com/questions/tagged/huawei-mobile-services) is the best place for any programming questions. Be sure to tag your question with **huawei-mobile-services**. +- [Github](https://github.com/HMS-Core/hms-flutter-plugin) is the official repository for these plugins, You can open an issue or submit your ideas. +- [Huawei Developer Forum](https://forums.developer.huawei.com/forumPortal/en/home?fid=0101187876626530001) HMS Core Module is great for general questions, or seeking recommendations and opinions. +- [Huawei Developer Docs](https://developer.huawei.com/consumer/en/doc/overview/HMS-Core-Plugin) is place to official documentation for all HMS Core Kits, you can find detailed documentations in there. + +If you run into a bug in our samples, please submit an issue to the Github Repository. + + +## Licensing and Terms + +Huawei Location Kit Flutter Plugin uses the Apache 2.0 license. \ No newline at end of file diff --git a/hms-plugins/flutter-hms-location/android/build.gradle b/hms-plugins/flutter-hms-location/android/build.gradle new file mode 100644 index 00000000..228af211 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/build.gradle @@ -0,0 +1,45 @@ +group 'com.huawei.hms.flutter.location' +version '1.0' + +buildscript { + repositories { + google() + jcenter() + maven { url 'https://developer.huawei.com/repo/' } + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.6.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + maven { url 'https://developer.huawei.com/repo/' } + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.3" + + defaultConfig { + minSdkVersion 19 + targetSdkVersion 29 + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + lintOptions { + disable 'InvalidPackage' + } +} + +dependencies { + implementation 'com.huawei.hms:location:5.0.0.301' +} diff --git a/hms-plugins/flutter-hms-location/android/gradle.properties b/hms-plugins/flutter-hms-location/android/gradle.properties new file mode 100644 index 00000000..38c8d454 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties b/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..a4b44297 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/hms-plugins/flutter-hms-location/android/gradlew b/hms-plugins/flutter-hms-location/android/gradlew new file mode 100644 index 00000000..2fe81a7d --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/gradlew @@ -0,0 +1,183 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# 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. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/hms-plugins/flutter-hms-location/android/gradlew.bat b/hms-plugins/flutter-hms-location/android/gradlew.bat new file mode 100644 index 00000000..62bd9b9c --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/gradlew.bat @@ -0,0 +1,103 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/hms-plugins/flutter-hms-location/android/settings.gradle b/hms-plugins/flutter-hms-location/android/settings.gradle new file mode 100644 index 00000000..2a0347f0 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'huawei_location' diff --git a/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml b/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000..d54dab86 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java new file mode 100644 index 00000000..4e98a26d --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/LocationPlugin.java @@ -0,0 +1,201 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location; + +import android.app.Activity; +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.huawei.hms.flutter.location.constants.Channel; +import com.huawei.hms.flutter.location.handlers.ActivityConversionStreamHandler; +import com.huawei.hms.flutter.location.handlers.ActivityIdentificationMethodHandler; +import com.huawei.hms.flutter.location.handlers.ActivityIdentificationStreamHandler; +import com.huawei.hms.flutter.location.handlers.FusedLocationMethodHandler; +import com.huawei.hms.flutter.location.handlers.FusedLocationStreamHandler; +import com.huawei.hms.flutter.location.handlers.GeofenceMethodHandler; +import com.huawei.hms.flutter.location.handlers.GeofenceStreamHandler; +import com.huawei.hms.flutter.location.handlers.HMSLoggerMethodHandler; +import com.huawei.hms.flutter.location.handlers.PermissionHandler; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.embedding.engine.plugins.activity.ActivityAware; +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.EventChannel; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.PluginRegistry.Registrar; + +public class LocationPlugin implements FlutterPlugin, ActivityAware { + private MethodChannel permissionMethodChannel; + private MethodChannel fusedLocationMethodChannel; + private MethodChannel geofenceMethodChannel; + private MethodChannel activityIdentificationMethodChannel; + private MethodChannel locationEnhanceMethodChannel; + private MethodChannel hmsLoggerMethodChannel; + private EventChannel mFusedLocationEventChannel; + private EventChannel mGeofenceEventChannel; + private EventChannel mActivityIdentificationEventChannel; + private EventChannel mActivityConversionEventChannel; + private PermissionHandler permissionHandler; + private EventChannel.StreamHandler mFusedLocationStreamHandler; + private EventChannel.StreamHandler mGeofenceStreamHandler; + private EventChannel.StreamHandler mActivityIdentificationStreamHandler; + private EventChannel.StreamHandler mActivityConversionStreamHandler; + private FusedLocationMethodHandler fusedLocationMethodHandler; + private GeofenceMethodHandler geofenceMethodHandler; + private ActivityIdentificationMethodHandler activityIdentificationMethodHandler; + private HMSLoggerMethodHandler hmsLoggerMethodHandler; + + public static void registerWith(final Registrar registrar) { + final LocationPlugin instance = new LocationPlugin(); + final Activity activity = registrar.activity(); + final Context context = activity.getApplicationContext(); + final BinaryMessenger messenger = registrar.messenger(); + + instance.onAttachedToEngine(context, messenger); + instance.permissionHandler = new PermissionHandler(activity); + instance.permissionMethodChannel.setMethodCallHandler(instance.permissionHandler); + instance.fusedLocationMethodHandler = new FusedLocationMethodHandler(activity, + instance.fusedLocationMethodChannel); + instance.fusedLocationMethodChannel.setMethodCallHandler(instance.fusedLocationMethodHandler); + instance.geofenceMethodHandler = new GeofenceMethodHandler(activity); + instance.geofenceMethodChannel.setMethodCallHandler(instance.geofenceMethodHandler); + instance.activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity); + instance.activityIdentificationMethodChannel.setMethodCallHandler(instance.activityIdentificationMethodHandler); + instance.hmsLoggerMethodHandler = new HMSLoggerMethodHandler(context); + instance.hmsLoggerMethodChannel.setMethodCallHandler(instance.hmsLoggerMethodHandler); + registrar.addRequestPermissionsResultListener(instance.permissionHandler); + registrar.addActivityResultListener(instance.fusedLocationMethodHandler); + } + + private void initChannels(final BinaryMessenger messenger) { + permissionMethodChannel = new MethodChannel(messenger, Channel.PERMISSON_METHOD.id()); + fusedLocationMethodChannel = new MethodChannel(messenger, Channel.FUSED_LOCATION_METHOD.id()); + geofenceMethodChannel = new MethodChannel(messenger, Channel.GEOFENCE_METHOD.id()); + activityIdentificationMethodChannel = new MethodChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_METHOD.id()); + locationEnhanceMethodChannel = new MethodChannel(messenger, Channel.LOCATION_ENHANCE_METHOD.id()); + hmsLoggerMethodChannel = new MethodChannel(messenger, Channel.HMSLOGGER_METHOD.id()); + mFusedLocationEventChannel = new EventChannel(messenger, Channel.FUSED_LOCATION_EVENT.id()); + mGeofenceEventChannel = new EventChannel(messenger, Channel.GEOFENCE_EVENT.id()); + mActivityIdentificationEventChannel = new EventChannel(messenger, Channel.ACTIVITY_IDENTIFICATION_EVENT.id()); + mActivityConversionEventChannel = new EventChannel(messenger, Channel.ACTIVITY_CONVERSION_EVENT.id()); + } + + private void initStreamHandlers(final Context context) { + mFusedLocationStreamHandler = new FusedLocationStreamHandler(context); + mGeofenceStreamHandler = new GeofenceStreamHandler(context); + mActivityIdentificationStreamHandler = new ActivityIdentificationStreamHandler(context); + mActivityConversionStreamHandler = new ActivityConversionStreamHandler(context); + } + + private void setStreamHandlers() { + mFusedLocationEventChannel.setStreamHandler(mFusedLocationStreamHandler); + mGeofenceEventChannel.setStreamHandler(mGeofenceStreamHandler); + mActivityIdentificationEventChannel.setStreamHandler(mActivityIdentificationStreamHandler); + mActivityConversionEventChannel.setStreamHandler(mActivityConversionStreamHandler); + } + + private void resetStreamHandlers() { + mFusedLocationEventChannel.setStreamHandler(null); + mGeofenceEventChannel.setStreamHandler(null); + mActivityIdentificationEventChannel.setStreamHandler(null); + mActivityConversionEventChannel.setStreamHandler(null); + } + + private void removeStreamHandlers() { + mFusedLocationStreamHandler = null; + mGeofenceStreamHandler = null; + mActivityIdentificationStreamHandler = null; + mActivityConversionStreamHandler = null; + } + + private void removeChannels() { + permissionMethodChannel = null; + fusedLocationMethodChannel = null; + geofenceMethodChannel = null; + activityIdentificationMethodChannel = null; + locationEnhanceMethodChannel = null; + hmsLoggerMethodChannel = null; + mFusedLocationEventChannel = null; + mGeofenceEventChannel = null; + mActivityIdentificationEventChannel = null; + mActivityConversionEventChannel = null; + } + + private void onAttachedToEngine(final Context context, final BinaryMessenger messenger) { + initChannels(messenger); + initStreamHandlers(context); + setStreamHandlers(); + } + + @Override + public void onAttachedToEngine(@NonNull final FlutterPluginBinding binding) { + onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger()); + } + + @Override + public void onDetachedFromEngine(@NonNull final FlutterPluginBinding binding) { + resetStreamHandlers(); + removeStreamHandlers(); + removeChannels(); + } + + @Override + public void onAttachedToActivity(@NonNull final ActivityPluginBinding binding) { + final Activity activity = binding.getActivity(); + + permissionHandler = new PermissionHandler(activity); + fusedLocationMethodHandler = new FusedLocationMethodHandler(activity, fusedLocationMethodChannel); + geofenceMethodHandler = new GeofenceMethodHandler(activity); + activityIdentificationMethodHandler = new ActivityIdentificationMethodHandler(activity); + hmsLoggerMethodHandler = new HMSLoggerMethodHandler(activity.getApplicationContext()); + + binding.addRequestPermissionsResultListener(permissionHandler); + binding.addActivityResultListener(fusedLocationMethodHandler); + + permissionMethodChannel.setMethodCallHandler(permissionHandler); + fusedLocationMethodChannel.setMethodCallHandler(fusedLocationMethodHandler); + geofenceMethodChannel.setMethodCallHandler(geofenceMethodHandler); + activityIdentificationMethodChannel.setMethodCallHandler(activityIdentificationMethodHandler); + hmsLoggerMethodChannel.setMethodCallHandler(hmsLoggerMethodHandler); + } + + @Override + public void onDetachedFromActivityForConfigChanges() { + onDetachedFromActivity(); + } + + @Override + public void onReattachedToActivityForConfigChanges(@NonNull final ActivityPluginBinding binding) { + onAttachedToActivity(binding); + } + + @Override + public void onDetachedFromActivity() { + activityIdentificationMethodChannel.setMethodCallHandler(null); + geofenceMethodChannel.setMethodCallHandler(null); + fusedLocationMethodChannel.setMethodCallHandler(null); + locationEnhanceMethodChannel.setMethodCallHandler(null); + hmsLoggerMethodChannel.setMethodCallHandler(null); + activityIdentificationMethodHandler = null; + geofenceMethodHandler = null; + fusedLocationMethodHandler = null; + permissionHandler = null; + hmsLoggerMethodHandler = null; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java new file mode 100644 index 00000000..9a83e743 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Action.java @@ -0,0 +1,24 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.constants; + +public interface Action { + String PROCESS_LOCATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_LOCATION"; + String PROCESS_GEOFENCE = "com.huawei.hms.flutter.location.ACTION_PROCESS_GEOFENCE"; + String PROCESS_CONVERSION = "com.huawei.hms.flutter.location.ACTION_PROCESS_CONVERSION"; + String PROCESS_IDENTIFICATION = "com.huawei.hms.flutter.location.ACTION_PROCESS_IDENTIFICATION"; +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java new file mode 100644 index 00000000..3e21a60f --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Channel.java @@ -0,0 +1,40 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.constants; + +public enum Channel { + PERMISSON_METHOD("com.huawei.flutter.location/permission_methodchannel"), + FUSED_LOCATION_METHOD("com.huawei.flutter.location/fusedlocation_methodchannel"), + FUSED_LOCATION_EVENT("com.huawei.flutter.location/fusedlocation_eventchannel"), + GEOFENCE_METHOD("com.huawei.flutter.location/geofence_methodchannel"), + GEOFENCE_EVENT("com.huawei.flutter.location/geofence_eventchannel"), + ACTIVITY_IDENTIFICATION_METHOD("com.huawei.flutter.location/activityidentification_methodchannel"), + ACTIVITY_IDENTIFICATION_EVENT("com.huawei.flutter.location/activityidentification_eventchannel"), + ACTIVITY_CONVERSION_EVENT("com.huawei.flutter.location/activityconversion_eventchannel"), + LOCATION_ENHANCE_METHOD("com.huawei.flutter.location/locationenhance_methodchannel"), + HMSLOGGER_METHOD("com.huawei.flutter.location/hmslogger_methodchannel"); + + private final String id; + + Channel(final String id) { + this.id = id; + } + + public String id() { + return id; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java new file mode 100644 index 00000000..35f42ea8 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/constants/Error.java @@ -0,0 +1,33 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.constants; + +public enum Error { + LOCATION_SETTINGS_NOT_AVAILABLE("Unable to get location settings"), + NON_EXISTING_REQUEST_ID("Request ID does not exists"), + SEND_INTENT_EXCEPTION("Unable to send intent"); + + private final String message; + + Error(final String message) { + this.message = message; + } + + public String message() { + return message; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java new file mode 100644 index 00000000..f761e0ca --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityConversionStreamHandler.java @@ -0,0 +1,53 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.IntentFilter; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.receivers.ActivityConversionBroadcastReceiver; + +import io.flutter.plugin.common.EventChannel.EventSink; +import io.flutter.plugin.common.EventChannel.StreamHandler; + +public class ActivityConversionStreamHandler implements StreamHandler { + private final Context context; + private BroadcastReceiver broadcastReceiver; + + public ActivityConversionStreamHandler(final Context context) { + this.context = context; + } + + @Override + public void onListen(final Object arguments, final EventSink events) { + broadcastReceiver = new ActivityConversionBroadcastReceiver(events); + context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_CONVERSION)); + + HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onListen"); + } + + @Override + public void onCancel(final Object arguments) { + context.unregisterReceiver(broadcastReceiver); + broadcastReceiver = null; + + HMSLogger.getInstance(context).sendSingleEvent("ActivityConversionStreamHandler.onCancel"); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java new file mode 100644 index 00000000..ab502248 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationMethodHandler.java @@ -0,0 +1,141 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Intent; + +import androidx.annotation.NonNull; +import androidx.core.util.Pair; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.constants.Error; +import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; +import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ActivityUtils; +import com.huawei.hms.location.ActivityConversionRequest; +import com.huawei.hms.location.ActivityIdentification; +import com.huawei.hms.location.ActivityIdentificationService; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +public class ActivityIdentificationMethodHandler implements MethodCallHandler { + private final Activity activity; + private final Map requests; + private final ActivityIdentificationService service; + + private int requestCode = 0; + + public ActivityIdentificationMethodHandler(final Activity activity) { + this.activity = activity; + service = ActivityIdentification.getService(activity); + requests = new HashMap<>(); + } + + private void createActivityIdentificationUpdates(final MethodCall call, final Result result) { + final Pair intentData = buildPendingIntent(Action.PROCESS_IDENTIFICATION); + + service.createActivityIdentificationUpdates(call.arguments(), intentData.second) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); + } + + private void createActivityConversionUpdates(final MethodCall call, final Result result) { + final List> args = call.arguments(); + final Pair intentData = buildPendingIntent(Action.PROCESS_CONVERSION); + final ActivityConversionRequest request + = ActivityUtils.fromActivityConversionInfoListToActivityConversionRequest(args); + + service.createActivityConversionUpdates(request, intentData.second) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); + } + + private void deleteActivityIdentificationUpdates(final MethodCall call, final Result result) { + final int incomingRequestCode = call.arguments(); + + if (!requests.containsKey(incomingRequestCode)) { + result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); + } else { + service.deleteActivityIdentificationUpdates(requests.get(incomingRequestCode)) + .addOnSuccessListener( + new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + } + + private void deleteActivityConversionUpdates(final MethodCall call, final Result result) { + final int incomingRequestCode = call.arguments(); + + if (!requests.containsKey(incomingRequestCode)) { + result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); + } else { + service.deleteActivityConversionUpdates(requests.get(incomingRequestCode)) + .addOnSuccessListener( + new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + } + + private Pair buildPendingIntent(final String action) { + final Intent intent = new Intent(); + + intent.setPackage(activity.getPackageName()); + intent.setAction(action); + + final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + + requests.put(requestCode, pendingIntent); + return Pair.create(requestCode, pendingIntent); + } + + @Override + public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { + HMSLogger.getInstance(activity).startMethodExecutionTimer(call.method); + + switch (call.method) { + case "createActivityIdentificationUpdates": + createActivityIdentificationUpdates(call, result); + break; + case "createActivityConversionUpdates": + createActivityConversionUpdates(call, result); + break; + case "deleteActivityIdentificationUpdates": + deleteActivityIdentificationUpdates(call, result); + break; + case "deleteActivityConversionUpdates": + deleteActivityConversionUpdates(call, result); + break; + default: + result.notImplemented(); + break; + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java new file mode 100644 index 00000000..8a2303d4 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/ActivityIdentificationStreamHandler.java @@ -0,0 +1,53 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.IntentFilter; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.receivers.ActivityIdentificationBroadcastReceiver; + +import io.flutter.plugin.common.EventChannel.EventSink; +import io.flutter.plugin.common.EventChannel.StreamHandler; + +public class ActivityIdentificationStreamHandler implements StreamHandler { + private final Context context; + private BroadcastReceiver broadcastReceiver; + + public ActivityIdentificationStreamHandler(final Context context) { + this.context = context; + } + + @Override + public void onListen(final Object arguments, final EventSink events) { + broadcastReceiver = new ActivityIdentificationBroadcastReceiver(events); + context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_IDENTIFICATION)); + + HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onListen"); + } + + @Override + public void onCancel(final Object arguments) { + context.unregisterReceiver(broadcastReceiver); + broadcastReceiver = null; + + HMSLogger.getInstance(context).sendSingleEvent("ActivityIdentificationStreamHandler.onCancel"); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java new file mode 100644 index 00000000..d4ec83a0 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationMethodHandler.java @@ -0,0 +1,265 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Intent; +import android.os.Looper; +import android.util.Pair; + +import androidx.annotation.NonNull; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.constants.Error; +import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; +import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener; +import com.huawei.hms.flutter.location.listeners.LocationSettingsFailureListener; +import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.LocationUtils; +import com.huawei.hms.location.FusedLocationProviderClient; +import com.huawei.hms.location.LocationEnhanceService; +import com.huawei.hms.location.LocationRequest; +import com.huawei.hms.location.LocationServices; +import com.huawei.hms.location.LocationSettingsRequest; +import com.huawei.hms.location.LocationSettingsStates; +import com.huawei.hms.location.NavigationRequest; +import com.huawei.hms.location.SettingsClient; + +import java.util.HashMap; +import java.util.Map; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.PluginRegistry.ActivityResultListener; + +public class FusedLocationMethodHandler implements MethodChannel.MethodCallHandler, ActivityResultListener { + private final Activity activity; + private final MethodChannel channel; + private final Map callbacks; + private final Map requests; + private final SettingsClient settingsClient; + private final FusedLocationProviderClient service; + private final LocationEnhanceService enhanceService; + + private int requestCode = 0; + private MethodChannel.Result result; + + public FusedLocationMethodHandler(final Activity activity, final MethodChannel channel) { + this.activity = activity; + this.channel = channel; + callbacks = new HashMap<>(); + requests = new HashMap<>(); + settingsClient = LocationServices.getSettingsClient(activity); + service = LocationServices.getFusedLocationProviderClient(activity); + enhanceService = LocationServices.getLocationEnhanceService(activity); + } + + private void checkLocationSettings(final MethodCall call, final MethodChannel.Result result) { + final LocationSettingsRequest request = LocationUtils.fromMapToLocationSettingsRequest(call.arguments()); + this.result = result; + + settingsClient.checkLocationSettings(request) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new LocationSettingsFailureListener(result, activity)); + } + + private void getLastLocation(final MethodCall call, final MethodChannel.Result result) { + service.getLastLocation() + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private void getLastLocationWithAddress(final MethodCall call, final MethodChannel.Result result) { + service.getLastLocationWithAddress( + LocationUtils.fromMapToLocationRequest(call.>arguments())) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private void getLocationAvailability(final MethodCall call, final MethodChannel.Result result) { + service.getLocationAvailability() + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private void setMockMode(final MethodCall call, final MethodChannel.Result result) { + service.setMockMode(call.arguments()) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private void setMockLocation(final MethodCall call, final MethodChannel.Result result) { + service.setMockLocation(LocationUtils.fromMapToLocation(call.arguments())) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private void requestLocationUpdates(final MethodCall call, final MethodChannel.Result result) { + final Pair intentData = buildLocationIntent(); + final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); + + service.requestLocationUpdates(request, intentData.second) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); + } + + private void requestLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) { + final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); + final Pair callbackData = buildCallback(call.method); + + service.requestLocationUpdates(request, callbackData.second, Looper.getMainLooper()) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks)); + } + + private void requestLocationUpdatesExCb(final MethodCall call, final MethodChannel.Result result) { + final LocationRequest request = LocationUtils.fromMapToLocationRequest(call.>arguments()); + final Pair callbackData = buildCallback(call.method); + + service.requestLocationUpdatesEx(request, callbackData.second, Looper.getMainLooper()) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, callbackData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, callbackData.first, callbacks)); + } + + private void removeLocationUpdates(final MethodCall call, final MethodChannel.Result result) { + final int incomingRequestCode = call.arguments(); + + if (!requests.containsKey(incomingRequestCode)) { + result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); + } else { + service.removeLocationUpdates(requests.get(incomingRequestCode)) + .addOnSuccessListener( + new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + } + + private void removeLocationUpdatesCb(final MethodCall call, final MethodChannel.Result result) { + final int callbackId = call.arguments(); + + if (!callbacks.containsKey(callbackId)) { + result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); + } else { + service.removeLocationUpdates(callbacks.get(callbackId)) + .addOnSuccessListener( + new RemoveUpdatesSuccessListener<>(call.method, activity, result, callbackId, callbacks)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + } + + private void getNavigationContextState(final MethodCall call, final MethodChannel.Result result) { + final NavigationRequest request = LocationUtils.fromMapToNavigationRequest(call.arguments()); + + enhanceService.getNavigationState(request) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private Pair buildCallback(final String methodName) { + final LocationCallbackHandler callBack = new LocationCallbackHandler(activity.getApplicationContext(), + methodName, ++requestCode, channel); + callbacks.put(requestCode, callBack); + return Pair.create(requestCode, callBack); + } + + private Pair buildLocationIntent() { + final Intent intent = new Intent(); + intent.setPackage(activity.getPackageName()); + intent.setAction(Action.PROCESS_LOCATION); + + final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + requests.put(requestCode, pendingIntent); + return Pair.create(requestCode, pendingIntent); + } + + @Override + public void onMethodCall(@NonNull final MethodCall call, @NonNull final MethodChannel.Result result) { + HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method); + + switch (call.method) { + case "checkLocationSettings": + checkLocationSettings(call, result); + break; + case "getLastLocation": + getLastLocation(call, result); + break; + case "getLastLocationWithAddress": + getLastLocationWithAddress(call, result); + break; + case "getLocationAvailability": + getLocationAvailability(call, result); + break; + case "setMockMode": + setMockMode(call, result); + break; + case "setMockLocation": + setMockLocation(call, result); + break; + case "requestLocationUpdates": + requestLocationUpdates(call, result); + break; + case "requestLocationUpdatesCb": + requestLocationUpdatesCb(call, result); + break; + case "requestLocationUpdatesExCb": + requestLocationUpdatesExCb(call, result); + break; + case "removeLocationUpdates": + removeLocationUpdates(call, result); + break; + case "removeLocationUpdatesCb": + removeLocationUpdatesCb(call, result); + break; + case "getNavigationContextState": + getNavigationContextState(call, result); + break; + default: + result.notImplemented(); + break; + } + } + + @Override + public boolean onActivityResult(final int requestCode, final int resultCode, final Intent intent) { + final MethodChannel.Result incomingResult = result; + result = null; + + if (incomingResult != null && requestCode == 0) { + if (resultCode == Activity.RESULT_OK) { + final LocationSettingsStates states = LocationSettingsStates.fromIntent(intent); + HMSLogger.getInstance(activity.getApplicationContext()) + .sendSingleEvent("checkLocationSettings.onActivityResult"); + incomingResult.success(LocationUtils.fromLocationSettingsStatesToMap(states)); + } else { + HMSLogger.getInstance(activity.getApplicationContext()) + .sendSingleEvent("checkLocationSettings" + ".onActivityResult", "-1"); + incomingResult.error(Error.LOCATION_SETTINGS_NOT_AVAILABLE.name(), + Error.LOCATION_SETTINGS_NOT_AVAILABLE.message(), null); + } + } + + return true; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java new file mode 100644 index 00000000..03d732b0 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/FusedLocationStreamHandler.java @@ -0,0 +1,51 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.IntentFilter; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.receivers.FusedLocationBroadcastReceiver; + +import io.flutter.plugin.common.EventChannel.EventSink; +import io.flutter.plugin.common.EventChannel.StreamHandler; + +public class FusedLocationStreamHandler implements StreamHandler { + private final Context context; + private BroadcastReceiver broadcastReceiver; + + public FusedLocationStreamHandler(final Context context) { + this.context = context; + } + + @Override + public void onListen(final Object arguments, final EventSink events) { + broadcastReceiver = new FusedLocationBroadcastReceiver(events); + context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_LOCATION)); + HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onListen"); + } + + @Override + public void onCancel(final Object arguments) { + context.unregisterReceiver(broadcastReceiver); + broadcastReceiver = null; + HMSLogger.getInstance(context).sendSingleEvent("FusedLocationStreamHandler.onCancel"); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java new file mode 100644 index 00000000..6c479b35 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceMethodHandler.java @@ -0,0 +1,119 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Intent; +import android.util.Pair; + +import androidx.annotation.NonNull; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.constants.Error; +import com.huawei.hms.flutter.location.listeners.DefaultFailureListener; +import com.huawei.hms.flutter.location.listeners.DefaultSuccessListener; +import com.huawei.hms.flutter.location.listeners.RemoveUpdatesSuccessListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesFailureListener; +import com.huawei.hms.flutter.location.listeners.RequestUpdatesSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.GeofenceUtils; +import com.huawei.hms.location.GeofenceRequest; +import com.huawei.hms.location.GeofenceService; +import com.huawei.hms.location.LocationServices; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +public class GeofenceMethodHandler implements MethodCallHandler { + private final Activity activity; + private final GeofenceService service; + private final Map requests; + + private int requestCode = 0; + + public GeofenceMethodHandler(final Activity activity) { + this.activity = activity; + service = LocationServices.getGeofenceService(activity); + requests = new HashMap<>(); + } + + private void createGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) { + final GeofenceRequest geofenceRequest = GeofenceUtils.fromMapToGeofenceRequest(call.arguments()); + final Pair intentData = buildGeofenceIntent(); + + service.createGeofenceList(geofenceRequest, intentData.second) + .addOnSuccessListener(new RequestUpdatesSuccessListener(call.method, activity, result, intentData.first)) + .addOnFailureListener( + new RequestUpdatesFailureListener<>(call.method, activity, result, intentData.first, requests)); + } + + private void deleteGeofenceList(@NonNull final MethodCall call, @NonNull final Result result) { + final int incomingRequestCode = call.arguments(); + + if (!requests.containsKey(incomingRequestCode)) { + result.error(Error.NON_EXISTING_REQUEST_ID.name(), Error.NON_EXISTING_REQUEST_ID.message(), null); + } else { + service.deleteGeofenceList(requests.get(incomingRequestCode)) + .addOnSuccessListener( + new RemoveUpdatesSuccessListener<>(call.method, activity, result, incomingRequestCode, requests)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + } + + private void deleteGeofenceListWithIds(@NonNull final MethodCall call, @NonNull final Result result) { + service.deleteGeofenceList(call.>arguments()) + .addOnSuccessListener(new DefaultSuccessListener<>(call.method, activity, result)) + .addOnFailureListener(new DefaultFailureListener(call.method, activity, result)); + } + + private Pair buildGeofenceIntent() { + final Intent intent = new Intent(); + intent.setPackage(activity.getPackageName()); + intent.setAction(Action.PROCESS_GEOFENCE); + + final PendingIntent pendingIntent = PendingIntent.getBroadcast(activity.getApplicationContext(), ++requestCode, + intent, PendingIntent.FLAG_UPDATE_CURRENT); + requests.put(requestCode, pendingIntent); + return Pair.create(requestCode, pendingIntent); + } + + @Override + public void onMethodCall(@NonNull final MethodCall call, @NonNull final Result result) { + HMSLogger.getInstance(activity.getApplicationContext()).startMethodExecutionTimer(call.method); + + switch (call.method) { + case "createGeofenceList": + createGeofenceList(call, result); + break; + case "deleteGeofenceList": + deleteGeofenceList(call, result); + break; + case "deleteGeofenceListWithIds": + deleteGeofenceListWithIds(call, result); + break; + default: + result.notImplemented(); + break; + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java new file mode 100644 index 00000000..d2c24d69 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/GeofenceStreamHandler.java @@ -0,0 +1,53 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.IntentFilter; + +import com.huawei.hms.flutter.location.constants.Action; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.receivers.GeofenceBroadcastReceiver; + +import io.flutter.plugin.common.EventChannel.EventSink; +import io.flutter.plugin.common.EventChannel.StreamHandler; + +public class GeofenceStreamHandler implements StreamHandler { + private final Context context; + private BroadcastReceiver broadcastReceiver; + + public GeofenceStreamHandler(final Context context) { + this.context = context; + } + + @Override + public void onListen(final Object arguments, final EventSink events) { + broadcastReceiver = new GeofenceBroadcastReceiver(events); + context.registerReceiver(broadcastReceiver, new IntentFilter(Action.PROCESS_GEOFENCE)); + + HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onListen"); + } + + @Override + public void onCancel(final Object arguments) { + context.unregisterReceiver(broadcastReceiver); + broadcastReceiver = null; + + HMSLogger.getInstance(context).sendSingleEvent("GeofenceStreamHandler.onCancel"); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java new file mode 100644 index 00000000..57d4a65e --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/HMSLoggerMethodHandler.java @@ -0,0 +1,51 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.huawei.hms.flutter.location.logger.HMSLogger; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; + +public class HMSLoggerMethodHandler implements MethodCallHandler { + private final Context context; + + public HMSLoggerMethodHandler(final Context context) { + this.context = context; + } + + @Override + public void onMethodCall(final MethodCall call, @NonNull final Result result) { + switch (call.method) { + case "enableLogger": + HMSLogger.getInstance(context).enableLogger(); + result.success(null); + break; + case "disableLogger": + HMSLogger.getInstance(context).disableLogger(); + result.success(null); + break; + default: + break; + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java new file mode 100644 index 00000000..d932988e --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/LocationCallbackHandler.java @@ -0,0 +1,71 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import android.content.Context; + +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.LocationUtils; +import com.huawei.hms.location.LocationAvailability; +import com.huawei.hms.location.LocationCallback; +import com.huawei.hms.location.LocationResult; + +import java.util.HashMap; +import java.util.Map; + +import io.flutter.plugin.common.MethodChannel; + +public class LocationCallbackHandler extends LocationCallback { + private final Context context; + private final String methodName; + private final int callbackId; + private final MethodChannel channel; + + LocationCallbackHandler(final Context context, final String methodName, final int callbackId, + final MethodChannel channel) { + this.context = context; + this.methodName = methodName; + this.callbackId = callbackId; + this.channel = channel; + } + + @Override + public void onLocationResult(final LocationResult locationResult) { + if (locationResult != null) { + final Map map = new HashMap<>(); + + map.put("callbackId", callbackId); + map.put("locationResult", LocationUtils.fromLocationResultToMap(locationResult)); + + HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationResult"); + channel.invokeMethod("onLocationResult", map); + } + } + + @Override + public void onLocationAvailability(final LocationAvailability locationAvailability) { + if (locationAvailability != null) { + final Map map = new HashMap<>(); + + map.put("callbackId", callbackId); + map.put("locationAvailability", LocationUtils.fromLocationAvailabilityToMap(locationAvailability)); + + HMSLogger.getInstance(context).sendPeriodicEvent(methodName + ".onLocationAvailability"); + channel.invokeMethod("onLocationAvailability", map); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java new file mode 100644 index 00000000..7db5a267 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/handlers/PermissionHandler.java @@ -0,0 +1,192 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.handlers; + +import static androidx.core.content.PermissionChecker.PERMISSION_GRANTED; +import static androidx.core.content.PermissionChecker.checkSelfPermission; + +import android.app.Activity; +import android.os.Build; + +import androidx.annotation.NonNull; + +import com.huawei.hms.flutter.location.logger.HMSLogger; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener; + +public class PermissionHandler implements MethodCallHandler, RequestPermissionsResultListener { + private static final String HUAWEI_ACTIVITY_RECOGNITION_PERMISSION = "android.permission.ACTIVITY_RECOGNITION"; + private static final String[] BG_LOC_PERMISSION_OLD = { + android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION + }; + private final Activity activity; + private final HMSLogger hmsLogger; + + private Result result; + + public PermissionHandler(final Activity activity) { + this.activity = activity; + hmsLogger = HMSLogger.getInstance(activity.getApplicationContext()); + } + + private boolean hasLocationPermission() { + hmsLogger.sendSingleEvent("hasLocationPermission"); + return isCoarseLocGranted() && isFineLocGranted(); + } + + private boolean hasBackgroundLocationPermission() { + hmsLogger.sendSingleEvent("hasBackgroundLocationPermission"); + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + return isFineLocGranted() && isBackgroundLocGranted(); + } + return isCoarseLocGranted() || isFineLocGranted(); + } + + private boolean hasActivityRecognitionPermission() { + hmsLogger.sendSingleEvent("hasActivityRecognitionPermission"); + + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(), + android.Manifest.permission.ACTIVITY_RECOGNITION); + } else { + return PERMISSION_GRANTED == checkSelfPermission(activity.getApplicationContext(), + HUAWEI_ACTIVITY_RECOGNITION_PERMISSION); + } + } + + private void requestLocationPermission() { + hmsLogger.sendSingleEvent("requestLocationPermission"); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + final String[] permissions = { + android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION + }; + activity.requestPermissions(permissions, 1); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { + activity.requestPermissions(BG_LOC_PERMISSION_OLD, 2); + } + } + } + + private void requestBackgroundLocationPermission() { + hmsLogger.sendSingleEvent("requestBackgroundLocationPermission"); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + final String[] permissions = { + android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION + }; + activity.requestPermissions(permissions, 3); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { + activity.requestPermissions(BG_LOC_PERMISSION_OLD, 4); + } + } + } + + private void requestActivityRecognitionPermission() { + hmsLogger.sendSingleEvent("requestActivityRecognitionPermission"); + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + final String[] permissions = {android.Manifest.permission.ACTIVITY_RECOGNITION}; + activity.requestPermissions(permissions, 5); + } else { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) { + final String[] permissions = {HUAWEI_ACTIVITY_RECOGNITION_PERMISSION}; + activity.requestPermissions(permissions, 6); + } + } + } + + private boolean isCoarseLocGranted() { + final int coarseLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION); + return coarseLoc == PERMISSION_GRANTED; + } + + private boolean isFineLocGranted() { + final int fineLoc = checkSelfPermission(activity, android.Manifest.permission.ACCESS_FINE_LOCATION); + return fineLoc == PERMISSION_GRANTED; + } + + private boolean isBackgroundLocGranted() { + if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + final int backgroundLoc = checkSelfPermission(activity, + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION); + return backgroundLoc == PERMISSION_GRANTED; + } + return true; + } + + private boolean checkGrantStatus(final int[] grantResults) { + for (final int i : grantResults) { + if (i != 0) { + return false; + } + } + return true; + } + + @Override + public void onMethodCall(final MethodCall call, @NonNull final Result result) { + this.result = result; + hmsLogger.startMethodExecutionTimer(call.method); + + switch (call.method) { + case "hasLocationPermission": + result.success(hasLocationPermission()); + break; + case "hasBackgroundLocationPermission": + result.success(hasBackgroundLocationPermission()); + break; + case "hasActivityRecognitionPermission": + result.success(hasActivityRecognitionPermission()); + break; + case "requestLocationPermission": + requestLocationPermission(); + break; + case "requestBackgroundLocationPermission": + requestBackgroundLocationPermission(); + break; + case "requestActivityRecognitionPermission": + requestActivityRecognitionPermission(); + break; + default: + break; + } + } + + @Override + public boolean onRequestPermissionsResult(final int requestCode, final String[] permissions, + final int[] grantResults) { + final Result incomingResult = result; + result = null; + + if (incomingResult != null) { + if (requestCode == 1) { + incomingResult.success(grantResults[0] == 0 || grantResults[1] == 0); + } else if (requestCode == 3) { + incomingResult.success((grantResults[0] == 0 || grantResults[1] == 0) && grantResults[2] == 0); + } else { + incomingResult.success(checkGrantStatus(grantResults)); + } + } + return true; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java new file mode 100644 index 00000000..c0a45044 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultFailureListener.java @@ -0,0 +1,47 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import android.content.Context; + +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hms.common.ApiException; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ObjectUtils; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class DefaultFailureListener implements OnFailureListener { + private final String methodName; + private final Context context; + private final Result result; + + public DefaultFailureListener(final String methodName, final Context context, final Result result) { + this.methodName = methodName; + this.context = context; + this.result = result; + } + + @Override + public void onFailure(final Exception e) { + final ApiException ex = ObjectUtils.cast(e, ApiException.class); + final String statusCodeString = Integer.toString(ex.getStatusCode()); + + HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString); + result.error(statusCodeString, ex.getMessage(), null); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java new file mode 100644 index 00000000..3576ad59 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/DefaultSuccessListener.java @@ -0,0 +1,79 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import android.content.Context; +import android.location.Location; + +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.LocationUtils; +import com.huawei.hms.flutter.location.utils.ObjectUtils; +import com.huawei.hms.location.HWLocation; +import com.huawei.hms.location.LocationAvailability; +import com.huawei.hms.location.LocationSettingsResponse; +import com.huawei.hms.location.LocationSettingsStates; +import com.huawei.hms.location.NavigationResult; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class DefaultSuccessListener implements OnSuccessListener { + private final String methodName; + private final Context context; + private final Result result; + + public DefaultSuccessListener(final String methodName, final Context context, final Result result) { + this.methodName = methodName; + this.context = context; + this.result = result; + } + + @Override + public void onSuccess(final T o) { + HMSLogger.getInstance(context).sendSingleEvent(methodName); + + if (o instanceof Void || o == null) { + result.success(null); + } + + if (o instanceof Location) { + final Location location = ObjectUtils.cast(o, Location.class); + result.success(LocationUtils.fromLocationToMap(location)); + } + + if (o instanceof HWLocation) { + final HWLocation hwLocation = ObjectUtils.cast(o, HWLocation.class); + result.success(LocationUtils.fromHWLocationToMap(hwLocation)); + } + + if (o instanceof LocationAvailability) { + final LocationAvailability locationAvailability = ObjectUtils.cast(o, LocationAvailability.class); + result.success(LocationUtils.fromLocationAvailabilityToMap(locationAvailability)); + } + + if (o instanceof LocationSettingsResponse) { + final LocationSettingsResponse response = ObjectUtils.cast(o, LocationSettingsResponse.class); + final LocationSettingsStates locationSettingsStates = response.getLocationSettingsStates(); + result.success(LocationUtils.fromLocationSettingsStatesToMap(locationSettingsStates)); + } + + if (o instanceof NavigationResult) { + final NavigationResult navigationResult = ObjectUtils.cast(o, NavigationResult.class); + result.success(LocationUtils.fromNavigationResultToMap(navigationResult)); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java new file mode 100644 index 00000000..361e5c8e --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/LocationSettingsFailureListener.java @@ -0,0 +1,62 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import static com.huawei.hms.location.LocationSettingsStatusCodes.RESOLUTION_REQUIRED; + +import android.app.Activity; +import android.content.IntentSender.SendIntentException; + +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hms.common.ApiException; +import com.huawei.hms.common.ResolvableApiException; +import com.huawei.hms.flutter.location.constants.Error; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ObjectUtils; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class LocationSettingsFailureListener implements OnFailureListener { + private final Result result; + private final Activity activity; + + public LocationSettingsFailureListener(final Result result, final Activity activity) { + this.result = result; + this.activity = activity; + } + + @Override + public void onFailure(final Exception e) { + final ApiException apiException = ObjectUtils.cast(e, ApiException.class); + final int statusCode = apiException.getStatusCode(); + final String statusCodeString = Integer.toString(statusCode); + + if (statusCode == RESOLUTION_REQUIRED) { + try { + final ResolvableApiException resolvableApiException = ObjectUtils.cast(e, ResolvableApiException.class); + resolvableApiException.startResolutionForResult(activity, 0); + } catch (final SendIntentException ex) { + HMSLogger.getInstance(activity.getApplicationContext()).sendSingleEvent("checkLocationSettings", "-1"); + result.error(Error.SEND_INTENT_EXCEPTION.name(), ex.getMessage(), null); + } + } else { + HMSLogger.getInstance(activity.getApplicationContext()) + .sendSingleEvent("checkLocationSettings", statusCodeString); + result.error(statusCodeString, apiException.getMessage(), null); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java new file mode 100644 index 00000000..ff83dca9 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RemoveUpdatesSuccessListener.java @@ -0,0 +1,50 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import android.content.Context; + +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; + +import java.util.Map; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class RemoveUpdatesSuccessListener implements OnSuccessListener { + private final String methodName; + private final Context context; + private final Result result; + private final Integer id; + private final Map map; + + public RemoveUpdatesSuccessListener(final String methodName, final Context context, final Result result, + final Integer id, final Map map) { + this.methodName = methodName; + this.context = context; + this.result = result; + this.id = id; + this.map = map; + } + + @Override + public void onSuccess(final Void avoid) { + map.remove(id); + HMSLogger.getInstance(context).sendSingleEvent(methodName); + result.success(null); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java new file mode 100644 index 00000000..6bc0131f --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesFailureListener.java @@ -0,0 +1,55 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import android.content.Context; + +import com.huawei.hmf.tasks.OnFailureListener; +import com.huawei.hms.common.ApiException; +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ObjectUtils; + +import java.util.Map; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class RequestUpdatesFailureListener implements OnFailureListener { + private final String methodName; + private final Context context; + private final Result result; + private final Integer id; + private final Map map; + + public RequestUpdatesFailureListener(final String methodName, final Context context, final Result result, + final Integer id, final Map map) { + this.methodName = methodName; + this.context = context; + this.result = result; + this.id = id; + this.map = map; + } + + @Override + public void onFailure(final Exception e) { + final ApiException ex = ObjectUtils.cast(e, ApiException.class); + final String statusCodeString = Integer.toString(ex.getStatusCode()); + + map.remove(id); + HMSLogger.getInstance(context).sendSingleEvent(methodName, statusCodeString); + result.error(statusCodeString, ex.getMessage(), null); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java new file mode 100644 index 00000000..b90fbd2d --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/listeners/RequestUpdatesSuccessListener.java @@ -0,0 +1,45 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.listeners; + +import android.content.Context; + +import com.huawei.hmf.tasks.OnSuccessListener; +import com.huawei.hms.flutter.location.logger.HMSLogger; + +import io.flutter.plugin.common.MethodChannel.Result; + +public class RequestUpdatesSuccessListener implements OnSuccessListener { + private final Result result; + private final Integer requestCode; + private final Context context; + private final String methodName; + + public RequestUpdatesSuccessListener(final String methodName, final Context context, final Result result, + final Integer requestCode) { + this.methodName = methodName; + this.context = context; + this.result = result; + this.requestCode = requestCode; + } + + @Override + public void onSuccess(final Void avoid) { + HMSLogger.getInstance(context).sendSingleEvent(methodName); + result.success(requestCode); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java new file mode 100644 index 00000000..80af0462 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/logger/HMSLogger.java @@ -0,0 +1,449 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.logger; + +import static android.os.Build.DEVICE; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.NetworkCapabilities; +import android.util.Log; + +import com.huawei.agconnect.config.AGConnectServicesConfig; +import com.huawei.hms.support.hianalytics.HiAnalyticsUtils; +import com.huawei.hms.utils.HMSBIInitializer; + +import java.lang.ref.WeakReference; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +public final class HMSLogger { + private static final String TAG = "HMSLogger"; + + private static final String VERSION = "5.0.0.301"; + private static final String SERVICE = "FlutterLocation"; + + private static final String SUCCESS = "0"; + private static final String UNKNOWN = "UNKNOWN"; + private static final String NOT_AVAILABLE = "NOT_AVAILABLE"; + + private static final String SINGLE_EVENT_ID = "60000"; + private static final String PERIODIC_EVENT_ID = "60001"; + + private static final String NETWORK_TYPE_WIFI = "WIFI"; + + private static volatile HMSLogger instance; + + private final WeakReference weakContext; + private final HiAnalyticsUtils hiAnalyticsUtils; + + private final Map singleEventMap = new HashMap<>(); + private final Map periodicEventMap = new HashMap<>(); + private final Map allCountMap = new HashMap<>(); + private final Map failCountMap = new HashMap<>(); + private final Map startTimeMap = new HashMap<>(); + private final Map firstReceiveTimeMap = new HashMap<>(); + private final Map lastReceiveTimeMap = new HashMap<>(); + private final Map> resultCodeCountMap = new HashMap<>(); + private final Map networkTypeMap = createNetworkTypeMap(); + + private boolean isEnabled = true; + + /** + * Private constructor of this class + * + * @param context Application's context + */ + private HMSLogger(final Context context) { + weakContext = new WeakReference<>(context); + hiAnalyticsUtils = HiAnalyticsUtils.getInstance(); + + setupEventMap(singleEventMap); + setupEventMap(periodicEventMap); + initHMSBI(HMSBIInitializer.getInstance(context)); + + Log.d(TAG, "HMS Plugin Dotting is Enabled!"); + } + + /** + * Returns the instance of this class + * + * @param context Application's context + * @return HMSLogger instance + */ + public static synchronized HMSLogger getInstance(final Context context) { + if (instance == null) { + synchronized (HMSLogger.class) { + if (instance == null) { + instance = new HMSLogger(context); + } + } + } + return instance; + } + + /** + * Returns actual context reference + * + * @return Actual context reference + */ + private Context getContext() { + return weakContext.get(); + } + + /** + * Enables HMSLogger + */ + public synchronized void enableLogger() { + isEnabled = true; + Log.d(TAG, "HMS Plugin Dotting is Enabled!"); + } + + /** + * Disables HMSLogger + */ + public synchronized void disableLogger() { + isEnabled = false; + Log.d(TAG, "HMS Plugin Dotting is Disabled!"); + } + + /** + * Sets method start time for given method name + * + * @param methodName Name of the method that will be logged + */ + public synchronized void startMethodExecutionTimer(final String methodName) { + startTimeMap.put(methodName, System.currentTimeMillis()); + } + + /** + * Sends successful single event + * + * @param methodName The name of the method called + */ + public synchronized void sendSingleEvent(final String methodName) { + sendEvent(SINGLE_EVENT_ID, methodName, SUCCESS); + } + + /** + * Sends unsuccessful single event + * + * @param methodName The name of the method called + * @param errorCode API error code + */ + public synchronized void sendSingleEvent(final String methodName, final String errorCode) { + sendEvent(SINGLE_EVENT_ID, methodName, errorCode); + } + + /** + * Sends successful periodic event + * + * @param methodName The name of the method called + */ + public synchronized void sendPeriodicEvent(final String methodName) { + sendEvent(PERIODIC_EVENT_ID, methodName, SUCCESS); + } + + /** + * Sends unsuccessful periodic event + * + * @param methodName The name of the method called + * @param errorCode API error code + */ + public synchronized void sendPeriodicEvent(final String methodName, final String errorCode) { + sendEvent(PERIODIC_EVENT_ID, methodName, errorCode); + } + + /** + * Calls initBI() method from HMSBIInitializer + * + * @param initializer HMSBIInitializer object + */ + private void initHMSBI(final HMSBIInitializer initializer) { + if (!initializer.isInit()) { + initializer.initBI(); + } + } + + /** + * Sends the event based on eventId, methodName, and resultCode + * + * @param eventId Constant id of the event + * @param methodName The name of the method called + * @param resultCode Code of the method's result. "0" for success, others for error + */ + private synchronized void sendEvent(final String eventId, final String methodName, final String resultCode) { + if (isEnabled) { + final long currentTime = System.currentTimeMillis(); + + if (eventId.equals(SINGLE_EVENT_ID)) { + putToSingleEventMap(methodName, resultCode, currentTime); + hiAnalyticsUtils.onNewEvent(getContext(), SINGLE_EVENT_ID, singleEventMap); + + Log.d(TAG, "singleEventMap -> " + singleEventMap); + } else { + putToPeriodicEventMap(methodName, resultCode, currentTime); + hiAnalyticsUtils.onNewEvent(getContext(), PERIODIC_EVENT_ID, periodicEventMap); + + Log.d(TAG, "periodicEventMap -> " + periodicEventMap); + } + } + } + + /** + * Gets "client/app_id" value from agconnect-services.json file + * + * @return app_id value or NOT_AVAILABLE if not found + */ + private String getAppId() { + try { + return AGConnectServicesConfig.fromContext(getContext()).getString("client/app_id"); + } catch (final NullPointerException e) { + Log.d(TAG, "AgConnect is not found. Setting appId value to " + NOT_AVAILABLE); + } + return NOT_AVAILABLE; + } + + /** + * Gets app version name + * + * @param packageName Package name of the app + * @return App version name in String type + */ + private String getAppVersionName(final String packageName) { + try { + return getContext().getPackageManager().getPackageInfo(packageName, 0).versionName; + } catch (final PackageManager.NameNotFoundException e) { + Log.e(TAG, "getAppVersionName -> Could not get appVersionName!"); + return NOT_AVAILABLE; + } + } + + /** + * Detects current network type + * + * @return Human readable network type; such as WIFI, LTE + */ + private String getNetworkType() { + final ConnectivityManager cm = objectCast(getContext().getSystemService(Context.CONNECTIVITY_SERVICE), + ConnectivityManager.class); + if (cm != null) { + if (cm.getActiveNetworkInfo() == null || !cm.getActiveNetworkInfo().isConnected()) { + return NOT_AVAILABLE; + } + + final int networkSubtype = Objects.requireNonNull(cm.getActiveNetworkInfo()).getSubtype(); + final String networkSubtypeString = getOrDefault(networkTypeMap, networkSubtype, UNKNOWN); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { + final NetworkCapabilities capabilities = cm.getNetworkCapabilities(cm.getActiveNetwork()); + if (capabilities != null) { + if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + return networkSubtypeString; + } else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { + return NETWORK_TYPE_WIFI; + } else { + return UNKNOWN; + } + } else { + return NOT_AVAILABLE; + } + } else { + final int networkType = Objects.requireNonNull(cm.getActiveNetworkInfo()).getType(); + switch (networkType) { + case ConnectivityManager.TYPE_WIFI: + return NETWORK_TYPE_WIFI; + case ConnectivityManager.TYPE_MOBILE: + return networkSubtypeString; + default: + return UNKNOWN; + } + } + } + return NOT_AVAILABLE; + } + + /** + * Sets default values to given map + * + * @param map HashMap to put default values + */ + private void setupEventMap(final Map map) { + map.put("version", VERSION); + map.put("service", SERVICE); + map.put("appid", getAppId()); + map.put("package", getContext().getPackageName()); + map.put("cpAppVersion", getAppVersionName(getContext().getPackageName())); + map.put("model", DEVICE); + } + + /** + * Prepares sing-event map according to input parameters + * + * @param methodName The name of the method called + * @param resultCode Code of the method's result. "0" for success, others for error + * @param currentTime Current timestamp in millisecond + */ + private void putToSingleEventMap(final String methodName, final String resultCode, final long currentTime) { + final long startTime = getOrDefault(startTimeMap, methodName, currentTime); + final int costTime = (int) (currentTime - startTime); + singleEventMap.put("apiName", methodName); + singleEventMap.put("result", resultCode); + singleEventMap.put("callTime", currentTime); + singleEventMap.put("costTime", costTime); + singleEventMap.put("networkType", getNetworkType()); + } + + /** + * Prepares periodic-event map according to input parameters + * + * @param methodName The name of the method called + * @param resultCode Code of the method's result. "0" for success, others for error + * @param currentTime Current timestamp in millisecond + */ + private void putToPeriodicEventMap(final String methodName, final String resultCode, final long currentTime) { + increaseResultCodeCount(methodName, resultCode); + increaseMapValue(methodName, allCountMap); + + if (!resultCode.equals(SUCCESS)) { + increaseMapValue(methodName, failCountMap); + } + + final long firstReceiveTime = getOrDefault(firstReceiveTimeMap, methodName, currentTime); + periodicEventMap.put("callTime", firstReceiveTime); + + final long lastReceiveTime = getOrDefault(lastReceiveTimeMap, methodName, currentTime); + final int costTime = (int) (currentTime - lastReceiveTime); + periodicEventMap.put("costTime", costTime); + + periodicEventMap.put("apiName", methodName); + periodicEventMap.put("result", resultCodeCountMap.get(methodName)); + + final long allCount = getOrDefault(allCountMap, methodName, 0L); + periodicEventMap.put("allCnt", allCount); + + final long failCount = getOrDefault(failCountMap, methodName, 0L); + periodicEventMap.put("failCnt", failCount); + + periodicEventMap.put("lastCallTime", currentTime); + periodicEventMap.put("networkType", getNetworkType()); + + putIfAbsent(firstReceiveTimeMap, methodName, currentTime); + lastReceiveTimeMap.put(methodName, currentTime); + } + + /** + * Prepares HashMap of network type id and its human-readable string pairs + * + * @return HashMap of human readable network type names + */ + private Map createNetworkTypeMap() { + final Map map = new HashMap<>(); + + map.put(0, UNKNOWN); + map.put(1, "2.5G"); + map.put(2, "2.75G"); + map.put(3, "3G"); + map.put(4, "2G"); + map.put(5, "3G"); + map.put(6, "3G"); + map.put(7, "2G"); + map.put(8, "3G"); + map.put(9, "3G"); + map.put(10, "3G"); + map.put(11, "2G"); + map.put(12, "3G"); + map.put(13, "4G"); + map.put(14, "3G"); + map.put(15, "3G"); + map.put(16, "2G"); + map.put(17, "3G"); + map.put(18, "4G"); + map.put(19, "4G"); + map.put(20, "5G"); + + return Collections.unmodifiableMap(map); + } + + /** + * Increases count of the given result code + * + * @param methodName Name of the calling method + * @param resultCode Code of the method's result. "0" for success, others for error + */ + private void increaseResultCodeCount(final String methodName, final String resultCode) { + final Map map = getOrDefault(resultCodeCountMap, methodName, new HashMap<>()); + + increaseMapValue(resultCode, map); + resultCodeCountMap.put(methodName, map); + } + + /** + * Increases the value of the corresponding key which in the map + * + * @param key Key for map lookup + * @param map The Map that contains the key and its corresponding value + */ + private void increaseMapValue(final String key, final Map map) { + map.put(key, getOrDefault(map, key, 0L) + 1); + } + + /** + * Get the corresponding value of the key. If the key does not exist in the map then the default value is returned. + * + * @param map The Map + * @param key Lookup key + * @param defaultValue The default value will be returned if the key is absent + * @param Generic type of the key + * @param Generic type of the value + * @return Corresponding value or default value + */ + private V getOrDefault(final Map map, final K key, final V defaultValue) { + return map.containsKey(key) ? map.get(key) : defaultValue; + } + + /** + * Put key-value pair to map if the key is absent + * + * @param map The Map + * @param key Lookup key + * @param value The value will be put to the map if the key is absent + * @param Generic type of the key + * @param Generic type of the value + */ + private void putIfAbsent(final Map map, final K key, final V value) { + if (!map.containsKey(key)) { + map.put(key, value); + } + } + + /** + * Utility method that castes given object to given class type + * + * @param source Source object to be casted + * @param clazz Class that object will be casted to its type + * @param Source object's type + * @param Destination type + * @return Object that casted to D type + */ + private D objectCast(final S source, final Class clazz) { + return clazz.cast(source); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java new file mode 100644 index 00000000..06d8e231 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityConversionBroadcastReceiver.java @@ -0,0 +1,45 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ActivityUtils; +import com.huawei.hms.location.ActivityConversionResponse; + +import io.flutter.plugin.common.EventChannel.EventSink; + +public class ActivityConversionBroadcastReceiver extends BroadcastReceiver { + private final EventSink eventSink; + + public ActivityConversionBroadcastReceiver(final EventSink eventSink) { + this.eventSink = eventSink; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + if (ActivityConversionResponse.containDataFromIntent(intent)) { + final ActivityConversionResponse response = ActivityConversionResponse.getDataFromIntent(intent); + + HMSLogger.getInstance(context).sendPeriodicEvent("ActivityConversionUpdates"); + eventSink.success(ActivityUtils.activityConversionResponseToMap(response)); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java new file mode 100644 index 00000000..bb2c9666 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/ActivityIdentificationBroadcastReceiver.java @@ -0,0 +1,45 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.ActivityUtils; +import com.huawei.hms.location.ActivityIdentificationResponse; + +import io.flutter.plugin.common.EventChannel.EventSink; + +public class ActivityIdentificationBroadcastReceiver extends BroadcastReceiver { + private final EventSink eventSink; + + public ActivityIdentificationBroadcastReceiver(final EventSink eventSink) { + this.eventSink = eventSink; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + if (ActivityIdentificationResponse.containDataFromIntent(intent)) { + final ActivityIdentificationResponse response = ActivityIdentificationResponse.getDataFromIntent(intent); + + HMSLogger.getInstance(context).sendPeriodicEvent("ActivityIdentificationUpdates"); + eventSink.success(ActivityUtils.activityIdentificationResponseToMap(response)); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java new file mode 100644 index 00000000..dcdfbd49 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/FusedLocationBroadcastReceiver.java @@ -0,0 +1,46 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.location.Location; + +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.LocationUtils; +import com.huawei.hms.location.LocationResult; + +import io.flutter.plugin.common.EventChannel.EventSink; + +public class FusedLocationBroadcastReceiver extends BroadcastReceiver { + private final EventSink eventSink; + + public FusedLocationBroadcastReceiver(final EventSink eventSink) { + this.eventSink = eventSink; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + if (LocationResult.hasResult(intent)) { + HMSLogger.getInstance(context).sendPeriodicEvent("LocationUpdates"); + for (final Location location : LocationResult.extractResult(intent).getLocations()) { + eventSink.success(LocationUtils.fromLocationToMap(location)); + } + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java new file mode 100644 index 00000000..ae9f5451 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/receivers/GeofenceBroadcastReceiver.java @@ -0,0 +1,44 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.receivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.huawei.hms.flutter.location.logger.HMSLogger; +import com.huawei.hms.flutter.location.utils.GeofenceUtils; +import com.huawei.hms.location.GeofenceData; + +import io.flutter.plugin.common.EventChannel.EventSink; + +public class GeofenceBroadcastReceiver extends BroadcastReceiver { + private final EventSink eventSink; + + public GeofenceBroadcastReceiver(final EventSink eventSink) { + this.eventSink = eventSink; + } + + @Override + public void onReceive(final Context context, final Intent intent) { + if (intent != null) { + final GeofenceData geofenceData = GeofenceData.getDataFromIntent(intent); + HMSLogger.getInstance(context).sendPeriodicEvent("GeofenceUpdates"); + eventSink.success(GeofenceUtils.fromGeofenceDataToMap(geofenceData)); + } + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java new file mode 100644 index 00000000..6600697a --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ActivityUtils.java @@ -0,0 +1,140 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.utils; + +import com.huawei.hms.location.ActivityConversionData; +import com.huawei.hms.location.ActivityConversionInfo; +import com.huawei.hms.location.ActivityConversionRequest; +import com.huawei.hms.location.ActivityConversionResponse; +import com.huawei.hms.location.ActivityIdentificationData; +import com.huawei.hms.location.ActivityIdentificationResponse; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public interface ActivityUtils { + /** + * Utility method + * @param list List of the ActivityConversionInfo + * @return ActivityConversionRequest object + */ + static ActivityConversionRequest fromActivityConversionInfoListToActivityConversionRequest( + final List> list) { + final List activityConversionInfos = new ArrayList<>(); + + for (final Map map : list) { + activityConversionInfos.add(fromMapToActivityConversionInfo(map)); + } + + return new ActivityConversionRequest(activityConversionInfos); + } + + /** + * Utility method + * @param map HashMap representation of the ActivityConversionInfo object + * @return ActivityConversionInfo object + */ + static ActivityConversionInfo fromMapToActivityConversionInfo(final Map map) { + return new ActivityConversionInfo(ValueGetter.getInt("activityType", map), + ValueGetter.getInt("conversionType", map)); + } + + /** + * Utility method + * @param data ActivityIdentificationData object + * @return HashMap representation of ActivityIdentificationData object + */ + static Map activityIdentificationDataToMap(final ActivityIdentificationData data) { + final Map map = new HashMap<>(); + + if (data == null) { + return map; + } + + map.put("identificationActivity", data.getIdentificationActivity()); + map.put("possibility", data.getPossibility()); + + return map; + } + + /** + * Utility method + * @param response ActivityIdentificationResponse object + * @return HashMap representation of ActivityIdentificationResponse object + */ + static Map activityIdentificationResponseToMap(final ActivityIdentificationResponse response) { + final Map map = new HashMap<>(); + + if (response == null) { + return map; + } + + map.put("time", response.getTime()); + map.put("elapsedTimeFromReboot", response.getElapsedTimeFromReboot()); + + final List> activityIdentificationDatas = new ArrayList<>(); + for (final ActivityIdentificationData data : response.getActivityIdentificationDatas()) { + activityIdentificationDatas.add(activityIdentificationDataToMap(data)); + } + map.put("activityIdentificationDatas", activityIdentificationDatas); + + return map; + } + + /** + * Utility method + * @param data ActivityConversionData object + * @return HashMap representation of the ActivityConversionData object + */ + static Map activityConversionDataToMap(final ActivityConversionData data) { + final Map map = new HashMap<>(); + + if (data == null) { + return map; + } + + map.put("activityType", data.getActivityType()); + map.put("conversionType", data.getConversionType()); + map.put("elapsedTimeFromReboot", data.getElapsedTimeFromReboot()); + + return map; + } + + /** + * Utility method + * @param response ActivityConversionResponse object + * @return HashMap representation of the ActivityConversionResponse object + */ + static Map activityConversionResponseToMap(final ActivityConversionResponse response) { + final Map map = new HashMap<>(); + + if (response == null) { + return map; + } + + final List> activityConversionDatas = new ArrayList<>(); + + for (final ActivityConversionData data : response.getActivityConversionDatas()) { + activityConversionDatas.add(ActivityUtils.activityConversionDataToMap(data)); + } + + map.put("activityConversionDatas", activityConversionDatas); + return map; + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java new file mode 100644 index 00000000..d79cf75d --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/GeofenceUtils.java @@ -0,0 +1,98 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.utils; + +import com.huawei.hms.location.Geofence; +import com.huawei.hms.location.GeofenceData; +import com.huawei.hms.location.GeofenceRequest; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public interface GeofenceUtils { + /** + * Utility method + * @param geofenceData GeofenceData object + * @return HashMap representation of the GeofenceData object + */ + static Map fromGeofenceDataToMap(final GeofenceData geofenceData) { + if (geofenceData == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + final List convertingGeofenceIdList = new ArrayList<>(); + + for (final Geofence geofence : geofenceData.getConvertingGeofenceList()) { + convertingGeofenceIdList.add(geofence.getUniqueId()); + } + + map.put("errorCode", geofenceData.getErrorCode()); + map.put("conversion", geofenceData.getConversion()); + map.put("convertingGeofenceIdList", convertingGeofenceIdList); + map.put("convertingLocation", LocationUtils.fromLocationToMap(geofenceData.getConvertingLocation())); + + return map; + } + + /** + * Utility method + * @param map HashMap representation of the Geofence object + * @return Geofence object + */ + static Geofence fromMapToGeofence(final Map map) { + final Geofence.Builder builder = new Geofence.Builder(); + + final double lat = ValueGetter.getDouble("latitude", map); + final double lng = ValueGetter.getDouble("longitude", map); + final float rad = ValueGetter.getFloat("radius", map); + + builder.setRoundArea(lat, lng, rad); + builder.setUniqueId(ValueGetter.getString("uniqueId", map)); + builder.setConversions(ValueGetter.getInt("conversions", map)); + builder.setDwellDelayTime(ValueGetter.getInt("dwellDelayTime", map)); + builder.setValidContinueTime(ValueGetter.getLong("validDuration", map)); + builder.setNotificationInterval(ValueGetter.getInt("notificationInterval", map)); + + return builder.build(); + } + + /** + * Utility method + * @param map HashMap representation of the GeofenceRequest object + * @return GeofenceRequest object + */ + static GeofenceRequest fromMapToGeofenceRequest(final Map map) { + final GeofenceRequest.Builder builder = new GeofenceRequest.Builder(); + final List geofenceMapList = ObjectUtils.cast(map.get("geofenceList"), List.class); + + if (geofenceMapList != null) { + for (final Object geofence : geofenceMapList) { + final Map geofenceMap = ObjectUtils.cast(geofence, Map.class); + builder.createGeofence(fromMapToGeofence(geofenceMap)); + } + } + + builder.setCoordinateType(ValueGetter.getInt("coordinateType", map)); + builder.setInitConversions(ValueGetter.getInt("initConversions", map)); + + return builder.build(); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java new file mode 100644 index 00000000..36931b67 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/LocationUtils.java @@ -0,0 +1,309 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.utils; + +import android.location.Location; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; + +import com.huawei.hms.location.HWLocation; +import com.huawei.hms.location.LocationAvailability; +import com.huawei.hms.location.LocationRequest; +import com.huawei.hms.location.LocationResult; +import com.huawei.hms.location.LocationSettingsRequest; +import com.huawei.hms.location.LocationSettingsStates; +import com.huawei.hms.location.NavigationRequest; +import com.huawei.hms.location.NavigationResult; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public interface LocationUtils { + /** + * Utility method + * @param location ActivityIdentificationData object + * @return HashMap representation of Location object + */ + static Map fromLocationToMap(final Location location) { + if (location == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + + map.put("provider", location.getProvider()); + map.put("latitude", location.getLatitude()); + map.put("longitude", location.getLongitude()); + map.put("altitude", location.getAltitude()); + map.put("speed", location.getSpeed()); + map.put("bearing", location.getBearing()); + map.put("horizontalAccuracyMeters", location.getAccuracy()); + map.put("time", location.getTime()); + map.put("elapsedRealtimeNanos", location.getElapsedRealtimeNanos()); + map.put("isFromMockProvider", location.isFromMockProvider()); + + if (VERSION.SDK_INT >= VERSION_CODES.O) { + map.put("verticalAccuracyMeters", location.getVerticalAccuracyMeters()); + map.put("speedAccuracyMetersPerSecond", location.getSpeedAccuracyMetersPerSecond()); + map.put("bearingAccuracyDegrees", location.getBearingAccuracyDegrees()); + } else { + map.put("verticalAccuracyMeters", 0.0); + map.put("speedAccuracyMetersPerSecond", 0.0); + map.put("bearingAccuracyDegrees", 0.0); + } + + return map; + } + + /** + * Utility method + * @param hwLocation HWLocation object + * @return HashMap representation of HWLocation object + */ + static Map fromHWLocationToMap(final HWLocation hwLocation) { + if (hwLocation == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + + map.put("provider", hwLocation.getProvider()); + map.put("latitude", hwLocation.getLatitude()); + map.put("longitude", hwLocation.getLongitude()); + map.put("altitude", hwLocation.getAltitude()); + map.put("speed", hwLocation.getSpeed()); + map.put("bearing", hwLocation.getBearing()); + map.put("horizontalAccuracyMeters", hwLocation.getAccuracy()); + map.put("verticalAccuracyMeters", hwLocation.getVerticalAccuracyMeters()); + map.put("speedAccuracyMetersPerSecond", hwLocation.getSpeedAccuracyMetersPerSecond()); + map.put("bearingAccuracyDegrees", hwLocation.getBearingAccuracyDegrees()); + map.put("time", hwLocation.getTime()); + map.put("elapsedRealtimeNanos", hwLocation.getElapsedRealtimeNanos()); + map.put("countryCode", hwLocation.getCountryCode()); + map.put("countryName", hwLocation.getCountryName()); + map.put("state", hwLocation.getState()); + map.put("city", hwLocation.getCity()); + map.put("county", hwLocation.getCounty()); + map.put("street", hwLocation.getStreet()); + map.put("featureName", hwLocation.getFeatureName()); + map.put("postalCode", hwLocation.getPostalCode()); + map.put("phone", hwLocation.getPhone()); + map.put("url", hwLocation.getUrl()); + map.put("extraInfo", hwLocation.getExtraInfo()); + + return map; + } + + /** + * Utility method + * @param locationAvailability LocationAvailability object + * @return HashMap representation of LocationAvailability object + */ + static Map fromLocationAvailabilityToMap(final LocationAvailability locationAvailability) { + if (locationAvailability == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + + map.put("cellStatus", locationAvailability.getCellStatus()); + map.put("wifiStatus", locationAvailability.getWifiStatus()); + map.put("elapsedRealtimeNs", locationAvailability.getElapsedRealtimeNs()); + map.put("locationStatus", locationAvailability.getLocationStatus()); + + return map; + } + + /** + * Utility method + * @param locationResult LocationResult object + * @return HashMap representation of LocationResult object + */ + static Map fromLocationResultToMap(final LocationResult locationResult) { + if (locationResult == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + final List> locationMaps = new ArrayList<>(); + final List> hwLocationMaps = new ArrayList<>(); + + for (final Location location : locationResult.getLocations()) { + locationMaps.add(fromLocationToMap(location)); + } + + for (final HWLocation hwLocation : locationResult.getHWLocationList()) { + hwLocationMaps.add(fromHWLocationToMap(hwLocation)); + } + + map.put("locations", locationMaps); + map.put("hwLocations", hwLocationMaps); + map.put("lastLocation", fromLocationToMap(locationResult.getLastLocation())); + map.put("lastHWLocation", fromHWLocationToMap(locationResult.getLastHWLocation())); + + return map; + } + + /** + * Utility method + * @param states LocationSettingsStates object + * @return HashMap representation of LocationSettingsStates object + */ + static Map fromLocationSettingsStatesToMap(final LocationSettingsStates states) { + if (states == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + + map.put("blePresent", states.isBlePresent()); + map.put("bleUsable", states.isBleUsable()); + map.put("gpsPresent", states.isGpsPresent()); + map.put("gpsUsable", states.isGpsUsable()); + map.put("locationPresent", states.isLocationPresent()); + map.put("locationUsable", states.isLocationUsable()); + map.put("networkLocationPresent", states.isNetworkLocationPresent()); + map.put("networkLocationUsable", states.isNetworkLocationUsable()); + + return map; + } + + /** + * Utility method + * @param result NavigationResult object + * @return HashMap representation of NavigationResult object + */ + static Map fromNavigationResultToMap(final NavigationResult result) { + if (result == null) { + return Collections.emptyMap(); + } + + final Map map = new HashMap<>(); + + map.put("state", result.getState()); + map.put("possibility", result.getPossibility()); + + return map; + } + + /** + * Utility method + * @param map HashMap representation of the LocationRequest object + * @return LocationRequest object + */ + static LocationRequest fromMapToLocationRequest(final Map map) { + final boolean isFastestIntervalExplicitlySet = ValueGetter.getBoolean("isFastestIntervalExplicitlySet", map); + + final LocationRequest result = LocationRequest.create(); + + if (isFastestIntervalExplicitlySet) { + result.setFastestInterval(ValueGetter.getLong("fastestInterval", map)); + } + + result.setPriority(ValueGetter.getInt("priority", map)); + result.setInterval(ValueGetter.getLong("interval", map)); + result.setExpirationTime(ValueGetter.getLong("expirationTime", map)); + result.setNumUpdates(ValueGetter.getInt("numUpdates", map)); + result.setSmallestDisplacement(ValueGetter.getFloat("smallestDisplacement", map)); + result.setMaxWaitTime(ValueGetter.getLong("maxWaitTime", map)); + result.setNeedAddress(ValueGetter.getBoolean("needAddress", map)); + result.setLanguage(ValueGetter.getString("language", map)); + result.setCountryCode(ValueGetter.getString("countryCode", map)); + + final Map extras = ObjectUtils.cast(map.get("extras"), Map.class); + + if (extras != null) { + final Set entries = extras.entrySet(); + for (final Object entry : entries) { + final Map.Entry mapEntry = ObjectUtils.cast(entry, Map.Entry.class); + final String key = ObjectUtils.cast(mapEntry.getKey(), String.class); + final String value = ObjectUtils.cast(mapEntry.getValue(), String.class); + result.putExtras(key, value); + } + } + + return result; + } + + /** + * Utility method + * @param map HashMap representation of the NavigationRequest object + * @return NavigationRequest object + */ + static NavigationRequest fromMapToNavigationRequest(final Map map) { + final int type = ValueGetter.getInt("type", map); + final Map extras = ObjectUtils.cast(map.get("extras"), Map.class); + + final NavigationRequest request = new NavigationRequest(type); + request.setExtras(extras); + + return request; + } + + /** + * Utility method + * @param map HashMap representation of the Location object + * @return Location object + */ + static Location fromMapToLocation(final Map map) { + final String provider = ValueGetter.getString("provider", map); + final Location location = new Location(provider); + + location.setLatitude(ValueGetter.getDouble("latitude", map)); + location.setLongitude(ValueGetter.getDouble("longitude", map)); + location.setAltitude(ValueGetter.getDouble("altitude", map)); + location.setSpeed(ValueGetter.getFloat("speed", map)); + location.setBearing(ValueGetter.getFloat("bearing", map)); + location.setAccuracy(ValueGetter.getFloat("horizontalAccuracyMeters", map)); + location.setTime(ValueGetter.getLong("time", map)); + location.setElapsedRealtimeNanos(ValueGetter.getLong("elapsedRealtimeNanos", map)); + + if (VERSION.SDK_INT >= VERSION_CODES.O) { + location.setVerticalAccuracyMeters(ValueGetter.getFloat("verticalAccuracyMeters", map)); + location.setSpeedAccuracyMetersPerSecond(ValueGetter.getFloat("speedAccuracyMetersPerSecond", map)); + location.setBearingAccuracyDegrees(ValueGetter.getFloat("bearingAccuracyDegrees", map)); + } + + return location; + } + + /** + * Utility method + * @param map HashMap representation of the LocationSettingsRequest object + * @return LocationSettingsRequest object + */ + static LocationSettingsRequest fromMapToLocationSettingsRequest(final Map map) { + final LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); + final List requests = ObjectUtils.cast(map.get("requests"), List.class); + + if (requests != null) { + for (final Object request : requests) { + final Map requestMap = ObjectUtils.cast(request, Map.class); + builder.addLocationRequest(fromMapToLocationRequest(requestMap)); + } + } + + builder.setAlwaysShow(ValueGetter.getBoolean("alwaysShow", map)); + builder.setNeedBle(ValueGetter.getBoolean("needBle", map)); + + return builder.build(); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java new file mode 100644 index 00000000..395d14a8 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ObjectUtils.java @@ -0,0 +1,31 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.utils; + +public interface ObjectUtils { + /** + * Utility method that castes given object to given class type + * @param source Source object to be casted + * @param clazz Class that object will be casted to its type + * @param Source object's type + * @param Destination type + * @return Object that casted to D type + */ + static D cast(final S source, final Class clazz) { + return clazz.cast(source); + } +} diff --git a/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java new file mode 100644 index 00000000..f5d2ba38 --- /dev/null +++ b/hms-plugins/flutter-hms-location/android/src/main/java/com/huawei/hms/flutter/location/utils/ValueGetter.java @@ -0,0 +1,112 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package com.huawei.hms.flutter.location.utils; + +import java.util.Map; +import java.util.Objects; + +public interface ValueGetter { + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "int" value for the corresponding key. + */ + static int getInt(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof Number) { + return ((Number) value).intValue(); + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "long" value for the corresponding key. + */ + static long getLong(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof Number) { + return ((Number) value).longValue(); + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "float" value for the corresponding key. + */ + static float getFloat(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof Number) { + return ((Number) value).floatValue(); + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "double" value for the corresponding key. + */ + static double getDouble(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof Number) { + return ((Number) value).doubleValue(); + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "boolean" value for the corresponding key. + */ + static boolean getBoolean(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof Boolean) { + return (boolean) value; + } else { + throw new IllegalArgumentException(); + } + } + + /** + * Utility method + * @param key Lookup key for the map + * @param map Map that contains argument keys and values + * @return The "String" value for the corresponding key. + */ + static String getString(final String key, final Map map) { + final Object value = Objects.requireNonNull(map.get(key)); + if (value instanceof String) { + return (String) value; + } else { + throw new IllegalArgumentException(); + } + } +} diff --git a/hms-plugins/flutter-hms-location/ios/Assets/.gitkeep b/hms-plugins/flutter-hms-location/ios/Assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h new file mode 100644 index 00000000..0676dadb --- /dev/null +++ b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.h @@ -0,0 +1,4 @@ +#import + +@interface LocationPlugin : NSObject +@end diff --git a/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m new file mode 100644 index 00000000..e71b90d2 --- /dev/null +++ b/hms-plugins/flutter-hms-location/ios/Classes/LocationPlugin.m @@ -0,0 +1,20 @@ +#import "LocationPlugin.h" + +@implementation LocationPlugin ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = [FlutterMethodChannel + methodChannelWithName:@"location" + binaryMessenger:[registrar messenger]]; + LocationPlugin* instance = [[LocationPlugin alloc] init]; + [registrar addMethodCallDelegate:instance channel:channel]; +} + +- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { + if ([@"getPlatformVersion" isEqualToString:call.method]) { + result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]); + } else { + result(FlutterMethodNotImplemented); + } +} + +@end diff --git a/hms-plugins/flutter-hms-location/ios/huawei_location.podspec b/hms-plugins/flutter-hms-location/ios/huawei_location.podspec new file mode 100644 index 00000000..cd8d7142 --- /dev/null +++ b/hms-plugins/flutter-hms-location/ios/huawei_location.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint location.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'huawei_location' + s.version = '5.0.0+301' + s.summary = 'HUAWEI Flutter Location Kit plugin.' + s.description = <<-DESC + HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities. + DESC + s.homepage = 'https://www.huawei.com' + s.license = { :type => 'Apache 2.0', :file => '../LICENSE' } + s.author = { 'Huawei Technologies' => 'huaweideveloper1@gmail.com' } + s.source = { :git => 'https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + + # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } +end diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart new file mode 100644 index 00000000..8b5c6444 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_data.dart @@ -0,0 +1,76 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class ActivityConversionData { + int activityType; + int conversionType; + int elapsedTimeFromReboot; + + ActivityConversionData({ + this.activityType, + this.conversionType, + this.elapsedTimeFromReboot, + }); + + Map toMap() { + return { + 'activityType': activityType, + 'conversionType': conversionType, + 'elapsedTimeFromReboot': elapsedTimeFromReboot, + }; + } + + factory ActivityConversionData.fromMap(Map map) { + if (map == null) return null; + + return ActivityConversionData( + activityType: map['activityType'], + conversionType: map['conversionType'], + elapsedTimeFromReboot: map['elapsedTimeFromReboot'], + ); + } + + String toJson() => json.encode(toMap()); + + factory ActivityConversionData.fromJson(String source) => + ActivityConversionData.fromMap(json.decode(source)); + + @override + String toString() => + 'ActivityConversionData(activityType: $activityType, conversionType: $conversionType, elapsedTimeFromReboot: $elapsedTimeFromReboot)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ActivityConversionData && + o.activityType == activityType && + o.conversionType == conversionType && + o.elapsedTimeFromReboot == elapsedTimeFromReboot; + } + + @override + int get hashCode { + return hashList([ + activityType, + conversionType, + elapsedTimeFromReboot, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart new file mode 100644 index 00000000..8eae9a55 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_info.dart @@ -0,0 +1,73 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class ActivityConversionInfo { + static const int ENTER_ACTIVITY_CONVERSION = 0; + static const int EXIT_ACTIVITY_CONVERSION = 1; + + int activityType; + int conversionType; + + ActivityConversionInfo({ + this.activityType, + this.conversionType, + }); + + Map toMap() { + return { + 'activityType': activityType, + 'conversionType': conversionType, + }; + } + + factory ActivityConversionInfo.fromMap(Map map) { + if (map == null) return null; + + return ActivityConversionInfo( + activityType: map['activityType'], + conversionType: map['conversionType'], + ); + } + + String toJson() => json.encode(toMap()); + + factory ActivityConversionInfo.fromJson(String source) => + ActivityConversionInfo.fromMap(json.decode(source)); + + @override + String toString() => + 'ActivityConversionInfo(activityType: $activityType, conversionType: $conversionType)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ActivityConversionInfo && + o.activityType == activityType && + o.conversionType == conversionType; + } + + @override + int get hashCode { + return hashList([ + activityType, + conversionType, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart new file mode 100644 index 00000000..28c44158 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_conversion_response.dart @@ -0,0 +1,71 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import 'activity_conversion_data.dart'; + +class ActivityConversionResponse { + List activityConversionDatas; + + ActivityConversionResponse({ + this.activityConversionDatas, + }); + + Map toMap() { + return { + 'activityConversionDatas': + activityConversionDatas?.map((x) => x?.toMap())?.toList(), + }; + } + + factory ActivityConversionResponse.fromMap(Map map) { + if (map == null) return null; + + return ActivityConversionResponse( + activityConversionDatas: List.from( + map['activityConversionDatas'] + ?.map((x) => ActivityConversionData.fromMap(x))), + ); + } + + String toJson() => json.encode(toMap()); + + factory ActivityConversionResponse.fromJson(String source) => + ActivityConversionResponse.fromMap(json.decode(source)); + + @override + String toString() => + 'ActivityConversionResponse(activityConversionDatas: $activityConversionDatas)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ActivityConversionResponse && + listEquals(o.activityConversionDatas, activityConversionDatas); + } + + @override + int get hashCode { + return hashList([ + activityConversionDatas, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart new file mode 100644 index 00000000..ed171175 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_data.dart @@ -0,0 +1,94 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class ActivityIdentificationData { + static const int VEHICLE = 100; + static const int BIKE = 101; + static const int FOOT = 102; + static const int STILL = 103; + static const int OTHERS = 104; + static const int TILTING = 105; + static const int WALKING = 107; + static const int RUNNING = 108; + + static const List _validTypes = [ + VEHICLE, + BIKE, + FOOT, + STILL, + OTHERS, + TILTING, + WALKING, + RUNNING + ]; + + int identificationActivity; + int possibility; + + ActivityIdentificationData({ + this.identificationActivity, + this.possibility, + }); + + static bool isValidType(int type) { + return _validTypes.contains(type) ? true : false; + } + + Map toMap() { + return { + 'identificationActivity': identificationActivity, + 'possibility': possibility, + }; + } + + factory ActivityIdentificationData.fromMap(Map map) { + if (map == null) return null; + + return ActivityIdentificationData( + identificationActivity: map['identificationActivity'], + possibility: map['possibility'], + ); + } + + String toJson() => json.encode(toMap()); + + factory ActivityIdentificationData.fromJson(String source) => + ActivityIdentificationData.fromMap(json.decode(source)); + + @override + String toString() => + 'ActivityIdentificationData(identificationActivity: $identificationActivity, possibility: $possibility)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ActivityIdentificationData && + o.identificationActivity == identificationActivity && + o.possibility == possibility; + } + + @override + int get hashCode { + return hashList([ + identificationActivity, + possibility, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart new file mode 100644 index 00000000..c059ca50 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_response.dart @@ -0,0 +1,106 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import 'activity_identification_data.dart'; + +class ActivityIdentificationResponse { + int time; + int elapsedTimeFromReboot; + List activityIdentificationDatas; + + ActivityIdentificationResponse({ + this.activityIdentificationDatas, + this.time, + this.elapsedTimeFromReboot, + }); + + ActivityIdentificationData get mostActivityIdentification { + return activityIdentificationDatas != null && + activityIdentificationDatas.length > 0 + ? activityIdentificationDatas[0] + : null; + } + + int getActivityPossibility(int activityType) { + if (activityIdentificationDatas != null && + activityIdentificationDatas.length > 0) { + Iterator iterator = activityIdentificationDatas.iterator; + + while (iterator.moveNext()) { + ActivityIdentificationData currentData = iterator.current; + if (currentData.identificationActivity == activityType) { + return currentData.possibility; + } + } + } + + return 0; + } + + Map toMap() { + return { + 'time': time, + 'elapsedTimeFromReboot': elapsedTimeFromReboot, + 'activityIdentificationDatas': + activityIdentificationDatas?.map((x) => x?.toMap())?.toList(), + }; + } + + factory ActivityIdentificationResponse.fromMap(Map map) { + if (map == null) return null; + + return ActivityIdentificationResponse( + time: map['time'], + elapsedTimeFromReboot: map['elapsedTimeFromReboot'], + activityIdentificationDatas: List.from( + map['activityIdentificationDatas'] + ?.map((x) => ActivityIdentificationData.fromMap(x))), + ); + } + + String toJson() => json.encode(toMap()); + + factory ActivityIdentificationResponse.fromJson(String source) => + ActivityIdentificationResponse.fromMap(json.decode(source)); + + @override + String toString() => + 'ActivityIdentificationResponse(time: $time, elapsedTimeFromReboot: $elapsedTimeFromReboot, activityIdentificationDatas: $activityIdentificationDatas)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is ActivityIdentificationResponse && + o.time == time && + o.elapsedTimeFromReboot == elapsedTimeFromReboot && + listEquals(o.activityIdentificationDatas, activityIdentificationDatas); + } + + @override + int get hashCode { + return hashList([ + time, + elapsedTimeFromReboot, + activityIdentificationDatas, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart new file mode 100644 index 00000000..c8598871 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/activity/activity_identification_service.dart @@ -0,0 +1,98 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'package:flutter/services.dart'; + +import 'activity_conversion_info.dart'; +import 'activity_conversion_response.dart'; +import 'activity_identification_response.dart'; + +class ActivityIdentificationService { + static ActivityIdentificationService _instance; + + final MethodChannel _methodChannel; + final EventChannel _activityIdentificationEventChannel; + final EventChannel _activityConversionEventChannel; + + Stream _onActivityIdentification; + Stream _onActivityConversion; + + ActivityIdentificationService._create( + this._methodChannel, + this._activityIdentificationEventChannel, + this._activityConversionEventChannel, + ); + + factory ActivityIdentificationService() { + if (_instance == null) { + final MethodChannel methodChannel = const MethodChannel( + 'com.huawei.flutter.location/activityidentification_methodchannel'); + + final EventChannel activityIdentificationEventChannel = const EventChannel( + 'com.huawei.flutter.location/activityidentification_eventchannel'); + + final EventChannel activityConversionEventChannel = const EventChannel( + 'com.huawei.flutter.location/activityconversion_eventchannel'); + + _instance = ActivityIdentificationService._create( + methodChannel, + activityIdentificationEventChannel, + activityConversionEventChannel, + ); + } + return _instance; + } + + Future createActivityIdentificationUpdates( + int detectionIntervalMillis) async { + return _methodChannel.invokeMethod( + 'createActivityIdentificationUpdates', detectionIntervalMillis); + } + + Future createActivityConversionUpdates( + List activityConversions) async { + return _methodChannel.invokeMethod('createActivityConversionUpdates', + activityConversions?.map((x) => x?.toMap())?.toList()); + } + + Future deleteActivityIdentificationUpdates(int requestCode) async { + return _methodChannel.invokeMethod( + 'deleteActivityIdentificationUpdates', requestCode); + } + + Future deleteActivityConversionUpdates(int requestCode) async { + return _methodChannel.invokeMethod( + 'deleteActivityConversionUpdates', requestCode); + } + + Stream get onActivityIdentification { + if (_onActivityIdentification == null) { + _onActivityIdentification = _activityIdentificationEventChannel + .receiveBroadcastStream() + .map((event) => ActivityIdentificationResponse.fromMap(event)); + } + return _onActivityIdentification; + } + + Stream get onActivityConversion { + if (_onActivityConversion == null) { + _onActivityConversion = _activityConversionEventChannel + .receiveBroadcastStream() + .map((event) => ActivityConversionResponse.fromMap(event)); + } + return _onActivityConversion; + } +} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart new file mode 100644 index 00000000..fc93cb7b --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/geofence/geofence.dart @@ -0,0 +1,113 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:core'; +import 'dart:ui'; + +class Geofence { + static const int ENTER_GEOFENCE_CONVERSION = 1; + static const int EXIT_GEOFENCE_CONVERSION = 2; + static const int DWELL_GEOFENCE_CONVERSION = 4; + static const int GEOFENCE_NEVER_EXPIRE = -1; + + String uniqueId; + int conversions; + int validDuration; + double latitude; + double longitude; + double radius; + int notificationInterval; + int dwellDelayTime; + + Geofence({ + this.uniqueId, + this.conversions, + this.validDuration, + this.latitude, + this.longitude, + this.radius, + this.notificationInterval = 0, + this.dwellDelayTime = 0, + }); + + Map toMap() { + return { + 'uniqueId': uniqueId, + 'conversions': conversions, + 'validDuration': validDuration, + 'latitude': latitude, + 'longitude': longitude, + 'radius': radius, + 'notificationInterval': notificationInterval, + 'dwellDelayTime': dwellDelayTime, + }; + } + + factory Geofence.fromMap(Map map) { + if (map == null) return null; + + return Geofence( + uniqueId: map['uniqueId'], + conversions: map['conversions'], + validDuration: map['validDuration'], + latitude: map['latitude'], + longitude: map['longitude'], + radius: map['radius'], + notificationInterval: map['notificationInterval'], + dwellDelayTime: map['dwellDelayTime'], + ); + } + + String toJson() => json.encode(toMap()); + + factory Geofence.fromJson(String source) => + Geofence.fromMap(json.decode(source)); + + @override + String toString() { + return 'Geofence(uniqueId: $uniqueId, conversions: $conversions, validDuration: $validDuration, latitude: $latitude, longitude: $longitude, radius: $radius, notificationInterval: $notificationInterval, dwellDelayTime: $dwellDelayTime)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is Geofence && + o.uniqueId == uniqueId && + o.conversions == conversions && + o.validDuration == validDuration && + o.latitude == latitude && + o.longitude == longitude && + o.radius == radius && + o.notificationInterval == notificationInterval && + o.dwellDelayTime == dwellDelayTime; + } + + @override + int get hashCode { + return hashList([ + uniqueId, + conversions, + validDuration, + latitude, + longitude, + radius, + notificationInterval, + dwellDelayTime, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart new file mode 100644 index 00000000..c2aca69e --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/geofence/geofence_data.dart @@ -0,0 +1,88 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import '../location/location.dart'; + +class GeofenceData { + int errorCode; + int conversion; + List convertingGeofenceIdList; + Location convertingLocation; + + GeofenceData({ + this.errorCode, + this.conversion, + this.convertingGeofenceIdList, + this.convertingLocation, + }); + + Map toMap() { + return { + 'errorCode': errorCode, + 'conversion': conversion, + 'convertingGeofenceIdList': convertingGeofenceIdList, + 'convertingLocation': convertingLocation?.toMap(), + }; + } + + factory GeofenceData.fromMap(Map map) { + if (map == null) return null; + + return GeofenceData( + errorCode: map['errorCode'], + conversion: map['conversion'], + convertingGeofenceIdList: + List.from(map['convertingGeofenceIdList']), + convertingLocation: Location.fromMap(map['convertingLocation']), + ); + } + + String toJson() => json.encode(toMap()); + + factory GeofenceData.fromJson(String source) => + GeofenceData.fromMap(json.decode(source)); + + @override + String toString() { + return 'GeofenceData(errorCode: $errorCode, conversion: $conversion, convertingGeofenceIdList: $convertingGeofenceIdList, convertingLocation: $convertingLocation)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is GeofenceData && + o.errorCode == errorCode && + o.conversion == conversion && + listEquals(o.convertingGeofenceIdList, convertingGeofenceIdList) && + o.convertingLocation == convertingLocation; + } + + @override + int get hashCode { + return hashList([ + errorCode, + conversion, + convertingGeofenceIdList, + convertingLocation, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart new file mode 100644 index 00000000..bbefb528 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/geofence/geofence_request.dart @@ -0,0 +1,91 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import 'geofence.dart'; + +class GeofenceRequest { + static const int ENTER_INIT_CONVERSION = 1; + static const int EXIT_INIT_CONVERSION = 2; + static const int DWELL_INIT_CONVERSION = 4; + static const int COORDINATE_TYPE_WGS_84 = 1; + static const int COORDINATE_TYPE_GCJ_02 = 0; + + List geofenceList; + int initConversions; + int coordinateType; + + GeofenceRequest({ + this.geofenceList, + this.initConversions = ENTER_INIT_CONVERSION | DWELL_INIT_CONVERSION, + this.coordinateType = COORDINATE_TYPE_WGS_84, + }) { + if (this.geofenceList == null) { + this.geofenceList = []; + } + } + + Map toMap() { + return { + 'geofenceList': geofenceList?.map((x) => x?.toMap())?.toList(), + 'initConversions': initConversions, + 'coordinateType': coordinateType, + }; + } + + factory GeofenceRequest.fromMap(Map map) { + if (map == null) return null; + + return GeofenceRequest( + geofenceList: List.from( + map['geofenceList']?.map((x) => Geofence.fromMap(x))), + initConversions: map['initConversions'], + coordinateType: map['coordinateType'], + ); + } + + String toJson() => json.encode(toMap()); + + factory GeofenceRequest.fromJson(String source) => + GeofenceRequest.fromMap(json.decode(source)); + + @override + String toString() => + 'GeofenceRequest(geofenceList: $geofenceList, initConversions: $initConversions, coordinateType: $coordinateType)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is GeofenceRequest && + listEquals(o.geofenceList, geofenceList) && + o.initConversions == initConversions && + o.coordinateType == coordinateType; + } + + @override + int get hashCode { + return hashList([ + geofenceList, + initConversions, + coordinateType, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart b/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart new file mode 100644 index 00000000..87e9d0a8 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/geofence/geofence_service.dart @@ -0,0 +1,72 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'package:flutter/services.dart'; + +import 'geofence_data.dart' show GeofenceData; +import 'geofence_request.dart' show GeofenceRequest; + +class GeofenceService { + static GeofenceService _instance; + + final MethodChannel _methodChannel; + final EventChannel _eventChannel; + + Stream _onGeofenceData; + + GeofenceService._create( + this._methodChannel, + this._eventChannel, + ); + + factory GeofenceService() { + if (_instance == null) { + final MethodChannel methodChannel = const MethodChannel( + 'com.huawei.flutter.location/geofence_methodchannel'); + final EventChannel eventChannel = const EventChannel( + 'com.huawei.flutter.location/geofence_eventchannel'); + + _instance = GeofenceService._create( + methodChannel, + eventChannel, + ); + } + return _instance; + } + + Future createGeofenceList(GeofenceRequest geofenceRequest) async { + return _methodChannel.invokeMethod( + 'createGeofenceList', geofenceRequest.toMap()); + } + + Future deleteGeofenceList(int requestCode) async { + return _methodChannel.invokeMethod('deleteGeofenceList', requestCode); + } + + Future deleteGeofenceListWithIds(List geofenceIds) async { + return _methodChannel.invokeMethod( + 'deleteGeofenceListWithIds', geofenceIds); + } + + Stream get onGeofenceData { + if (_onGeofenceData == null) { + _onGeofenceData = _eventChannel + .receiveBroadcastStream() + .map((event) => GeofenceData.fromMap(event)); + } + return _onGeofenceData; + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart b/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart new file mode 100644 index 00000000..b67c49af --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/fused_location_provider_client.dart @@ -0,0 +1,158 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'package:flutter/services.dart'; + +import 'hwlocation.dart'; +import 'location.dart'; +import 'location_availability.dart'; +import 'location_callback.dart'; +import 'location_request.dart'; +import 'location_result.dart'; +import 'location_settings_request.dart'; +import 'location_settings_states.dart'; +import 'navigation_request.dart'; +import 'navigation_result.dart'; + +class FusedLocationProviderClient { + static FusedLocationProviderClient _instance; + + final MethodChannel _methodChannel; + final EventChannel _eventChannel; + final Map _callbacks; + + Stream _onLocationData; + + FusedLocationProviderClient._create( + this._methodChannel, + this._eventChannel, + this._callbacks, + ) { + _methodChannel.setMethodCallHandler(_methodCallHandler); + } + + factory FusedLocationProviderClient() { + if (_instance == null) { + _instance = FusedLocationProviderClient._create( + const MethodChannel( + 'com.huawei.flutter.location/fusedlocation_methodchannel'), + const EventChannel( + 'com.huawei.flutter.location/fusedlocation_eventchannel'), + {}, + ); + } + return _instance; + } + + Future _methodCallHandler(MethodCall methodCall) async { + switch (methodCall.method) { + case 'onLocationResult': + _callbacks[methodCall.arguments['callbackId']].onLocationResult( + LocationResult.fromMap(methodCall.arguments['locationResult'])); + break; + case 'onLocationAvailability': + _callbacks[methodCall.arguments['callbackId']].onLocationAvailability( + LocationAvailability.fromMap( + methodCall.arguments['locationAvailability'])); + break; + default: + break; + } + } + + Future checkLocationSettings( + LocationSettingsRequest locationSettingsRequest) async { + return LocationSettingsStates.fromMap( + await _methodChannel.invokeMapMethod( + 'checkLocationSettings', locationSettingsRequest.toMap())); + } + + Future getLastLocation() async { + return Location.fromMap(await _methodChannel + .invokeMapMethod('getLastLocation')); + } + + Future getLastLocationWithAddress( + LocationRequest locationRequest) async { + return HWLocation.fromMap( + await _methodChannel.invokeMapMethod( + 'getLastLocationWithAddress', locationRequest.toMap())); + } + + Future getLocationAvailability() async { + return LocationAvailability.fromMap(await _methodChannel + .invokeMapMethod('getLocationAvailability')); + } + + Future setMockMode(bool mockMode) async { + return _methodChannel.invokeMethod('setMockMode', mockMode); + } + + Future setMockLocation(Location location) async { + return _methodChannel.invokeMethod( + 'setMockLocation', location.toMap()); + } + + Future requestLocationUpdates(LocationRequest locationRequest) async { + return _methodChannel.invokeMethod( + 'requestLocationUpdates', locationRequest.toMap()); + } + + Future requestLocationUpdatesCb(LocationRequest locationRequest, + LocationCallback locationCallback) async { + int callbackId = await _methodChannel.invokeMethod( + 'requestLocationUpdatesCb', locationRequest.toMap()); + _callbacks.putIfAbsent(callbackId, () => locationCallback); + return callbackId; + } + + Future requestLocationUpdatesExCb(LocationRequest locationRequest, + LocationCallback locationCallback) async { + int callbackId = await _methodChannel.invokeMethod( + 'requestLocationUpdatesExCb', + (locationRequest..priority = LocationRequest.PRIORITY_HD_ACCURACY) + .toMap()); + _callbacks.putIfAbsent(callbackId, () => locationCallback); + return callbackId; + } + + Future removeLocationUpdates(int requestCode) async { + return _methodChannel.invokeMethod( + 'removeLocationUpdates', requestCode); + } + + Future removeLocationUpdatesCb(int callbackId) async { + await _methodChannel.invokeMethod( + 'removeLocationUpdatesCb', callbackId); + _callbacks.remove(callbackId); + } + + Future getNavigationContextState( + NavigationRequest navigationRequest) async { + return NavigationResult.fromMap( + await _methodChannel.invokeMapMethod( + 'getNavigationContextState', navigationRequest.toMap())); + } + + Stream get onLocationData { + if (_onLocationData == null) { + _onLocationData = _eventChannel + .receiveBroadcastStream() + .map((event) => Location.fromMap(event)); + } + return _onLocationData; + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart b/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart new file mode 100644 index 00000000..97c92db5 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/hwlocation.dart @@ -0,0 +1,207 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +class HWLocation { + String provider; + double latitude; + double longitude; + double altitude; + double speed; + double bearing; + double horizontalAccuracyMeters; + double verticalAccuracyMeters; + double speedAccuracyMetersPerSecond; + double bearingAccuracyDegrees; + int time; + int elapsedRealtimeNanos; + String countryCode; + String countryName; + String state; + String city; + String county; + String street; + String featureName; + String postalCode; + String phone; + String url; + Map extraInfo; + + HWLocation({ + this.provider, + this.latitude, + this.longitude, + this.altitude, + this.speed, + this.bearing, + this.horizontalAccuracyMeters, + this.verticalAccuracyMeters, + this.speedAccuracyMetersPerSecond, + this.bearingAccuracyDegrees, + this.time, + this.elapsedRealtimeNanos, + this.countryCode, + this.countryName, + this.state, + this.city, + this.county, + this.street, + this.featureName, + this.postalCode, + this.phone, + this.url, + this.extraInfo, + }); + + Map toMap() { + return { + 'provider': provider, + 'latitude': latitude, + 'longitude': longitude, + 'altitude': altitude, + 'speed': speed, + 'bearing': bearing, + 'horizontalAccuracyMeters': horizontalAccuracyMeters, + 'verticalAccuracyMeters': verticalAccuracyMeters, + 'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond, + 'bearingAccuracyDegrees': bearingAccuracyDegrees, + 'time': time, + 'elapsedRealtimeNanos': elapsedRealtimeNanos, + 'countryCode': countryCode, + 'countryName': countryName, + 'state': state, + 'city': city, + 'county': county, + 'street': street, + 'featureName': featureName, + 'postalCode': postalCode, + 'phone': phone, + 'url': url, + 'extraInfo': extraInfo, + }; + } + + factory HWLocation.fromMap(Map map) { + if (map == null) return null; + + return HWLocation( + provider: map["provider"] == null ? null : map["provider"], + latitude: map["latitude"] == null ? null : map["latitude"], + longitude: map["longitude"] == null ? null : map["longitude"], + altitude: map["altitude"] == null ? null : map["altitude"], + speed: map["speed"] == null ? null : map["speed"], + bearing: map["bearing"] == null ? null : map["bearing"], + horizontalAccuracyMeters: map["horizontalAccuracyMeters"], + verticalAccuracyMeters: map["verticalAccuracyMeters"] == null + ? null + : map["verticalAccuracyMeters"], + speedAccuracyMetersPerSecond: + map["speedAccuracyMetersPerSecond"] == null + ? null + : map["speedAccuracyMetersPerSecond"], + bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null + ? null + : map["bearingAccuracyDegrees"], + time: map["time"] == null ? null : map["time"], + elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null + ? null + : map["elapsedRealtimeNanos"], + countryCode: map["countryCode"] == null ? null : map["countryCode"], + countryName: map["countryName"] == null ? null : map["countryName"], + state: map["state"] == null ? null : map["state"], + city: map["city"] == null ? null : map["city"], + county: map["county"] == null ? null : map["county"], + street: map["street"] == null ? null : map["street"], + featureName: map["featureName"] == null ? null : map["featureName"], + postalCode: map["postalCode"] == null ? null : map["postalCode"], + phone: map["phone"] == null ? null : map["phone"], + url: map["url"] == null ? null : map["url"], + extraInfo: + map["extraInfo"] == null ? null : Map.from(map["extraInfo"])); + } + + String toJson() => json.encode(toMap()); + + factory HWLocation.fromJson(String source) => + HWLocation.fromMap(json.decode(source)); + + @override + String toString() { + return 'HWLocation(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos, countryCode: $countryCode, countryName: $countryName, state: $state, city: $city, county: $county, street: $street, featureName: $featureName, postalCode: $postalCode, phone: $phone, url: $url, extraInfo: $extraInfo)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + return o is HWLocation && + o.provider == provider && + o.latitude == latitude && + o.longitude == longitude && + o.altitude == altitude && + o.speed == speed && + o.bearing == bearing && + o.horizontalAccuracyMeters == horizontalAccuracyMeters && + o.verticalAccuracyMeters == verticalAccuracyMeters && + o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond && + o.bearingAccuracyDegrees == bearingAccuracyDegrees && + o.time == time && + o.elapsedRealtimeNanos == elapsedRealtimeNanos && + o.countryCode == countryCode && + o.countryName == countryName && + o.state == state && + o.city == city && + o.county == county && + o.street == street && + o.featureName == featureName && + o.postalCode == postalCode && + o.phone == phone && + o.url == url && + mapEquals(o.extraInfo, extraInfo); + } + + @override + int get hashCode { + return hashList([ + provider, + latitude, + longitude, + altitude, + speed, + bearing, + horizontalAccuracyMeters, + verticalAccuracyMeters, + speedAccuracyMetersPerSecond, + bearingAccuracyDegrees, + time, + elapsedRealtimeNanos, + countryCode, + countryName, + state, + city, + county, + street, + featureName, + postalCode, + phone, + url, + extraInfo, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location.dart b/hms-plugins/flutter-hms-location/lib/location/location.dart new file mode 100644 index 00000000..5fa17b6a --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location.dart @@ -0,0 +1,141 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class Location { + String provider; + double latitude; + double longitude; + double altitude; + double speed; + double bearing; + double horizontalAccuracyMeters; + double verticalAccuracyMeters; + double speedAccuracyMetersPerSecond; + double bearingAccuracyDegrees; + int time; + int elapsedRealtimeNanos; + + Location({ + this.provider = 'HMS Mock Location', + this.latitude = 0.0, + this.longitude = 0.0, + this.altitude = 0.0, + this.speed = 0.0, + this.bearing = 0.0, + this.horizontalAccuracyMeters = 0.0, + this.verticalAccuracyMeters = 0.0, + this.speedAccuracyMetersPerSecond = 0.0, + this.bearingAccuracyDegrees = 0.0, + this.time = 0, + this.elapsedRealtimeNanos = 0, + }); + + Map toMap() { + return { + 'provider': provider, + 'latitude': latitude, + 'longitude': longitude, + 'altitude': altitude, + 'speed': speed, + 'bearing': bearing, + 'horizontalAccuracyMeters': horizontalAccuracyMeters, + 'verticalAccuracyMeters': verticalAccuracyMeters, + 'speedAccuracyMetersPerSecond': speedAccuracyMetersPerSecond, + 'bearingAccuracyDegrees': bearingAccuracyDegrees, + 'time': time, + 'elapsedRealtimeNanos': elapsedRealtimeNanos, + }; + } + + factory Location.fromMap(Map map) { + if (map == null) return null; + + return Location( + provider: map["provider"] == null ? null : map["provider"], + latitude: map["latitude"] == null ? null : map["latitude"], + longitude: map["longitude"] == null ? null : map["longitude"], + altitude: map["altitude"] == null ? null : map["altitude"], + speed: map["speed"] == null ? null : map["speed"], + bearing: map["bearing"] == null ? null : map["bearing"], + horizontalAccuracyMeters: map["horizontalAccuracyMeters"] == null + ? null + : map["horizontalAccuracyMeters"], + verticalAccuracyMeters: map["verticalAccuracyMeters"] == null + ? null + : map["verticalAccuracyMeters"], + speedAccuracyMetersPerSecond: map["speedAccuracyMetersPerSecond"] == null + ? null + : map["speedAccuracyMetersPerSecond"], + bearingAccuracyDegrees: map["bearingAccuracyDegrees"] == null + ? null + : map["bearingAccuracyDegrees"], + time: map["time"] == null ? null : map["time"], + elapsedRealtimeNanos: map["elapsedRealtimeNanos"] == null + ? null + : map["elapsedRealtimeNanos"], + ); + } + + String toJson() => json.encode(toMap()); + + factory Location.fromJson(String source) => + Location.fromMap(json.decode(source)); + + @override + String toString() { + return 'Location(provider: $provider, latitude: $latitude, longitude: $longitude, altitude: $altitude, speed: $speed, bearing: $bearing, horizontalAccuracyMeters: $horizontalAccuracyMeters, verticalAccuracyMeters: $verticalAccuracyMeters, speedAccuracyMetersPerSecond: $speedAccuracyMetersPerSecond, bearingAccuracyDegrees: $bearingAccuracyDegrees, time: $time, elapsedRealtimeNanos: $elapsedRealtimeNanos)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is Location && + o.provider == provider && + o.latitude == latitude && + o.longitude == longitude && + o.altitude == altitude && + o.speed == speed && + o.bearing == bearing && + o.horizontalAccuracyMeters == horizontalAccuracyMeters && + o.verticalAccuracyMeters == verticalAccuracyMeters && + o.speedAccuracyMetersPerSecond == speedAccuracyMetersPerSecond && + o.bearingAccuracyDegrees == bearingAccuracyDegrees && + o.time == time && + o.elapsedRealtimeNanos == elapsedRealtimeNanos; + } + + @override + int get hashCode { + return hashList([ + provider, + latitude, + longitude, + altitude, + speed, + bearing, + horizontalAccuracyMeters, + verticalAccuracyMeters, + speedAccuracyMetersPerSecond, + bearingAccuracyDegrees, + time, + elapsedRealtimeNanos, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_availability.dart b/hms-plugins/flutter-hms-location/lib/location/location_availability.dart new file mode 100644 index 00000000..a93a1061 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_availability.dart @@ -0,0 +1,85 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class LocationAvailability { + int cellStatus; + int wifiStatus; + int elapsedRealtimeNs; + int locationStatus; + + LocationAvailability({ + this.cellStatus, + this.wifiStatus, + this.elapsedRealtimeNs, + this.locationStatus, + }); + + bool get isLocationAvailable => locationStatus < 1000; + + Map toMap() { + return { + 'cellStatus': cellStatus, + 'wifiStatus': wifiStatus, + 'elapsedRealtimeNs': elapsedRealtimeNs, + 'locationStatus': locationStatus, + }; + } + + factory LocationAvailability.fromMap(Map map) { + if (map == null) return null; + + return LocationAvailability( + cellStatus: map['cellStatus'], + wifiStatus: map['wifiStatus'], + elapsedRealtimeNs: map['elapsedRealtimeNs'], + locationStatus: map['locationStatus'], + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationAvailability.fromJson(String source) => + LocationAvailability.fromMap(json.decode(source)); + + @override + String toString() { + return 'LocationAvailability(cellStatus: $cellStatus, wifiStatus: $wifiStatus, elapsedRealtimeNs: $elapsedRealtimeNs, locationStatus: $locationStatus)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is LocationAvailability && + o.cellStatus == cellStatus && + o.wifiStatus == wifiStatus && + o.elapsedRealtimeNs == elapsedRealtimeNs && + o.locationStatus == locationStatus; + } + + @override + int get hashCode { + return hashList([ + cellStatus, + wifiStatus, + elapsedRealtimeNs, + locationStatus, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_callback.dart b/hms-plugins/flutter-hms-location/lib/location/location_callback.dart new file mode 100644 index 00000000..b67068ae --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_callback.dart @@ -0,0 +1,31 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'location_availability.dart'; +import 'location_result.dart'; + +typedef void OnLocationResult(LocationResult locationResult); +typedef void OnLocationAvailability(LocationAvailability locationAvailability); + +class LocationCallback { + OnLocationResult onLocationResult; + OnLocationAvailability onLocationAvailability; + + LocationCallback({ + this.onLocationResult, + this.onLocationAvailability, + }); +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_request.dart b/hms-plugins/flutter-hms-location/lib/location/location_request.dart new file mode 100644 index 00000000..af4ee2ea --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_request.dart @@ -0,0 +1,231 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +class LocationRequest { + static const int PRIORITY_HIGH_ACCURACY = 100; + static const int PRIORITY_BALANCED_POWER_ACCURACY = 102; + static const int PRIORITY_LOW_POWER = 104; + static const int PRIORITY_NO_POWER = 105; + static const int PRIORITY_HD_ACCURACY = 200; + static const double _FASTEST_INTERVAL_FACTOR = 6.0; + + int _priority; + int _interval; + int _fastestInterval; + bool _isFastestIntervalExplicitlySet; + int _expirationTime; + int _numUpdates; + double _smallestDisplacement; + int _maxWaitTime; + bool needAddress; + String language; + String countryCode; + Map extras; + + LocationRequest._create( + this._priority, + this._interval, + this._fastestInterval, + this._isFastestIntervalExplicitlySet, + this._expirationTime, + this._numUpdates, + this._smallestDisplacement, + this._maxWaitTime, + this.needAddress, + this.language, + this.countryCode, + this.extras, + ); + + LocationRequest() { + _priority = PRIORITY_BALANCED_POWER_ACCURACY; + _interval = 3600000; + _fastestInterval = (_interval ~/ _FASTEST_INTERVAL_FACTOR); + _isFastestIntervalExplicitlySet = false; + _expirationTime = 9223372036854775807; + _numUpdates = 2147483647; + _smallestDisplacement = 0.0; + _maxWaitTime = 0; + needAddress = false; + language = ''; + countryCode = ''; + } + + int get priority => _priority; + + set priority(int value) { + if (value == PRIORITY_HIGH_ACCURACY || + value == PRIORITY_BALANCED_POWER_ACCURACY || + value == PRIORITY_LOW_POWER || + value == PRIORITY_NO_POWER || + value == PRIORITY_HD_ACCURACY) { + _priority = value; + } else { + throw ArgumentError('Priority is not a known constant'); + } + } + + int get interval => _interval; + + set interval(int value) { + if (value.isNegative) { + throw ArgumentError('Interval is invalid'); + } else { + _interval = value; + _fastestInterval = _isFastestIntervalExplicitlySet + ? _fastestInterval + : (_interval ~/ _FASTEST_INTERVAL_FACTOR); + } + } + + int get fastestInterval => _fastestInterval; + + set fastestInterval(int value) { + if (value.isNegative) { + throw ArgumentError('FastestInterval is invalid'); + } else { + _isFastestIntervalExplicitlySet = true; + _fastestInterval = value; + } + } + + bool get isFastestIntervalExplicitlySet => _isFastestIntervalExplicitlySet; + + int get expirationTime => _expirationTime; + + set expirationTime(int value) { + _expirationTime = value.isNegative ? 0 : value; + } + + int get numUpdates => _numUpdates; + + set numUpdates(int value) { + if (value <= 0) { + throw ArgumentError('numUpdates is invalid'); + } else { + _numUpdates = value; + } + } + + double get smallestDisplacement => _smallestDisplacement; + + set smallestDisplacement(double value) { + if (value.isNegative) { + throw ArgumentError('smallestDisplacement param invalid'); + } else { + _smallestDisplacement = value; + } + } + + int get maxWaitTime => _maxWaitTime < _interval ? _interval : _maxWaitTime; + + set maxWaitTime(int value) => _maxWaitTime = value; + + void putExtras(String key, String value) { + if (extras == null) { + extras = Map(); + } + extras.putIfAbsent(key, () => value); + } + + Map toMap() { + return { + 'priority': _priority, + 'interval': _interval, + 'fastestInterval': _fastestInterval, + 'isFastestIntervalExplicitlySet': _isFastestIntervalExplicitlySet, + 'expirationTime': _expirationTime, + 'numUpdates': _numUpdates, + 'smallestDisplacement': _smallestDisplacement, + 'maxWaitTime': _maxWaitTime, + 'needAddress': needAddress, + 'language': language, + 'countryCode': countryCode, + 'extras': extras, + }; + } + + factory LocationRequest.fromMap(Map map) { + if (map == null) return null; + + return LocationRequest._create( + map['priority'], + map['interval'], + map['fastestInterval'], + map['isFastestIntervalExplicitlySet'], + map['expirationTime'], + map['numUpdates'], + map['smallestDisplacement'], + map['maxWaitTime'], + map['needAddress'], + map['language'], + map['countryCode'], + Map.from(map['extras']), + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationRequest.fromJson(String source) => + LocationRequest.fromMap(json.decode(source)); + + @override + String toString() { + return 'LocationRequest(_priority: $_priority, _interval: $_interval, _fastestInterval: $_fastestInterval, _isFastestIntervalExplicitlySet: $_isFastestIntervalExplicitlySet, _expirationTime: $_expirationTime, _numUpdates: $_numUpdates, _smallestDisplacement: $_smallestDisplacement, _maxWaitTime: $_maxWaitTime, _needAddress: $needAddress, _language: $language, _countryCode: $countryCode, _extras: $extras)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is LocationRequest && + o._priority == _priority && + o._interval == _interval && + o._fastestInterval == _fastestInterval && + o._isFastestIntervalExplicitlySet == _isFastestIntervalExplicitlySet && + o._expirationTime == _expirationTime && + o._numUpdates == _numUpdates && + o._smallestDisplacement == _smallestDisplacement && + o._maxWaitTime == _maxWaitTime && + o.needAddress == needAddress && + o.language == language && + o.countryCode == countryCode && + mapEquals(o.extras, extras); + } + + @override + int get hashCode { + return hashList([ + _priority, + _interval, + _fastestInterval, + _isFastestIntervalExplicitlySet, + _expirationTime, + _numUpdates, + _smallestDisplacement, + _maxWaitTime, + needAddress, + language, + countryCode, + extras, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_result.dart b/hms-plugins/flutter-hms-location/lib/location/location_result.dart new file mode 100644 index 00000000..04cac6d5 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_result.dart @@ -0,0 +1,98 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import 'hwlocation.dart' show HWLocation; +import 'location.dart' show Location; + +class LocationResult { + List locations; + List hwLocations; + Location lastLocation; + HWLocation lastHWLocation; + + LocationResult({ + this.locations, + this.hwLocations, + this.lastLocation, + this.lastHWLocation, + }); + + Map toMap() { + return { + 'locations': locations?.map((x) => x?.toMap())?.toList(), + 'hwLocations': hwLocations?.map((x) => x?.toMap())?.toList(), + 'lastLocation': lastLocation?.toMap(), + 'lastHWLocation': lastHWLocation?.toMap(), + }; + } + + factory LocationResult.fromMap(Map map) { + if (map == null) return null; + + return LocationResult( + locations: map["locations"] == null + ? null + : List.from( + map["locations"].map((x) => Location.fromMap(x))), + hwLocations: map["hwLocations"] == null + ? null + : List.from( + map["hwLocations"].map((x) => HWLocation.fromMap(x))), + lastLocation: map["lastLocation"] == null + ? null + : Location.fromMap(map["lastLocation"]), + lastHWLocation: map["lastHWLocation"] == null + ? null + : HWLocation.fromMap(map["lastHWLocation"]), + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationResult.fromJson(String source) => + LocationResult.fromMap(json.decode(source)); + + @override + String toString() { + return 'LocationResult(locations: $locations, hwLocations: $hwLocations, lastLocation: $lastLocation, lastHWLocation: $lastHWLocation)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is LocationResult && + listEquals(o.locations, locations) && + listEquals(o.hwLocations, hwLocations) && + o.lastLocation == lastLocation && + o.lastHWLocation == lastHWLocation; + } + + @override + int get hashCode { + return hashList([ + locations, + hwLocations, + lastLocation, + lastHWLocation, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart b/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart new file mode 100644 index 00000000..f03d7224 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_settings_request.dart @@ -0,0 +1,81 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +import 'location_request.dart'; + +class LocationSettingsRequest { + List requests; + bool alwaysShow; + bool needBle; + + LocationSettingsRequest({ + this.requests = const [], + this.alwaysShow = false, + this.needBle = false, + }); + + Map toMap() { + return { + 'requests': requests?.map((x) => x?.toMap())?.toList(), + 'alwaysShow': alwaysShow, + 'needBle': needBle, + }; + } + + factory LocationSettingsRequest.fromMap(Map map) { + if (map == null) return null; + + return LocationSettingsRequest( + requests: List.from( + map['requests']?.map((x) => LocationRequest.fromMap(x))), + alwaysShow: map['alwaysShow'], + needBle: map['needBle'], + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationSettingsRequest.fromJson(String source) => + LocationSettingsRequest.fromMap(json.decode(source)); + + @override + String toString() => + 'LocationSettingsRequest(requests: $requests, alwaysShow: $alwaysShow, needBle: $needBle)'; + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is LocationSettingsRequest && + listEquals(o.requests, requests) && + o.alwaysShow == alwaysShow && + o.needBle == needBle; + } + + @override + int get hashCode { + return hashList([ + requests, + alwaysShow, + needBle, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart b/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart new file mode 100644 index 00000000..096374c6 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/location_settings_states.dart @@ -0,0 +1,107 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +class LocationSettingsStates { + bool blePresent; + bool bleUsable; + bool gpsPresent; + bool gpsUsable; + bool locationPresent; + bool locationUsable; + bool networkLocationPresent; + bool networkLocationUsable; + + LocationSettingsStates({ + this.blePresent, + this.bleUsable, + this.gpsPresent, + this.gpsUsable, + this.locationPresent, + this.locationUsable, + this.networkLocationPresent, + this.networkLocationUsable, + }); + + Map toMap() { + return { + 'blePresent': blePresent, + 'bleUsable': bleUsable, + 'gpsPresent': gpsPresent, + 'gpsUsable': gpsUsable, + 'locationPresent': locationPresent, + 'locationUsable': locationUsable, + 'networkLocationPresent': networkLocationPresent, + 'networkLocationUsable': networkLocationUsable, + }; + } + + factory LocationSettingsStates.fromMap(Map map) { + if (map == null) return null; + + return LocationSettingsStates( + blePresent: map['blePresent'], + bleUsable: map['bleUsable'], + gpsPresent: map['gpsPresent'], + gpsUsable: map['gpsUsable'], + locationPresent: map['locationPresent'], + locationUsable: map['locationUsable'], + networkLocationPresent: map['networkLocationPresent'], + networkLocationUsable: map['networkLocationUsable'], + ); + } + + String toJson() => json.encode(toMap()); + + factory LocationSettingsStates.fromJson(String source) => + LocationSettingsStates.fromMap(json.decode(source)); + + @override + String toString() { + return 'LocationSettingsStates(blePresent: $blePresent, bleUsable: $bleUsable, gpsPresent: $gpsPresent, gpsUsable: $gpsUsable, locationPresent: $locationPresent, locationUsable: $locationUsable, networkLocationPresent: $networkLocationPresent, networkLocationUsable: $networkLocationUsable)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + + return o is LocationSettingsStates && + o.blePresent == blePresent && + o.bleUsable == bleUsable && + o.gpsPresent == gpsPresent && + o.gpsUsable == gpsUsable && + o.locationPresent == locationPresent && + o.locationUsable == locationUsable && + o.networkLocationPresent == networkLocationPresent && + o.networkLocationUsable == networkLocationUsable; + } + + @override + int get hashCode { + return hashList([ + blePresent, + bleUsable, + gpsPresent, + gpsUsable, + locationPresent, + locationUsable, + networkLocationPresent, + networkLocationUsable, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart b/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart new file mode 100644 index 00000000..d929ec2b --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/navigation_request.dart @@ -0,0 +1,82 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; + +class NavigationRequest { + static const int OVERPASS = 1; + static const int IS_SUPPORT_EX = 2; + + int type; + Map extras; + + NavigationRequest({ + this.type, + this.extras, + }); + + void putExtras(String key, String value) { + if (extras == null) { + extras = Map(); + } + extras.putIfAbsent(key, () => value); + } + + Map toMap() { + return { + 'type': type, + 'extras': extras, + }; + } + + factory NavigationRequest.fromMap(Map map) { + if (map == null) return null; + + return NavigationRequest( + type: map['type'], + extras: Map.from(map['extras']), + ); + } + + String toJson() => json.encode(toMap()); + + factory NavigationRequest.fromJson(String source) => + NavigationRequest.fromMap(json.decode(source)); + + @override + String toString() { + return 'NavigationRequest(type: $type, extras: $extras)'; + } + + @override + bool operator ==(Object o) { + if (identical(this, o)) return true; + return o is NavigationRequest && + o.type == type && + mapEquals(o.extras, extras); + } + + @override + int get hashCode { + return hashList([ + type, + extras, + ]); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart b/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart new file mode 100644 index 00000000..71d3a177 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/location/navigation_result.dart @@ -0,0 +1,53 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'dart:convert'; + +class NavigationResult { + int possibility; + int state; + + NavigationResult({ + this.possibility, + this.state, + }); + + Map toMap() { + return { + 'state': state, + 'possibility': possibility, + }; + } + + factory NavigationResult.fromMap(Map map) { + if (map == null) return null; + + return NavigationResult( + state: map["state"] == null ? null : map["state"], + possibility: map["possibility"] == null ? null : map["possibility"], + ); + } + + String toJson() => json.encode(toMap()); + + factory NavigationResult.fromJson(String source) => + NavigationResult.fromMap(json.decode(source)); + + @override + String toString() { + return 'State: $state, Possibility: $possibility'; + } +} diff --git a/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart b/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart new file mode 100644 index 00000000..f35113e6 --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/logger/hmslogger.dart @@ -0,0 +1,30 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'package:flutter/services.dart'; + +class HMSLogger { + static const MethodChannel _methodChannel = + MethodChannel("com.huawei.flutter.location/hmslogger_methodchannel"); + + static Future enableLogger() async { + return _methodChannel.invokeMethod('enableLogger'); + } + + static Future disableLogger() async { + return _methodChannel.invokeMethod('disableLogger'); + } +} diff --git a/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart b/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart new file mode 100644 index 00000000..865234fb --- /dev/null +++ b/hms-plugins/flutter-hms-location/lib/permission/permission_handler.dart @@ -0,0 +1,63 @@ +/* + Copyright 2020. Huawei Technologies Co., Ltd. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + 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. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +import 'package:flutter/services.dart'; + +class PermissionHandler { + static PermissionHandler _instance; + + final MethodChannel _methodChannel; + + PermissionHandler._create( + this._methodChannel, + ); + + factory PermissionHandler() { + if (_instance == null) { + final MethodChannel methodChannel = const MethodChannel( + 'com.huawei.flutter.location/permission_methodchannel'); + _instance = PermissionHandler._create(methodChannel); + } + return _instance; + } + + Future hasLocationPermission() async { + return _methodChannel.invokeMethod('hasLocationPermission'); + } + + Future hasBackgroundLocationPermission() async { + return _methodChannel.invokeMethod('hasBackgroundLocationPermission'); + } + + Future hasActivityRecognitionPermission() async { + return _methodChannel + .invokeMethod('hasActivityRecognitionPermission'); + } + + Future requestLocationPermission() async { + return _methodChannel.invokeMethod('requestLocationPermission'); + } + + Future requestBackgroundLocationPermission() async { + return _methodChannel + .invokeMethod('requestBackgroundLocationPermission'); + } + + Future requestActivityRecognitionPermission() async { + return _methodChannel + .invokeMethod('requestActivityRecognitionPermission'); + } +} diff --git a/hms-plugins/flutter-hms-location/pubspec.yaml b/hms-plugins/flutter-hms-location/pubspec.yaml new file mode 100644 index 00000000..74c68492 --- /dev/null +++ b/hms-plugins/flutter-hms-location/pubspec.yaml @@ -0,0 +1,24 @@ +name: huawei_location +description: HUAWEI Flutter Location Kit plugin combines the GPS, Wi-Fi and base station locations to help you quickly obtain precise user locations & build up global positioning capabilities. +version: 5.0.0+301 +homepage: https://www.huawei.com +repository: https://github.com/HMS-Core/hms-flutter-plugin/tree/master/flutter-hms-location + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.13+hotfix.6 <2.0.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +flutter: + plugin: + platforms: + android: + package: com.huawei.hms.flutter.location + pluginClass: LocationPlugin diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index b8024672..3b4ea73f 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file +45a7d43b55124e1b314759554f9a14d3 \ No newline at end of file diff --git a/ios/GoogleService-Info.plist b/ios/GoogleService-Info.plist index 0c093a2a..633037cb 100644 --- a/ios/GoogleService-Info.plist +++ b/ios/GoogleService-Info.plist @@ -3,21 +3,23 @@ CLIENT_ID - 864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r.apps.googleusercontent.com + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.864393916058-ekeb4s8tgfo58dutv0l54399t7ivr06r + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com API_KEY - AIzaSyA_6ayGCk4fly7o7eTVBrj9kuHBYHMAOfs + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA GCM_SENDER_ID - 864393916058 + 815750722565 PLIST_VERSION 1 BUNDLE_ID - com.cloud.diplomaticquarterapp + com.HMG.HMG-Smartphone PROJECT_ID - diplomaticquarter-d2385 + api-project-815750722565 STORAGE_BUCKET - diplomaticquarter-d2385.appspot.com + api-project-815750722565.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,8 +31,8 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:864393916058:ios:13f787bbfe6051f8b97923 + 1:815750722565:ios:328ec247a81a2ca23c186c DATABASE_URL - https://diplomaticquarter-d2385.firebaseio.com + https://api-project-815750722565.firebaseio.com \ No newline at end of file diff --git a/ios/Podfile b/ios/Podfile index 5579d926..d68afba2 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project - platform :ios, '11.0' +# platform :ios, '11.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a09481c1..d7619384 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,455 +1,25 @@ PODS: - - android_intent (0.0.1): - - Flutter - - barcode_scan_fix (0.0.1): - - Flutter - - MTBBarcodeScanner - - connectivity (0.0.1): - - Flutter - - Reachability - - connectivity_for_web (0.1.0): - - Flutter - - connectivity_macos (0.0.1): - - Flutter - - device_calendar (0.0.1): - - Flutter - - device_info (0.0.1): - - Flutter - - Firebase/CoreOnly (6.33.0): - - FirebaseCore (= 6.10.3) - - Firebase/Messaging (6.33.0): - - Firebase/CoreOnly - - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.3): - - Firebase/CoreOnly (~> 6.33.0) - - Flutter - - firebase_core_web (0.1.0): - - Flutter - - firebase_messaging (7.0.3): - - Firebase/CoreOnly (~> 6.33.0) - - Firebase/Messaging (~> 6.33.0) - - firebase_core - - Flutter - - FirebaseCore (6.10.3): - - FirebaseCoreDiagnostics (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - FirebaseCoreDiagnostics (1.7.0): - - GoogleDataTransport (~> 7.4) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Logger (~> 6.7) - - nanopb (~> 1.30906.0) - - FirebaseInstallations (1.7.0): - - FirebaseCore (~> 6.10) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - PromisesObjC (~> 1.2) - - FirebaseInstanceID (4.8.0): - - FirebaseCore (~> 6.10) - - FirebaseInstallations (~> 1.6) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - FirebaseMessaging (4.7.1): - - FirebaseCore (~> 6.10) - - FirebaseInstanceID (~> 4.7) - - GoogleUtilities/AppDelegateSwizzler (~> 6.7) - - GoogleUtilities/Environment (~> 6.7) - - GoogleUtilities/Reachability (~> 6.7) - - GoogleUtilities/UserDefaults (~> 6.7) - - Protobuf (>= 3.9.2, ~> 3.9) - Flutter (1.0.0) - - flutter_email_sender (0.0.1): - - Flutter - - flutter_flexible_toast (0.0.1): - - Flutter - - flutter_inappwebview (0.0.1): - - Flutter - - flutter_local_notifications (0.0.1): - - Flutter - - flutter_plugin_android_lifecycle (0.0.1): - - Flutter - - flutter_tts (0.0.1): - - Flutter - - geolocator (6.1.9): - - Flutter - - google_maps_flutter (0.0.1): - - Flutter - - GoogleMaps (< 3.10) - - GoogleDataTransport (7.5.1): - - nanopb (~> 1.30906.0) - - GoogleMaps (3.9.0): - - GoogleMaps/Maps (= 3.9.0) - - GoogleMaps/Base (3.9.0) - - GoogleMaps/Maps (3.9.0): - - GoogleMaps/Base - - GoogleUtilities/AppDelegateSwizzler (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Logger - - GoogleUtilities/Network - - GoogleUtilities/Environment (6.7.2): - - PromisesObjC (~> 1.2) - - GoogleUtilities/Logger (6.7.2): - - GoogleUtilities/Environment - - GoogleUtilities/Network (6.7.2): - - GoogleUtilities/Logger - - "GoogleUtilities/NSData+zlib" - - GoogleUtilities/Reachability - - "GoogleUtilities/NSData+zlib (6.7.2)" - - GoogleUtilities/Reachability (6.7.2): - - GoogleUtilities/Logger - - GoogleUtilities/UserDefaults (6.7.2): - - GoogleUtilities/Logger - - hexcolor (0.0.1): - - Flutter - - image_cropper (0.0.3): - - Flutter - - TOCropViewController (~> 2.5.4) - - image_picker (0.0.1): - - Flutter - - just_audio (0.0.1): - - Flutter - - local_auth (0.0.1): - - Flutter - - manage_calendar_events (0.0.1): - - Flutter - - map_launcher (0.0.1): - - Flutter - - maps_launcher (0.0.1): - - Flutter - - MTBBarcodeScanner (5.0.11) - - nanopb (1.30906.0): - - nanopb/decode (= 1.30906.0) - - nanopb/encode (= 1.30906.0) - - nanopb/decode (1.30906.0) - - nanopb/encode (1.30906.0) - - native_device_orientation (0.0.1): - - Flutter - - native_progress_hud (0.0.1): - - Flutter - NVActivityIndicatorView (5.1.1): - NVActivityIndicatorView/Base (= 5.1.1) - NVActivityIndicatorView/Base (5.1.1) - - path_provider (0.0.1): - - Flutter - - path_provider_linux (0.0.1): - - Flutter - - path_provider_macos (0.0.1): - - Flutter - - path_provider_windows (0.0.1): - - Flutter - - "permission_handler (5.0.1+1)": - - Flutter - - PromisesObjC (1.2.11) - - Protobuf (3.13.0) - - Reachability (3.2) - - screen (0.0.1): - - Flutter - - shared_preferences (0.0.1): - - Flutter - - shared_preferences_linux (0.0.1): - - Flutter - - shared_preferences_macos (0.0.1): - - Flutter - - shared_preferences_web (0.0.1): - - Flutter - - shared_preferences_windows (0.0.1): - - Flutter - - speech_to_text (0.0.1): - - Flutter - - Try - - TOCropViewController (2.5.5) - - Try (2.1.1) - - "twilio_programmable_video (0.5.0+4)": - - Flutter - - TwilioVideo (~> 3.4) - - TwilioVideo (3.7.2) - - url_launcher (0.0.1): - - Flutter - - url_launcher_linux (0.0.1): - - Flutter - - url_launcher_macos (0.0.1): - - Flutter - - url_launcher_web (0.0.1): - - Flutter - - url_launcher_windows (0.0.1): - - Flutter - - vibration (1.7.3): - - Flutter - - vibration_web (1.6.2): - - Flutter - - video_player (0.0.1): - - Flutter - - video_player_web (0.0.1): - - Flutter - - wakelock (0.0.1): - - Flutter - - webview_flutter (0.0.1): - - Flutter - - wifi (0.0.1): - - Flutter DEPENDENCIES: - - android_intent (from `.symlinks/plugins/android_intent/ios`) - - barcode_scan_fix (from `.symlinks/plugins/barcode_scan_fix/ios`) - - connectivity (from `.symlinks/plugins/connectivity/ios`) - - connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`) - - connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`) - - device_calendar (from `.symlinks/plugins/device_calendar/ios`) - - device_info (from `.symlinks/plugins/device_info/ios`) - - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - - firebase_core_web (from `.symlinks/plugins/firebase_core_web/ios`) - - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) - - flutter_email_sender (from `.symlinks/plugins/flutter_email_sender/ios`) - - flutter_flexible_toast (from `.symlinks/plugins/flutter_flexible_toast/ios`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - - flutter_tts (from `.symlinks/plugins/flutter_tts/ios`) - - geolocator (from `.symlinks/plugins/geolocator/ios`) - - google_maps_flutter (from `.symlinks/plugins/google_maps_flutter/ios`) - - hexcolor (from `.symlinks/plugins/hexcolor/ios`) - - image_cropper (from `.symlinks/plugins/image_cropper/ios`) - - image_picker (from `.symlinks/plugins/image_picker/ios`) - - just_audio (from `.symlinks/plugins/just_audio/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) - - manage_calendar_events (from `.symlinks/plugins/manage_calendar_events/ios`) - - map_launcher (from `.symlinks/plugins/map_launcher/ios`) - - maps_launcher (from `.symlinks/plugins/maps_launcher/ios`) - - native_device_orientation (from `.symlinks/plugins/native_device_orientation/ios`) - - native_progress_hud (from `.symlinks/plugins/native_progress_hud/ios`) - NVActivityIndicatorView - - path_provider (from `.symlinks/plugins/path_provider/ios`) - - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) - - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) - - path_provider_windows (from `.symlinks/plugins/path_provider_windows/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - - screen (from `.symlinks/plugins/screen/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`) - - shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`) - - shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`) - - shared_preferences_windows (from `.symlinks/plugins/shared_preferences_windows/ios`) - - speech_to_text (from `.symlinks/plugins/speech_to_text/ios`) - - twilio_programmable_video (from `.symlinks/plugins/twilio_programmable_video/ios`) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - url_launcher_linux (from `.symlinks/plugins/url_launcher_linux/ios`) - - url_launcher_macos (from `.symlinks/plugins/url_launcher_macos/ios`) - - url_launcher_web (from `.symlinks/plugins/url_launcher_web/ios`) - - url_launcher_windows (from `.symlinks/plugins/url_launcher_windows/ios`) - - vibration (from `.symlinks/plugins/vibration/ios`) - - vibration_web (from `.symlinks/plugins/vibration_web/ios`) - - video_player (from `.symlinks/plugins/video_player/ios`) - - video_player_web (from `.symlinks/plugins/video_player_web/ios`) - - wakelock (from `.symlinks/plugins/wakelock/ios`) - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) - - wifi (from `.symlinks/plugins/wifi/ios`) SPEC REPOS: trunk: - - Firebase - - FirebaseCore - - FirebaseCoreDiagnostics - - FirebaseInstallations - - FirebaseInstanceID - - FirebaseMessaging - - GoogleDataTransport - - GoogleMaps - - GoogleUtilities - - MTBBarcodeScanner - - nanopb - NVActivityIndicatorView - - PromisesObjC - - Protobuf - - Reachability - - TOCropViewController - - Try - - TwilioVideo EXTERNAL SOURCES: - android_intent: - :path: ".symlinks/plugins/android_intent/ios" - barcode_scan_fix: - :path: ".symlinks/plugins/barcode_scan_fix/ios" - connectivity: - :path: ".symlinks/plugins/connectivity/ios" - connectivity_for_web: - :path: ".symlinks/plugins/connectivity_for_web/ios" - connectivity_macos: - :path: ".symlinks/plugins/connectivity_macos/ios" - device_calendar: - :path: ".symlinks/plugins/device_calendar/ios" - device_info: - :path: ".symlinks/plugins/device_info/ios" - firebase_core: - :path: ".symlinks/plugins/firebase_core/ios" - firebase_core_web: - :path: ".symlinks/plugins/firebase_core_web/ios" - firebase_messaging: - :path: ".symlinks/plugins/firebase_messaging/ios" Flutter: :path: Flutter - flutter_email_sender: - :path: ".symlinks/plugins/flutter_email_sender/ios" - flutter_flexible_toast: - :path: ".symlinks/plugins/flutter_flexible_toast/ios" - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" - flutter_local_notifications: - :path: ".symlinks/plugins/flutter_local_notifications/ios" - flutter_plugin_android_lifecycle: - :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" - flutter_tts: - :path: ".symlinks/plugins/flutter_tts/ios" - geolocator: - :path: ".symlinks/plugins/geolocator/ios" - google_maps_flutter: - :path: ".symlinks/plugins/google_maps_flutter/ios" - hexcolor: - :path: ".symlinks/plugins/hexcolor/ios" - image_cropper: - :path: ".symlinks/plugins/image_cropper/ios" - image_picker: - :path: ".symlinks/plugins/image_picker/ios" - just_audio: - :path: ".symlinks/plugins/just_audio/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" - manage_calendar_events: - :path: ".symlinks/plugins/manage_calendar_events/ios" - map_launcher: - :path: ".symlinks/plugins/map_launcher/ios" - maps_launcher: - :path: ".symlinks/plugins/maps_launcher/ios" - native_device_orientation: - :path: ".symlinks/plugins/native_device_orientation/ios" - native_progress_hud: - :path: ".symlinks/plugins/native_progress_hud/ios" - path_provider: - :path: ".symlinks/plugins/path_provider/ios" - path_provider_linux: - :path: ".symlinks/plugins/path_provider_linux/ios" - path_provider_macos: - :path: ".symlinks/plugins/path_provider_macos/ios" - path_provider_windows: - :path: ".symlinks/plugins/path_provider_windows/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" - screen: - :path: ".symlinks/plugins/screen/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - shared_preferences_linux: - :path: ".symlinks/plugins/shared_preferences_linux/ios" - shared_preferences_macos: - :path: ".symlinks/plugins/shared_preferences_macos/ios" - shared_preferences_web: - :path: ".symlinks/plugins/shared_preferences_web/ios" - shared_preferences_windows: - :path: ".symlinks/plugins/shared_preferences_windows/ios" - speech_to_text: - :path: ".symlinks/plugins/speech_to_text/ios" - twilio_programmable_video: - :path: ".symlinks/plugins/twilio_programmable_video/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - url_launcher_linux: - :path: ".symlinks/plugins/url_launcher_linux/ios" - url_launcher_macos: - :path: ".symlinks/plugins/url_launcher_macos/ios" - url_launcher_web: - :path: ".symlinks/plugins/url_launcher_web/ios" - url_launcher_windows: - :path: ".symlinks/plugins/url_launcher_windows/ios" - vibration: - :path: ".symlinks/plugins/vibration/ios" - vibration_web: - :path: ".symlinks/plugins/vibration_web/ios" - video_player: - :path: ".symlinks/plugins/video_player/ios" - video_player_web: - :path: ".symlinks/plugins/video_player_web/ios" - wakelock: - :path: ".symlinks/plugins/wakelock/ios" - webview_flutter: - :path: ".symlinks/plugins/webview_flutter/ios" - wifi: - :path: ".symlinks/plugins/wifi/ios" SPEC CHECKSUMS: - android_intent: 367df2f1277a74e4a90e14a8ab3df3112d087052 - barcode_scan_fix: 80dd65de55f27eec6591dd077c8b85f2b79e31f1 - connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 - connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b - connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191 - device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 - device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 - Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 - firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 - firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 - FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd - FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 - FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 - FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 - FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a Flutter: 0e3d915762c693b495b44d77113d4970485de6ec - flutter_email_sender: f787522d0e82f50e5766c1213dbffff22fdcf009 - flutter_flexible_toast: 0547e740cae0c33bb7c51bcd931233f4584e1143 - flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 - flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 - flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 - flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d - geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899 - google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 - GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 - GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac - GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 - hexcolor: fdfb9c4258ad96e949c2dbcdf790a62194b8aa89 - image_cropper: c8f9b4157933c7bb965a66d1c5e6c8fd408c6eb4 - image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 - just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd - manage_calendar_events: 0338d505ea26cdfd20cd883279bc28afa11eca34 - map_launcher: e325db1261d029ff33e08e03baccffe09593ffea - maps_launcher: eae38ee13a9c3f210fa04e04bb4c073fa4c6ed92 - MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb - nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc - native_device_orientation: e24d00be281de72996640885d80e706142707660 - native_progress_hud: f95f5529742b36a3c7fdecfa88dc018319e39bf9 NVActivityIndicatorView: 1f6c5687f1171810aa27a3296814dc2d7dec3667 - path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c - path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 - path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 - path_provider_windows: a2b81600c677ac1959367280991971cb9a1edb3b - permission_handler: eac8e15b4a1a3fba55b761d19f3f4e6b005d15b6 - PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f - Protobuf: 3dac39b34a08151c6d949560efe3f86134a3f748 - Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 - screen: abd91ca7bf3426e1cc3646d27e9b2358d6bf07b0 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 - shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 - shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 - shared_preferences_windows: 36b76d6f54e76ead957e60b49e2f124b4cd3e6ae - speech_to_text: b43a7d99aef037bd758ed8e45d79bbac035d2dfe - TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe - Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 - twilio_programmable_video: 6a41593640f3d86af60b22541fd457b22deaae7f - TwilioVideo: 5257640fab00d1b9f44db060815b03516a9eb0e8 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 - url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 - url_launcher_web: e5527357f037c87560776e36436bf2b0288b965c - url_launcher_windows: 683d7c283894db8d1914d3ab2223b20cc1ad95d5 - vibration: b5a33e764c3f609a975b9dca73dce20fdde627dc - vibration_web: 0ba303d92469ba34d71c612a228b315908d7fcd9 - video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e - video_player_web: da8cadb8274ed4f8dbee8d7171b420dedd437ce7 - wakelock: 0d4a70faf8950410735e3f61fb15d517c8a6efc4 - webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 - wifi: d7d77c94109e36c4175d845f0a5964eadba71060 -PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 +PODFILE CHECKSUM: ac5efa1ac3c9555d0008dc18004313c84746da62 -COCOAPODS: 1.10.0 +COCOAPODS: 1.10.0.rc.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 009006ed..366647c0 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -28,8 +28,10 @@ E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */; }; E923EFD82588D17700E3E751 /* gpx.gpx in Resources */ = {isa = PBXBuildFile; fileRef = E923EFD72588D17700E3E751 /* gpx.gpx */; }; E9620805255C2ED100D3A35D /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9620804255C2ED100D3A35D /* NetworkExtension.framework */; }; + E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */; }; 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 */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -78,8 +80,10 @@ E923EFD72588D17700E3E751 /* gpx.gpx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = gpx.gpx; sourceTree = ""; }; E9620803255C2ED100D3A35D /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; E9620804255C2ED100D3A35D /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; + E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; E9C8C135256BACDA00EFFB62 /* HMG_Guest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HMG_Guest.swift; sourceTree = ""; }; E9E27167256E3A4000F49B69 /* LocalizedFromFlutter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizedFromFlutter.swift; sourceTree = ""; }; + E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlutterConstants.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -128,6 +132,7 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */, E923EFD72588D17700E3E751 /* gpx.gpx */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, @@ -177,6 +182,7 @@ E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, ); path = Helper; sourceTree = ""; @@ -213,8 +219,7 @@ 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 125A739F71A29FBAE7B4D5AC /* [CP] Embed Pods Frameworks */, - 940F4A376A48B060117A1E5D /* [CP] Copy Pods Resources */, + EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -265,6 +270,7 @@ files = ( E91B53A0256AAC1400E96549 /* GuestPOC_Certificate.cer in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + E9A35329258B8E8F00CBA688 /* GoogleService-Info.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, E923EFD82588D17700E3E751 /* gpx.gpx in Resources */, E91B539F256AAC1400E96549 /* GuestPOC_Certificate.p12 in Resources */, @@ -277,23 +283,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 125A739F71A29FBAE7B4D5AC /* [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; - }; 299B8FE131E5BAE7FA7E2FC9 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -330,36 +319,36 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 940F4A376A48B060117A1E5D /* [CP] Copy Pods Resources */ = { + 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + inputPaths = ( ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + name = "Run Script"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 9740EEB61CF901F6004384FC /* Run Script */ = { + EFDAD5E1235DCA1DB6187148 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", ); - name = "Run Script"; - outputPaths = ( + 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 = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ @@ -374,6 +363,7 @@ E91B5396256AAA6500E96549 /* GlobalHelper.swift in Sources */, E923EFD4258645C100E3E751 /* HMG_Geofence.swift in Sources */, E923EFD62587443800E3E751 /* HMGPlatformBridge.swift in Sources */, + E9F7623B25922BCE00FB5CCF /* FlutterConstants.swift in Sources */, 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, E9E27168256E3A4000F49B69 /* LocalizedFromFlutter.swift in Sources */, 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, @@ -472,7 +462,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -488,7 +478,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -611,7 +601,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -627,7 +617,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -644,7 +634,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = 3A359E86ZF; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -660,7 +650,7 @@ "$(inherited)", "$(PROJECT_DIR)/Flutter", ); - PRODUCT_BUNDLE_IDENTIFIER = "com.HMG.HMG-Smartphone"; + PRODUCT_BUNDLE_IDENTIFIER = com.hmg.smartphone; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e686619c..c4a74c80 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,46 +2,67 @@ import UIKit import Flutter import GoogleMaps +var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { let locationManager = CLLocationManager() + var flutterViewController:MainFlutterVC! override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { -// initLocationManager() - GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") + GMSServices.provideAPIKey("AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw") GeneratedPluginRegistrant.register(with: self) - if let mainViewController = window.rootViewController as? MainFlutterVC{ - HMGPlatformBridge.initialize(flutterViewController: mainViewController) - } + initializePlatformChannel() if let _ = launchOptions?[.location] { HMG_Geofence.initGeofencing() } + UNUserNotificationCenter.current().delegate = self return super.application(application, didFinishLaunchingWithOptions: launchOptions) } -} - -extension AppDelegate: CLLocationManagerDelegate { - func initLocationManager(){ - locationManager.allowsBackgroundLocationUpdates = true - locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters - locationManager.activityType = .other - locationManager.delegate = self - locationManager.requestAlwaysAuthorization() + + func initializePlatformChannel(){ + if let mainViewController = window.rootViewController as? MainFlutterVC{ // platform initialization suppose to be in foreground + flutterViewController = mainViewController + HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + + }else if let mainViewController = initialViewController(){ // platform initialization suppose to be in background + flutterViewController = mainViewController + HMGPlatformBridge.initialize(flutterViewController: flutterViewController) + } } - - func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { - if region is CLCircularRegion { + + + func initialViewController() -> MainFlutterVC?{ + return nil //UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() as? MainFlutterVC } - } - - func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { - if region is CLCircularRegion { +} + +extension AppDelegate{ + override func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + if (notification.request.content.categoryIdentifier == HmgLocalNotificationCategoryIdentifier){ + completionHandler([.alert,.sound]) + }else{ + super.userNotificationCenter(center, willPresent: notification, withCompletionHandler: completionHandler) + } } - } } + + +/* + let dart = FlutterDartProject(precompiledDartBundle: .main) + let engine = FlutterEngine(name: "com.hmg.cs", project: dart, allowHeadlessExecution: true) + if engine.run(){ + flutterMethodChannel = FlutterMethodChannel(name: "HMG-Platform-Bridge", binaryMessenger: engine.binaryMessenger) + + Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { (timer) in + FlutterText.with(key: "alreadyConnectedHmgNetwork"){ localized in + print(localized) + } + } + } + */ diff --git a/ios/Runner/Helper/API.swift b/ios/Runner/Helper/API.swift index 763147c8..b487f033 100644 --- a/ios/Runner/Helper/API.swift +++ b/ios/Runner/Helper/API.swift @@ -13,5 +13,10 @@ fileprivate let BASE_URL = "\(DOMAIN)/\(SERVICE)" struct API { static let WIFI_CREDENTIALS = "\(BASE_URL)/Hmg_SMS_Get_By_ProjectID_And_PatientID" - } + + +//struct API { +// static let WIFI_CREDENTIALS = FlutterConstants.WIFI_CREDENTIALS_URL +// static let LOG_GEOFENCE = FlutterConstants.LOG_GEOFENCE_URL +//} diff --git a/ios/Runner/Helper/Extensions.swift b/ios/Runner/Helper/Extensions.swift index a8793617..de67f9b9 100644 --- a/ios/Runner/Helper/Extensions.swift +++ b/ios/Runner/Helper/Extensions.swift @@ -18,6 +18,24 @@ extension String{ } } +extension Date{ + func toString(format:String) -> String{ + let df = DateFormatter() + df.dateFormat = format + return df.string(from: self) + } +} + +extension Dictionary{ + func merge(dict:[String:Any?]) -> [String:Any?]{ + var self_ = self as! [String:Any?] + dict.forEach { (kv) in + self_.updateValue(kv.value, forKey: kv.key) + } + return self_ + } +} + extension Bundle { func certificate(named name: String) -> SecCertificate { diff --git a/ios/Runner/Helper/FlutterConstants.swift b/ios/Runner/Helper/FlutterConstants.swift new file mode 100644 index 00000000..f1b3f098 --- /dev/null +++ b/ios/Runner/Helper/FlutterConstants.swift @@ -0,0 +1,36 @@ +// +// FlutterConstants.swift +// Runner +// +// Created by ZiKambrani on 22/12/2020. +// + +import UIKit + +class FlutterConstants{ + static var LOG_GEOFENCE_URL:String? + static var WIFI_CREDENTIALS_URL:String? + static var DEFAULT_HTTP_PARAMS:[String:Any?]? + + class func set(){ + + // (FiX) Take a start with FlutterMethodChannel (kikstart) + /* First call to flutter method is not returning the correct value (Always returning 'NSObject') then after it wroking fine and returning correct value*/ + FlutterText.with(key: "test") { (test) in + + flutterMethodChannel?.invokeMethod("getDefaultHttpParameters", arguments: nil){ (response) in + if let defaultHTTPParams = response as? [String:Any?]{ + DEFAULT_HTTP_PARAMS = defaultHTTPParams + } + + } + + flutterMethodChannel?.invokeMethod("getLogGeofenceFullUrl", arguments:nil){ (response) in + if let url = response as? String{ + LOG_GEOFENCE_URL = url + } + } + + } + } +} diff --git a/ios/Runner/Helper/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index c5eb7295..37687806 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -31,27 +31,59 @@ func dictionary(from:String) -> [String:Any]?{ } -func showNotification(identifier:String? = nil, title:String?, subtitle:String?, message:String?, sound:UNNotificationSound = UNNotificationSound.default){ - let notificationContent = UNMutableNotificationContent() - - if identifier != nil { notificationContent.categoryIdentifier = identifier! } - if title != nil { notificationContent.title = title! } - if subtitle != nil { notificationContent.body = message! } - if message != nil { notificationContent.subtitle = subtitle! } - - notificationContent.sound = UNNotificationSound.default - let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) - let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)", content: notificationContent, trigger: trigger) - UNUserNotificationCenter.current().add(request) { error in - if let error = error { - print("Error: \(error)") +let HmgLocalNotificationCategoryIdentifier = "hmg.local.notification" +func showNotification(identifier:String? = nil, title:String?, subtitle:String?, message:String?, sound:UNNotificationSound = UNNotificationSound.default, categoryIdentifier:String = HmgLocalNotificationCategoryIdentifier){ + DispatchQueue.main.async { + let notificationContent = UNMutableNotificationContent() + notificationContent.categoryIdentifier = categoryIdentifier + + if identifier != nil { notificationContent.categoryIdentifier = identifier! } + if title != nil { notificationContent.title = title! } + if subtitle != nil { notificationContent.body = message! } + if message != nil { notificationContent.subtitle = subtitle! } + + notificationContent.sound = UNNotificationSound.default + let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) + let request = UNNotificationRequest(identifier: "\(Date().timeIntervalSinceNow)", content: notificationContent, trigger: trigger) + + + UNUserNotificationCenter.current().add(request) { error in + if let error = error { + print("Error: \(error)") + } } } } +func appLanguageCode() -> Int{ + let lang = UserDefaults.standard.string(forKey: "language") ?? "ar" + return lang == "ar" ? 2 : 1 +} + +func userProfile() -> [String:Any?]?{ + var userProf = UserDefaults.standard.string(forKey: "flutter.imei-user-data") + if(userProf == nil){ + userProf = UserDefaults.standard.string(forKey: "flutter.user-profile") + } + return dictionary(from: userProf ?? "{}") +} + +fileprivate let defaultHTTPParams:[String : Any?] = [ + "ZipCode" : "966", + "VersionID" : 5.8, + "Channel" : 3, + "LanguageID" : appLanguageCode(), + "IPAdress" : "10.20.10.20", + "generalid" : "Cs2020@2016$2958", + "PatientOutSA" : 0, + "SessionID" : nil, + "isDentalAllowedBackend" : false, + "DeviceTypeID" : 2 +] -func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool,[String:Any]?)->Void)?){ - let json: [String: Any] = jsonBody +func httpPostRequest(urlString:String, jsonBody:[String:Any?], completion:((Bool,[String:Any]?)->Void)?){ + var json: [String: Any?] = jsonBody + json = json.merge(dict: defaultHTTPParams) let jsonData = try? JSONSerialization.data(withJSONObject: json) // create post request @@ -77,6 +109,8 @@ func httpPostRequest(urlString:String, jsonBody:[String:Any], completion:((Bool, completion?(false,responseJSON) } + }else{ + completion?(false,nil) } } diff --git a/ios/Runner/Helper/HMGPlatformBridge.swift b/ios/Runner/Helper/HMGPlatformBridge.swift index f897188c..f94f9b34 100644 --- a/ios/Runner/Helper/HMGPlatformBridge.swift +++ b/ios/Runner/Helper/HMGPlatformBridge.swift @@ -49,6 +49,9 @@ class HMGPlatformBridge{ print("") } + Timer.scheduledTimer(withTimeInterval: 0.1, repeats: false) { (timer) in + FlutterConstants.set() + } } diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index fb469165..47454d3e 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -129,8 +129,10 @@ extension HMG_Geofence : CLLocationManagerDelegate{ extension HMG_Geofence{ func handleEvent(for region: CLRegion!, transition:Transition, location:CLLocation?) { - notifyUser(forRegion: region, transition: transition, location: locationManager.location) - notifyServer(forRegion: region, transition: transition, location: locationManager.location) + if let userProfile = userProfile(){ + notifyUser(forRegion: region, transition: transition, location: locationManager.location, userProfile: userProfile) + notifyServer(forRegion: region, transition: transition, location: locationManager.location, userProfile: userProfile) + } } func geoZone(by id: String) -> GeoZoneModel? { @@ -144,20 +146,14 @@ extension HMG_Geofence{ } - func notifyUser(forRegion:CLRegion, transition:Transition, location:CLLocation?){ - if let zone = geoZone(by: forRegion.identifier){ - if UIApplication.shared.applicationState == .active { - mainViewController.showAlert(withTitle: transition.name(), message: zone.message()) - }else{ - - } + func notifyUser(forRegion:CLRegion, transition:Transition, location:CLLocation?, userProfile:[String:Any?]){ + if let patientId = userProfile["PatientID"] as? Int{ + } } - func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ - df.dateFormat = "MMM/dd/yyyy hh:mm:ss" - if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.user-profile"), - let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ + func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?, userProfile:[String:Any?]){ + if let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ let body:[String:Any] = [ @@ -165,22 +161,20 @@ extension HMG_Geofence{ "GeoType":transition.rawValue, "PatientID":patientId ] + + var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_LOGS") ?? [:] + var geo = (logs[forRegion.identifier] as? [String]) ?? [] let url = "https://hmgwebservices.com/Services/Patients.svc/REST/GeoF_InsertPatientFileInfo" httpPostRequest(urlString: url, jsonBody: body){ (status,json) in - let status_ = status ? "Notified" : "Not notified" + let status_ = status ? "Notified successfully:" : "Failed to notify:" showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) - var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "LOGS") ?? [:] - if var geo = logs[forRegion.identifier] as? [String]{ - geo.append("\(status_) at \(df.string(from: Date()))") - }else{ - logs.updateValue(["\(status_) at \(df.string(from: Date()))"], forKey: forRegion.identifier) - } - - UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "LOGS") + geo.append("\(status_) \(transition.name()) at \(Date().toString(format: "dd/MMM/yyy hh:mm:ss"))") + logs.updateValue( geo, forKey: forRegion.identifier) + UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "GEOFENCE_LOGS") } } } diff --git a/ios/Runner/WifiConnect/GoogleService-Info.plist b/ios/Runner/WifiConnect/GoogleService-Info.plist new file mode 100644 index 00000000..633037cb --- /dev/null +++ b/ios/Runner/WifiConnect/GoogleService-Info.plist @@ -0,0 +1,38 @@ + + + + + CLIENT_ID + 815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.815750722565-da8p56le8bd6apsbm9eft0jjl1rtpgkt + ANDROID_CLIENT_ID + 815750722565-m14h8mkosm7cnq6uh6rhqr54dn02d705.apps.googleusercontent.com + API_KEY + AIzaSyDiXnCO00li4V7Ioa2YZ_M4ECxRsu_P9tA + GCM_SENDER_ID + 815750722565 + PLIST_VERSION + 1 + BUNDLE_ID + com.HMG.HMG-Smartphone + PROJECT_ID + api-project-815750722565 + STORAGE_BUCKET + api-project-815750722565.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:815750722565:ios:328ec247a81a2ca23c186c + DATABASE_URL + https://api-project-815750722565.firebaseio.com + + \ No newline at end of file diff --git a/ios/gpx.gpx b/ios/gpx.gpx index 9cc26956..ed8e9be6 100644 --- a/ios/gpx.gpx +++ b/ios/gpx.gpx @@ -1 +1 @@ - Sverrir Sigmundarson Office Office Mahmoud Home Mahmoud Home Panorama Mall Panorama Mall Saudi Architects Crossing Saudi Architects Crossing Office Office \ No newline at end of file + Sverrir Sigmundarson 608.26 620.97 617.77 643.86 \ No newline at end of file diff --git a/key b/key new file mode 100644 index 00000000..15b9f5d1 Binary files /dev/null and b/key differ diff --git a/lib/config/config.dart b/lib/config/config.dart index cd7a5383..1ea16a37 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -1,36 +1,48 @@ import 'dart:io'; -import 'package:diplomaticquarterapp/core/service/geofencing/GeofencingServices.dart'; import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; const MAX_SMALL_SCREEN = 660; // PACKAGES and OFFERS -const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; +const EXA_CART_API_BASE_URL = 'http://10.200.101.75:9000'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; +const PACKAGES_CUSTOMER = '/api/customers'; +const PACKAGES_SHOPPING_CART = '/api/shopping_cart_items'; +const PACKAGES_ORDERS = '/api/orders'; const BASE_URL = 'https://uat.hmgwebservices.com/'; // const BASE_URL = 'https://hmgwebservices.com/'; -//const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; +// Pharmacy UAT URLs const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; const PHARMACY_BASE_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; -const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity'; +// Pharmacy Production URLs +// const BASE_PHARMACY_URL = 'https://mdlaboratories.com/exacartapi/api/'; +// const PHARMACY_BASE_URL = 'https://mdlaboratories.com/exacartapi/api/'; + +const PING_SERVICE = 'Services/Weather.svc/REST/CheckConnectivity'; const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; ///Geofencing const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; + +// Delivery Driver +const DRIVER_LOCATION = 'Services/Patients.svc/REST/PatientER_GetDriverLocation'; + //weather const WEATHER_INDICATOR = 'Services/Weather.svc/REST/GetCityInfo'; const GET_PRIVILEGE = 'Services/Patients.svc/REST/Service_Privilege'; +// Wifi Credentials +const WIFI_CREDENTIALS = + "Services/Patients.svc/Hmg_SMS_Get_By_ProjectID_And_PatientID"; ///Doctor const GET_MY_DOCTOR = @@ -55,7 +67,8 @@ const GET_PRESCRIPTION_REPORT_ENH = ///Lab Order const GET_Patient_LAB_ORDERS = 'Services/Patients.svc/REST/GetPatientLabOrders'; -const GET_Patient_LAB_SPECIAL_RESULT = 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; +const GET_Patient_LAB_SPECIAL_RESULT = + 'Services/Patients.svc/REST/GetPatientLabSpecialResults'; const SEND_LAB_RESULT_EMAIL = 'Services/Notifications.svc/REST/SendLabReportEmail'; const GET_Patient_LAB_RESULT = @@ -68,9 +81,11 @@ const GET_PATIENT_ORDERS = 'Services/Patients.svc/REST/GetPatientRadOrders'; const GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT = 'Services/Patients.svc/REST/GetPatientLabResultsByAppointmentNo'; -const GET_PATIENT_ORDERS_DETAILS = 'Services/Patients.svc/REST/Rad_UpdatePatientRadOrdersToRead'; +const GET_PATIENT_ORDERS_DETAILS = + 'Services/Patients.svc/REST/Rad_UpdatePatientRadOrdersToRead'; const GET_RAD_IMAGE_URL = 'Services/Patients.svc/Rest/GetRadImageURL'; -const SEND_RAD_REPORT_EMAIL = 'Services/Notifications.svc/REST/SendRadReportEmail'; +const SEND_RAD_REPORT_EMAIL = + 'Services/Notifications.svc/REST/SendRadReportEmail'; ///Feedback const SEND_FEEDBACK = 'Services/COCWS.svc/REST/InsertCOCItemInSPList'; @@ -79,17 +94,32 @@ const GET_PATIENT_AppointmentHistory = 'Services' '/Doctors.svc/REST/PateintHasAppoimentHistory'; ///VITAL SIGN -const GET_PATIENT_VITAL_SIGN = 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; +const GET_PATIENT_VITAL_SIGN = + 'Services/Doctors.svc/REST/Doctor_GetPatientVitalSign'; ///Er Nearest -const GET_NEAREST_HOSPITAL = 'Services/Patients.svc/REST/Patient_GetProjectAvgERWaitingTime'; +const GET_NEAREST_HOSPITAL = + 'Services/Patients.svc/REST/Patient_GetProjectAvgERWaitingTime'; + +///ED Online +const ER_GET_VISUAL_TRIAGE_QUESTIONS = + "services/Doctors.svc/REST/ER_GetVisualTriageQuestions"; +const ER_SAVE_TRIAGE_INFORMATION = + "services/Doctors.svc/REST/ER_SaveTriageInformation"; +const ER_GetPatientPaymentInformationForERClinic = + "services/Doctors.svc/REST/ER_GetPatientPaymentInformationForERClinic"; ///Er Nearest -const GET_AMBULANCE_REQUEST = 'Services/Patients.svc/REST/PatientER_RRT_GetAllTransportationMethod'; -const GET_PATIENT_ALL_PRES_ORDERS = 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; -const GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID = 'Services/Patients.svc/REST/PatientER_RRT_GetPickUpRequestByPresOrderID'; -const UPDATE_PRESS_ORDER = 'Services/Patients.svc/REST/PatientER_UpdatePresOrder'; -const INSERT_ER_INERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; +const GET_AMBULANCE_REQUEST = + 'Services/Patients.svc/REST/PatientER_RRT_GetAllTransportationMethod'; +const GET_PATIENT_ALL_PRES_ORDERS = + 'Services/Patients.svc/REST/PatientER_GetPatientAllPresOrders'; +const GET_PICK_UP_REQUEST_BY_PRES_ORDER_ID = + 'Services/Patients.svc/REST/PatientER_RRT_GetPickUpRequestByPresOrderID'; +const UPDATE_PRESS_ORDER = + 'Services/Patients.svc/REST/PatientER_UpdatePresOrder'; +const INSERT_ER_INERT_PRES_ORDER = + 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; ///FindUs const GET_FINDUS_REQUEST = 'Services/Lists.svc/REST/Get_HMG_Locations'; @@ -98,13 +128,15 @@ const GET_FINDUS_REQUEST = 'Services/Lists.svc/REST/Get_HMG_Locations'; const GET_LIVECHAT_REQUEST = 'Services/Patients.svc/REST/GetPatientICProjects'; ///babyInformation -const GET_BABYINFORMATION_REQUEST = 'Services/Community.svc/REST/GetBabyByUserID'; +const GET_BABYINFORMATION_REQUEST = + 'Services/Community.svc/REST/GetBabyByUserID'; ///Get Baby By User ID const GET_BABY_BY_USER_ID = 'Services/Community.svc/REST/GetBabyByUserID'; ///userInformation -const GET_USERINFORMATION_REQUEST = 'Services/Community.svc/REST/GetUserInformation_New'; +const GET_USERINFORMATION_REQUEST = + 'Services/Community.svc/REST/GetUserInformation_New'; ///Update email const UPDATE_PATENT_EMAIL = 'Services/Patients.svc/REST/UpdatePateintEmail'; @@ -126,17 +158,29 @@ const GET_TABLE_REQUEST = 'Services/Community.svc/REST/CreateVaccinationTable'; const GET_CITIES_REQUEST = 'Services/Lists.svc/REST/GetAllCities'; ///BloodDetails -const GET_BLOOD_REQUEST = 'services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails'; +const GET_BLOOD_REQUEST = + 'services/PatientVarification.svc/REST/BloodDonation_GetBloodGroupDetails'; + +const SAVE_BLOOD_REQUEST = + 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; + +const GET_BLOOD_AGREEMENT = + 'Services/PatientVarification.svc/REST/CheckUserAgreementForBloodDonation'; +const SAVE_BLOOD_AGREEMENT = + 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; ///Reports const REPORTS = 'Services/Doctors.svc/REST/GetPatientMedicalReportStatusInfo'; -const INSERT_REQUEST_FOR_MEDICAL_REPORT = 'Services/Doctors.svc/REST/InsertRequestForMedicalReport'; +const INSERT_REQUEST_FOR_MEDICAL_REPORT = + 'Services/Doctors.svc/REST/InsertRequestForMedicalReport'; const SEND_MEDICAL_REPORT_EMAIL = 'Services/Notifications.svc/REST/SendMedicalReportEmail'; ///Rate -const IS_LAST_APPOITMENT_RATED = 'Services/Doctors.svc/REST/IsLastAppoitmentRated'; -const GET_APPOINTMENT_DETAILS_BY_NO = 'Services/MobileNotifications.svc/REST/GetAppointmentDetailsByApptNo'; +const IS_LAST_APPOITMENT_RATED = + 'Services/Doctors.svc/REST/IsLastAppoitmentRated'; +const GET_APPOINTMENT_DETAILS_BY_NO = + 'Services/MobileNotifications.svc/REST/GetAppointmentDetailsByApptNo'; const GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID'; @@ -148,7 +192,8 @@ const GET_QR_PARKING = 'Services/SWP.svc/REST/GetQRParkingByID'; const GET_CLINICS_LIST_URL = "Services/lists.svc/REST/GetClinicCentralized"; //URL to get active appointment list -const GET_ACTIVE_APPOINTMENTS_LIST_URL = "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; +const GET_ACTIVE_APPOINTMENTS_LIST_URL = + "Services/Doctors.svc/Rest/Dr_GetAppointmentActiveNumber"; //URL to get projects list const GET_PROJECTS_LIST = 'Services/Lists.svc/REST/GetProject'; @@ -157,82 +202,119 @@ const GET_PROJECTS_LIST = 'Services/Lists.svc/REST/GetProject'; const GET_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/SearchDoctorsByTime"; //URL to dental doctors list -const GET_DENTAL_DOCTORS_LIST_URL = "Services/Doctors.svc/REST/Dental_DoctorChiefComplaintMapping"; +const GET_DENTAL_DOCTORS_LIST_URL = + "Services/Doctors.svc/REST/Dental_DoctorChiefComplaintMapping"; //URL to get doctor free slots const GET_DOCTOR_FREE_SLOTS = "Services/Doctors.svc/REST/GetDoctorFreeSlots"; //URL to insert appointment -const INSERT_SPECIFIC_APPOINTMENT = "Services/Doctors.svc/REST/InsertSpecificAppointment"; +const INSERT_SPECIFIC_APPOINTMENT = + "Services/Doctors.svc/REST/InsertSpecificAppointment"; //URL to get patient share -const GET_PATIENT_SHARE = "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNO"; +const GET_PATIENT_SHARE = + "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNO"; //URL to get patient appointment history -const GET_PATIENT_APPOINTMENT_HISTORY = "Services/Doctors.svc/REST/PateintHasAppoimentHistory"; +const GET_PATIENT_APPOINTMENT_HISTORY = + "Services/Doctors.svc/REST/PateintHasAppoimentHistory"; + +const SEND_REPORT_EYE_EMAIL = "Services/Notifications.svc/REST/SendGlassesPrescriptionEmail"; + +const SEND_CONTACT_LENS_PRESCRIPTION_EMAIL = "Services/Notifications.svc/REST/SendContactLensPrescriptionEmail"; //URL to get patient appointment curfew history -const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = "Services/Doctors.svc/REST/AppoimentHistoryForCurfew"; +const GET_PATIENT_APPOINTMENT_CURFEW_HISTORY = + "Services/Doctors.svc/REST/AppoimentHistoryForCurfew"; //URL to confirm appointment -const CONFIRM_APPOINTMENT = "Services/MobileNotifications.svc/REST/ConfirmAppointment"; +const CONFIRM_APPOINTMENT = + "Services/MobileNotifications.svc/REST/ConfirmAppointment"; -const INSERT_VIDA_REQUEST = "Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart"; +const INSERT_VIDA_REQUEST = + "Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart"; //URL to cancel appointment const CANCEL_APPOINTMENT = "Services/Doctors.svc/REST/CancelAppointment"; //URL get appointment QR -const GENERATE_QR_APPOINTMENT = "Services/Doctors.svc/REST/GenerateQRAppointmentNo"; +const GENERATE_QR_APPOINTMENT = + "Services/Doctors.svc/REST/GenerateQRAppointmentNo"; //URL send email appointment QR -const EMAIL_QR_APPOINTMENT = "Services/Notifications.svc/REST/sendEmailForOnLineCheckin"; +const EMAIL_QR_APPOINTMENT = + "Services/Notifications.svc/REST/sendEmailForOnLineCheckin"; //URL check payment status -const CHECK_PAYMENT_STATUS = "Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID"; +const CHECK_PAYMENT_STATUS = + "Services/PayFort_Serv.svc/REST/GetRequestStatusByRequestID"; //URL create advance payment const CREATE_ADVANCE_PAYMENT = "Services/Doctors.svc/REST/CreateAdvancePayment"; -const HIS_CREATE_ADVANCE_PAYMENT = "Services/Patients.svc/REST/HIS_CreateAdvancePayment"; +const HIS_CREATE_ADVANCE_PAYMENT = + "Services/Patients.svc/REST/HIS_CreateAdvancePayment"; -const ADD_ADVANCE_NUMBER_REQUEST = 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest'; +const ADD_ADVANCE_NUMBER_REQUEST = + 'Services/PayFort_Serv.svc/REST/AddAdvancedNumberRequest'; + +const IS_ALLOW_ASK_DOCTOR = + 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; +const GET_CALL_REQUEST_TYPE = + 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; +const ADD_VIDA_REQUEST = + 'Services/ER_VirtualCall.svc/REST/PatientER_VidaRequestInseart'; -const IS_ALLOW_ASK_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; -const GET_CALL_REQUEST_TYPE = 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; const SEND_CALL_REQUEST = 'Services/Doctors.svc/REST/InsertCallInfo'; -const GET_LIVECARE_CLINICS = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinics'; +const GET_LIVECARE_CLINICS = + 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinics'; -const GET_LIVECARE_SCHEDULE_CLINICS = 'Services/Doctors.svc/REST/PatientER_GetClinicsHaveSchedule'; +const GET_LIVECARE_SCHEDULE_CLINICS = + 'Services/Doctors.svc/REST/PatientER_GetClinicsHaveSchedule'; -const GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST = 'Services/Doctors.svc/REST/PatientER_GetDoctorByClinicID'; +const GET_LIVECARE_SCHEDULE_CLINIC_DOCTOR_LIST = + 'Services/Doctors.svc/REST/PatientER_GetDoctorByClinicID'; -const GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS = 'Services/Doctors.svc/REST/PatientER_GetDoctorFreeSlots'; +const GET_LIVECARE_SCHEDULE_DOCTOR_TIME_SLOTS = + 'Services/Doctors.svc/REST/PatientER_GetDoctorFreeSlots'; -const INSERT_LIVECARE_SCHEDULE_APPOINTMENT = 'Services/Doctors.svc/REST/InsertSpecificAppoitmentForSchedule'; +const INSERT_LIVECARE_SCHEDULE_APPOINTMENT = + 'Services/Doctors.svc/REST/InsertSpecificAppoitmentForSchedule'; -const GET_PATIENT_SHARE_LIVECARE = "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; +const GET_PATIENT_SHARE_LIVECARE = + "Services/Doctors.svc/REST/GetCheckinScreenAppointmentDetailsByAppointmentNOForLiveCare"; -const GET_LIVECARE_CLINIC_TIMING = 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; +const GET_LIVECARE_CLINIC_TIMING = + 'Services/ER_VirtualCall.svc/REST/PatientER_GetClinicsServiceTimingsSchedule'; -const GET_ER_APPOINTMENT_FEES = 'Services/DoctorApplication.svc/REST/GetERAppointmentFees'; +const GET_ER_APPOINTMENT_FEES = + 'Services/DoctorApplication.svc/REST/GetERAppointmentFees'; const GET_ER_APPOINTMENT_TIME = 'Services/ER_VirtualCall.svc/REST/GetRestTime'; -const ADD_NEW_CALL_FOR_PATIENT_ER = 'Services/DoctorApplication.svc/REST/NewCallForPatientER'; +const ADD_NEW_CALL_FOR_PATIENT_ER = + 'Services/DoctorApplication.svc/REST/NewCallForPatientER'; + +const GET_LIVECARE_HISTORY = + 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; +const CANCEL_LIVECARE_REQUEST = + 'Services/ER_VirtualCall.svc/REST/DeleteErRequest'; +const SEND_LIVECARE_INVOICE_EMAIL = + 'Services/Notifications.svc/REST/SendInvoiceForLiveCare'; -const GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtualHistory'; -const CANCEL_LIVECARE_REQUEST = 'Services/ER_VirtualCall.svc/REST/DeleteErRequest'; -const SEND_LIVECARE_INVOICE_EMAIL = 'Services/Notifications.svc/REST/SendInvoiceForLiveCare'; +const GET_USER_TERMS = 'Services/Patients.svc/REST/GetUserTermsAndConditions'; +const UPDATE_HEALTH_TERMS = + 'services/Patients.svc/REST/UpdatePateintHealthSummaryReport'; -const GET_USER_TERMS = '/Services/Patients.svc/REST/GetUserTermsAndConditions'; -const UPDATE_HEALTH_TERMS = '/services/Patients.svc/REST/UpdatePateintHealthSummaryReport'; +const GET_PATIENT_HEALTH_STATS = + 'Services/Patients.svc/REST/Med_GetTransactionsSts'; //URL to get medicine and pharmacies list const CHANNEL = 3; const GENERAL_ID = 'Cs2020@2016\$2958'; const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 5.8; +const VERSION_ID = 8.8; const SETUP_ID = '91877'; const LANGUAGE = 2; const PATIENT_OUT_SA = 0; @@ -241,12 +323,16 @@ const IS_DENTAL_ALLOWED_BACKEND = false; const PATIENT_TYPE = 1; const PATIENT_TYPE_ID = 1; var DEVICE_TOKEN = ""; +var IS_VOICE_COMMAND_CLOSED = false; +var IS_TEXT_COMPLETED = false; var DeviceTypeID = Platform.isIOS ? 1 : 2; -const LANGUAGE_ID = 1; +const LANGUAGE_ID = 2; const GET_PHARMCY_ITEMS = "Services/Lists.svc/REST/GetPharmcyItems_Region"; const GET_PHARMACY_LIST = "Services/Patients.svc/REST/GetPharmcyList"; -const GET_PAtIENTS_INSURANCE = "Services/Patients.svc/REST/Get_PatientInsuranceDetails"; -const GET_PAtIENTS_INSURANCE_UPDATED = "Services/Patients.svc/REST/PatientER_GetPatientInsuranceCardUpdateHistory"; +const GET_PAtIENTS_INSURANCE = + "Services/Patients.svc/REST/Get_PatientInsuranceDetails"; +const GET_PAtIENTS_INSURANCE_UPDATED = + "Services/Patients.svc/REST/PatientER_GetPatientInsuranceCardUpdateHistory"; const INSURANCE_DETAILS = "Services/Patients.svc/REST/Get_InsuranceCheckList"; const GET_PATIENT_INSURANCE_DETAILS = @@ -256,7 +342,8 @@ const UPLOAD_INSURANCE_CARD = const GET_VACCINES = "Services/Patients.svc/REST/GetDoneVaccinesByPatientID"; const GET_VACCINES_EMAIL = "Services/Notifications.svc/REST/SendVaccinesEmail"; -const GET_PAtIENTS_INSURANCE_APPROVALS = "Services/Patients.svc/REST/GetApprovalStatus"; +const GET_PAtIENTS_INSURANCE_APPROVALS = + "Services/Patients.svc/REST/GetApprovalStatus"; const SEARCH_BOT = 'HabibiChatBotApi/BotInterface/GetVoiceCommandResponse'; const GET_VACCINATIONS_ITEMS = "/Services/ERP.svc/REST/GET_VACCINATIONS_ITEMS"; @@ -266,38 +353,81 @@ const GET_PATIENT_SICK_LEAVE = 'Services/Patients.svc/REST/GetPatientSickLeave'; const SendSickLeaveEmail = 'Services/Notifications.svc/REST/SendSickLeaveEmail'; -const GET_PATIENT_AdVANCE_BALANCE_AMOUNT = 'Services/Patients.svc/REST/GetPatientAdvanceBalanceAmount'; -const GET_PATIENT_INFO_BY_ID = 'Services/Doctors.svc/REST/GetPatientInfoByPatientID'; -const GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER = 'Services/Patients.svc/REST/AP_GetPatientInfoByPatientIDandMobileNumber'; -const SEND_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/SendActivationCodeForAdvancePayment'; -const CHECK_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = 'Services/Authentication.svc/REST/CheckActivationCodeForAdvancePayment'; +const GET_PATIENT_AdVANCE_BALANCE_AMOUNT = + 'Services/Patients.svc/REST/GetPatientAdvanceBalanceAmount'; +const GET_PATIENT_INFO_BY_ID = + 'Services/Doctors.svc/REST/GetPatientInfoByPatientID'; +const GET_PATIENT_INFO_BY_ID_AND_MOBILE_NUMBER = + 'Services/Patients.svc/REST/AP_GetPatientInfoByPatientIDandMobileNumber'; +const SEND_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = + 'Services/Authentication.svc/REST/SendActivationCodeForAdvancePayment'; +const CHECK_ACTIVATION_CODE_FOR_ADVANCE_PAYMENT = + 'Services/Authentication.svc/REST/CheckActivationCodeForAdvancePayment'; -const GET_COVID_DRIVETHRU_PROJECT_LIST = 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; +const GET_COVID_DRIVETHRU_PROJECT_LIST = + 'Services/Doctors.svc/REST/COVID19_ProjectDriveThroughTestingCenter'; -const GET_COVID_DRIVETHRU_PAYMENT_INFO = 'Services/Doctors.svc/REST/COVID19_GetPatientPaymentInormation'; +const GET_COVID_DRIVETHRU_PAYMENT_INFO = + 'Services/Doctors.svc/REST/COVID19_GetPatientPaymentInormation'; -const GET_COVID_DRIVETHRU_FREE_SLOTS = 'Services/Doctors.svc/REST/COVID19_GetFreeSlots'; +const GET_COVID_DRIVETHRU_FREE_SLOTS = + 'Services/Doctors.svc/REST/COVID19_GetFreeSlots'; ///Smartwatch Integration Services -const GET_PATIENT_LAST_RECORD = 'Services/Patients.svc/REST/Med_GetPatientLastRecord'; +const GET_PATIENT_LAST_RECORD = + 'Services/Patients.svc/REST/Med_GetPatientLastRecord'; ///My Trackers -const GET_DIABETIC_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; -const GET_DIABTEC_RESULT = 'Services/Patients.svc/REST/Patient_GetDiabtecResults'; -const ADD_DIABTEC_RESULT = 'Services/Patients.svc/REST/Patient_AddDiabtecResult'; - -const GET_BLOOD_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; -const GET_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetBloodPressureResult'; -const ADD_BLOOD_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_AddBloodPressureResult'; - -const GET_WEIGHT_PRESSURE_RESULT_AVERAGE = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage'; -const GET_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult'; -const ADD_WEIGHT_PRESSURE_RESULT = 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult'; - -const ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID = 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID'; - -const GET_CALL_INFO_HOURS_RESULT = 'Services/Doctors.svc/REST/GetCallInfoHoursResult'; -const GET_CALL_REQUEST_TYPE_LOV = 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; +const GET_DIABETIC_RESULT_AVERAGE = + 'Services/Patients.svc/REST/Patient_GetDiabeticResultAverage'; +const GET_DIABTEC_RESULT = + 'Services/Patients.svc/REST/Patient_GetDiabtecResults'; +const ADD_DIABTEC_RESULT = + 'Services/Patients.svc/REST/Patient_AddDiabtecResult'; + +const GET_BLOOD_PRESSURE_RESULT_AVERAGE = + 'Services/Patients.svc/REST/Patient_GetBloodPressureResultAverage'; +const GET_BLOOD_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_GetBloodPressureResult'; +const ADD_BLOOD_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_AddBloodPressureResult'; + +const GET_WEIGHT_PRESSURE_RESULT_AVERAGE = + 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResultAverage'; +const GET_WEIGHT_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_GetWeightMeasurementResult'; +const ADD_WEIGHT_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_AddWeightMeasurementResult'; + +const ADD_ACTIVE_PRESCRIPTIONS_REPORT_BY_PATIENT_ID = + 'Services/Patients.svc/Rest/GetActivePrescriptionReportByPatientID'; + +const GET_CALL_INFO_HOURS_RESULT = + 'Services/Doctors.svc/REST/GetCallInfoHoursResult'; +const GET_CALL_REQUEST_TYPE_LOV = + 'Services/Doctors.svc/REST/GetCallRequestType_LOV'; + +const UPDATE_DIABETIC_RESULT = + 'Services/Patients.svc/REST/Patient_UpdateDiabeticResult'; + +const SEND_AVERAGE_BLOOD_SUGAR_REPORT = + 'Services/Notifications.svc/REST/SendAverageBloodSugarReport'; +const DEACTIVATE_DIABETIC_STATUS = + 'services/Patients.svc/REST/Patient_DeactivateDiabeticStatus'; +const DEACTIVATE_BLOOD_PRESSURES_STATUS = + 'services/Patients.svc/REST/Patient_DeactivateBloodPressureStatus'; + +const UPDATE_BLOOD_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_UpdateBloodPressureResult'; +const SEND_AVERAGE_BLOOD_WEIGHT_REPORT = + 'Services/Notifications.svc/REST/SendAverageBodyWeightReport'; +const SEND_AVERAGE_BLOOD_PRESSURE_REPORT = + 'Services/Notifications.svc/REST/SendAverageBloodPressureReport'; + +const UPDATE_WEIGHT_PRESSURE_RESULT = + 'Services/Patients.svc/REST/Patient_UpdateWeightMeasurementResult'; +const DEACTIVATE_WEIGHT_PRESSURE_RESULT = + 'services/Patients.svc/REST/Patient_DeactivateWeightMeasurementStatus'; const GET_DOCTOR_RESPONSE = 'Services/Patients.svc/REST/GetDoctorResponse'; const UPDATE_READ_STATUS = 'Services/Patients.svc/REST/UpdateReadStatus'; const INSERT_CALL_INFO = 'Services/Doctors.svc/REST/InsertCallInfo'; @@ -305,43 +435,64 @@ const INSERT_CALL_INFO = 'Services/Doctors.svc/REST/InsertCallInfo'; const GET_PATIENT_ALLERGIES = 'Services/Patients.svc/REST/GetPatientAllergies'; // H2O -const H2O_GET_USER_PROGRESS = "Services/H2ORemainder.svc/REST/H2O_GetUserProgress"; -const H2O_INSERT_USER_ACTIVITY = "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity"; +const H2O_GET_USER_PROGRESS = + "Services/H2ORemainder.svc/REST/H2O_GetUserProgress"; +const H2O_INSERT_USER_ACTIVITY = + "Services/H2ORemainder.svc/REST/H2O_InsertUserActivity"; +const H2O_GET_USER_DETAIL = + "Services/H2ORemainder.svc/REST/H2O_GetUserDetails_New"; +const H2O_UPDATE_USER_DETAIL = + "Services/H2ORemainder.svc/REST/H2O_UpdateUserDetails_New"; +const H2O_UNDO_USER_ACTIVITY = + "Services/H2ORemainder.svc/REST/H2o_UndoUserActivity"; //E_Referral Services -const GET_ALL_RELATIONSHIP_TYPES = "Services/Patients.svc/REST/GetAllRelationshipTypes"; -const SEND_ACTIVATION_CODE_FOR_E_REFERRAL = 'Services/Authentication.svc/REST/SendActivationCodeForEReferral'; -const CHECK_ACTIVATION_CODE_FOR_E_REFERRAL = 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral'; +const GET_ALL_RELATIONSHIP_TYPES = + "Services/Patients.svc/REST/GetAllRelationshipTypes"; +const SEND_ACTIVATION_CODE_FOR_E_REFERRAL = + 'Services/Authentication.svc/REST/SendActivationCodeForEReferral'; +const CHECK_ACTIVATION_CODE_FOR_E_REFERRAL = + 'Services/Authentication.svc/REST/CheckActivationCodeForEReferral'; const GET_ALL_CITIES = 'services/Lists.svc/rest/GetAllCities'; const CREATE_E_REFERRAL = "Services/Patients.svc/REST/CreateEReferral"; const GET_E_REFERRALS = "Services/Patients.svc/REST/GetEReferrals"; +// Encillary Orders + +const GET_ANCILLARY_ORDERS = + 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderList'; + +const GET_ANCILLARY_ORDERS_DETAILS = + 'Services/Doctors.svc/REST/GetOnlineAncillaryOrderProcList'; + //Pharmacy wishlist // const GET_WISHLIST = "http://swd-pharapp-01:7200/api/shopping_cart_items/"; // pharmacy -const PHARMACY_VERIFY_CUSTOMER = "epharmacy/api/VerifyCustomer"; -const PHARMACY_GET_COUNTRY = "epharmacy/api/countries"; +const PHARMACY_AUTORZIE_CUSTOMER = "AutorizeCustomer"; +const PHARMACY_VERIFY_CUSTOMER = "VerifyCustomer"; +const PHARMACY_GET_COUNTRY = "countries"; const PHARMACY_CREATE_CUSTOMER = "epharmacy/api/CreateCustomer"; -const GET_PHARMACY_BANNER = "epharmacy/api/promotionbanners"; -const GET_PHARMACY_TOP_MANUFACTURER = "epharmacy/api/topmanufacturer"; -const GET_PHARMACY_BEST_SELLER_PRODUCT = "epharmacy/api/bestsellerproducts"; -const GET_PHARMACY_PRODUCTs_BY_IDS = "epharmacy/api/productsbyids/"; -const GET_CUSTOMERS_ADDRESSES = "epharmacy/api/Customers/"; +const GET_PHARMACY_BANNER = "promotionbanners"; +const GET_PHARMACY_TOP_MANUFACTURER = "topmanufacturer"; +const GET_PHARMACY_BEST_SELLER_PRODUCT = "bestsellerproducts"; +const GET_PHARMACY_PRODUCTs_BY_IDS = "productsbyids/"; +const GET_PHARMACY_PRODUCTs_BY_SKU = "productbysku/"; +const GET_CUSTOMERS_ADDRESSES = "Customers/"; +const SUBSCRIBE_PRODUCT = "subscribe?"; const GET_ORDER = "orders?"; -const GET_ORDER_DETAILS = "epharmacy/api/orders/"; +const GET_ORDER_DETAILS = "orders/"; const ADD_CUSTOMER_ADDRESS = "epharmacy/api/addcustomeraddress"; const EDIT_CUSTOMER_ADDRESS = "epharmacy/api/editcustomeraddress"; const DELETE_CUSTOMER_ADDRESS = "epharmacy/api/deletecustomeraddress"; const GET_ADDRESS = "Customers/"; const GET_Cancel_ORDER = "cancelorder/"; const WRITE_REVIEW = "Content-Type" + "text/plain; charset=utf-8"; -const GET_SHOPPING_CART = "epharmacy/api/shopping_cart_items/"; -const GET_SHIPPING_OPTIONS = "epharmacy/api/get_shipping_option/"; -const DELETE_SHOPPING_CART = "epharmacy/api/delete_shopping_cart_items/"; -const DELETE_SHOPPING_CART_ALL = - "epharmacy/api/delete_shopping_cart_item_by_customer/"; -const ORDER_SHOPPING_CART = "epharmacy/api/orders"; +const GET_SHOPPING_CART = "shopping_cart_items/"; +const GET_SHIPPING_OPTIONS = "get_shipping_option/"; +const DELETE_SHOPPING_CART = "delete_shopping_cart_items/"; +const DELETE_SHOPPING_CART_ALL = "delete_shopping_cart_item_by_customer/"; +const ORDER_SHOPPING_CART = "orders"; const GET_LACUM_ACCOUNT_INFORMATION = "Services/Patients.svc/REST/GetLakumAccountInformation"; const GET_LACUM_GROUP_INFORMATION = @@ -356,13 +507,22 @@ const TRANSFER_YAHALA_LOYALITY_POINTS = "Services/Patients.svc/REST/TransferYaHalaLoyaltyPoints"; const LAKUM_GET_USER_TERMS_AND_CONDITIONS = "Services/ERP.svc/REST/GetUserTermsAndConditionsForEPharmcy"; +const PRESCRIPTION = 'Services/Patients.svc/REST/GetPrescriptionApptList'; +const GET_RECOMMENDED_PRODUCT = 'alsoProduct/'; +const GET_MOST_VIEWED_PRODUCTS ="mostview?"; +const GET_NEW_PRODUCTS = "newproducts?"; // Home Health Care -const HHC_GET_ALL_SERVICES = "Services/Patients.svc/REST/PatientER_HHC_GetAllServices"; -const HHC_GET_ALL_CMC_SERVICES = "Services/Patients.svc/REST/PatientER_CMC_GetAllServices"; -const PATIENT_ER_UPDATE_PRES_ORDER = "Services/Patients.svc/REST/PatientER_UpdatePresOrder"; -const GET_ORDER_DETAIL_BY_ID = "Services/Patients.svc/REST/PatientER_HHC_GetTransactionsForOrder"; -const GET_CMC_ORDER_DETAIL_BY_ID = "Services/Patients.svc/REST/PatientER_CMC_GetTransactionsForOrder"; +const HHC_GET_ALL_SERVICES = + "Services/Patients.svc/REST/PatientER_HHC_GetAllServices"; +const HHC_GET_ALL_CMC_SERVICES = + "Services/Patients.svc/REST/PatientER_CMC_GetAllServices"; +const PATIENT_ER_UPDATE_PRES_ORDER = + "Services/Patients.svc/REST/PatientER_UpdatePresOrder"; +const GET_ORDER_DETAIL_BY_ID = + "Services/Patients.svc/REST/PatientER_HHC_GetTransactionsForOrder"; +const GET_CMC_ORDER_DETAIL_BY_ID = + "Services/Patients.svc/REST/PatientER_CMC_GetTransactionsForOrder"; const GET_CHECK_UP_ITEMS = "Services/Patients.svc/REST/GetCheckUpItems"; const PUSH_NOTIFICATION_GET_ALL_NOTIFICATIONS = 'Services/MobileNotifications.svc/REST/PushNotification_GetAllNotifications'; @@ -373,6 +533,10 @@ const GET_PATIENT_ALL_PRES_ORD = const PATIENT_ER_INSERT_PRES_ORDER = 'Services/Patients.svc/REST/PatientER_InsertPresOrder'; const PHARMACY_MAKE_REVIEW = 'epharmacy/api/insertreviews'; +const BLOOD_DONATION_REGISTER_BLOOD_TYPE = + 'Services/PatientVarification.svc/REST/BloodDonation_RegisterBloodType'; +const ADD_USER_AGREEMENT_FOR_BLOOD_DONATION = + 'Services/PatientVarification.svc/REST/AddUserAgreementForBloodDonation'; //Pharmacy wishlist const GET_WISHLIST = "shopping_cart_items/"; @@ -383,42 +547,44 @@ const GET_TOP_BRANDS = "topmanufacturer?page=1&limit=8"; const GET_PRODUCT_DETAIL = "products/"; const GET_LOCATION = "Services/Patients.svc/REST/GetPharmcyListBySKU"; const GET_SPECIFICATION = "productspecification/"; -const GET_BRAND_ITEMS = "products?ManufacturerId="; +const GET_BRAND_ITEMS = "products"; // External API -const ADD_ADDRESS_INFO = - "https://mdlaboratories.com/exacartapi/api/addcustomeraddress"; -const GET_CUSTOMER_ADDRESSES = - "https://mdlaboratories.com/exacartapi/api/Customers/"; -const GET_CUSTOMER_INFO = - "https://mdlaboratories.com/exacartapi/api/VerifyCustomer"; +const ADD_ADDRESS_INFO = "addcustomeraddress"; +const GET_CUSTOMER_ADDRESSES = "Customers/"; +const GET_CUSTOMER_INFO = "VerifyCustomer"; //Pharmacy const GET_PHARMACY_CATEGORISE = - 'epharmacy/api/categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; -const GET_OFFERS_CATEGORISE = 'epharmacy/api/discountcategories'; -const GET_OFFERS_PRODUCTS = 'epharmacy/api/offerproducts/'; + 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id=0'; +const GET_OFFERS_CATEGORISE = 'discountcategories'; +const GET_OFFERS_PRODUCTS = 'offerproducts/'; const GET_CATEGORISE_PARENT = - 'epharmacy/api/categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; -const GET_PARENT_PRODUCTS = 'epharmacy/api/products?categoryid='; + 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; +const GET_PARENT_PRODUCTS = 'products?categoryid='; const GET_SUB_CATEGORISE = - 'epharmacy/api/categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; -const GET_SUB_PRODUCTS = 'epharmacy/api/products?categoryid='; + 'categories?fields=id,name,namen,description,image,localized_names,display_order,parent_category_id,is_leaf&parent_id='; +const GET_SUB_PRODUCTS = 'products?categoryid='; const GET_FINAL_PRODUCTS = - 'epharmacy/api/products?fields=id,reviews,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&CategoryId='; - + 'products?fields=id,reviews,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&CategoryId='; +const GET_CLINIC_CATEGORY = 'Services/Doctors.svc/REST/DP_GetClinicCategory'; +const GET_DISEASE_BY_CLINIC_ID = + 'Services/Doctors.svc/REST/DP_GetDiseasesByClinicID'; +const SEARCH_DOCTOR_BY_TIME = 'Services/Doctors.svc/REST/SearchDoctorsByTime'; const TIMER_MIN = 10; const GOOGLE_API_KEY = "AIzaSyCmevVlr2Bh-c8W1VUzo8gt8JRY7n5PANw"; -const GET_BRANDS_LIST = 'epharmacy/api/categoryManufacturer?categoryids='; +const GET_BRANDS_LIST = 'categoryManufacturer?categoryids='; const GET_SEARCH_PRODUCTS = - 'epharmacy/api/searchproducts?fields=id,discount_ids,reviews,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&search_key='; + 'searchproducts?fields=id,discount_ids,reviews,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage&search_key='; + +const SCAN_QR_CODE = 'productbysku/'; -const SCAN_QR_CODE = 'epharmacy/api/productbysku/'; +const FILTERED_PRODUCTS = 'products?categoryids='; class AppGlobal { static var context; @@ -427,7 +593,6 @@ class AppGlobal { Request getPublicRequest() { Request request = new Request(); - request.VersionID = 5.6; //3.6; request.Channel = 3; request.IPAdress = "10.20.10.20"; request.generalid = 'Cs2020@2016\$2958'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 387dbcb1..2987e621a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -2,23 +2,45 @@ // Used for Native through Platform Method Channel // --------- - -- - - - - - - - - ---------------- const Map platformLocalizedValues = { - "errorConnectingHmgNetwork": {"en": "Sorry you are not connecting to HMG network", "ar": "نعتذر لست متصل في شكبة مستشفى د.سليمان الحبيب"}, - "successConnectingHmgNetwork": {"en": "You connected to HMG network successfully, you can access the app", "ar": "تم التصال بشبكة د.سليمان الحبيب بنجاح, تستطيع الان استخدام تطبيق الحبيب"}, + "errorConnectingHmgNetwork": { + "en": "Sorry you are not connecting to HMG network", + "ar": "نعتذر لست متصل في شكبة مستشفى د.سليمان الحبيب" + }, + "successConnectingHmgNetwork": { + "en": "You connected to HMG network successfully, you can access the app", + "ar": + "تم التصال بشبكة د.سليمان الحبيب بنجاح, تستطيع الان استخدام تطبيق الحبيب" + }, "failedConnectingHmgNetwork": { - "en": "Sorry the connection to HMG network had been failed, make sure you are in range of HMG network", - "ar": "نعتذر لقد فشل الاتصال بشبكة د.سليمان الحبيب, تاكد من وجودك داخل نطاق الشبكة" + "en": + "Sorry the connection to HMG network had been failed, make sure you are in range of HMG network", + "ar": + "نعتذر لقد فشل الاتصال بشبكة د.سليمان الحبيب, تاكد من وجودك داخل نطاق الشبكة" + }, + "alreadyConnectedHmgNetwork": { + "en": " You already connected to HMG network to access Alhabib app", + "ar": "انت متصل مسبقاً بالشبكة تستطيع استخدام تطبيق الحبيب" + }, + "somethingWentWrong": { + "en": "Sorry something went wrong please try again later", + "ar": "نعتذر لخدمتكم يرجى المحاولة لاحقا" }, - "alreadyConnectedHmgNetwork": {"en": " You already connected to HMG network to access Alhabib app", "ar": "انت متصل مسبقاً بالشبكة تستطيع استخدام تطبيق الحبيب"}, - "somethingWentWrong": {"en": "Sorry something went wrong please try again later", "ar": "نعتذر لخدمتكم يرجى المحاولة لاحقا"}, "enablingWifi": {"en": "Enabling wifi...", "ar": "Enabling wifi..."}, - "connectedHmgNetworkWithInternet": {"en": "Successfully connected to the HMG network to access internet", "ar": "Successfully connected to the HMG network to access internet"}, + "connectedHmgNetworkWithInternet": { + "en": "Successfully connected to the HMG network to access internet", + "ar": "Successfully connected to the HMG network to access internet" + }, "connectedToHmgNetworkWithNoInternet": { - "en": "Successfully connected to the HMG network but it have no internet access", - "ar": "Successfully connected to the HMG network but it have no internet access" + "en": + "Successfully connected to the HMG network but it have no internet access", + "ar": + "Successfully connected to the HMG network but it have no internet access" }, "notConnectedToHmgNetworkSecurityIssue": { - "en": "We are not able to connect you to HMG network due to security reasons", - "ar": "We are not able to connect you to HMG network due to security reasons" + "en": + "We are not able to connect you to HMG network due to security reasons", + "ar": + "We are not able to connect you to HMG network due to security reasons" } }; @@ -45,7 +67,10 @@ const Map localizedValues = { 'clinicName': {'en': 'Clinic Name', 'ar': 'اسم العيادة'}, 'doctorName': {'en': 'Doctor Name', 'ar': 'إسم الطبيب'}, 'nearestAppo': {'en': 'Nearest appointment', 'ar': 'أقرب موعد'}, - 'searchByDocText': {'en': 'Type the name of the doctor to help you find him', 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه'}, + 'searchByDocText': { + 'en': 'Type the name of the doctor to help you find him', + 'ar': 'اكتب اسم الطبيب لمساعدتك في العثور عليه' + }, 'enterDocName': {'en': 'Enter Doctor name', 'ar': 'أدخل إسم الطبيب'}, 'search': {'en': 'Search', 'ar': 'بحث'}, 'bookNow': {'en': 'BOOK NOW', 'ar': 'احجز الآن'}, @@ -55,11 +80,17 @@ const Map localizedValues = { 'gender': {'en': 'Gender', 'ar': 'الجنس'}, 'nationality': {'en': 'Nationality', 'ar': 'الجنسية'}, 'docQualifications': {'en': 'Doctor Qualifications', 'ar': 'مؤهلات الطبيب'}, - 'confirmAppoHeading': {'en': 'Kindly confirm your Appointment', 'ar': 'يرجى تأكيد موعدك'}, + 'confirmAppoHeading': { + 'en': 'Kindly confirm your Appointment', + 'ar': 'يرجى تأكيد موعدك' + }, 'patientInfo': {'en': 'Patient Information', 'ar': 'معلومات المريض'}, 'bookSuccess': {'en': 'Book Success', 'ar': 'تم حجز الموعد بنجاح'}, 'patientShare': {'en': 'Patient Share', 'ar': 'المبلغ المستحق'}, - 'patientShareWithTax': {'en': 'Patient Share with Tax', 'ar': 'المبلغ الإجمالي المستحق'}, + 'patientShareWithTax': { + 'en': 'Patient Share with Tax', + 'ar': 'المبلغ الإجمالي المستحق' + }, 'confirmAppo': {'en': 'Confirm Appointment', 'ar': 'تأكيد الموعد'}, 'confirm': {'en': 'Confirm', 'ar': 'تأكيد'}, 'confirmLiveCare': {'en': 'Confirm LiveCare', 'ar': 'تأكيد لايف كير'}, @@ -81,18 +112,41 @@ const Map localizedValues = { 'ar': 'هل أنت متأكد أنك تريد إلغاء هذا الموعد؟' }, - 'upcoming-noAction': {'en': 'No Action Required', 'ar': 'لا يوجد إجراء مطلوب'}, - 'upcoming-confirm': {'en': 'Please confirm the appointment to avoid cancellation', 'ar': 'يرجى تأكيد الموعد لتفادي الإلغاء'}, + 'upcoming-noAction': { + 'en': 'No Action Required', + 'ar': 'لا يوجد إجراء مطلوب' + }, + 'upcoming-confirm': { + 'en': 'Please confirm the appointment to avoid cancellation', + 'ar': 'يرجى تأكيد الموعد لتفادي الإلغاء' + }, "book-success-confirm-more-24-1-2": { "en": "The online payment process will be available 24 hours before the appointment.", "ar": "- عملية الدفع الالكتروني ستكون متاحة قبل الموعد ب 24 ساعة." }, - 'upcoming-payment-pending': {'en': 'Online Payment will be Activated before 24 Hours of Appointment Time', 'ar': 'سيتم تفعيل خدمة الدفع الالكتروني قبل 24 ساعة من موعد الحجز'}, - 'upcoming-payment-now': {'en': 'Pay Online now to avoid long waiting queue', 'ar': 'ادفع الآن لتفادي الانتظار'}, - 'upcoming-QR': {'en': 'Use the QR Code to Check-In in hospital', 'ar': 'استخدم الرمز لتسجيل الحضور في المستشفى'}, - 'upcoming-virtual': {'en': 'This is a virtual appointment, Please adhere to the instructions for a seamless experience.', 'ar': 'هذا موعد اتصال مرئي عن بعد ، يرجى اتباع تعليمات الخدمة.'}, - 'upcoming-livecare': {'en': 'This is a LiveCare appointment', 'ar': 'هذا موعد لايف كير'}, + 'upcoming-payment-pending': { + 'en': + 'Online Payment will be Activated before 24 Hours of Appointment Time', + 'ar': 'سيتم تفعيل خدمة الدفع الالكتروني قبل 24 ساعة من موعد الحجز' + }, + 'upcoming-payment-now': { + 'en': 'Pay Online now to avoid long waiting queue', + 'ar': 'ادفع الآن لتفادي الانتظار' + }, + 'upcoming-QR': { + 'en': 'Use the QR Code to Check-In in hospital', + 'ar': 'استخدم الرمز لتسجيل الحضور في المستشفى' + }, + 'upcoming-virtual': { + 'en': + 'This is a virtual appointment, Please adhere to the instructions for a seamless experience.', + 'ar': 'هذا موعد اتصال مرئي عن بعد ، يرجى اتباع تعليمات الخدمة.' + }, + 'upcoming-livecare': { + 'en': 'This is a LiveCare appointment', + 'ar': 'هذا موعد لايف كير' + }, 'upcoming-details': {'en': 'More Details', 'ar': 'المزيد'}, 'reschedule': {'en': 'Reschedule', 'ar': 'إعادة جدولة'}, 'raise': {'en': 'Raise', 'ar': 'رفع'}, @@ -177,6 +231,7 @@ const Map localizedValues = { 'ar': 'ابحث عن الدواء هنا' }, 'description': {'en': 'Description', 'ar': 'الوصف'}, + 'howToUse': {'en': 'How to Use', 'ar': 'طريقة الأستخدام'}, 'price': {'en': 'Price', 'ar': 'السعر'}, 'youCanFindItIn': {'en': 'You can find it in', 'ar': 'يمكنكة ان تجده في'}, 'pleaseEnterMedicineName': { @@ -238,10 +293,15 @@ const Map localizedValues = { 'ar': 'مسح فوق رمز الاستجابة السريعة للتحقق في الجهاز في المستشفى' }, "sendEmail": {"en": "Send Email", "ar": "ارسال نسخة"}, + "success": {"en": "Done successfully", "ar": "تم تنفذ الطلب بنجاح"}, "EmailSentSuccessfully": { "en": "Email Sent Successfully", "ar": "تم إرسال البريد الإلكتروني بنجاح" }, + "EmailSentError": { + "en": "Error Sending Email", + "ar": "خطأ في إرسال البريد الإلكتروني" + }, "close": {"en": "Close", "ar": "مغلق"}, "booked": {"en": "Booked", "ar": "محجوز"}, "confirmed": {"en": "Confirmed", "ar": "مؤكد"}, @@ -288,7 +348,7 @@ const Map localizedValues = { }, "ksa": {"en": "KSA", "ar": "السعودية"}, "dubai": {"en": "Dubai", "ar": "دبي"}, - "enter-email": {"en": "Enter Email", "ar": "ادخل البريد الالكتروني"}, + "enter-email": {"en": "Please Enter Email", "ar": "ادخل البريد الالكتروني"}, "family": {"en": "My Family", "ar": "عائلتي"}, "family-title": {"en": "My Family Files", "ar": "ملفات العائلة"}, "myFamily": {"en": "My Family", "ar": "ملفات العائلة"}, @@ -305,8 +365,9 @@ const Map localizedValues = { 'painScale': {'en': 'Pain Scale', 'ar': 'مقياس الألم'}, 'weight': {'en': 'Weight', 'ar': 'الوزن'}, 'height': {'en': 'Height', 'ar': 'الطول'}, - 'heart': {'en': 'Heart', 'ar': 'قلب'}, - + 'heart': {'en': 'Heart Rate', 'ar': 'معدل النبض'}, + "heightUnit": {"en": "height unit", "ar": "وحدة الطول"}, + "weightUnit": {"en": "Weight Unit", "ar": "وحدة الوزن"}, "request": {"en": "Request", "ar": "طلبات الاضافة"}, "member-name": {"en": "Member Name", "ar": "اسم العضو"}, "switch-login": {"en": "Switch User", "ar": "تغير المستخدم"}, @@ -335,35 +396,70 @@ const Map localizedValues = { "seeDetails": {"en": "SEE DETAILS", "ar": "منافعك التامينية"}, "insuranceCards": {"en": "Insurance Cards", "ar": "بطاقات التأمين"}, "requestType": {"en": "Request Type", "ar": "نوع الاستفسار"}, - "register-info-family": {"en": "How would like to add the new member?", "ar": "كيف ترغب باضافة العضو الجديد؟"}, - "remove-family-member": {"en": "Remove this member?", "ar": "إزالة ملف العضو؟"}, + "register-info-family": { + "en": "How would like to add the new member?", + "ar": "كيف ترغب باضافة العضو الجديد؟" + }, + "remove-family-member": { + "en": "Remove this member?", + "ar": "إزالة ملف العضو؟" + }, "MyMedicalFile": {"en": "My Medical File", 'ar': 'ملف الطبي الالكتروني'}, - "myMedicalFileSubTitle": {"en": "All your medical records", 'ar': 'جميع سجلاتك الطبية'}, + "myMedicalFileSubTitle": { + "en": "All your medical records", + 'ar': 'جميع سجلاتك الطبية' + }, "viewMore": {"en": "View More", 'ar': 'عرض المزيد'}, - "homeHealthCareService": {"en": "Home Health Care Service", 'ar': 'الرعاية الصحية المنزلية'}, + "homeHealthCareService": { + "en": "Home Health Care Service", + 'ar': 'الرعاية الصحية المنزلية' + }, "OnlinePharmacy": {"en": "Online Pharmacy", 'ar': 'صيدليات الحبيب'}, "EmergencyService": {"en": "Emergency Service", 'ar': 'الفحص الطبي الشامل'}, - "OnlinePaymentService": {"en": "Online Payment Service", 'ar': 'خدمة الدفع الإلكتدوني'}, - "OffersAndPackages": {"en": "Online transfer request", 'ar': 'طلب التحويل الالكتروني'}, - "ComprehensiveMedicalCheckup": {"en": "Comprehensive Medical Check up", 'ar': 'فحص طبي شامل'}, + "OnlinePaymentService": { + "en": "Online Payment Service", + 'ar': 'خدمة الدفع الإلكتدوني' + }, + "OffersAndPackages": { + "en": "Online transfer request", + 'ar': 'طلب التحويل الالكتروني' + }, + "ComprehensiveMedicalCheckup": { + "en": "Comprehensive Medical Check up", + 'ar': 'فحص طبي شامل' + }, "HMGService": {"en": "HMG Service", 'ar': 'جميع خدمات الحبيب'}, - "ViewAllHabibMedicalService": {"en": "View All Habib Medical Service", 'ar': 'عرض خدمات الحبيب الطبية'}, + "ViewAllHabibMedicalService": { + "en": "View All Habib Medical Service", + 'ar': 'عرض خدمات الحبيب الطبية' + }, "viewAll": {"en": "View All", 'ar': 'عرض الكل'}, "view": {"en": "View", 'ar': 'عرض'}, "ContactUs": {"en": "Contact Us", 'ar': 'الوصول إلينا'}, - "ViewAllWaysReachUs": {"en": "View All Ways Reach Us", 'ar': 'جميع طرق الاتصال بنا'}, + "ViewAllWaysReachUs": { + "en": "View All Ways Reach Us", + 'ar': 'جميع طرق الاتصال بنا' + }, "medicalProfile": {"en": "Medical Profile", 'ar': 'الملف الطبي'}, "consultation": {"en": "Consultation", "ar": "استشارة"}, "logs": {"en": "Logs", "ar": "السجلات"}, "textToSpeech": {"en": "How May I Help You?", "ar": "كيف يمكنني مساعدتك؟"}, "locationDialogMessage": { - "en": "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", - "ar": "السماح لتطبيق مجموعة الحبيب الطبية بالوصول إلى موقعك سيساعدك في إظهار المستشفيات وفقًا للأقرب إليك." + "en": + "Allow the HMG app to access your location will assist you in showing the hospitals according to the nearest to you.", + "ar": + "السماح لتطبيق مجموعة الحبيب الطبية بالوصول إلى موقعك سيساعدك في إظهار المستشفيات وفقًا للأقرب إليك." }, - "user-view-requester": {"en": "User Wants To View Your Medical File", "ar": "أشخاص يرغبون الاطلاع على ملفك الطبي"}, - "user-view": {"en": "User Can View Your Medical File", "ar": "أشخاص يمكنهم الاطلاع على ملفك الطبي"}, + "user-view-requester": { + "en": "User Wants To View Your Medical File", + "ar": "أشخاص يرغبون الاطلاع على ملفك الطبي" + }, + "user-view": { + "en": "User Can View Your Medical File", + "ar": "أشخاص يمكنهم الاطلاع على ملفك الطبي" + }, "parking": {"en": "Parking", "ar": "مواقف"}, "alhabiServices": {"en": "HMG Service", "ar": "خدمات الحبيب"}, @@ -450,6 +546,9 @@ const Map localizedValues = { "History": {"en": "History", "ar": "السجلات"}, "OrderNo": {"en": "Order No", "ar": "رقم الطلب"}, "OrderDetails": {"en": "Order Details", "ar": "تفاصيل الطلب"}, + "DeliveryDriverTrack": {"en": "Driver Tracking", "ar": "تتبع السائق"}, + "DeliveryLocation": {"en": "Delivery Location", "ar": "موقع التسليم"}, + "Driver": {"en": "Driver", "ar": "السائق"}, "VitalSign": {"en": "Vital Sign", "ar": "العلامة حيوية"}, "MonthlyReports": {"en": "Monthly Reports", "ar": "تقارير شهرية"}, "km": {"en": "KMs:", "ar": "كم"}, @@ -486,18 +585,27 @@ const Map localizedValues = { "PaymentOnline": {"en": "Service", "ar": "الالكتروني"}, "OnlineCheckIn": {"en": "Online Check-In", "ar": "مدفوعات معلقة"}, "MyBalances": {"en": "My Balances", "ar": "رصيدي"}, - "BalanceAmount": {"en": "Balance Amount", "ar": "رصيدالحساب"}, - "TotalBalance": {"en": "Total Balance", "ar": "الرصيد الكلي"}, - "CreateAdvancedPayment": {"en": "Create Advanced Payment", "ar": "إنشاء دفعة مقدمة"}, + "BalanceAmount": {"en": "Wallet Amount", "ar": "مبلغ المحفظة"}, + "TotalBalance": {"en": "Total Amount", "ar": "المبلغ الإجمالي"}, + "CreateAdvancedPayment": {"en": "Recharge Wallet", "ar": "إعادة شحن المحفظة"}, + "AdvancePayment": {"en": "Advance Payment", "ar": "الدفع مقدما"}, - "AdvancePaymentLabel": {"en": "You can create and add an Advanced Payment for you account or other accounts.", "ar": "يمكنك تحويل مبلغ لحسابك لدى المجموعة أو لحساب احد المراجعين"}, + "AdvancePaymentLabel": { + "en": + "You can create and add an Advanced Payment for you account or other accounts.", + "ar": "يمكنك تحويل مبلغ لحسابك لدى المجموعة أو لحساب احد المراجعين" + }, "FileNumber": {"en": "File Number", "ar": "رقم الملف"}, "Amount": {"en": "Amount *", "ar": "المبلغ *"}, - "DepositorEmail": {"en": "Depositor Email *", "ar": "البريد الإلكتروني للمودع *"}, + "DepositorEmail": { + "en": "Depositor Email *", + "ar": "البريد الإلكتروني للمودع *" + }, "Notes": {"en": "Notes", "ar": "ملاحظات"}, "SelectPatientName": {"en": "Select Patient Name", "ar": "اختر اسم المريض"}, "SelectFamilyPatientName": {"en": "Family Members", "ar": "أفراد الأسرة"}, "SelectHospital": {"en": "Select Hospital", "ar": "اختر المستشفى"}, + "selectCity": {"en": "Select City", "ar": "اختر المدينة"}, "MyAccount": {"en": "My Account", "ar": "حسابي"}, "OtherAccount": {"en": "Other Account", "ar": "حساب آخر"}, "SelectBeneficiary": {"en": "Select Beneficiary", "ar": "حدد المستفيد"}, @@ -505,6 +613,14 @@ const Map localizedValues = { "DepositorName": {"en": "Depositor Name", "ar": "اسم المودع *"}, "MobileNumber": {"en": "Mobile Number", "ar": "رقم الجوال"}, "Ok": {"en": "Ok", "ar": "حسنا"}, + "WaterConsumedInWeek": { + "en": "Water consumed in a week", + "ar": "معدل شرب الماء خلال الاسبوع" + }, + "WaterConsumedInMonth": { + "en": "Water consumed in a month", + "ar": "معدل شرب الماء خلال الشهر" + }, "TheVerificationCodeExpiresIn": { "en": "The Verification Code Expires In", "ar": "تنتهي صلاحية رمز التحقق في" @@ -530,8 +646,8 @@ const Map localizedValues = { "Remarks": {"en": "Remarks", "ar": "ملاحضات"}, "ActiveMedications": {"en": "Active Medications", "ar": "ادويتي النشطة"}, "ExpDate": {"en": "Active Exp Date :", "VA": "تاريخ الإنتهاء"}, - "Route": {"en": "Route :", "ar": "الطريقة"}, - "Frequency": {"en": "Frequency :", "ar": "المعدل"}, + "Route": {"en": "Route", "ar": "الطريقة"}, + "Frequency": {"en": "Frequency", "ar": "المعدل"}, "DailyQuantity": {"en": "Daily Quantity :", "ar": "جرعات يومية"}, "AddReminder": {"en": "Add Reminder", "ar": "إضافة تذكير"}, "reminderDes": { @@ -603,6 +719,7 @@ const Map localizedValues = { "order": {"en": "My Order", "ar": " طلباتي"}, "delivered": {"en": "Delivered", "ar": " تم التوصيل"}, "pending": {"en": "Pending", "ar": " معلقة "}, + "enterNameHere": {"en": "Enter the name here", "ar": " أدخل الاسم هنا "}, "processing": {"en": "Processing", "ar": " تحت المعالجة"}, "cancelled": {"en": "Cancelled", "ar": " ملغي"}, "writeReview": {"en": "Write Review", "ar": " اكتب تقييمك"}, @@ -614,6 +731,7 @@ const Map localizedValues = { "cancelledOrder": {"en": " CANCELLED", "ar": "ملغي"}, "compare": {"en": " Compare", "ar": "مقارنه"}, "medicationsRefill": {"en": " Medication Refill", "ar": "طلب أعادة صرف"}, + "recommended": {"en": " Recommended For You", "ar": "موصى لك"}, "myPrescription": {"en": " My Prescriptions", "ar": "وصفاتي"}, "quantity": {"en": " QTY ", "ar": "الكمية"}, "backMyAccount": { @@ -707,14 +825,21 @@ const Map localizedValues = { // pharmacy module "medicationRefill": {"en": "MEDICATION REFILL", "ar": "إعادة تعبئة الدواء"}, - "offersAndPromotions": {"en": "OFFERS & SPECIAL PROMOTIONS", "ar": "العروض والترقيات الخاصة"}, + "offersAndPromotions": { + "en": "OFFERS & SPECIAL PROMOTIONS", + "ar": "العروض والترقيات الخاصة" + }, "myPrescriptions": {"en": "MY PRESCRIPTIONS", "ar": "وصفاتي"}, - "searchAndScanMedication": {"en": "SEARCH & SCAN FOR MEDICATION", "ar": "البحث والمسح للأدوية"}, + "searchAndScanMedication": { + "en": "SEARCH & SCAN FOR MEDICATION", + "ar": "البحث والمسح للأدوية" + }, "shopByBrands": {"en": "Shop By Brands", "ar": "تسوق حسب الماركات"}, "recentlyViewed": {"en": "Recently Viewed", "ar": "شوهدت مؤخرا"}, "bestSellers": {"en": "Best Sellers", "ar": "أفضل البائعين"}, "deleteAllItems": {"en": "Delete All Items", "ar": "حذف كافة العناصر"}, "total": {"en": "Total", "ar": "المجموع"}, + "totalWithColonRight": {"en": "Total:", "ar": ":المجموع"}, "selectAddress": {"en": "Select Address", "ar": "حدد العنوان"}, "shippingAddress": {"en": "SHIPPING ADDRESS", "ar": "عنوان الشحن"}, "changeAddress": {"en": "Change Address", "ar": "تغيير العنوان"}, @@ -733,6 +858,7 @@ const Map localizedValues = { "checkBeneficiary": {"en": "CHECK BENEFICIARY", "ar": "تحقق من المستفيد"}, "beneficiaryName": {"en": "Beneficiary Name", "ar": "اسم المستفيد"}, "accountActivation": {"en": "Account Activation", "ar": "تفعيل الحساب"}, + "lakumTransfer": {"en": "Lakum Transfer", "ar": "تفعيل الحساب"}, "acceptLbl": {"en": "Accept", "ar": "موافقة"}, "select-gender": {"en": "Select Gender", "ar": "اختر الجنس"}, "i-am-a": {"en": "I am a ...", "ar": "أنا ..."}, @@ -756,7 +882,7 @@ const Map localizedValues = { "en": "This service provides a set of home health care services, continuous and comprehensive follow-up in their places of residence for those who cannot access health facilities, such as (laboratory analyzes - radiology - vaccinations - physical therapy), etc.", "ar": - "من خلال هذه الخدمة يمكنك طلب مجموعة من الفحوصات التي تساعدك وتساعد طبيبك في فهم حالتك الصحية الحالية ومن ثم تحديد المخاطر المحتملة" + "توفر هذه الخدمة مجموعه من خدمات الرعايه الصحيه المنزلية و متابعه مستمره وشامله للذين لا يستطيعون الوصول للمنشات الصحيه في اماكن اقامتهم (التحاليل المخبرية – الاشعة – التطعيمات – العلاج الطبيعي)..." }, "email": {"en": "Email", "ar": "البريد الالكتروني"}, "Book": {"en": "Book", "ar": "احجز"}, @@ -767,7 +893,10 @@ const Map localizedValues = { "profile": {"en": "Profile", "ar": "ملفي"}, "notifications": {"en": "Notifications", "ar": "إشعارات"}, "notificationDetails": {"en": "Notification Details", "ar": "تفاصيل الاشعار"}, - "notificationDetailsa": {"en": "Notification Details", "ar": "تفاصيل الاشعار"}, + "notificationDetailsa": { + "en": "Notification Details", + "ar": "تفاصيل الاشعار" + }, "info-my-doctor-points": { "en": [ @@ -776,15 +905,24 @@ const Map localizedValues = { "View details of your appointments with the selected doctor.", "Book appointment with the doctor. ", ], - "ar": ["الاطلاع على معلومات الطبيب ومؤهلاته.", "الاطلاع على جدول الطبيب.", "الاطلاع على تفاصيل المواعيد التي تمت مع الطبيب.", "حجز موعد مع الطبيب."] + "ar": [ + "الاطلاع على معلومات الطبيب ومؤهلاته.", + "الاطلاع على جدول الطبيب.", + "الاطلاع على تفاصيل المواعيد التي تمت مع الطبيب.", + "حجز موعد مع الطبيب." + ] }, "info-my-doctor": { - "en": "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", - "ar": "خدمة اطبائي: هذه الخدمة تمكنك من الاطلاع على جميع الاطباء الذين قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" + "en": + "This service allows you to see all the doctors you have visited in Al Habib Medical Group, and through this service:", + "ar": + "خدمة اطبائي: هذه الخدمة تمكنك من الاطلاع على جميع الاطباء الذين قمت بزيارتهم في مجموعة الحبيب الطبية, كما تستطيع من خلال هذه الخدمة:" }, "info-prescriptions": { - "en": "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", - "ar": "خدمة الوصفات الطبية: هذه الخدمة تمكنك من الاطلاع على جميع الوصفات الطبية التي تم اصدارها في مجموعة الحبيب الطبية، كما تستطيع من خلال هذه الخدمة:" + "en": + "This service allows you to view all the medical prescriptions issued by Al Habib Medical Group, and through this service, you can:", + "ar": + "خدمة الوصفات الطبية: هذه الخدمة تمكنك من الاطلاع على جميع الوصفات الطبية التي تم اصدارها في مجموعة الحبيب الطبية، كما تستطيع من خلال هذه الخدمة:" }, "info-my-prescription-points": { "en": [ @@ -808,8 +946,10 @@ const Map localizedValues = { }, "info-insurance-cards": { - "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", - "ar": "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" + "en": + "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", + "ar": + "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" }, "info-insurance-cards-points": { @@ -948,8 +1088,12 @@ const Map localizedValues = { "Average": {"en": "Average", "ar": "المعدل"}, "DailyDoses": {"en": "Daily Doses", "ar": "جرعات يومية"}, "Period": {"en": "Period", "ar": "الفترة"}, + "duration": {"en": "Duration", "ar": "المدة"}, "cm": {"en": "CM", "ar": "سم"}, + "ft": {"en": "ft", "ar": "قدم"}, "kg": {"en": "kg", "ar": "كجم"}, + "lb": {"en": "lb", "ar": "رطل"}, + "birth_date": {"en": "Birth Date", "ar": "تاريخ الميلاد"}, "mass": {"en": "Mass", "ar": "كتلة"}, "temp-c": {"en": "°C", "ar": "°س"}, "bpm": {"en": "bpm", "ar": "نبضة"}, @@ -982,7 +1126,10 @@ const Map localizedValues = { "message-type": {"en": "Message Type", "ar": "نوع الرسالة"}, "compliment": {"en": "compliment", "ar": "ثناء"}, "suggestion": {"en": "Suggestion", "ar": "إقتراح"}, - "your-feedback": {"en": "Your feedback was sent", "ar": "لقد تم ارسال اقراحك شكرا لك"}, + "your-feedback": { + "en": "Your feedback was sent", + "ar": "لقد تم ارسال اقراحك شكرا لك" + }, "select-part": { "en": "Please select the part that complain about", "ar": "يرجى تحديد الجزء الذي تشكو منه" @@ -996,13 +1143,28 @@ const Map localizedValues = { }, "YouCanFind": {"en": "You Can Find ", "ar": "باستطاعتك العثور على "}, "ItemInSearch": {"en": " Item In Search", "ar": " عنصر في البحث "}, + "blood-donation": {"en": "Blood Donation", "ar": "التبرع بالدم"}, + "blood-instruction": { + "en": + "Enter the required information, In order to register for Blood Donation Service", + "ar": "ادخل المعلومات المطلوبة للتسجيل بخدمة التبرع بالدم" + }, + "view-terms": { + "en": "To view the terms and conditions", + "ar": "عرض الشروط والأحكام" + }, "wantConnectHmgNetwork": { - "en": "Dear customer there is no internet access, Do you want to connect with HMG network to use our app, make sure you are in range of HMG network", - "ar": "عزيز العميل لا يوجد اتصال بالإنترنت, هل تريد الاتصال بشبكة مستشفى د. سليمان الحبيب لاستخدام التطبيق. يجب عليك ان تكون في نطاق شبكة المستشفى" + "en": + "Dear customer there is no internet access, Do you want to connect with HMG network to use our app, make sure you are in range of HMG network", + "ar": + "عزيز العميل لا يوجد اتصال بالإنترنت, هل تريد الاتصال بشبكة مستشفى د. سليمان الحبيب لاستخدام التطبيق. يجب عليك ان تكون في نطاق شبكة المستشفى" + }, + "failedToAccessHmgServices": { + "en": "Connected with HMG Network,\n\nBut failed to access HMG services", + "ar": "Connected with HMG Network,\n\nBut failed to access HMG services" }, - "failedToAccessHmgServices": {"en": "Connected with HMG Network,\n\nBut failed to access HMG services", "ar": "Connected with HMG Network,\n\nBut failed to access HMG services"}, "offerAndPackages": {"en": "Offers And Packages", "ar": "العروض والباقات"}, - "InvoiceNo": {"en": " Invoice No", "ar": "رقم الفاتورة"}, + "InvoiceNo": {"en": "Invoice No", "ar": "رقم الفاتورة"}, "SpecialResult": {"en": " Special Result", "ar": "نتيجة خاصة"}, "GeneralResult": {"en": "General Result", "ar": "نتيجة عامة"}, "show-more-btn": {"en": "Flow Chart", "ar": "النتائج التراكمية"}, @@ -1065,7 +1227,7 @@ const Map localizedValues = { "pickup-location": {"en": "Pickup Location", "ar": "نقطة الانطلاق"}, "pickup-spot": {"en": "Pickup Spot", "ar": "نقطة اللقاء"}, "inside-home": {"en": "Inside Home", "ar": "داخل المنزل"}, - "have-appo": {"en": "Do you have an appointment?", "ar": "هل لديك موعد؟"}, + "have-appo": {"en": "Do you have an appointment ?", "ar": "هل لديك موعد ؟"}, "dropoff-location": {"en": "Dropoff Location", "ar": "نقطة الوصول"}, "select-all": { "en": "Please select all fields", @@ -1148,7 +1310,8 @@ const Map localizedValues = { "child-vaccine": {"en": "Child Vaccines", "ar": "تطعيمات الأطفال"}, "calculators": {"en": "Health Calculators", "ar": "الحاسبات الصحية"}, "converters": {"en": "Health Converter", "ar": "تحويل القياسات"}, - "h2o": {"en": "Water Tracker", "ar": "حساب كمية الماء"}, + "waterTracker": {"en": "Water Tracker", "ar": "حساب كمية الماء"}, + "h2o": {"en": "H2O", "ar": "استهلاك"}, "v-tour": {"en": "Virtual Tour", "ar": "جولة إفتراضية"}, "hmg-news": {"en": "HMG News", "ar": "أخبار المجموعة"}, "blood-d": {"en": "Blood Donation", "ar": "تبرع بالدم"}, @@ -1218,6 +1381,10 @@ const Map localizedValues = { "en": "Send a copy of this report to the email", "ar": "أرسل نسخة من هذا التقرير إلى البريد الإلكتروني" }, + "update-email-msg": { + "en": "Email updated", + "ar": "تم تحديث البريد الالكتروني" + }, "update-email": {"en": "Update Email", "ar": "تحديث البريد الالكتروني"}, "booked-success": { "en": "The appointment has been successfully booked.", @@ -1248,18 +1415,9 @@ const Map localizedValues = { "selectFileSouse": {"en": "Select file souse", "ar": "حدد الملف"}, "gallery": {"en": "Gallery", "ar": "معرض الصور"}, "camera": {"en": "Camera", "ar": "كاميرا"}, - "med-report": { - "en": "Medical Reports", - "ar": "التقارير الطبية" - }, - "new-med-report": { - "en": "Requests", - "ar": "الطلبات" - }, - "requestReport":{ - "en":"Request a report", - "ar":" طلب تقرير" - }, + "med-report": {"en": "Medical Reports", "ar": "التقارير الطبية"}, + "new-med-report": {"en": "Requests", "ar": "الطلبات"}, + "requestReport": {"en": "Request a report", "ar": " طلب تقرير"}, "confirm-msg-report": { "en": "Request for medical report?", "ar": "طلب تقرير طبي؟" @@ -1268,26 +1426,11 @@ const Map localizedValues = { "en": "The request has been submitted successfully", "ar": "تم تنفيذ طلبك بنجاح" }, - "pulseTitle": { - "en": "Heart rate", - "ar": "معدل النبض بالدقيقة" - }, - "systolic-lng": { - "en": "Systolic", - "ar": "الإنقباض" - }, - "diastolic-lng": { - "en": "Diastolic", - "ar": "الإنبساط" - }, - "policy-holder": { - "en": "Policy Holder", - "ar": "حامل بطاقة التأمين" - }, - "policy-no": { - "en": "Policy Number", - "ar": "رقم سياسات" - }, + "pulseTitle": {"en": "Heart rate", "ar": "معدل النبض بالدقيقة"}, + "systolic-lng": {"en": "Systolic", "ar": "الإنقباض"}, + "diastolic-lng": {"en": "Diastolic", "ar": "الإنبساط"}, + "policy-holder": {"en": "Policy Holder", "ar": "حامل بطاقة التأمين"}, + "policy-no": {"en": "Policy Number", "ar": "رقم سياسات"}, "agree": { "en": "I agree, this is the correct information", "ar": "موافق، هذه المعلومات صحيحة" @@ -1296,30 +1439,12 @@ const Map localizedValues = { "en": "No, this is not the correct information", "ar": "غير موافق، هذه المعلومات غير الصحيحة" }, - "expiry-date": { - "en": "Expiry Date", - "ar": "تاريخ انتهاء الصلاحية" - }, - "class": { - "en": "Class", - "ar": "فئة" - }, - "approval": { - "en": "Approval", - "ar": "موافقة" - }, - "no-data": { - "en": "No data found", - "ar": "لاتوجد بيانات" - }, - "insurance-details": { - "en": "Insurance Details", - "ar": "تفاصيل التأمين" - }, - "nearest-hospital": { - "en": "Nearest Hospital", - "ar": "أقرب مستشفى" - }, + "expiry-date": {"en": "Expiry Date", "ar": "تاريخ انتهاء الصلاحية"}, + "class": {"en": "Class", "ar": "فئة"}, + "approval": {"en": "Approval", "ar": "موافقة"}, + "no-data": {"en": "No data found", "ar": "لاتوجد بيانات"}, + "insurance-details": {"en": "Insurance Details", "ar": "تفاصيل التأمين"}, + "nearest-hospital": {"en": "Nearest Hospital", "ar": "أقرب مستشفى"}, "request-sent": { "en": "Request sent successfully", "ar": "تم إرسال الطلب بنجاح" @@ -1328,10 +1453,7 @@ const Map localizedValues = { "en": "Message sent successfully", "ar": "تم إرسال الرسالة بنجاح" }, - "sent-on": { - "en": "Sent on", - "ar": "أرسلت في" - }, + "sent-on": {"en": "Sent on", "ar": "أرسلت في"}, "attach-insurace-image": { "en": "Attach insurance card image", "ar": "إرفاق صورة بطاقة التأمين" @@ -1341,56 +1463,33 @@ const Map localizedValues = { "ar": "لا يزال بإمكانك الإرسال ، إذا لم يكن لديك صورة تأمين" }, "info-insur-cards": { - "en": "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", - "ar": "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" + "en": + "This service allows you to view all the insurance cards that recorded during your visits to Al Habib Medical Group in addition to:", + "ar": + "خدمة بطاقات التامين: هذه الخدمة تمكنك من الاطلاع على جميع بطاقات التامين والتي تم تسجيلها اثناء زياراتك لمجموعة الحبيب الطبية بالاضافة الى:" }, "scan-now": { "en": "If you have a card / Document Scan now", "ar": "إذا كانت لديك بطاقة / مستند ارفقها الان" }, - "liveCare": { - "en": "Live Care", - "ar": "لايف كير" - }, - "topBrands":{ - "en":"Top Brands", - "ar":"اعلى العلامات التجارية" - }, + "liveCare": {"en": "Live Care", "ar": "لايف كير"}, + "topBrands": {"en": "Top Brands", "ar": "اعلى العلامات التجارية"}, - "notifyMe":{ - "en":"notify me", - "ar":"اعلمني" - }, - "specification":{ - "en":"Specification", - "ar":"تخصيص" - }, + "notifyMe": {"en": "notify me", "ar": "اعلمني"}, + "specification": {"en": "Specification", "ar": "تخصيص"}, - "availability":{ - "en":"Availability", - "ar":"التوفر" - }, - - "quantitySize":{ - "en":"Quantity", - "ar":"كميه" - }, - "addToCart":{ - "en":"add to cart", - "ar":"إضفة للسلة" - }, - "buyNow":{ - "en":"buy now", - "ar":"إشتري الان" - }, - "quantityShortcut":{ - "en":"QTY", - "ar":"كمية" - }, + "availability": {"en": "Availability", "ar": "التوفر"}, + "vaccination": {"en": "Vaccination", "ar": "جدول التطعيمات"}, + "welcomeBack": {"en": "Welcome back", "ar": "مرحبا مرة أخرى"}, + "quantitySize": {"en": "Quantity", "ar": "كميه"}, + "addToCart": {"en": "add to cart", "ar": "إضفة للسلة"}, + "buyNow": {"en": "buy now", "ar": "إشتري الان"}, + "quantityShortcut": {"en": "QTY", "ar": "كمية"}, "pharmacyServiceTermsCondition": { - "en": "I agree with the terms of service and I adhere to them unconditionally", + "en": + "I agree with the terms of service and I adhere to them unconditionally", "ar": " أوافق على شروط الخدمة وألتزم بها دون قيد أو شرط" }, "Year": {"en": "YEAR", "ar": "السنة"}, @@ -1400,6 +1499,16 @@ const Map localizedValues = { "termOfService": {"en": "Terms of service", "ar": "شروط الخدمة"}, "shoppingCart": {"en": "Shopping Cart", "ar": "عربة التسوق"}, + "add-child": {"en": "Add New Child", "ar": "اضافة طفل"}, + "child-name": {"en": "Child Name", "ar": "اسم الطفل"}, + "childDob": {"en": "Birth Date", "ar": "تاريخ الولادة"}, + "deleted-child-mes": { + "en": + "The request was successful. The children have removed from the vaccination schedule subscription service.", + "ar": "تم حذف الطفل بنجاح" + }, + "deleted-child": {"en": "Delete child", "ar": "إالغاء الطفل"}, + "visit": {"en": "Visit", "ar": "زيارة"}, "referralStatus": {"en": "Referral Status", "ar": "حالة الإحالة"}, "referralDate": {"en": "Referral Date", "ar": "تاريخ الإحالة"}, "patientName": {"en": "Patient Name", "ar": "اسم المريض"}, @@ -1437,9 +1546,36 @@ const Map localizedValues = { "en": "Send the child's schedule to the email?", "ar": "ارسال جدول التطعيمات الى بريدك الالكتروني؟" }, - "vaccination": {"en": "Vaccination", "ar": "جدول التطعيمات"}, - "welcomeBack": {"en": "Welcome back", "ar": "مرحبا مرة أخرى"}, + "email-success": { + "en": + " The request was successful. You will receive the Schedule in moments.", + "ar": "تم ارسال جدول التطعيمات " + }, + "add-instructions": { + "en": + "Add the child's information below to recieve the schedule of vaccinations.", + "ar": "أضف معلومات الطفل لاستلام جدول التطعيمات" + }, + "added-child": { + "en": + "The request was successful. You have added a child to the vaccination schedule subscription service.", + "ar": "تمت الاضافة بنجاح." + }, + "appUpdate": {"en": "UPDATE THE APP", "ar": "تحديث التطبيق"}, + "ereferralSaveSuccess": { + "en": + "The referral request has been submitted successfully, you will be contacted ASAP to complete the process. Referral request no is ", + "ar": + " تم إرسال طلب الإحالة بنجاح ، وسيتم الاتصال بك في أسرع وقت ممكن لإكمال العملية. رقم طلب الإحالة" + }, + + "help": {"en": "Help", "ar": "مساعدة"}, + "habibRobotText": { + "en": + "Hi, This is HABIB, your personal assistant. I'm here to assist you by voice commands. How can I help?", + "ar": "مرحباً ، معك حبيب مساعدك الشخصي. أنا هنا لمساعدتك بالأوامر الصوتية." + }, "updated-email": { "en": "Updated email successfully", "ar": "تم تحديث البريد الالكتروني" @@ -1449,4 +1585,415 @@ const Map localizedValues = { "en": "View List of Children", "ar": "عرض قائمة الأطفال" }, + "covidTest": {"en": "COVID-19 TEST", "ar": "فحص كورونا"}, + "driveThru": {"en": "Drive-Thru", "ar": "من السيارة"}, + "trackDeliveryDriver": { + "en": "Track Delivery Driver", + "ar": "trackDeliveryDriver" + }, + + "NearestErDesc": { + "en": + "\nThis service Displays nearest branch\n among all the branches of All Habib \n medical Group based on your current Location", + "ar": + "\nتعرض هذه الخدمة أقرب فرع\n من بين جميع فروع مجموعة \nالحبيب الطبية بناءً على موقعك الحالي." + }, + "NearestEr": {"en": "Nearest ER", "ar": "أقرب ER"}, + "infoCMC": { + "en": + "Through this service, you can request a set of tests that help you and your doctor to understand the current health condition and then identify potential risks.", + "ar": + "من خلال هذه الخدمة يمكنك طلب مجموعة من الفحوصات التي تساعدك وتساعد طبيبك في فهم حالتك الصحية الحالية ومن ثم تحديد المخاطر المحتملة" + }, + "instructionAgree": { + "en": + "This monthly Health Summary Report reflects the health indicators and analysis results of the latest visits. Please note that this will be sent automatically from the system and it's not considered as an official report so no medical decisions should be taken based on it.", + "ar": + "هذا ملخص التقرير الصحي الشهري و الذي يسرد المؤشرات الصحية و نتائج التحاليل لأخر الزيارات. يرجى ملاحظة أن هذا التقرير هو تقرير يتم ارساله بشكل آلي من النظام و لا يعتبر رسمي و لا تؤخذ عليه أي قرارات طبية" + }, + "reqId": {"en": "Request ID:", "ar": " رقم الطلب"}, + "RRT-orders-log": {"en": "Orders Log", "ar": "سجل الطلبات"}, + "blood-sugar": {"en": "Blood Sugar", "ar": "سكر الدم"}, + + "covid19_driveThrueTest": { + "en": "'Covid-19- Drive-Thru Test'", + "ar": "Covid-19- الفحص من خلال القيادة" + }, + "E-Referral": {"en": "'E-Referral'", "ar": "الإحالة الإلكترونية"}, + "childName": {"en": "'CHILD NAME'", "ar": "إسم الطفل"}, + "recordDeleted": {"en": "'Record Deleted'", "ar": "تم حذف السجل"}, + "msg_email_address_up_to_date": { + "en": + "Please ensure that the email address is up-to-date and process to view the schedule", + "ar": + "يرجى التأكد من أن عنوان البريد الإلكتروني محدث وأن العملية لعرض الجدول الزمني" + }, + "add-new-child": {"en": "ADD NEW CHILD", "ar": "إضافة طفل جديد"}, + + "send-child-email-msg": { + "en": "Send the child's schedule to the email", + "ar": "أرسل جدول الطفل إلى البريد الإلكتروني" + }, + + "vaccination-add-child-msg": { + "en": + "Add the child's information below to receive the schedule of vaccinations.", + "ar": "أضف معلومات الطفل أدناه للحصول على جدول التطعيمات." + }, + "child_added_successfully": { + "en": "Child added successfully", + "ar": "تمت إضافة الطفل بنجاح" + }, + "bloodSugar": {"en": "Blood", "ar": "السكر في الدم"}, + "sugar": {"en": "Sugar", "ar": ""}, + "bloodCholesterol": {"en": "Blood", "ar": " الكولسترول في الدم"}, + + "cholesterol": {"en": "Cholesterol", "ar": ""}, + "triglycerides": {"en": "Triglycerides", "ar": "الدهون الثلاثية"}, + + "fatInBlood": {"en": "Fat In Blood", "ar": ""}, + "convertFrom": {"en": "Convert From", "ar": "تحويل من"}, + "calculate": {"en": "calculate", "ar": "حساب"}, + "enterReadingValue": {"en": "Enter the reading value", "ar": "ادخل القيمة"}, + "result": {"en": "Result", "ar": "النتيجة"}, + "sort": {"en": "Sort", "ar": "فرز"}, + "bloodSugarConversion": { + "en": "Blood Sugar Conversion", + "ar": "السكر في الدم" + }, + "convertBloodSugarStatement": { + "en": + "Convert blood sugar/glucose from mmol/l (UK standard) to mg/dlt (US standard) and vice versa.", + "ar": + "تحويل مستوى السكر في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + }, + "convertCholesterolStatement": { + "en": "Convert blood cholesterol from\n mmol/l to mg/dlt and vice versa.", + "ar": + "تحويل مستوى الكولسترول في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + }, + "triglyceridesConvertStatement": { + "en": "Convert Triglycerides from mmol/l to mg/dlt and vice versa.", + "ar": + "تحويل مستوى الدهون الثلاثية في الدم من مليمول/ لتر (مقياس المملكة المتحدة) الى ملغ/ ديسيلتر (مقياس الولايات المتحدة) والعكس" + }, + "my-tracker": {"en": "My Tracker", "ar": "قراءاتي"}, + "weekly": {"en": "Weekly", "ar": "أسبوعي"}, + "monthly": {"en": "Monthly", "ar": "شهري"}, + "yearly": {"en": "Yearly", "ar": "سنوي"}, + "measured": {"en": "Measured", "ar": "قياس"}, + "sugar-add": {"en": "Enter Blood Sugar Value", "ar": "أدخل قيمة قراءة السكر"}, + "other": {"en": "Other", "ar": "آخر"}, + "measure-unit": {"en": "Measure unit", "ar": "وحدة القياس"}, + "measure-time": {"en": "Measure time", "ar": "وقت القياس"}, + "update": {"en": "Update", "ar": "تعديل"}, + "bloodD-enter-desc": { + "en": + "Enter the required information, In order to register for Blood Donation Service", + "ar": "أدخل المعلومات المطلوبة ، للتسجيل في خدمة التبرع بالدم" + }, + "viewTermsConditions": { + "en": "To view the terms and conditions", + "ar": "لعرض الشروط والأحكام" + }, + "WalkinAppo": { + "en": "Hospital Visit Appointment", + "ar": "موعد زيارة للمستشفى" + }, + + "videoAppo": {"en": "Video Call Appointment", "ar": "موعد اتصال فيديو"}, + + "generalHealth": {"en": "General Health", "ar": "صحة عامة"}, + "womanHealth": {"en": "Women's Health", "ar": "صحة المرأة"}, + "bmi": {"en": "BMI", "ar": "الكتلة"}, + "calc-health": {"en": "Calculators", "ar": "الصحية"}, + "calories": {"en": "Calories", "ar": "سعرات"}, + "bmr": {"en": "BMR", "ar": "معدل الأيض القاعدي"}, + "idealBody": {"en": "Ideal Body", "ar": "الجسم المثالي"}, + "body_word": {"en": "Body", "ar": "الجسم"}, + "fat": {"en": "Fat", "ar": "دهون"}, + "carbohydrate": {"en": "Carbohydrate", "ar": "كربوهيدرات"}, + "proteinFat": {"en": "Protein Fat", "ar": "دهون البروتين"}, + "ovulation": {"en": "Ovulation", "ar": "الإباضة"}, + "delivery": {"en": "Delivery", "ar": "الولادة"}, + "bmiCalcDesc": { + "en": + "'Calculate the BMI value and weight\n status to identify the healthy weight .\n Not appropriate for children and women\n who are pregnant or breastfeeding'", + "ar": + "حساب قيمة مؤشر كتلة الجسم وحالة الوزن لتحديد الوزن الصحي. \n وغير مناسب للأطفال والنساء الحوامل أو المرضعات" + }, + "selectUnit": {"en": "Select Unit", "ar": "اختر الوحدة"}, + "feet": {"en": "Feet", "ar": "قدم"}, + "pound": {"en": "Pound", "ar": "رطل"}, + "seeListOfDoctor": {"en": "See List Of Doctors", "ar": "انظر قائمة الأطباء"}, + "obese": {"en": "Obese", "ar": "سمين"}, + "overWeight": {"en": "OverWeight", "ar": "وزن زائد"}, + "healthy": {"en": "Healthy", "ar": "صحي"}, + "underWeight": {"en": "UnderWeight", "ar": "نقص الوزن"}, + "bmiCalcMsgObese": { + "en": + "A BMI of over 30 indicates that are heavily overweight. Health may be at risk if not lose weight. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get started.", + "ar": + "يشير مؤشر كتلة الجسم الذي يزيد عن 30 إلى زيادة الوزن بشكل كبير. قد تكون الصحة في خطر إذا لم تفقد الوزن. يوصى بالتحدث إلى الطبيب أو أخصائي التغذية للحصول على المشورة. لحجز موعد ، انقر أدناه للبدء." + }, + "bmiCalcMsgOverweight": { + "en": + 'A BMI of 25 - 30 indicates that are slightly overweight. May be advised to lose some weight for health reasons. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get ', + "ar": + "يشير مؤشر كتلة الجسم من 25 إلى 30 إلى زيادة الوزن قليلاً. قد ينصح بفقدان بعض الوزن لأسباب صحية. يوصى بالتحدث إلى الطبيب أو أخصائي التغذية للحصول على المشورة. لحجز موعد ، انقر أدناه للحصول على" + }, + "bmiCalcMsgHealthy": { + "en": + "A BMI of 18.5 - 25 indicates that are at a healthy weight for the height. By maintaining a healthy weight, lower the risk of developing severe health problems. To book an appointment, click below to get started.", + "ar": + "يشير مؤشر كتلة الجسم من 18.5 - 25 إلى وزن صحي بالنسبة للطول. بالحفاظ على وزن صحي ، قلل من خطر الإصابة بمشاكل صحية خطيرة. لحجز موعد ، انقر أدناه للبدء." + }, + "bmiCalcMsgUnderWeight": { + "en": + "A BMI of less than 18.5 indicates that are underweight, so may need to put on some weight. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get started.", + "ar": + "يشير مؤشر كتلة الجسم الذي يقل عن 18.5 إلى أنك تعاني من نقص الوزن ، لذلك قد تحتاج إلى زيادة الوزن. يوصى بالتحدث إلى الطبيب أو أخصائي التغذية للحصول على المشورة. لحجز موعد ، انقر أدناه للبدء." + }, + "bariatrics": {"en": "Bariatrics", "ar": "طب السمنة"}, + "bariatricsHeaderMsg": { + "en": + "Choose one of the following symptoms to show the right doctors or choose a consultation to show all", + "ar": + "اختر أحد الأعراض التالية لتظهر للأطباء المناسبين أو اختر استشارة لإظهار الكل" + }, + "continue": {"en": "CONTINUE", "ar": "إستمرار"}, + "skip": {"en": "SKIP", "ar": "تخطى"}, + "calorieCalcDesc": { + "en": + "Calculates daily calorie intake based on several factors, like height, weight, age, gender and daily physical activity ", + "ar": + "يحسب السعرات الحرارية اليومية بناءً على عدة عوامل ، مثل الطول والوزن والعمر والجنس والنشاط البدني اليومي" + }, + "age11_120_years": { + "en": "The Age ( 11 - 120 ) yrs", + "ar": "العمر (11 - 120) سنة" + }, + "weight-add": {"en": "Enter Weight Value", "ar": "أدخل الوزن "}, + "systolic-add": {"en": "Enter Systolic Value", "ar": "أدخل قيمة الإنقباض "}, + "diastolic-add": {"en": "Enter Diastolic Value", "ar": "أدخل قيمة الإنبساط "}, + "cmc-heading": {"en": "Comprehensive Medical Checkup", "ar": "فحص طبي شامل"}, + "today": {"en": "Today", "ar": "اليوم"}, + "week": {"en": "Week", "ar": "أسبوع"}, + "month": {"en": "Month", "ar": "شهر"}, + "h2o-amount-of-water": { + "en": "Enter the amount of water:", + "ar": "ادخل كمية الماء:" + }, + "update-user": {"en": "Update Information", "ar": "تحديث بيانات"}, + "editname": {"en": "Enter the name here", "ar": "أدخل الاسم هنا"}, + "activity-level": {"en": "Activity Level", "ar": "مستوى النشاط"}, + "light-active": {"en": "Lightly Active", "ar": " قليل النشاط"}, + "mod-active": {"en": "Moderately Active", "ar": "متوسط النشاط"}, + "reminder-label": { + "en": "Activate the reminder of drink water?", + "ar": "تفعيل خاصية تذكير شرب الماء؟" + }, + "reminder-times-label": { + "en": "How many times do you want to be reminded?", + "ar": "عدد مرات التذكير" + }, + "times": {"en": "Times", "ar": "مرات"}, + "WaterCalculate": {"en": "Save", "ar": "حفظ"}, + "notif-title": {"en": "Water Reminder", "ar": "تذكير"}, + "notif-text": { + "en": " Don't forget to drink water.", + "ar": "لا تنسى شرب الماء" + }, + "custom": {"en": "Custom", "ar": "خاص"}, + "undo": {"en": "Undo", "ar": "تراجع"}, + "drinking": {"en": "Drinkning", "ar": "الشرب"}, + "remaining": {"en": "Remaining", "ar": "المتبقي"}, + "taken": {"en": "Taken", "ar": " مأخوذ"}, + "ml": {"en": "ml", "ar": "مل"}, + "l": {"en": "L", "ar": "لتر"}, + "custom-label": {"en": "Enter amount", "ar": "أدخل كمية الماء"}, + "custom-label-in-litres": { + "en": "Enter amount in liters", + "ar": "أدخل الكمية باللتر" + }, + "custom-label-in-mililitres": { + "en": "Enter amount in millilitres", + "ar": "أدخل الكمية بالملليتر" + }, + "amount": {"en": "Amount", "ar": "الكمية"}, + "target-reach": { + "en": "You have reached the target for the day!", + "ar": "لقد حققت هدفك اليومي! مبروك" + }, + "week-header": { + "en": "Water consumed in a week", + "ar": "معدل شرب الماء خلال الاسبوع" + }, + "month-header": { + "en": "Water consumed in a month", + "ar": "معدل شرب الماء خلال الشهر" + }, + "notif-permission-title": { + "en": "Could not set the water reminders", + "ar": "لا يمكن ضبط اشعار شرب الماء" + }, + "notif-permission-msg": { + "en": + "To recieve water reminders, please turn on notifications in the system settings", + "ar": "الرجاء تفعيل الاشعارات في الاعدادات" + }, + "verification_message_code": { + "en": "Please enter verification code", + "ar": "الرجاء إدخال رمز التحقق" + }, + "select-location": {"en": "Select Location", "ar": "اختر موقعا"}, + "result-header": { + "en": "Get The Result During 8 Hours", + "ar": "احصل على النتيجة خلال 8 ساعة" + }, + "covid-info": { + "en": + "We are using the advance technology to test COVID-19, The sample for examination is taking between the nose and mouth (nasopharyngeal swab), the examination is done by ELITE In Genius of the company ELITECH GROUP MOLECULAR DIAGNOSTICS, Note that the device belongs to an Italian company and is manufactured in Japan with RC- PCR​", + "ar": + "يتوفر لدينا أحدث جهاز خاص بفحص مرض الكورونا (COVID-19) طريقة الفحص تؤخذ مسحة من البلعوم الأنفي ( عن طريف الأنف) ويتم الفحص بواسطة جهاز ELITE In Genius التابع لشركة ELITECH GROUP MOLECULAR DIAGNOSTICS علما بأن الجهاز تابع لشركة إيطالية ومصنع في اليابان بتقينة RC-PCR" + }, + "select-appo": { + "en": "Kindly select one of the available appointments from below:", + "ar": "يرجى اختيار أحد المواعيد المتاحة من أدناه:" + }, + "covid-alert-header": { + "en": "Pay With-in 15 mins to confirm the appointment", + "ar": "الرجاء اتمام عملية الدفع خلال 15 دقيقه لتاكيد الموعد" + }, + "covid-alert-info": { + "en": + "Payment for Covid-19 Test should Be made with-in 15 mins otherwise The system will Cancel the Scheduled appointment automatically​", + "ar": + "سيتم الغاء الموعد عن طريق النظام بشكل الي في حال عدم اتمام عمليه الدفع خلال 15 دقيقة​" + }, + "covid-alert-mins": {"en": "Pay With-in 15 mins", "ar": "ادفع خلال 15 دقيقة"}, + "back": {"en": "Back", "ar": "رجوع"}, + "get-directions": {"en": "Get Directions", "ar": "احصل على الاتجاهات"}, + "selected-location": {"en": "Selected Location:", "ar": "الموقع المحدد:"}, + "test-fee": {"en": "Test Fee", "ar": "رسوم الاختبار"}, + "pay-options": { + "en": "You can pay by the following Options:", + "ar": "يمكنك الدفع عن طريق الخيارات التالية:" + }, + "livecare-service": {"en": "LiveCare Service", "ar": "خدمة لايف كير"}, + "livecare-service-desc": { + "en": + "is to obtain medical advice with a specialist doctor Via a video call", + "ar": "هي الحصول على استشارة طبية مع طبيب مختص عن طريق اتصال فيديو" + }, + "why-livecare": {"en": "WHY LIVECARE", "ar": "لماذا خدمة اللايف كير"}, + "livecare-point-1": { + "en": + "No need to wait you will get Medical consultation immediately via Video call", + "ar": + "لا داعي للانتظار سوف تحصل على الاستشارة الطبية فورا عن طريق مكالمة الفيديو" + }, + "doc-virtual-appo-ins4": { + "en": "The doctor will see your medical file", + "ar": "سوف يتمكن الطبيب من الاطلاع على ملفك الطبي كامل" + }, + "doc-virtual-appo-ins5": { + "en": "Free prescription delivery service", + "ar": "خدمة توصيل الادوية مجانا" + }, + "livecare-summary": { + "en": + "** The service is included with some insurance companies according to the terms and conditions With our best wishes for health and wellness", + "ar": + "** الخدمة مشمولة لدى بعض شركات التامين على حسب الشروط والاحكام مع تمنياتنا لكم بدوام الصحة والعافية" + }, + "livecare-option-1": { + "en": "Get Medical consultation immediately", + "ar": "الحصول على الاستشارة فورا" + }, + "livecare-option-2": {"en": "Instant video call", "ar": "اتصال فيديو فوري"}, + "livecare-option-3": {"en": "Book Appointment", "ar": "حجز موعد"}, + "livecare-option-4": {"en": "Schedule video call", "ar": "اتصال فيديو مجدول"}, + "sms_code": {"en": "Enter SMS Code here", "ar": "أدخل رمز التحقق هنا"}, + "code_failure": { + "en": "Didn’t received the code", + "ar": "لم أستلم رمز التحقق" + }, + "resend": {"en": "Resend", "ar": "إعادة إرسال"}, + "submitncontinue": {"en": "Submit and continue", "ar": "إرسال ومتابعة"}, + "areyousure": { + "en": "Are you sure you want to Add", + "ar": "هل أنت متأكد أنك تريد إضافة" + }, + "preferredunit": { + "en": "Select the preferred unit", + "ar": "اختر الوحدة المفضلة" + }, + "select-unit": {"en": "Select unit", "ar": "اختر وحدة القياس"}, + "try-saying": {"en": "Try saying something", "ar": 'حاول قول شيء ما'}, + + "app-update": {"en": "UPDATE THE APP", "ar": "تحديث التطبيق"}, + "covid-alert": {"en": "Alert", "ar": "تنبيه"}, + "enterIdentificationNumber": { + "en": "Enter Identification Number", + "ar": "أدخل رقم التعريف" + }, + "accountActivationDesc": { + "en": + "This service allows you to activate your LAKUM account after registering through the Vida system.", + "ar": + "تتيح لك هذه الخدمة تفعيل حساب LAKUM الخاص بك بعد التسجيل من خلال نظام Vida." + }, + "pointsToTransfer": { + "en": "Point's to Transfer :", + "ar": "النقاط المراد تحويلها:" + }, + "enterBeneficiaryAccountNo": { + "en": "Enter Beneficiary Account No.", + "ar": "أدخل رقم حساب المستفيد" + }, + "confirm-prescription": { + "en": "Are you sure !! you want to send this request", + "ar": "تاكيد ارسال الطلب؟" + }, + "you-already-have-order": { + "en": "You already have this order! do you want to view it?", + "ar": "لديك هذا الطلب بالفعل! هل تريد مشاهدته؟" + }, + "order-overview": {"en": "Order Overview", "ar": "ملخص الطلب"}, + "shipping-address": {"en": "Delivery Address", "ar": "عنوان التوصيل"}, + "pharmacy-relogin": { + "en": "Your session has timed out, Please try again", + "ar": "انتهت مهلة جلسة الخاص بها. يرجى المحاولة مرة أخرى" + }, + "ancillary-orders": {"en": "Ancillary Orders", "ar": "الأوامر التبعية"}, + + "onlineCheckInAgreement": { + "en": + "The online check-in is for non-life threatening situationCall the red crescent (number) or go to the nearest emergency department if there are:signs of stroke or heart attack history of seizure or syncope there is limb or life threatening injury picture of severe injuries​", + "ar": + "تسجيل الذهاب الى الطوارئ عبر الإنترنت هو فقط للحالات  التي لا تهدد الحياة يجب الاتصل بالهلال الأحمر (رقم) أو الذهاب إلى أقرب قسم طوارئ إذا كان هناك علامات السكتة الدماغية أو النوبة القلبية او هناك نوبة تشنج او حالة فقدان الوعي او وجود إصابة تهدد أحد الأطراف او تهدد الحياة او وجود إصابات خطيرة" + }, + "MRN": {"en": "MRN", "ar": "ایم آر این"}, + "appointment-date": {"en": "Appointment Date", "ar": "تقرری کی تاریخ"}, + "appointment-no": {"en": "Appointment No", "ar": "تقرری نمبر"}, + "insurance-id": {"en": "Insurance ID", "ar": "انشورنس ID"}, + "chiefComplaints": {"en": "Chief Complaints", "ar": "الشكوى الرئيسة"}, + "errorChiefComplaints": { + "en": "Please Chief Complaints", + "ar": "يرجى ادخال الشكوى الرئيسة" + }, + "errorExpectedArrivalTimes": { + "en": "Please Expected arrival time", + "ar": "يرجى ادخال الوقت المتوقع للوصول" + }, + "expectedArrivalTime": { + "en": "Expected arrival time", + "ar": "الوقت المتوقع للوصول" + }, + "add-address": {"en": "Add new address", "ar": "اضف عنوان جديد"}, + "enter-file": { + "en": "Please enter the mobile number and the medical file number", + "ar": "الرجاء إدخال رقم الجوال ورقم الملف الطبي" + } }; diff --git a/lib/config/shared_pref_kay.dart b/lib/config/shared_pref_kay.dart index 458040bb..caada21f 100644 --- a/lib/config/shared_pref_kay.dart +++ b/lib/config/shared_pref_kay.dart @@ -20,9 +20,12 @@ const IS_VIBRATION = 'is_vibration'; const THEME_VALUE = 'is_vibration'; const MAIN_USER = 'main-user'; const PHARMACY_LAST_VISITED_PRODUCTS = 'last-visited'; -const HMG_GEOFENCES = 'hmg-geo-fences'; const PHARMACY_CUSTOMER_ID = 'costumer-id'; +const IS_ROBOT_VISIBLE = 'robot-visible'; +const IS_ROBOT_INIT = 'robot-init'; +const HMG_GEOFENCES = 'hmg-geo-fences'; const WEATHER = 'weather'; const BLOOD_TYPE = 'blood-type'; const NOTIFICATION_COUNT = 'notification-count'; const PHARMACY_SELECTED_ADDRESS = 'selected-address'; +const PHARMACY_AUTORZIE_TOKEN = 'PHARMACY_AUTORZIE_TOKEN'; diff --git a/lib/core/enum/Ambulate.dart b/lib/core/enum/Ambulate.dart index f8b2e8be..e4714cb2 100644 --- a/lib/core/enum/Ambulate.dart +++ b/lib/core/enum/Ambulate.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; enum Ambulate { Wheelchair, Walker, Stretcher, None } @@ -6,19 +7,19 @@ extension SelectedAmbulate on Ambulate { String getAmbulateTitle(BuildContext context) { switch (this) { case Ambulate.Wheelchair: - return 'Wheelchair'; + return TranslationBase.of(context).wheelchair; break; case Ambulate.Walker: - return 'Walker'; + return TranslationBase.of(context).walker; break; case Ambulate.Stretcher: - return 'Stretcher'; + return TranslationBase.of(context).stretcher; break; case Ambulate.None: - return 'None'; + return TranslationBase.of(context).none; break; } - return 'None'; + return TranslationBase.of(context).none; } int selectAmbulateNumber() { diff --git a/lib/core/enum/PaymentOptions.dart b/lib/core/enum/PaymentOptions.dart new file mode 100644 index 00000000..bbf43cb2 --- /dev/null +++ b/lib/core/enum/PaymentOptions.dart @@ -0,0 +1,34 @@ +enum PaymentOptions { + VISA, + MASTERCARD, + MADA, + INSTALLMENT, + APPLEPAY +} + +extension PaymentOptions_ on PaymentOptions{ + String value(){ + switch(this){ + case PaymentOptions.VISA: + return "VISA"; + break; + + case PaymentOptions.MASTERCARD: + return "MASTERCARD"; + break; + + case PaymentOptions.MADA: + return "MADA"; + break; + + case PaymentOptions.INSTALLMENT: + return "INSTALLMENT"; + break; + case PaymentOptions.APPLEPAY: + return "APPLEPAY"; + break; + } + + return null; + } +} diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart new file mode 100644 index 00000000..bb100219 --- /dev/null +++ b/lib/core/model/AlHabibMedicalService/H2O/user_detail_model.dart @@ -0,0 +1,104 @@ +class UserDetailModel { + int userID; + int patientID; + int patientType; + bool patientOutSA; + String firstName; + String middleName; + String lastName; + String firstNameN; + String middleNameN; + String lastNameN; + String identificationNo; + String mobile; + String emailID; + String zipCode; + String dOB; + String gender; + int activityID; + String createdDate; + double height; + double weight; + bool isHeightInCM; + bool isWeightInKG; + bool isNotificationON; + + UserDetailModel( + {this.userID, + this.patientID, + this.patientType, + this.patientOutSA, + this.firstName, + this.middleName, + this.lastName, + this.firstNameN, + this.middleNameN, + this.lastNameN, + this.identificationNo, + this.mobile, + this.emailID, + this.zipCode, + this.dOB, + this.gender, + this.activityID, + this.createdDate, + this.height, + this.weight, + this.isHeightInCM, + this.isWeightInKG, + this.isNotificationON}); + + UserDetailModel.fromJson(Map json) { + userID = json['UserID']; + patientID = json['PatientID']; + patientType = json['PatientType']; + patientOutSA = json['PatientOutSA']; + firstName = json['FirstName']; + middleName = json['MiddleName']; + lastName = json['LastName']; + firstNameN = json['FirstNameN']; + middleNameN = json['MiddleNameN']; + lastNameN = json['LastNameN']; + identificationNo = json['IdentificationNo']; + mobile = json['Mobile']; + emailID = json['EmailID']; + zipCode = json['ZipCode']; + dOB = json['DOB']; + gender = json['Gender']; + activityID = json['ActivityID']; + createdDate = json['CreatedDate']; + height = json['Height']; + weight = json['Weight']; + isHeightInCM = json['IsHeightInCM']; + isWeightInKG = json['IsWeightInKG']; + isNotificationON = json['IsNotificationON']; + } + + Map toJson() { + final Map data = new Map(); + data['UserID'] = this.userID; + data['PatientID'] = this.patientID; + data['PatientType'] = this.patientType; + data['PatientOutSA'] = this.patientOutSA; + data['FirstName'] = this.firstName; + data['MiddleName'] = this.middleName; + data['LastName'] = this.lastName; + data['FirstNameN'] = this.firstNameN; + data['MiddleNameN'] = this.middleNameN; + data['LastNameN'] = this.lastNameN; + data['IdentificationNo'] = this.identificationNo; + data['Mobile'] = this.mobile; + data['EmailID'] = this.emailID; + data['ZipCode'] = this.zipCode; + data['DOB'] = this.dOB; + data['Gender'] = this.gender; + data['ActivityID'] = this.activityID; + data['CreatedDate'] = this.createdDate; + data['Height'] = this.height; + data['Weight'] = this.weight; + data['IsHeightInCM'] = this.isHeightInCM; + data['IsWeightInKG'] = this.isWeightInKG; + data['IsNotificationON'] = this.isNotificationON; + return data; + } +} diff --git a/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart b/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart new file mode 100644 index 00000000..9d23d383 --- /dev/null +++ b/lib/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart @@ -0,0 +1,124 @@ +class UserDetailRequestModel { + String activityID; + int channel; + int deviceTypeID; + String dOB; + String email; + String firstName; + String gender; + String generalid; + double height; + String identificationNo; + String iPAdress; + bool isDentalAllowedBackend; + bool isHeightInCM; + bool isNotificationOn; + bool isWeightInKG; + int languageID; + String lastName; + String middleName; + String mobileNumber; + int patientID; + int patientOutSA; + int patientType; + int patientTypeID; + String sessionID; + String tokenID; + double versionID; + double weight; + String zipCode; + + UserDetailRequestModel( + {this.activityID, + this.channel, + this.deviceTypeID, + this.dOB, + this.email, + this.firstName, + this.gender, + this.generalid, + this.height, + this.identificationNo, + this.iPAdress, + this.isDentalAllowedBackend, + this.isHeightInCM, + this.isNotificationOn, + this.isWeightInKG, + this.languageID, + this.lastName, + this.middleName, + this.mobileNumber, + this.patientID, + this.patientOutSA, + this.patientType, + this.patientTypeID, + this.sessionID, + this.tokenID, + this.versionID, + this.weight, + this.zipCode}); + + UserDetailRequestModel.fromJson(Map json) { + activityID = json['ActivityID']; + channel = json['Channel']; + deviceTypeID = json['DeviceTypeID']; + dOB = json['DOB']; + email = json['Email']; + firstName = json['FirstName']; + gender = json['Gender']; + generalid = json['generalid']; + height = json['Height']; + identificationNo = json['IdentificationNo']; + iPAdress = json['IPAdress']; + isDentalAllowedBackend = json['isDentalAllowedBackend']; + isHeightInCM = json['IsHeightInCM']; + isNotificationOn = json['isNotificationOn']; + isWeightInKG = json['IsWeightInKG']; + languageID = json['LanguageID']; + lastName = json['LastName']; + middleName = json['MiddleName']; + mobileNumber = json['MobileNumber']; + patientID = json['PatientID']; + patientOutSA = json['PatientOutSA']; + patientType = json['PatientType']; + patientTypeID = json['PatientTypeID']; + sessionID = json['SessionID']; + tokenID = json['TokenID']; + versionID = json['VersionID']; + weight = json['Weight']; + zipCode = json['ZipCode']; + } + + Map toJson() { + final Map data = new Map(); + data['ActivityID'] = this.activityID; + data['Channel'] = this.channel; + data['DeviceTypeID'] = this.deviceTypeID; + data['DOB'] = this.dOB; + data['Email'] = this.email; + data['FirstName'] = this.firstName; + data['Gender'] = this.gender; + data['generalid'] = this.generalid; + data['Height'] = this.height; + data['IdentificationNo'] = this.identificationNo; + data['IPAdress'] = this.iPAdress; + data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; + data['IsHeightInCM'] = this.isHeightInCM; + data['isNotificationOn'] = this.isNotificationOn; + data['IsWeightInKG'] = this.isWeightInKG; + data['LanguageID'] = this.languageID; + data['LastName'] = this.lastName; + data['MiddleName'] = this.middleName; + data['MobileNumber'] = this.mobileNumber; + data['PatientID'] = this.patientID; + data['PatientOutSA'] = this.patientOutSA; + data['PatientType'] = this.patientType; + data['PatientTypeID'] = this.patientTypeID; + data['SessionID'] = this.sessionID; + data['TokenID'] = this.tokenID; + data['VersionID'] = this.versionID; + data['Weight'] = this.weight; + data['ZipCode'] = this.zipCode; + return data; + } +} \ No newline at end of file diff --git a/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart b/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart new file mode 100644 index 00000000..ff1f0eb0 --- /dev/null +++ b/lib/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart @@ -0,0 +1,68 @@ +class ClinicCategory { + int clinicID; + int categoryID; + String categoryName; + String categoryNameN; + String icon; + String bodyImageEN; + String fullImageEN; + String bodyImageAR; + String fullmageAR; + bool isActive; + bool isCategoryGroup; + Null sortOrderAR; + Null sortOrderEN; + String clinicName; + + ClinicCategory( + {this.clinicID, + this.categoryID, + this.categoryName, + this.categoryNameN, + this.icon, + this.bodyImageEN, + this.fullImageEN, + this.bodyImageAR, + this.fullmageAR, + this.isActive, + this.isCategoryGroup, + this.sortOrderAR, + this.sortOrderEN, + this.clinicName}); + + ClinicCategory.fromJson(Map json) { + clinicID = json['ClinicID']; + categoryID = json['CategoryID']; + categoryName = json['CategoryName']; + categoryNameN = json['CategoryNameN']; + icon = json['Icon']; + bodyImageEN = json['BodyImageEN']; + fullImageEN = json['FullImageEN']; + bodyImageAR = json['BodyImageAR']; + fullmageAR = json['FullmageAR']; + isActive = json['IsActive']; + isCategoryGroup = json['IsCategoryGroup']; + sortOrderAR = json['SortOrderAR']; + sortOrderEN = json['SortOrderEN']; + clinicName = json['ClinicName']; + } + + Map toJson() { + final Map data = new Map(); + data['ClinicID'] = this.clinicID; + data['CategoryID'] = this.categoryID; + data['CategoryName'] = this.categoryName; + data['CategoryNameN'] = this.categoryNameN; + data['Icon'] = this.icon; + data['BodyImageEN'] = this.bodyImageEN; + data['FullImageEN'] = this.fullImageEN; + data['BodyImageAR'] = this.bodyImageAR; + data['FullmageAR'] = this.fullmageAR; + data['IsActive'] = this.isActive; + data['IsCategoryGroup'] = this.isCategoryGroup; + data['SortOrderAR'] = this.sortOrderAR; + data['SortOrderEN'] = this.sortOrderEN; + data['ClinicName'] = this.clinicName; + return data; + } +} diff --git a/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart b/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart new file mode 100644 index 00000000..e92fa8da --- /dev/null +++ b/lib/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart @@ -0,0 +1,44 @@ +class DiseasesByClinic { + int diseasesID; + String diseasesEN; + String diseasesAR; + int diseasesCategoryID; + Null diseasesCategoryEN; + Null diseasesCategoryAR; + String diseases; + Null diseasesCategory; + + DiseasesByClinic( + {this.diseasesID, + this.diseasesEN, + this.diseasesAR, + this.diseasesCategoryID, + this.diseasesCategoryEN, + this.diseasesCategoryAR, + this.diseases, + this.diseasesCategory}); + + DiseasesByClinic.fromJson(Map json) { + diseasesID = json['DiseasesID']; + diseasesEN = json['Diseases_EN']; + diseasesAR = json['Diseases_AR']; + diseasesCategoryID = json['Diseases_CategoryID']; + diseasesCategoryEN = json['Diseases_CategoryEN']; + diseasesCategoryAR = json['Diseases_CategoryAR']; + diseases = json['Diseases']; + diseasesCategory = json['Diseases_Category']; + } + + Map toJson() { + final Map data = new Map(); + data['DiseasesID'] = this.diseasesID; + data['Diseases_EN'] = this.diseasesEN; + data['Diseases_AR'] = this.diseasesAR; + data['Diseases_CategoryID'] = this.diseasesCategoryID; + data['Diseases_CategoryEN'] = this.diseasesCategoryEN; + data['Diseases_CategoryAR'] = this.diseasesCategoryAR; + data['Diseases'] = this.diseases; + data['Diseases_Category'] = this.diseasesCategory; + return data; + } +} \ No newline at end of file diff --git a/lib/core/model/ImagesInfo.dart b/lib/core/model/ImagesInfo.dart index 5ab48fb3..54e8042b 100644 --- a/lib/core/model/ImagesInfo.dart +++ b/lib/core/model/ImagesInfo.dart @@ -1,6 +1,7 @@ class ImagesInfo { final String imageAr; final String imageEn; + final bool isAsset; - ImagesInfo({this.imageAr, this.imageEn}); + ImagesInfo({this.imageAr, this.imageEn, this.isAsset = false}); } diff --git a/lib/core/model/ResponseModel.dart b/lib/core/model/ResponseModel.dart new file mode 100644 index 00000000..f34abf7d --- /dev/null +++ b/lib/core/model/ResponseModel.dart @@ -0,0 +1,7 @@ +class ResponseModel{ + final bool status; + final String error; + final T data; + + ResponseModel({this.status, this.data, this.error}); +} \ No newline at end of file diff --git a/lib/core/model/er/ErPatientShareModel.dart b/lib/core/model/er/ErPatientShareModel.dart new file mode 100644 index 00000000..4c6a4165 --- /dev/null +++ b/lib/core/model/er/ErPatientShareModel.dart @@ -0,0 +1,92 @@ +class ErPatientShareModel { + int cashPrice; + int cashPriceTax; + int cashPriceWithTax; + int companyId; + String companyName; + int companyShareWithTax; + dynamic errCode; + int groupID; + dynamic insurancePolicyNo; + String message; + dynamic patientCardID; + double patientShare; + double patientShareWithTax; + double patientTaxAmount; + int policyId; + String policyName; + String procedureName; + dynamic setupID; + int statusCode; + dynamic subPolicyNo; + + ErPatientShareModel( + {this.cashPrice, + this.cashPriceTax, + this.cashPriceWithTax, + this.companyId, + this.companyName, + this.companyShareWithTax, + this.errCode, + this.groupID, + this.insurancePolicyNo, + this.message, + this.patientCardID, + this.patientShare, + this.patientShareWithTax, + this.patientTaxAmount, + this.policyId, + this.policyName, + this.procedureName, + this.setupID, + this.statusCode, + this.subPolicyNo}); + + ErPatientShareModel.fromJson(Map json) { + cashPrice = json['CashPrice']; + cashPriceTax = json['CashPriceTax']; + cashPriceWithTax = json['CashPriceWithTax']; + companyId = json['CompanyId']; + companyName = json['CompanyName']; + companyShareWithTax = json['CompanyShareWithTax']; + errCode = json['ErrCode']; + groupID = json['GroupID']; + insurancePolicyNo = json['InsurancePolicyNo']; + message = json['Message']; + patientCardID = json['PatientCardID']; + patientShare = json['PatientShare']; + patientShareWithTax = json['PatientShareWithTax']; + patientTaxAmount = json['PatientTaxAmount']; + policyId = json['PolicyId']; + policyName = json['PolicyName']; + procedureName = json['ProcedureName']; + setupID = json['SetupID']; + statusCode = json['StatusCode']; + subPolicyNo = json['SubPolicyNo']; + } + + Map toJson() { + final Map data = new Map(); + data['CashPrice'] = this.cashPrice; + data['CashPriceTax'] = this.cashPriceTax; + data['CashPriceWithTax'] = this.cashPriceWithTax; + data['CompanyId'] = this.companyId; + data['CompanyName'] = this.companyName; + data['CompanyShareWithTax'] = this.companyShareWithTax; + data['ErrCode'] = this.errCode; + data['GroupID'] = this.groupID; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + data['Message'] = this.message; + data['PatientCardID'] = this.patientCardID; + data['PatientShare'] = this.patientShare; + data['PatientShareWithTax'] = this.patientShareWithTax; + data['PatientTaxAmount'] = this.patientTaxAmount; + data['PolicyId'] = this.policyId; + data['PolicyName'] = this.policyName; + data['ProcedureName'] = this.procedureName; + data['SetupID'] = this.setupID; + data['StatusCode'] = this.statusCode; + data['SubPolicyNo'] = this.subPolicyNo; + return data; + } +} diff --git a/lib/core/model/er/PickUpRequestPresOrder.dart b/lib/core/model/er/PickUpRequestPresOrder.dart index 376e30ae..c4f359f5 100644 --- a/lib/core/model/er/PickUpRequestPresOrder.dart +++ b/lib/core/model/er/PickUpRequestPresOrder.dart @@ -18,8 +18,8 @@ class PickUpRequestPresOrder { int pickupSpot; dynamic dropoffLocationId; int transportationMethodId; - double cost; - double vAT; + dynamic cost; + dynamic vAT; double totalPrice; int amountCollected; int selectedAmbulate; diff --git a/lib/core/model/er/TriageInformationRequest.dart b/lib/core/model/er/TriageInformationRequest.dart new file mode 100644 index 00000000..a9717d3d --- /dev/null +++ b/lib/core/model/er/TriageInformationRequest.dart @@ -0,0 +1,147 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; + +class TriageInformationRequest { + double versionID; + int channel; + int languageID; + String iPAdress; + String sessionID; + int patientID; + String tokenID; + String generalid; + int patientOutSA; + int patientTypeID; + int patientType; + int projectID; + ERTriageInformation eRTriageInformation; + HospitalsModel selectedHospital; + TriageInformationRequest( + {this.versionID, + this.channel, + this.languageID, + this.iPAdress, + this.sessionID, + this.patientID, + this.tokenID, + this.generalid, + this.patientOutSA, + this.patientTypeID, + this.patientType, + this.projectID, + this.eRTriageInformation,this.selectedHospital}); + + TriageInformationRequest.fromJson(Map json) { + versionID = json['VersionID']; + channel = json['Channel']; + languageID = json['LanguageID']; + iPAdress = json['IPAdress']; + sessionID = json['SessionID']; + patientID = json['PatientID']; + tokenID = json['TokenID']; + generalid = json['generalid']; + patientOutSA = json['PatientOutSA']; + patientTypeID = json['PatientTypeID']; + patientType = json['PatientType']; + projectID = json['ProjectID']; + eRTriageInformation = json['ERTriageInformation'] != null + ? new ERTriageInformation.fromJson(json['ERTriageInformation']) + : null; + } + + Map toJson() { + final Map data = new Map(); + data['VersionID'] = this.versionID; + data['Channel'] = this.channel; + data['LanguageID'] = this.languageID; + data['IPAdress'] = this.iPAdress; + data['SessionID'] = this.sessionID; + data['PatientID'] = this.patientID; + data['TokenID'] = this.tokenID; + data['generalid'] = this.generalid; + data['PatientOutSA'] = this.patientOutSA; + data['PatientTypeID'] = this.patientTypeID; + data['PatientType'] = this.patientType; + data['ProjectID'] = this.projectID; + if (this.eRTriageInformation != null) { + data['ERTriageInformation'] = this.eRTriageInformation.toJson(); + } + return data; + } +} + +class ERTriageInformation { + String notes; + String chiefComplaint; + int patientId; + int projectId; + int riskScore; + List checklist; + + ERTriageInformation( + {this.notes, + this.chiefComplaint, + this.patientId, + this.projectId, + this.riskScore, + this.checklist}); + + ERTriageInformation.fromJson(Map json) { + notes = json['Notes']; + chiefComplaint = json['ChiefComplaint']; + patientId = json['PatientId']; + projectId = json['ProjectId']; + riskScore = json['RiskScore']; + if (json['checklist'] != null) { + checklist = new List(); + json['checklist'].forEach((v) { + checklist.add(new Checklist.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['Notes'] = this.notes; + data['ChiefComplaint'] = this.chiefComplaint; + data['PatientId'] = this.patientId; + data['ProjectId'] = this.projectId; + data['RiskScore'] = this.riskScore; + if (this.checklist != null) { + data['checklist'] = this.checklist.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Checklist { + int isSelected; + int parameterCode; + int parameterGroup; + int parameterType; + int score; + + Checklist( + {this.isSelected, + this.parameterCode, + this.parameterGroup, + this.parameterType, + this.score}); + + Checklist.fromJson(Map json) { + isSelected = json['IsSelected']; + parameterCode = json['ParameterCode']; + parameterGroup = json['ParameterGroup']; + parameterType = json['ParameterType']; + score = json['Score']; + } + + Map toJson() { + final Map data = new Map(); + data['IsSelected'] = this.isSelected; + data['ParameterCode'] = this.parameterCode; + data['ParameterGroup'] = this.parameterGroup; + data['ParameterType'] = this.parameterType; + data['Score'] = this.score; + return data; + } +} diff --git a/lib/core/model/er/TriageQuestionsModel.dart b/lib/core/model/er/TriageQuestionsModel.dart new file mode 100644 index 00000000..8960973e --- /dev/null +++ b/lib/core/model/er/TriageQuestionsModel.dart @@ -0,0 +1,52 @@ +class TriageQuestionsModel { + String adultPoints; + String headerSequence; + int parameterCode; + int parameterGroup; + int parameterType; + String pediaPoints; + String question; + String questionN; + String scoreGroup; + String titles; + + TriageQuestionsModel( + {this.adultPoints, + this.headerSequence, + this.parameterCode, + this.parameterGroup, + this.parameterType, + this.pediaPoints, + this.question, + this.questionN, + this.scoreGroup, + this.titles}); + + TriageQuestionsModel.fromJson(Map json) { + adultPoints = json['AdultPoints']; + headerSequence = json['HeaderSequence']; + parameterCode = json['ParameterCode']; + parameterGroup = json['ParameterGroup']; + parameterType = json['ParameterType']; + pediaPoints = json['PediaPoints']; + question = json['Question']; + questionN = json['QuestionN']; + scoreGroup = json['ScoreGroup']; + titles = json['Titles']; + } + + Map toJson() { + final Map data = new Map(); + data['AdultPoints'] = this.adultPoints; + data['HeaderSequence'] = this.headerSequence; + data['ParameterCode'] = this.parameterCode; + data['ParameterGroup'] = this.parameterGroup; + data['ParameterType'] = this.parameterType; + data['PediaPoints'] = this.pediaPoints; + data['Question'] = this.question; + data['QuestionN'] = this.questionN; + data['ScoreGroup'] = this.scoreGroup; + data['Titles'] = this.titles; + return data; + } +} diff --git a/lib/core/model/hospitals/hospitals_model.dart b/lib/core/model/hospitals/hospitals_model.dart index 264528c7..246de0b1 100644 --- a/lib/core/model/hospitals/hospitals_model.dart +++ b/lib/core/model/hospitals/hospitals_model.dart @@ -1,11 +1,11 @@ class HospitalsModel { String desciption; - Null desciptionN; + dynamic desciptionN; dynamic iD; String legalName; String legalNameN; String name; - Null nameN; + dynamic nameN; String phoneNumber; String setupID; dynamic distanceInKilometers; @@ -13,7 +13,7 @@ class HospitalsModel { String latitude; String longitude; dynamic mainProjectID; - Null projectOutSA; + dynamic projectOutSA; bool usingInDoctorApp; HospitalsModel( diff --git a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart index 5b95409e..86263155 100644 --- a/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart +++ b/lib/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart @@ -17,7 +17,7 @@ class DiabtecPatientResult { int patientID; var remark; var resultDesc; - int resultValue; + dynamic resultValue; String unit; var weekAverageResult; String weekDesc; diff --git a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart index c18e5433..3b1a8d9c 100644 --- a/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart +++ b/lib/core/model/my_trakers/blood_sugar/WeekDiabtectResultAverage.dart @@ -1,7 +1,7 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class WeekDiabtectResultAverage { - int dailyAverageResult; + dynamic dailyAverageResult; DateTime dateChart; WeekDiabtectResultAverage({this.dailyAverageResult, this.dateChart}); diff --git a/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart new file mode 100644 index 00000000..69e56ad7 --- /dev/null +++ b/lib/core/model/packages_offers/requests/AddProductToCartRequestModel.dart @@ -0,0 +1,26 @@ +import 'package:flutter/cupertino.dart'; + +class AddProductToCartRequestModel { + int quantity; + int product_id; + String shopping_cart_type; + int customer_id; + + AddProductToCartRequestModel({@required this.product_id, this.customer_id, this.shopping_cart_type = "ShoppingCart", this.quantity = 1}); + + Map json() { + return { + "shopping_cart_item" : { + "quantity": quantity, + "product_id": product_id, + "shopping_cart_type": shopping_cart_type, + "customer_id": customer_id + } + }; + } +} + +class UpdateProductToCartRequestModel extends AddProductToCartRequestModel{ + UpdateProductToCartRequestModel({@required int product_id, @required int customer_id, String shopping_cart_type = "ShoppingCart", int quantity = 1}) + : super(customer_id: customer_id, product_id: product_id, quantity: quantity, shopping_cart_type: shopping_cart_type); +} diff --git a/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart new file mode 100644 index 00000000..116545bd --- /dev/null +++ b/lib/core/model/packages_offers/requests/CreateCustomerRequestModel.dart @@ -0,0 +1,21 @@ +import 'package:flutter/cupertino.dart'; + +class PackagesCustomerRequestModel { + + String email; + String phoneNumber; + + PackagesCustomerRequestModel({@required this.email, @required this.phoneNumber}); + + Map json() { + return { + "customer" : { + "email": email, + "addresses": [{ + "email": email, + "phone_number": phoneNumber + }] + } + }; + } +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart index f2f4af11..13dba945 100644 --- a/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart @@ -6,6 +6,12 @@ class OffersCategoriesRequestModel { OffersCategoriesRequestModel({this.limit, this.page, this.sinceId}); Map toFlatMap() { - return {"limit": limit.toString(), "page": page.toString(), "sinceId": sinceId.toString()}; + return { + if(limit != null && limit > 0) + "limit": limit.toString(), + + if(page != null && page > 0) + "page": page.toString(), + }; } } diff --git a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart index 84862568..583932bb 100644 --- a/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart +++ b/lib/core/model/packages_offers/requests/OffersProductsRequestModel.dart @@ -1,12 +1,24 @@ class OffersProductsRequestModel { final int categoryId; final int limit; - final int page; - final int sinceId; + // final int page; + int sinceId; - OffersProductsRequestModel({this.categoryId, this.limit, this.page, this.sinceId}); + OffersProductsRequestModel({this.categoryId, this.limit = 50}); Map toFlatMap() { - return {"limit": limit.toString(), "page": page.toString(), "sinceId": sinceId.toString(), "categoryId": categoryId.toString()}; + return { + + if(limit != null && limit > 0) + "limit": limit.toString(), + + // if(page != null && page > 0) + // "page": page.toString(), + + if(categoryId != null && categoryId > 0) + "categoryId": categoryId.toString(), + + "sinceId": sinceId != null ? sinceId.toString() : "0", + }; } } diff --git a/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart new file mode 100644 index 00000000..99c8a8b4 --- /dev/null +++ b/lib/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart @@ -0,0 +1,132 @@ + +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; + +class PackagesCartItemsResponseModel { + int _quantity; + + set quantity(int value) { + _quantity = value; + } + + String _shoppingCartType; + int _productId; + PackagesResponseModel _product; + int _id; + + int get quantity => _quantity; + String get shoppingCartType => _shoppingCartType; + int get productId => _productId; + PackagesResponseModel get product => _product; + int get id => _id; + + PackagesCartItemsResponseModel({ + int quantity, + String shoppingCartType, + int productId, + PackagesResponseModel product, + int id}){ + _quantity = quantity; + _shoppingCartType = shoppingCartType; + _productId = productId; + _product = product; + _id = id; +} + + PackagesCartItemsResponseModel.fromJson(dynamic json) { + _quantity = json["quantity"]; + _shoppingCartType = json["shopping_cart_type"]; + _productId = json["product_id"]; + _product = json["product"] != null ? PackagesResponseModel().fromJson(json["product"]) : null; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["quantity"] = _quantity; + map["shopping_cart_type"] = _shoppingCartType; + map["product_id"] = _productId; + if (_product != null) { + map["product"] = _product.toJson(); + } + map["id"] = _id; + return map; + } + +} + +class Images { + int _id; + int _pictureId; + int _position; + String _src; + dynamic _attachment; + + int get id => _id; + int get pictureId => _pictureId; + int get position => _position; + String get src => _src; + dynamic get attachment => _attachment; + + Images({ + int id, + int pictureId, + int position, + String src, + dynamic attachment}){ + _id = id; + _pictureId = pictureId; + _position = position; + _src = src; + _attachment = attachment; +} + + Images.fromJson(dynamic json) { + _id = json["id"]; + _pictureId = json["picture_id"]; + _position = json["position"]; + _src = json["src"]; + _attachment = json["attachment"]; + } + + Map toJson() { + var map = {}; + map["id"] = _id; + map["picture_id"] = _pictureId; + map["position"] = _position; + map["src"] = _src; + map["attachment"] = _attachment; + return map; + } + +} + +/// language_id : 1 +/// localized_name : "Dermatology testing" + +class Localized_names { + int _languageId; + String _localizedName; + + int get languageId => _languageId; + String get localizedName => _localizedName; + + Localized_names({ + int languageId, + String localizedName}){ + _languageId = languageId; + _localizedName = localizedName; +} + + Localized_names.fromJson(dynamic json) { + _languageId = json["language_id"]; + _localizedName = json["localized_name"]; + } + + Map toJson() { + var map = {}; + map["language_id"] = _languageId; + map["localized_name"] = _localizedName; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart similarity index 82% rename from lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart rename to lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart index 087f1961..292022c0 100644 --- a/lib/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart @@ -1,8 +1,8 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class OfferCategoriesResponseModel with JsonConvert { - String id; +class PackagesCategoriesResponseModel with JsonConvert { + int id; String name; String namen; @JSONField(name: "localized_names") @@ -49,6 +49,18 @@ class OfferCategoriesResponseModel with JsonConvert { diff --git a/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart new file mode 100644 index 00000000..245973dd --- /dev/null +++ b/lib/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart @@ -0,0 +1,367 @@ +import 'PackagesCartItemsResponseModel.dart'; + +/// shopping_cart_items : [] +/// billing_address : null +/// shipping_address : null +/// addresses : [{"first_name":null,"last_name":null,"email":"a2zzuhaib@gmil.com","company":null,"country_id":null,"country":null,"state_province_id":null,"city":null,"address1":null,"address2":null,"zip_postal_code":null,"phone_number":"0500409598","fax_number":null,"customer_attributes":null,"created_on_utc":"2021-03-11T09:40:23.8091261Z","province":null,"id":0}] +/// customer_guid : "1367e5c7-be3b-43cc-ad81-ff1fc8d3b130" +/// username : null +/// email : "a2zzuhaib@gmil.com" +/// first_name : null +/// last_name : null +/// language_id : null +/// date_of_birth : null +/// gender : null +/// admin_comment : null +/// is_tax_exempt : false +/// has_shopping_cart_items : false +/// active : true +/// deleted : false +/// is_system_account : false +/// system_name : null +/// last_ip_address : null +/// created_on_utc : "2021-03-11T09:40:23.7535859Z" +/// last_login_date_utc : null +/// last_activity_date_utc : "2021-03-11T09:40:23.7535892Z" +/// registered_in_store_id : 0 +/// subscribed_to_newsletter : false +/// role_ids : [] +/// id : 76823 + +class PackagesCustomerResponseModel { + List _shoppingCartItems; + dynamic _billingAddress; + dynamic _shippingAddress; + List _addresses; + String _customerGuid; + dynamic _username; + String _email; + dynamic _firstName; + dynamic _lastName; + dynamic _languageId; + dynamic _dateOfBirth; + dynamic _gender; + dynamic _adminComment; + bool _isTaxExempt; + bool _hasShoppingCartItems; + bool _active; + bool _deleted; + bool _isSystemAccount; + dynamic _systemName; + dynamic _lastIpAddress; + String _createdOnUtc; + dynamic _lastLoginDateUtc; + String _lastActivityDateUtc; + int _registeredInStoreId; + bool _subscribedToNewsletter; + List _roleIds; + int _id; + + List get shoppingCartItems => _shoppingCartItems; + dynamic get billingAddress => _billingAddress; + dynamic get shippingAddress => _shippingAddress; + List get addresses => _addresses; + String get customerGuid => _customerGuid; + dynamic get username => _username; + String get email => _email; + dynamic get firstName => _firstName; + dynamic get lastName => _lastName; + dynamic get languageId => _languageId; + dynamic get dateOfBirth => _dateOfBirth; + dynamic get gender => _gender; + dynamic get adminComment => _adminComment; + bool get isTaxExempt => _isTaxExempt; + bool get hasShoppingCartItems => _hasShoppingCartItems; + bool get active => _active; + bool get deleted => _deleted; + bool get isSystemAccount => _isSystemAccount; + dynamic get systemName => _systemName; + dynamic get lastIpAddress => _lastIpAddress; + String get createdOnUtc => _createdOnUtc; + dynamic get lastLoginDateUtc => _lastLoginDateUtc; + String get lastActivityDateUtc => _lastActivityDateUtc; + int get registeredInStoreId => _registeredInStoreId; + bool get subscribedToNewsletter => _subscribedToNewsletter; + List get roleIds => _roleIds; + int get id => _id; + + PackagesCustomerResponseModel({ + List shoppingCartItems, + dynamic billingAddress, + dynamic shippingAddress, + List addresses, + String customerGuid, + dynamic username, + String email, + dynamic firstName, + dynamic lastName, + dynamic languageId, + dynamic dateOfBirth, + dynamic gender, + dynamic adminComment, + bool isTaxExempt, + bool hasShoppingCartItems, + bool active, + bool deleted, + bool isSystemAccount, + dynamic systemName, + dynamic lastIpAddress, + String createdOnUtc, + dynamic lastLoginDateUtc, + String lastActivityDateUtc, + int registeredInStoreId, + bool subscribedToNewsletter, + List roleIds, + int id}){ + _shoppingCartItems = shoppingCartItems; + _billingAddress = billingAddress; + _shippingAddress = shippingAddress; + _addresses = addresses; + _customerGuid = customerGuid; + _username = username; + _email = email; + _firstName = firstName; + _lastName = lastName; + _languageId = languageId; + _dateOfBirth = dateOfBirth; + _gender = gender; + _adminComment = adminComment; + _isTaxExempt = isTaxExempt; + _hasShoppingCartItems = hasShoppingCartItems; + _active = active; + _deleted = deleted; + _isSystemAccount = isSystemAccount; + _systemName = systemName; + _lastIpAddress = lastIpAddress; + _createdOnUtc = createdOnUtc; + _lastLoginDateUtc = lastLoginDateUtc; + _lastActivityDateUtc = lastActivityDateUtc; + _registeredInStoreId = registeredInStoreId; + _subscribedToNewsletter = subscribedToNewsletter; + _roleIds = roleIds; + _id = id; +} + + PackagesCustomerResponseModel.fromJson(dynamic json) { + _billingAddress = json["billing_address"]; + _shippingAddress = json["shipping_address"]; + if (json["addresses"] != null) { + _addresses = []; + json["addresses"].forEach((v) { + _addresses.add(Addresses.fromJson(v)); + }); + } + _customerGuid = json["customer_guid"]; + _username = json["username"]; + _email = json["email"]; + _firstName = json["first_name"]; + _lastName = json["last_name"]; + _languageId = json["language_id"]; + _dateOfBirth = json["date_of_birth"]; + _gender = json["gender"]; + _adminComment = json["admin_comment"]; + _isTaxExempt = json["is_tax_exempt"]; + _hasShoppingCartItems = json["has_shopping_cart_items"]; + _active = json["active"]; + _deleted = json["deleted"]; + _isSystemAccount = json["is_system_account"]; + _systemName = json["system_name"]; + _lastIpAddress = json["last_ip_address"]; + _createdOnUtc = json["created_on_utc"]; + _lastLoginDateUtc = json["last_login_date_utc"]; + _lastActivityDateUtc = json["last_activity_date_utc"]; + _registeredInStoreId = json["registered_in_store_id"]; + _subscribedToNewsletter = json["subscribed_to_newsletter"]; + + if (json["role_ids"] != null) { + _roleIds = []; + json["role_ids"].forEach((v) { + _roleIds.add(v); + }); + } + + if (json["shopping_cart_items"] != null) { + _shoppingCartItems = []; + json["shopping_cart_items"].forEach((v) { + _shoppingCartItems.add(PackagesCartItemsResponseModel.fromJson(v)); + }); + } + + _id = json["id"]; + } + + Map toJson() { + var map = {}; + if (_shoppingCartItems != null) { + map["shopping_cart_items"] = _shoppingCartItems.map((v) => v.toJson()).toList(); + } + map["billing_address"] = _billingAddress; + map["shipping_address"] = _shippingAddress; + if (_addresses != null) { + map["addresses"] = _addresses.map((v) => v.toJson()).toList(); + } + map["customer_guid"] = _customerGuid; + map["username"] = _username; + map["email"] = _email; + map["first_name"] = _firstName; + map["last_name"] = _lastName; + map["language_id"] = _languageId; + map["date_of_birth"] = _dateOfBirth; + map["gender"] = _gender; + map["admin_comment"] = _adminComment; + map["is_tax_exempt"] = _isTaxExempt; + map["has_shopping_cart_items"] = _hasShoppingCartItems; + map["active"] = _active; + map["deleted"] = _deleted; + map["is_system_account"] = _isSystemAccount; + map["system_name"] = _systemName; + map["last_ip_address"] = _lastIpAddress; + map["created_on_utc"] = _createdOnUtc; + map["last_login_date_utc"] = _lastLoginDateUtc; + map["last_activity_date_utc"] = _lastActivityDateUtc; + map["registered_in_store_id"] = _registeredInStoreId; + map["subscribed_to_newsletter"] = _subscribedToNewsletter; + if (_roleIds != null) { + map["role_ids"] = _roleIds.map((v) => v).toList(); + } + map["id"] = _id; + return map; + } + +} + +/// first_name : null +/// last_name : null +/// email : "a2zzuhaib@gmil.com" +/// company : null +/// country_id : null +/// country : null +/// state_province_id : null +/// city : null +/// address1 : null +/// address2 : null +/// zip_postal_code : null +/// phone_number : "0500409598" +/// fax_number : null +/// customer_attributes : null +/// created_on_utc : "2021-03-11T09:40:23.8091261Z" +/// province : null +/// id : 0 + +class Addresses { + dynamic _firstName; + dynamic _lastName; + String _email; + dynamic _company; + dynamic _countryId; + dynamic _country; + dynamic _stateProvinceId; + dynamic _city; + dynamic _address1; + dynamic _address2; + dynamic _zipPostalCode; + String _phoneNumber; + dynamic _faxNumber; + dynamic _customerAttributes; + String _createdOnUtc; + dynamic _province; + int _id; + + dynamic get firstName => _firstName; + dynamic get lastName => _lastName; + String get email => _email; + dynamic get company => _company; + dynamic get countryId => _countryId; + dynamic get country => _country; + dynamic get stateProvinceId => _stateProvinceId; + dynamic get city => _city; + dynamic get address1 => _address1; + dynamic get address2 => _address2; + dynamic get zipPostalCode => _zipPostalCode; + String get phoneNumber => _phoneNumber; + dynamic get faxNumber => _faxNumber; + dynamic get customerAttributes => _customerAttributes; + String get createdOnUtc => _createdOnUtc; + dynamic get province => _province; + int get id => _id; + + Addresses({ + dynamic firstName, + dynamic lastName, + String email, + dynamic company, + dynamic countryId, + dynamic country, + dynamic stateProvinceId, + dynamic city, + dynamic address1, + dynamic address2, + dynamic zipPostalCode, + String phoneNumber, + dynamic faxNumber, + dynamic customerAttributes, + String createdOnUtc, + dynamic province, + int id}){ + _firstName = firstName; + _lastName = lastName; + _email = email; + _company = company; + _countryId = countryId; + _country = country; + _stateProvinceId = stateProvinceId; + _city = city; + _address1 = address1; + _address2 = address2; + _zipPostalCode = zipPostalCode; + _phoneNumber = phoneNumber; + _faxNumber = faxNumber; + _customerAttributes = customerAttributes; + _createdOnUtc = createdOnUtc; + _province = province; + _id = id; +} + + Addresses.fromJson(dynamic json) { + _firstName = json["first_name"]; + _lastName = json["last_name"]; + _email = json["email"]; + _company = json["company"]; + _countryId = json["country_id"]; + _country = json["country"]; + _stateProvinceId = json["state_province_id"]; + _city = json["city"]; + _address1 = json["address1"]; + _address2 = json["address2"]; + _zipPostalCode = json["zip_postal_code"]; + _phoneNumber = json["phone_number"]; + _faxNumber = json["fax_number"]; + _customerAttributes = json["customer_attributes"]; + _createdOnUtc = json["created_on_utc"]; + _province = json["province"]; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["first_name"] = _firstName; + map["last_name"] = _lastName; + map["email"] = _email; + map["company"] = _company; + map["country_id"] = _countryId; + map["country"] = _country; + map["state_province_id"] = _stateProvinceId; + map["city"] = _city; + map["address1"] = _address1; + map["address2"] = _address2; + map["zip_postal_code"] = _zipPostalCode; + map["phone_number"] = _phoneNumber; + map["fax_number"] = _faxNumber; + map["customer_attributes"] = _customerAttributes; + map["created_on_utc"] = _createdOnUtc; + map["province"] = _province; + map["id"] = _id; + return map; + } + +} \ No newline at end of file diff --git a/lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart similarity index 95% rename from lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart rename to lib/core/model/packages_offers/responses/PackagesResponseModel.dart index 58481a8b..7297a20a 100644 --- a/lib/core/model/packages_offers/responses/OfferProductsResponseModel.dart +++ b/lib/core/model/packages_offers/responses/PackagesResponseModel.dart @@ -1,8 +1,8 @@ import 'package:diplomaticquarterapp/generated/json/base/json_convert_content.dart'; import 'package:diplomaticquarterapp/generated/json/base/json_field.dart'; -class OfferProductsResponseModel with JsonConvert { - String id; +class PackagesResponseModel with JsonConvert { + int id; @JSONField(name: "visible_individually") bool visibleIndividually; String name; @@ -205,6 +205,17 @@ class OfferProductsResponseModel with JsonConvert { int vendorId; @JSONField(name: "se_name") String seName; + + String getName() { + if(localizedNames.length == 2){ + if(localizedNames.first.languageId == 2) + return localizedNames.first.localizedName ?? name; + + else if(localizedNames.first.languageId == 1) + return localizedNames.last.localizedName ?? name; + } + return name; + } } class OfferProductsResponseModelLocalizedName with JsonConvert { diff --git a/lib/core/model/packages_offers/responses/order_response_model.dart b/lib/core/model/packages_offers/responses/order_response_model.dart new file mode 100644 index 00000000..ed53a765 --- /dev/null +++ b/lib/core/model/packages_offers/responses/order_response_model.dart @@ -0,0 +1,323 @@ + + +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'PackagesCartItemsResponseModel.dart'; + +class PackagesOrderResponseModel { + String _customOrderNumber; + int _storeId; + dynamic _pickUpInStore; + String _paymentMethodSystemName; + String _customerCurrencyCode; + double _currencyRate; + int _customerTaxDisplayTypeId; + dynamic _vatNumber; + double _orderSubtotalInclTax; + double _orderSubtotalExclTax; + double _orderSubTotalDiscountInclTax; + double _orderSubTotalDiscountExclTax; + double _orderShippingInclTax; + double _orderShippingExclTax; + double _paymentMethodAdditionalFeeInclTax; + double _paymentMethodAdditionalFeeExclTax; + String _taxRates; + double _orderTax; + double _orderDiscount; + double _orderTotal; + double _refundedAmount; + dynamic _rewardPointsWereAdded; + String _checkoutAttributeDescription; + int _customerLanguageId; + int _affiliateId; + String _customerIp; + dynamic _authorizationTransactionId; + dynamic _authorizationTransactionCode; + dynamic _authorizationTransactionResult; + dynamic _captureTransactionId; + dynamic _captureTransactionResult; + dynamic _subscriptionTransactionId; + dynamic _paidDateUtc; + dynamic _shippingMethod; + dynamic _shippingRateComputationMethodSystemName; + String _customValuesXml; + dynamic _paymentOption; + bool _deleted; + String _createdOnUtc; + PackagesCustomerResponseModel _customer; + int _customerId; + dynamic _billingAddress; + dynamic _shippingAddress; + List _orderItems; + String _orderStatus; + String _paymentStatus; + String _shippingStatus; + String _customerTaxDisplayType; + int _id; + + String get customOrderNumber => _customOrderNumber; + int get storeId => _storeId; + dynamic get pickUpInStore => _pickUpInStore; + String get paymentMethodSystemName => _paymentMethodSystemName; + String get customerCurrencyCode => _customerCurrencyCode; + double get currencyRate => _currencyRate; + int get customerTaxDisplayTypeId => _customerTaxDisplayTypeId; + dynamic get vatNumber => _vatNumber; + double get orderSubtotalInclTax => _orderSubtotalInclTax; + double get orderSubtotalExclTax => _orderSubtotalExclTax; + double get orderSubTotalDiscountInclTax => _orderSubTotalDiscountInclTax; + double get orderSubTotalDiscountExclTax => _orderSubTotalDiscountExclTax; + double get orderShippingInclTax => _orderShippingInclTax; + double get orderShippingExclTax => _orderShippingExclTax; + double get paymentMethodAdditionalFeeInclTax => _paymentMethodAdditionalFeeInclTax; + double get paymentMethodAdditionalFeeExclTax => _paymentMethodAdditionalFeeExclTax; + String get taxRates => _taxRates; + double get orderTax => _orderTax; + double get orderDiscount => _orderDiscount; + double get orderTotal => _orderTotal; + double get refundedAmount => _refundedAmount; + dynamic get rewardPointsWereAdded => _rewardPointsWereAdded; + String get checkoutAttributeDescription => _checkoutAttributeDescription; + int get customerLanguageId => _customerLanguageId; + int get affiliateId => _affiliateId; + String get customerIp => _customerIp; + dynamic get authorizationTransactionId => _authorizationTransactionId; + dynamic get authorizationTransactionCode => _authorizationTransactionCode; + dynamic get authorizationTransactionResult => _authorizationTransactionResult; + dynamic get captureTransactionId => _captureTransactionId; + dynamic get captureTransactionResult => _captureTransactionResult; + dynamic get subscriptionTransactionId => _subscriptionTransactionId; + dynamic get paidDateUtc => _paidDateUtc; + dynamic get shippingMethod => _shippingMethod; + dynamic get shippingRateComputationMethodSystemName => _shippingRateComputationMethodSystemName; + String get customValuesXml => _customValuesXml; + dynamic get paymentOption => _paymentOption; + bool get deleted => _deleted; + String get createdOnUtc => _createdOnUtc; + PackagesCustomerResponseModel get customer => _customer; + int get customerId => _customerId; + dynamic get billingAddress => _billingAddress; + dynamic get shippingAddress => _shippingAddress; + List get orderItems => _orderItems; + String get orderStatus => _orderStatus; + String get paymentStatus => _paymentStatus; + String get shippingStatus => _shippingStatus; + String get customerTaxDisplayType => _customerTaxDisplayType; + int get id => _id; + + OrderResponseModel({ + String customOrderNumber, + int storeId, + dynamic pickUpInStore, + String paymentMethodSystemName, + String customerCurrencyCode, + double currencyRate, + int customerTaxDisplayTypeId, + dynamic vatNumber, + double orderSubtotalInclTax, + double orderSubtotalExclTax, + double orderSubTotalDiscountInclTax, + double orderSubTotalDiscountExclTax, + double orderShippingInclTax, + double orderShippingExclTax, + double paymentMethodAdditionalFeeInclTax, + double paymentMethodAdditionalFeeExclTax, + String taxRates, + double orderTax, + double orderDiscount, + double orderTotal, + double refundedAmount, + dynamic rewardPointsWereAdded, + String checkoutAttributeDescription, + int customerLanguageId, + int affiliateId, + String customerIp, + dynamic authorizationTransactionId, + dynamic authorizationTransactionCode, + dynamic authorizationTransactionResult, + dynamic captureTransactionId, + dynamic captureTransactionResult, + dynamic subscriptionTransactionId, + dynamic paidDateUtc, + dynamic shippingMethod, + dynamic shippingRateComputationMethodSystemName, + String customValuesXml, + dynamic paymentOption, + bool deleted, + String createdOnUtc, + PackagesCustomerResponseModel customer, + int customerId, + dynamic billingAddress, + dynamic shippingAddress, + List orderItems, + String orderStatus, + String paymentStatus, + String shippingStatus, + String customerTaxDisplayType, + int id}){ + _customOrderNumber = customOrderNumber; + _storeId = storeId; + _pickUpInStore = pickUpInStore; + _paymentMethodSystemName = paymentMethodSystemName; + _customerCurrencyCode = customerCurrencyCode; + _currencyRate = currencyRate; + _customerTaxDisplayTypeId = customerTaxDisplayTypeId; + _vatNumber = vatNumber; + _orderSubtotalInclTax = orderSubtotalInclTax; + _orderSubtotalExclTax = orderSubtotalExclTax; + _orderSubTotalDiscountInclTax = orderSubTotalDiscountInclTax; + _orderSubTotalDiscountExclTax = orderSubTotalDiscountExclTax; + _orderShippingInclTax = orderShippingInclTax; + _orderShippingExclTax = orderShippingExclTax; + _paymentMethodAdditionalFeeInclTax = paymentMethodAdditionalFeeInclTax; + _paymentMethodAdditionalFeeExclTax = paymentMethodAdditionalFeeExclTax; + _taxRates = taxRates; + _orderTax = orderTax; + _orderDiscount = orderDiscount; + _orderTotal = orderTotal; + _refundedAmount = refundedAmount; + _rewardPointsWereAdded = rewardPointsWereAdded; + _checkoutAttributeDescription = checkoutAttributeDescription; + _customerLanguageId = customerLanguageId; + _affiliateId = affiliateId; + _customerIp = customerIp; + _authorizationTransactionId = authorizationTransactionId; + _authorizationTransactionCode = authorizationTransactionCode; + _authorizationTransactionResult = authorizationTransactionResult; + _captureTransactionId = captureTransactionId; + _captureTransactionResult = captureTransactionResult; + _subscriptionTransactionId = subscriptionTransactionId; + _paidDateUtc = paidDateUtc; + _shippingMethod = shippingMethod; + _shippingRateComputationMethodSystemName = shippingRateComputationMethodSystemName; + _customValuesXml = customValuesXml; + _paymentOption = paymentOption; + _deleted = deleted; + _createdOnUtc = createdOnUtc; + _customer = customer; + _customerId = customerId; + _billingAddress = billingAddress; + _shippingAddress = shippingAddress; + _orderItems = orderItems; + _orderStatus = orderStatus; + _paymentStatus = paymentStatus; + _shippingStatus = shippingStatus; + _customerTaxDisplayType = customerTaxDisplayType; + _id = id; +} + + PackagesOrderResponseModel.fromJson(dynamic json) { + _customOrderNumber = json["custom_order_number"]; + _storeId = json["store_id"]; + _pickUpInStore = json["pick_up_in_store"]; + _paymentMethodSystemName = json["payment_method_system_name"]; + _customerCurrencyCode = json["customer_currency_code"]; + _currencyRate = json["currency_rate"]; + _customerTaxDisplayTypeId = json["customer_tax_display_type_id"]; + _vatNumber = json["vat_number"]; + _orderSubtotalInclTax = json["order_subtotal_incl_tax"]; + _orderSubtotalExclTax = json["order_subtotal_excl_tax"]; + _orderSubTotalDiscountInclTax = json["order_sub_total_discount_incl_tax"]; + _orderSubTotalDiscountExclTax = json["order_sub_total_discount_excl_tax"]; + _orderShippingInclTax = json["order_shipping_incl_tax"]; + _orderShippingExclTax = json["order_shipping_excl_tax"]; + _paymentMethodAdditionalFeeInclTax = json["payment_method_additional_fee_incl_tax"]; + _paymentMethodAdditionalFeeExclTax = json["payment_method_additional_fee_excl_tax"]; + _taxRates = json["tax_rates"]; + _orderTax = json["order_tax"]; + _orderDiscount = json["order_discount"]; + _orderTotal = json["order_total"]; + _refundedAmount = json["refunded_amount"]; + _rewardPointsWereAdded = json["reward_points_were_added"]; + _checkoutAttributeDescription = json["checkout_attribute_description"]; + _customerLanguageId = json["customer_language_id"]; + _affiliateId = json["affiliate_id"]; + _customerIp = json["customer_ip"]; + _authorizationTransactionId = json["authorization_transaction_id"]; + _authorizationTransactionCode = json["authorization_transaction_code"]; + _authorizationTransactionResult = json["authorization_transaction_result"]; + _captureTransactionId = json["capture_transaction_id"]; + _captureTransactionResult = json["capture_transaction_result"]; + _subscriptionTransactionId = json["subscription_transaction_id"]; + _paidDateUtc = json["paid_date_utc"]; + _shippingMethod = json["shipping_method"]; + _shippingRateComputationMethodSystemName = json["shipping_rate_computation_method_system_name"]; + _customValuesXml = json["custom_values_xml"]; + _paymentOption = json["payment_option"]; + _deleted = json["deleted"]; + _createdOnUtc = json["created_on_utc"]; + _customer = json["customer"] != null ? PackagesCustomerResponseModel.fromJson(json["customer"]) : null; + _customerId = json["customer_id"]; + _billingAddress = json["billing_address"]; + _shippingAddress = json["shipping_address"]; + if (json["order_items"] != null) { + _orderItems = []; + json["order_items"].forEach((v) { + _orderItems.add(PackagesCartItemsResponseModel.fromJson(v)); + }); + } + _orderStatus = json["order_status"]; + _paymentStatus = json["payment_status"]; + _shippingStatus = json["shipping_status"]; + _customerTaxDisplayType = json["customer_tax_display_type"]; + _id = json["id"]; + } + + Map toJson() { + var map = {}; + map["custom_order_number"] = _customOrderNumber; + map["store_id"] = _storeId; + map["pick_up_in_store"] = _pickUpInStore; + map["payment_method_system_name"] = _paymentMethodSystemName; + map["customer_currency_code"] = _customerCurrencyCode; + map["currency_rate"] = _currencyRate; + map["customer_tax_display_type_id"] = _customerTaxDisplayTypeId; + map["vat_number"] = _vatNumber; + map["order_subtotal_incl_tax"] = _orderSubtotalInclTax; + map["order_subtotal_excl_tax"] = _orderSubtotalExclTax; + map["order_sub_total_discount_incl_tax"] = _orderSubTotalDiscountInclTax; + map["order_sub_total_discount_excl_tax"] = _orderSubTotalDiscountExclTax; + map["order_shipping_incl_tax"] = _orderShippingInclTax; + map["order_shipping_excl_tax"] = _orderShippingExclTax; + map["payment_method_additional_fee_incl_tax"] = _paymentMethodAdditionalFeeInclTax; + map["payment_method_additional_fee_excl_tax"] = _paymentMethodAdditionalFeeExclTax; + map["tax_rates"] = _taxRates; + map["order_tax"] = _orderTax; + map["order_discount"] = _orderDiscount; + map["order_total"] = _orderTotal; + map["refunded_amount"] = _refundedAmount; + map["reward_points_were_added"] = _rewardPointsWereAdded; + map["checkout_attribute_description"] = _checkoutAttributeDescription; + map["customer_language_id"] = _customerLanguageId; + map["affiliate_id"] = _affiliateId; + map["customer_ip"] = _customerIp; + map["authorization_transaction_id"] = _authorizationTransactionId; + map["authorization_transaction_code"] = _authorizationTransactionCode; + map["authorization_transaction_result"] = _authorizationTransactionResult; + map["capture_transaction_id"] = _captureTransactionId; + map["capture_transaction_result"] = _captureTransactionResult; + map["subscription_transaction_id"] = _subscriptionTransactionId; + map["paid_date_utc"] = _paidDateUtc; + map["shipping_method"] = _shippingMethod; + map["shipping_rate_computation_method_system_name"] = _shippingRateComputationMethodSystemName; + map["custom_values_xml"] = _customValuesXml; + map["payment_option"] = _paymentOption; + map["deleted"] = _deleted; + map["created_on_utc"] = _createdOnUtc; + if (_customer != null) { + map["customer"] = _customer.toJson(); + } + map["customer_id"] = _customerId; + map["billing_address"] = _billingAddress; + map["shipping_address"] = _shippingAddress; + if (_orderItems != null) { + map["order_items"] = _orderItems.map((v) => v.toJson()).toList(); + } + map["order_status"] = _orderStatus; + map["payment_status"] = _paymentStatus; + map["shipping_status"] = _shippingStatus; + map["customer_tax_display_type"] = _customerTaxDisplayType; + map["id"] = _id; + return map; + } + +} diff --git a/lib/core/model/pharmacies/BillingAddress.dart b/lib/core/model/pharmacies/BillingAddress.dart index 765ac54d..418b28a7 100644 --- a/lib/core/model/pharmacies/BillingAddress.dart +++ b/lib/core/model/pharmacies/BillingAddress.dart @@ -1,3 +1,5 @@ +import 'package:google_maps_flutter/google_maps_flutter.dart'; + class BillingAddress { String id; String firstName; @@ -81,4 +83,19 @@ class BillingAddress { data['lat_long'] = this.latLong; return data; } + + LatLng getLocation(){ + if(latLong.contains(',')){ + var parts = latLong.trim().split(','); + if(parts.length == 2){ + var lat = double.tryParse(parts.first); + var lng = double.tryParse(parts.last); + if(lat != null || lng != null) { + var location = LatLng(lat, lng); + return location; + } + } + } + return null; + } } diff --git a/lib/core/model/pharmacies/Customer.dart b/lib/core/model/pharmacies/Customer.dart index e3defbbe..9042930e 100644 --- a/lib/core/model/pharmacies/Customer.dart +++ b/lib/core/model/pharmacies/Customer.dart @@ -32,6 +32,7 @@ class Customer { String lastLoginDateUtc; String lastActivityDateUtc; int registeredInStoreId; + List roleIds; Customer( {this.billingAddress, @@ -63,7 +64,8 @@ class Customer { this.createdOnUtc, this.lastLoginDateUtc, this.lastActivityDateUtc, - this.registeredInStoreId}); + this.registeredInStoreId, + this.roleIds}); Customer.fromJson(Map json) { billingAddress = json['billing_address'] != null @@ -105,6 +107,12 @@ class Customer { lastLoginDateUtc = json['last_login_date_utc']; lastActivityDateUtc = json['last_activity_date_utc']; registeredInStoreId = json['registered_in_store_id']; + if (json['role_ids'] != null) { + roleIds = new List(); + json['role_ids'].forEach((v) { + roleIds.add(v); + }); + } } Map toJson() { @@ -145,6 +153,7 @@ class Customer { data['last_login_date_utc'] = this.lastLoginDateUtc; data['last_activity_date_utc'] = this.lastActivityDateUtc; data['registered_in_store_id'] = this.registeredInStoreId; + data['role_ids'] = this.roleIds; return data; } } diff --git a/lib/core/model/pharmacies/PharmacyProduct.dart b/lib/core/model/pharmacies/PharmacyProduct.dart index c472cb4c..f69d035b 100644 --- a/lib/core/model/pharmacies/PharmacyProduct.dart +++ b/lib/core/model/pharmacies/PharmacyProduct.dart @@ -4,29 +4,29 @@ import 'PharmacyImageObject.dart'; import 'Reviews.dart'; class PharmacyProduct { - String id; + dynamic id; bool visibleIndividually; - String name; - String namen; - String shortDescription; - String shortDescriptionn; - String fullDescription; - String fullDescriptionn; + dynamic name; + dynamic namen; + dynamic shortDescription; + dynamic shortDescriptionn; + dynamic fullDescription; + dynamic fullDescriptionn; bool markasNew; bool showOnHomePage; - String metaKeywords; - String metaDescription; - String metaTitle; + dynamic metaKeywords; + dynamic metaDescription; + dynamic metaTitle; bool allowCustomerReviews; int approvedRatingSum; int notApprovedRatingSum; int approvedTotalReviews; int notApprovedTotalReviews; - String sku; + dynamic sku; bool isRx; bool prescriptionRequired; - String rxMessage; - String rxMessagen; + dynamic rxMessage; + dynamic rxMessagen; String manufacturerPartNumber; String gtin; bool isGiftCard; @@ -115,118 +115,117 @@ class PharmacyProduct { int vendorId; String seName; - PharmacyProduct( {this.id, - this.visibleIndividually, - this.name, - this.namen, - this.shortDescription, - this.shortDescriptionn, - this.fullDescription, - this.fullDescriptionn, - this.markasNew, - this.showOnHomePage, - this.metaKeywords, - this.metaDescription, - this.metaTitle, - this.allowCustomerReviews, - this.approvedRatingSum, - this.notApprovedRatingSum, - this.approvedTotalReviews, - this.notApprovedTotalReviews, - this.sku, - this.isRx, - this.prescriptionRequired, - this.rxMessage, - this.rxMessagen, - this.manufacturerPartNumber, - this.gtin, - this.isGiftCard, - this.requireOtherProducts, - this.automaticallyAddRequiredProducts, - this.isDownload, - this.unlimitedDownloads, - this.maxNumberOfDownloads, - this.downloadExpirationDays, - this.hasSampleDownload, - this.hasUserAgreement, - this.isRecurring, - this.recurringCycleLength, - this.recurringTotalCycles, - this.isRental, - this.rentalPriceLength, - this.isShipEnabled, - this.isFreeShipping, - this.shipSeparately, - this.additionalShippingCharge, - this.isTaxExempt, - this.isTelecommunicationsOrBroadcastingOrElectronicServices, - this.useMultipleWarehouses, - this.manageInventoryMethodId, - this.stockQuantity, - this.stockAvailability, - this.stockAvailabilityn, - this.displayStockAvailability, - this.displayStockQuantity, - this.minStockQuantity, - this.notifyAdminForQuantityBelow, - this.allowBackInStockSubscriptions, - this.orderMinimumQuantity, - this.orderMaximumQuantity, - this.allowedQuantities, - this.allowAddingOnlyExistingAttributeCombinations, - this.disableBuyButton, - this.disableWishlistButton, - this.availableForPreOrder, - this.preOrderAvailabilityStartDateTimeUtc, - this.callForPrice, - this.price, - this.oldPrice, - this.productCost, - this.specialPrice, - this.specialPriceStartDateTimeUtc, - this.specialPriceEndDateTimeUtc, - this.customerEntersPrice, - this.minimumCustomerEnteredPrice, - this.maximumCustomerEnteredPrice, - this.basepriceEnabled, - this.basepriceAmount, - this.basepriceBaseAmount, - this.hasTierPrices, - this.hasDiscountsApplied, - this.discountName, - this.discountNamen, - this.discountDescription, - this.discountDescriptionn, - this.discountPercentage, - this.currency, - this.currencyn, - this.weight, - this.length, - this.width, - this.height, - this.availableStartDateTimeUtc, - this.availableEndDateTimeUtc, - this.displayOrder, - this.published, - this.deleted, - this.createdOnUtc, - this.updatedOnUtc, - this.productType, - this.parentGroupedProductId, - this.roleIds, - this.discountIds, - this.storeIds, - this.manufacturerIds, - this.reviews, - this.images, - this.attributes, - this.specifications, - this.associatedProductIds, - this.tags, - this.vendorId, - this.seName}); + this.visibleIndividually, + this.name, + this.namen, + this.shortDescription, + this.shortDescriptionn, + this.fullDescription, + this.fullDescriptionn, + this.markasNew, + this.showOnHomePage, + this.metaKeywords, + this.metaDescription, + this.metaTitle, + this.allowCustomerReviews, + this.approvedRatingSum, + this.notApprovedRatingSum, + this.approvedTotalReviews, + this.notApprovedTotalReviews, + this.sku, + this.isRx, + this.prescriptionRequired, + this.rxMessage, + this.rxMessagen, + this.manufacturerPartNumber, + this.gtin, + this.isGiftCard, + this.requireOtherProducts, + this.automaticallyAddRequiredProducts, + this.isDownload, + this.unlimitedDownloads, + this.maxNumberOfDownloads, + this.downloadExpirationDays, + this.hasSampleDownload, + this.hasUserAgreement, + this.isRecurring, + this.recurringCycleLength, + this.recurringTotalCycles, + this.isRental, + this.rentalPriceLength, + this.isShipEnabled, + this.isFreeShipping, + this.shipSeparately, + this.additionalShippingCharge, + this.isTaxExempt, + this.isTelecommunicationsOrBroadcastingOrElectronicServices, + this.useMultipleWarehouses, + this.manageInventoryMethodId, + this.stockQuantity, + this.stockAvailability, + this.stockAvailabilityn, + this.displayStockAvailability, + this.displayStockQuantity, + this.minStockQuantity, + this.notifyAdminForQuantityBelow, + this.allowBackInStockSubscriptions, + this.orderMinimumQuantity, + this.orderMaximumQuantity, + this.allowedQuantities, + this.allowAddingOnlyExistingAttributeCombinations, + this.disableBuyButton, + this.disableWishlistButton, + this.availableForPreOrder, + this.preOrderAvailabilityStartDateTimeUtc, + this.callForPrice, + this.price, + this.oldPrice, + this.productCost, + this.specialPrice, + this.specialPriceStartDateTimeUtc, + this.specialPriceEndDateTimeUtc, + this.customerEntersPrice, + this.minimumCustomerEnteredPrice, + this.maximumCustomerEnteredPrice, + this.basepriceEnabled, + this.basepriceAmount, + this.basepriceBaseAmount, + this.hasTierPrices, + this.hasDiscountsApplied, + this.discountName, + this.discountNamen, + this.discountDescription, + this.discountDescriptionn, + this.discountPercentage, + this.currency, + this.currencyn, + this.weight, + this.length, + this.width, + this.height, + this.availableStartDateTimeUtc, + this.availableEndDateTimeUtc, + this.displayOrder, + this.published, + this.deleted, + this.createdOnUtc, + this.updatedOnUtc, + this.productType, + this.parentGroupedProductId, + this.roleIds, + this.discountIds, + this.storeIds, + this.manufacturerIds, + this.reviews, + this.images, + this.attributes, + this.specifications, + this.associatedProductIds, + this.tags, + this.vendorId, + this.seName}); PharmacyProduct.fromJson(Map json) { id = json['id']; @@ -257,7 +256,7 @@ class PharmacyProduct { isGiftCard = json['is_gift_card']; requireOtherProducts = json['require_other_products']; automaticallyAddRequiredProducts = - json['automatically_add_required_products']; + json['automatically_add_required_products']; isDownload = json['is_download']; unlimitedDownloads = json['unlimited_downloads']; maxNumberOfDownloads = json['max_number_of_downloads']; @@ -275,7 +274,7 @@ class PharmacyProduct { additionalShippingCharge = json['additional_shipping_charge']; isTaxExempt = json['is_tax_exempt']; isTelecommunicationsOrBroadcastingOrElectronicServices = - json['is_telecommunications_or_broadcasting_or_electronic_services']; + json['is_telecommunications_or_broadcasting_or_electronic_services']; useMultipleWarehouses = json['use_multiple_warehouses']; manageInventoryMethodId = json['manage_inventory_method_id']; stockQuantity = json['stock_quantity']; @@ -290,12 +289,12 @@ class PharmacyProduct { orderMaximumQuantity = json['order_maximum_quantity']; allowedQuantities = json['allowed_quantities']; allowAddingOnlyExistingAttributeCombinations = - json['allow_adding_only_existing_attribute_combinations']; + json['allow_adding_only_existing_attribute_combinations']; disableBuyButton = json['disable_buy_button']; disableWishlistButton = json['disable_wishlist_button']; availableForPreOrder = json['available_for_pre_order']; preOrderAvailabilityStartDateTimeUtc = - json['pre_order_availability_start_date_time_utc']; + json['pre_order_availability_start_date_time_utc']; callForPrice = json['call_for_price']; price = json['price']; oldPrice = json['old_price']; diff --git a/lib/core/model/pharmacies/Prescriptions.dart b/lib/core/model/pharmacies/Prescriptions.dart new file mode 100644 index 00000000..80caff0a --- /dev/null +++ b/lib/core/model/pharmacies/Prescriptions.dart @@ -0,0 +1,157 @@ + + +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class Prescriptions { + String setupID; + int projectID; + int patientID; + int appointmentNo; + String appointmentDate; + String doctorName; + String clinicDescription; + String name; + int episodeID; + int actualDoctorRate; + int admission; + int clinicID; + String companyName; + String despensedStatus; + DateTime dischargeDate; + int dischargeNo; + int doctorID; + String doctorImageURL; + int doctorRate; + String doctorTitle; + int gender; + String genderDescription; + bool isActiveDoctorProfile; + bool isDoctorAllowVedioCall; + bool isExecludeDoctor; + bool isInOutPatient; + String isInOutPatientDescription; + String isInOutPatientDescriptionN; + bool isInsurancePatient; + String nationalityFlagURL; + int noOfPatientsRate; + String qR; + List speciality; + + Prescriptions( + {this.setupID, + this.projectID, + this.patientID, + this.appointmentNo, + this.appointmentDate, + this.doctorName, + this.clinicDescription, + this.name, + this.episodeID, + this.actualDoctorRate, + this.admission, + this.clinicID, + this.companyName, + this.despensedStatus, + this.dischargeDate, + this.dischargeNo, + this.doctorID, + this.doctorImageURL, + this.doctorRate, + this.doctorTitle, + this.gender, + this.genderDescription, + this.isActiveDoctorProfile, + this.isDoctorAllowVedioCall, + this.isExecludeDoctor, + this.isInOutPatient, + this.isInOutPatientDescription, + this.isInOutPatientDescriptionN, + this.isInsurancePatient, + this.nationalityFlagURL, + this.noOfPatientsRate, + this.qR, + this.speciality}); + + Prescriptions.fromJson(Map json) { + setupID = json['SetupID']; + projectID = json['ProjectID']; + patientID = json['PatientID']; + appointmentNo = json['AppointmentNo']; + appointmentDate = json['AppointmentDate']; + doctorName = json['DoctorName']; + clinicDescription = json['ClinicDescription']; + name = json['Name']; + episodeID = json['EpisodeID']; + actualDoctorRate = json['ActualDoctorRate']; + admission = json['Admission']; + clinicID = json['ClinicID']; + companyName = json['CompanyName']; + despensedStatus = json['Despensed_Status']; + dischargeDate = DateUtil.convertStringToDate(json['DischargeDate']); + dischargeNo = json['DischargeNo']; + doctorID = json['DoctorID']; + doctorImageURL = json['DoctorImageURL']; + doctorRate = json['DoctorRate']; + doctorTitle = json['DoctorTitle']; + gender = json['Gender']; + genderDescription = json['GenderDescription']; + isActiveDoctorProfile = json['IsActiveDoctorProfile']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isExecludeDoctor = json['IsExecludeDoctor']; + isInOutPatient = json['IsInOutPatient']; + isInOutPatientDescription = json['IsInOutPatientDescription']; + isInOutPatientDescriptionN = json['IsInOutPatientDescriptionN']; + isInsurancePatient = json['IsInsurancePatient']; + nationalityFlagURL = json['NationalityFlagURL']; + noOfPatientsRate = json['NoOfPatientsRate']; + qR = json['QR']; + // speciality = json['Speciality'].cast(); + } + + Map toJson() { + final Map data = new Map(); + data['SetupID'] = this.setupID; + data['ProjectID'] = this.projectID; + data['PatientID'] = this.patientID; + data['AppointmentNo'] = this.appointmentNo; + data['AppointmentDate'] = this.appointmentDate; + data['DoctorName'] = this.doctorName; + data['ClinicDescription'] = this.clinicDescription; + data['Name'] = this.name; + data['EpisodeID'] = this.episodeID; + data['ActualDoctorRate'] = this.actualDoctorRate; + data['Admission'] = this.admission; + data['ClinicID'] = this.clinicID; + data['CompanyName'] = this.companyName; + data['Despensed_Status'] = this.despensedStatus; + data['DischargeDate'] = this.dischargeDate; + data['DischargeNo'] = this.dischargeNo; + data['DoctorID'] = this.doctorID; + data['DoctorImageURL'] = this.doctorImageURL; + data['DoctorRate'] = this.doctorRate; + data['DoctorTitle'] = this.doctorTitle; + data['Gender'] = this.gender; + data['GenderDescription'] = this.genderDescription; + data['IsActiveDoctorProfile'] = this.isActiveDoctorProfile; + data['IsDoctorAllowVedioCall'] = this.isDoctorAllowVedioCall; + data['IsExecludeDoctor'] = this.isExecludeDoctor; + data['IsInOutPatient'] = this.isInOutPatient; + data['IsInOutPatientDescription'] = this.isInOutPatientDescription; + data['IsInOutPatientDescriptionN'] = this.isInOutPatientDescriptionN; + data['IsInsurancePatient'] = this.isInsurancePatient; + data['NationalityFlagURL'] = this.nationalityFlagURL; + data['NoOfPatientsRate'] = this.noOfPatientsRate; + data['QR'] = this.qR; + data['Speciality'] = this.speciality; + return data; + } +} + +//class PrescriptionsList { +// String filterName = ""; +// List prescriptionsList = List(); +// +// PrescriptionsList({this.filterName, Prescriptions prescriptions}) { +// prescriptionsList.add(prescriptions); +// } +//} diff --git a/lib/core/model/pharmacies/Reviews.dart b/lib/core/model/pharmacies/Reviews.dart index f924dce3..2c767cdd 100644 --- a/lib/core/model/pharmacies/Reviews.dart +++ b/lib/core/model/pharmacies/Reviews.dart @@ -10,13 +10,13 @@ class Reviews { bool isApproved; String title; String reviewText; - Null replyText; + String replyText; int rating; int helpfulYesTotal; int helpfulNoTotal; String createdOnUtc; Customer customer; - Null product; + //Null product; Reviews( {this.id, @@ -34,7 +34,8 @@ class Reviews { this.helpfulNoTotal, this.createdOnUtc, this.customer, - this.product}); + // this.product + }); Reviews.fromJson(Map json) { id = json['id']; @@ -54,7 +55,7 @@ class Reviews { customer = json['customer'] != null ? new Customer.fromJson(json['customer']) : null; - product = json['product']; + // product = json['product']; } Map toJson() { @@ -76,7 +77,7 @@ class Reviews { if (this.customer != null) { data['customer'] = this.customer.toJson(); } - data['product'] = this.product; + // data['product'] = this.product; return data; } } \ No newline at end of file diff --git a/lib/core/model/pharmacies/ShoppingCart.dart b/lib/core/model/pharmacies/ShoppingCart.dart index f965203a..4bd460aa 100644 --- a/lib/core/model/pharmacies/ShoppingCart.dart +++ b/lib/core/model/pharmacies/ShoppingCart.dart @@ -7,22 +7,33 @@ class ShoppingCart { // List productAttributes; double customerEnteredPrice; int quantity; - String discountAmountInclTax; - String subtotal; - String subtotalWithVat; - String subtotalVatAmount; - String subtotalVatRate; - String currency; - String currencyn; - String rentalStartDateUtc; - String rentalEndDateUtc; - String createdOnUtc; - String updatedOnUtc; - String shoppingCartType; + dynamic discountAmountInclTax; + dynamic subtotal; + dynamic subtotalWithVat; + dynamic subtotalVatAmount; + dynamic subtotalVatRate; + dynamic currency; + dynamic currencyn; + dynamic rentalStartDateUtc; + dynamic rentalEndDateUtc; + dynamic createdOnUtc; + dynamic updatedOnUtc; + dynamic shoppingCartType; int productId; PharmacyProduct product; int customerId; Customer customer; + double unitPriceInclTax; + double unitPriceExclTax; + double priceInclTax; + double priceExclTax; + dynamic discountAmountExclTax; + double originalProductCost; + String attributeDescription; + int downloadCount; + bool isDownloadActivated; + int licenseDownloadId; + double itemWeight; ShoppingCart( {this.languageId, @@ -45,7 +56,19 @@ class ShoppingCart { this.productId, this.product, this.customerId, - this.customer}); + this.customer, + this.unitPriceInclTax, + this.unitPriceExclTax, + this.priceInclTax, + this.priceExclTax, + this.discountAmountExclTax, + this.originalProductCost, + this.attributeDescription, + this.downloadCount, + this.isDownloadActivated, + this.licenseDownloadId, + this.itemWeight, + }); ShoppingCart.fromJson(Map json) { languageId = json['language_id']; @@ -78,6 +101,18 @@ class ShoppingCart { customer = json['customer'] != null ? new Customer.fromJson(json['customer']) : null; + + unitPriceInclTax = json['unit_price_incl_tax']; + unitPriceExclTax = json['unit_price_excl_tax']; + priceInclTax = json['price_incl_tax']; + priceExclTax = json['price_excl_tax']; + discountAmountExclTax = json['discount_amount_excl_tax']; + originalProductCost = json['original_product_cost']; + attributeDescription = json['attribute_description']; + downloadCount = json['download_count']; + isDownloadActivated = json['isDownload_activated']; + licenseDownloadId = json['license_download_id']; + itemWeight = json['item_weight']; } Map toJson() { @@ -110,6 +145,18 @@ class ShoppingCart { if (this.customer != null) { data['customer'] = this.customer.toJson(); } + data['unit_price_incl_tax'] = this.unitPriceInclTax; + data['unit_price_excl_tax'] = this.unitPriceExclTax; + data['price_incl_tax'] = this.priceInclTax; + data['price_excl_tax'] = this.priceExclTax; + data['discount_amount_excl_tax'] = this.discountAmountExclTax; + data['original_product_cost'] = this.originalProductCost; + data['attribute_description'] = this.attributeDescription; + data['download_count'] = this.downloadCount; + data['isDownload_activated'] = this.isDownloadActivated; + data['license_download_id'] = this.licenseDownloadId; + data['item_weight'] = this.itemWeight; + return data; } } diff --git a/lib/core/model/pharmacies/order_detail.dart b/lib/core/model/pharmacies/order_detail.dart new file mode 100644 index 00000000..74e89295 --- /dev/null +++ b/lib/core/model/pharmacies/order_detail.dart @@ -0,0 +1,305 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/BillingAddress.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Customer.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; + +class OrderDetailModel { + String id; + int storeId; + String orderGuid; + bool pickUpInStore; + String paymentMethodSystemName; + String paymentName; + String paymentNamen; + String customerCurrencyCode; + dynamic currencyRate; + dynamic customerTaxDisplayTypeId; + dynamic vatNumber; + double orderSubtotalInclTax; + double orderSubtotalExclTax; + dynamic orderSubTotalDiscountInclTax; + dynamic orderSubTotalDiscountExclTax; + double orderShippingInclTax; + dynamic orderShippingExclTax; + dynamic paymentMethodAdditionalFeeInclTax; + dynamic paymentMethodAdditionalFeeExclTax; + String taxRates; + double orderTax; + dynamic orderDiscount; + dynamic productCount; + dynamic orderTotal; + dynamic refundedAmount; + dynamic rewardPointsWereAdded; + dynamic rxAttachments; + String checkoutAttributeDescription; + int customerLanguageId; + int affiliateId; + String customerIp; + dynamic authorizationTransactionId; + dynamic authorizationTransactionCode; + dynamic authorizationTransactionResult; + dynamic captureTransactionId; + dynamic captureTransactionResult; + dynamic subscriptionTransactionId; + dynamic paidDateUtc; + String shippingMethod; + String shippingRateComputationMethodSystemName; + String customValuesXml; + bool deleted; + String createdOnUtc; + Customer customer; + int customerId; + BillingAddress billingAddress; + BillingAddress shippingAddress; + List orderItems; + int orderStatusId; + String orderStatus; + String orderStatusn; + int paymentStatusId; + String paymentStatus; + String paymentStatusn; + String shippingStatus; + String shippingStatusn; + String customerTaxDisplayType; + bool canCancel; + bool canRefund; + dynamic lakumAmount; + String preferDeliveryDate; + String preferDeliveryTime; + String preferDeliveryTimen; + String driverOTP; + String driverID; + + OrderDetailModel( + {this.id, + this.storeId, + this.orderGuid, + this.pickUpInStore, + this.paymentMethodSystemName, + this.paymentName, + this.paymentNamen, + this.customerCurrencyCode, + this.currencyRate, + this.customerTaxDisplayTypeId, + this.vatNumber, + this.orderSubtotalInclTax, + this.orderSubtotalExclTax, + this.orderSubTotalDiscountInclTax, + this.orderSubTotalDiscountExclTax, + this.orderShippingInclTax, + this.orderShippingExclTax, + this.paymentMethodAdditionalFeeInclTax, + this.paymentMethodAdditionalFeeExclTax, + this.taxRates, + this.orderTax, + this.orderDiscount, + this.productCount, + this.orderTotal, + this.refundedAmount, + this.rewardPointsWereAdded, + this.rxAttachments, + this.checkoutAttributeDescription, + this.customerLanguageId, + this.affiliateId, + this.customerIp, + this.authorizationTransactionId, + this.authorizationTransactionCode, + this.authorizationTransactionResult, + this.captureTransactionId, + this.captureTransactionResult, + this.subscriptionTransactionId, + this.paidDateUtc, + this.shippingMethod, + this.shippingRateComputationMethodSystemName, + this.customValuesXml, + this.deleted, + this.createdOnUtc, + this.customer, + this.customerId, + this.billingAddress, + this.shippingAddress, + this.orderItems, + this.orderStatusId, + this.orderStatus, + this.orderStatusn, + this.paymentStatusId, + this.paymentStatus, + this.paymentStatusn, + this.shippingStatus, + this.shippingStatusn, + this.customerTaxDisplayType, + this.canCancel, + this.canRefund, + this.lakumAmount, + this.preferDeliveryDate, + this.preferDeliveryTime, + this.preferDeliveryTimen, + this.driverID, + this.driverOTP,}); + + OrderDetailModel.fromJson(Map json) { + id = json['id']; + storeId = json['store_id']; + orderGuid = json['order_guid']; + pickUpInStore = json['pick_up_in_store']; + paymentMethodSystemName = json['payment_method_system_name']; + paymentName = json['payment_name']; + paymentNamen = json['payment_namen']; + customerCurrencyCode = json['customer_currency_code']; + currencyRate = json['currency_rate']; + customerTaxDisplayTypeId = json['customer_tax_display_type_id']; + vatNumber = json['vat_number']; + orderSubtotalInclTax = json['order_subtotal_incl_tax']; + orderSubtotalExclTax = json['order_subtotal_excl_tax']; + orderSubTotalDiscountInclTax = json['order_sub_total_discount_incl_tax']; + orderSubTotalDiscountExclTax = json['order_sub_total_discount_excl_tax']; + orderShippingInclTax = json['order_shipping_incl_tax']; + orderShippingExclTax = json['order_shipping_excl_tax']; + paymentMethodAdditionalFeeInclTax = + json['payment_method_additional_fee_incl_tax']; + paymentMethodAdditionalFeeExclTax = + json['payment_method_additional_fee_excl_tax']; + taxRates = json['tax_rates']; + orderTax = json['order_tax']; + orderDiscount = json['order_discount']; + productCount = json['product_count']; + orderTotal = json['order_total']; + refundedAmount = json['refunded_amount']; + rewardPointsWereAdded = json['reward_points_were_added']; + rxAttachments = json['rx_attachments']; + checkoutAttributeDescription = json['checkout_attribute_description']; + customerLanguageId = json['customer_language_id']; + affiliateId = json['affiliate_id']; + customerIp = json['customer_ip']; + authorizationTransactionId = json['authorization_transaction_id']; + authorizationTransactionCode = json['authorization_transaction_code']; + authorizationTransactionResult = json['authorization_transaction_result']; + captureTransactionId = json['capture_transaction_id']; + captureTransactionResult = json['capture_transaction_result']; + subscriptionTransactionId = json['subscription_transaction_id']; + paidDateUtc = json['paid_date_utc']; + shippingMethod = json['shipping_method']; + shippingRateComputationMethodSystemName = + json['shipping_rate_computation_method_system_name']; + customValuesXml = json['custom_values_xml']; + deleted = json['deleted']; + createdOnUtc = json['created_on_utc']; + customer = json['customer'] != null + ? new Customer.fromJson(json['customer']) + : null; + customerId = json['customer_id']; + billingAddress = json['billing_address'] != null + ? new BillingAddress.fromJson(json['billing_address']) + : null; + shippingAddress = json['shipping_address'] != null + ? new BillingAddress.fromJson(json['shipping_address']) + : null; + if (json['order_items'] != null) { + orderItems = new List(); + json['order_items'].forEach((v) { + orderItems.add(new ShoppingCart.fromJson(v)); + }); + } + orderStatusId = json['order_status_id']; + orderStatus = json['order_status']; + orderStatusn = json['order_statusn']; + paymentStatusId = json['payment_status_id']; + paymentStatus = json['payment_status']; + paymentStatusn = json['payment_statusn']; + shippingStatus = json['shipping_status']; + shippingStatusn = json['shipping_statusn']; + customerTaxDisplayType = json['customer_tax_display_type']; + canCancel = json['can_cancel']; + canRefund = json['can_refund']; + lakumAmount = json['lakum_amount']; + preferDeliveryDate = json['prefer_delivery_date']; + preferDeliveryTime = json['prefer_delivery_time']; + preferDeliveryTimen = json['prefer_delivery_timen']; + + // Driver Detail + driverID: json["DriverID"]; + driverOTP: json["DriverOTP"]; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['store_id'] = this.storeId; + data['order_guid'] = this.orderGuid; + data['pick_up_in_store'] = this.pickUpInStore; + data['payment_method_system_name'] = this.paymentMethodSystemName; + data['payment_name'] = this.paymentName; + data['payment_namen'] = this.paymentNamen; + data['customer_currency_code'] = this.customerCurrencyCode; + data['currency_rate'] = this.currencyRate; + data['customer_tax_display_type_id'] = this.customerTaxDisplayTypeId; + data['vat_number'] = this.vatNumber; + data['order_subtotal_incl_tax'] = this.orderSubtotalInclTax; + data['order_subtotal_excl_tax'] = this.orderSubtotalExclTax; + data['order_sub_total_discount_incl_tax'] = + this.orderSubTotalDiscountInclTax; + data['order_sub_total_discount_excl_tax'] = + this.orderSubTotalDiscountExclTax; + data['order_shipping_incl_tax'] = this.orderShippingInclTax; + data['order_shipping_excl_tax'] = this.orderShippingExclTax; + data['payment_method_additional_fee_incl_tax'] = + this.paymentMethodAdditionalFeeInclTax; + data['payment_method_additional_fee_excl_tax'] = + this.paymentMethodAdditionalFeeExclTax; + data['tax_rates'] = this.taxRates; + data['order_tax'] = this.orderTax; + data['order_discount'] = this.orderDiscount; + data['product_count'] = this.productCount; + data['order_total'] = this.orderTotal; + data['refunded_amount'] = this.refundedAmount; + data['reward_points_were_added'] = this.rewardPointsWereAdded; + data['rx_attachments'] = this.rxAttachments; + data['checkout_attribute_description'] = this.checkoutAttributeDescription; + data['customer_language_id'] = this.customerLanguageId; + data['affiliate_id'] = this.affiliateId; + data['customer_ip'] = this.customerIp; + data['authorization_transaction_id'] = this.authorizationTransactionId; + data['authorization_transaction_code'] = this.authorizationTransactionCode; + data['authorization_transaction_result'] = + this.authorizationTransactionResult; + data['capture_transaction_id'] = this.captureTransactionId; + data['capture_transaction_result'] = this.captureTransactionResult; + data['subscription_transaction_id'] = this.subscriptionTransactionId; + data['paid_date_utc'] = this.paidDateUtc; + data['shipping_method'] = this.shippingMethod; + data['shipping_rate_computation_method_system_name'] = + this.shippingRateComputationMethodSystemName; + data['custom_values_xml'] = this.customValuesXml; + data['deleted'] = this.deleted; + data['created_on_utc'] = this.createdOnUtc; + if (this.customer != null) { + data['customer'] = this.customer.toJson(); + } + data['customer_id'] = this.customerId; + if (this.billingAddress != null) { + data['billing_address'] = this.billingAddress.toJson(); + } + if (this.shippingAddress != null) { + data['shipping_address'] = this.shippingAddress.toJson(); + } + if (this.orderItems != null) { + data['order_items'] = this.orderItems.map((v) => v.toJson()).toList(); + } + data['order_status_id'] = this.orderStatusId; + data['order_status'] = this.orderStatus; + data['order_statusn'] = this.orderStatusn; + data['payment_status_id'] = this.paymentStatusId; + data['payment_status'] = this.paymentStatus; + data['payment_statusn'] = this.paymentStatusn; + data['shipping_status'] = this.shippingStatus; + data['shipping_statusn'] = this.shippingStatusn; + data['customer_tax_display_type'] = this.customerTaxDisplayType; + data['can_cancel'] = this.canCancel; + data['can_refund'] = this.canRefund; + data['lakum_amount'] = this.lakumAmount; + data['prefer_delivery_date'] = this.preferDeliveryDate; + data['prefer_delivery_time'] = this.preferDeliveryTime; + data['prefer_delivery_timen'] = this.preferDeliveryTimen; + return data; + } + +} \ No newline at end of file diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index 027d1f81..d025faa6 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -2,12 +2,80 @@ import 'dart:convert'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; List orderModelFromJson(String str) => List.from(json.decode(str).map((x) => OrderModel.fromJson(x))); String orderModelToJson(List data) => json.encode(List.from(data.map((x) => x.toJson()))); class OrderModel { + + String id; + dynamic storeId; + String orderGuid; + bool pickUpInStore; + PaymentMethodSystemName paymentMethodSystemName; + PaymentName paymentName; + PaymentName paymentNamen; + CustomerCurrencyCode customerCurrencyCode; + dynamic currencyRate; + dynamic customerTaxDisplayTypeId; + dynamic vatNumber; + double orderSubtotalInclTax; + double orderSubtotalExclTax; + dynamic orderSubTotalDiscountInclTax; + dynamic orderSubTotalDiscountExclTax; + double orderShippingInclTax; + dynamic orderShippingExclTax; + dynamic paymentMethodAdditionalFeeInclTax; + dynamic paymentMethodAdditionalFeeExclTax; + String taxRates; + double orderTax; + dynamic orderDiscount; + dynamic productCount; + double orderTotal; + dynamic refundedAmount; + dynamic rewardPointsWereAdded; + String rxAttachments; + CheckoutAttributeDescription checkoutAttributeDescription; + dynamic customerLanguageId; + dynamic affiliateId; + CustomerIp customerIp; + String authorizationTransactionId; + dynamic authorizationTransactionCode; + dynamic authorizationTransactionResult; + dynamic captureTransactionId; + dynamic captureTransactionResult; + dynamic subscriptionTransactionId; + DateTime paidDateUtc; + ShippingMethod shippingMethod; + ShippingRateComputationMethodSystemName shippingRateComputationMethodSystemName; + String customValuesXml; + bool deleted; + DateTime createdOnUtc; + OrderModelCustomer customer; + dynamic customerId; + IngAddress billingAddress; + IngAddress shippingAddress; + List orderItems; + dynamic orderStatusId; + OrderStatus orderStatus; + OrderStatusn orderStatusn; + dynamic paymentStatusId; + PaymentStatus paymentStatus; + PaymentStatusn paymentStatusn; + ShippingStatus shippingStatus; + ShippingStatusn shippingStatusn; + CustomerTaxDisplayType customerTaxDisplayType; + bool canCancel; + bool canRefund; + dynamic lakumAmount; + DateTime preferDeliveryDate; + PreferDeliveryTime preferDeliveryTime; + PreferDeliveryTimen preferDeliveryTimen; + String driverOTP; + String driverID; + OrderModel({ this.id, this.storeId, @@ -31,6 +99,7 @@ class OrderModel { this.taxRates, this.orderTax, this.orderDiscount, + this.productCount, this.orderTotal, this.refundedAmount, this.rewardPointsWereAdded, @@ -71,71 +140,10 @@ class OrderModel { this.preferDeliveryDate, this.preferDeliveryTime, this.preferDeliveryTimen, + this.driverID, + this.driverOTP, }); - String id; - dynamic storeId; - String orderGuid; - bool pickUpInStore; - PaymentMethodSystemName paymentMethodSystemName; - PaymentName paymentName; - PaymentName paymentNamen; - CustomerCurrencyCode customerCurrencyCode; - dynamic currencyRate; - dynamic customerTaxDisplayTypeId; - dynamic vatNumber; - double orderSubtotalInclTax; - double orderSubtotalExclTax; - dynamic orderSubTotalDiscountInclTax; - dynamic orderSubTotalDiscountExclTax; - double orderShippingInclTax; - dynamic orderShippingExclTax; - dynamic paymentMethodAdditionalFeeInclTax; - dynamic paymentMethodAdditionalFeeExclTax; - String taxRates; - double orderTax; - dynamic orderDiscount; - double orderTotal; - dynamic refundedAmount; - dynamic rewardPointsWereAdded; - String rxAttachments; - CheckoutAttributeDescription checkoutAttributeDescription; - dynamic customerLanguageId; - dynamic affiliateId; - CustomerIp customerIp; - String authorizationTransactionId; - dynamic authorizationTransactionCode; - dynamic authorizationTransactionResult; - dynamic captureTransactionId; - dynamic captureTransactionResult; - dynamic subscriptionTransactionId; - DateTime paidDateUtc; - ShippingMethod shippingMethod; - ShippingRateComputationMethodSystemName shippingRateComputationMethodSystemName; - String customValuesXml; - bool deleted; - DateTime createdOnUtc; - OrderModelCustomer customer; - dynamic customerId; - IngAddress billingAddress; - IngAddress shippingAddress; - List orderItems; - dynamic orderStatusId; - OrderStatus orderStatus; - OrderStatusn orderStatusn; - dynamic paymentStatusId; - PaymentStatus paymentStatus; - PaymentStatusn paymentStatusn; - ShippingStatus shippingStatus; - ShippingStatusn shippingStatusn; - CustomerTaxDisplayType customerTaxDisplayType; - bool canCancel; - bool canRefund; - dynamic lakumAmount; - DateTime preferDeliveryDate; - PreferDeliveryTime preferDeliveryTime; - PreferDeliveryTimen preferDeliveryTimen; - factory OrderModel.fromJson(Map json) => OrderModel( id: json["id"], storeId: json["store_id"], @@ -159,6 +167,7 @@ class OrderModel { taxRates: json["tax_rates"], orderTax: json["order_tax"].toDouble(), orderDiscount: json["order_discount"], + productCount: json["product_count"], orderTotal: json["order_total"].toDouble(), refundedAmount: json["refunded_amount"], rewardPointsWereAdded: json["reward_points_were_added"], @@ -199,6 +208,11 @@ class OrderModel { preferDeliveryDate: json["prefer_delivery_date"] == null ? null : DateTime.parse(json["prefer_delivery_date"]), preferDeliveryTime: json["prefer_delivery_time"] == null ? null : preferDeliveryTimeValues.map[json["prefer_delivery_time"]], preferDeliveryTimen: json["prefer_delivery_timen"] == null ? null : preferDeliveryTimenValues.map[json["prefer_delivery_timen"]], + + // Driver Detail + driverID: json["DriverID"], + driverOTP: json["DriverOTP"], + ); Map toJson() => { @@ -306,7 +320,22 @@ class IngAddress { String customerAttributes; DateTime createdOnUtc; dynamic province; - LatLong latLong; + String latLong; + + LatLng getLocation(){ + if(latLong.contains(',')){ + var parts = latLong.trim().split(','); + if(parts.length == 2){ + var lat = double.tryParse(parts.first); + var lng = double.tryParse(parts.last); + if(lat != null || lng != null) { + var location = LatLng(lat, lng); + return location; + } + } + } + return null; + } factory IngAddress.fromJson(Map json) => IngAddress( id: json["id"], @@ -326,7 +355,7 @@ class IngAddress { customerAttributes: json["customer_attributes"], createdOnUtc: DateTime.parse(json["created_on_utc"]), province: json["province"], - latLong: latLongValues.map[json["lat_long"]], + latLong: json["lat_long"], ); Map toJson() => { @@ -347,7 +376,7 @@ class IngAddress { "customer_attributes": customerAttributes, "created_on_utc": createdOnUtc.toIso8601String(), "province": province, - "lat_long": latLongValues.reverse[latLong], + "lat_long": latLong, }; } @@ -457,10 +486,10 @@ class OrderModelCustomer { }); String id; - Username username; - BillingAddressEmail email; - FirstName firstName; - LastName lastName; + dynamic username; + dynamic email; + dynamic firstName; + dynamic lastName; String languageId; dynamic adminComment; bool isTaxExempt; @@ -469,10 +498,10 @@ class OrderModelCustomer { bool deleted; bool isSystemAccount; dynamic systemName; - LastIpAddress lastIpAddress; - DateTime createdOnUtc; - DateTime lastLoginDateUtc; - DateTime lastActivityDateUtc; + dynamic lastIpAddress; + dynamic createdOnUtc; + dynamic lastLoginDateUtc; + dynamic lastActivityDateUtc; dynamic registeredInStoreId; List roleIds; @@ -491,9 +520,9 @@ class OrderModelCustomer { isSystemAccount: json["is_system_account"], systemName: json["system_name"], lastIpAddress: lastIpAddressValues.map[json["last_ip_address"]], - createdOnUtc: DateTime.parse(json["created_on_utc"]), - lastLoginDateUtc: DateTime.parse(json["last_login_date_utc"]), - lastActivityDateUtc: DateTime.parse(json["last_activity_date_utc"]), + createdOnUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["created_on_utc"]) : null, + lastLoginDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_login_date_utc"]) : null, + lastActivityDateUtc: (json["created_on_utc"] != null) ? DateTime.parse(json["last_activity_date_utc"]) : null, registeredInStoreId: json["registered_in_store_id"], roleIds: List.from(json["role_ids"].map((x) => x)), ); @@ -558,6 +587,7 @@ final customerTaxDisplayTypeValues = EnumValues({ "ExcludingTax": CustomerTaxDisplayType.EXCLUDING_TAX }); + class OrderItem { OrderItem({ this.quantity, @@ -848,9 +878,9 @@ class Product { dynamic displayOrder; bool published; bool deleted; - DateTime createdOnUtc; - DateTime updatedOnUtc; - ProductType productType; + dynamic createdOnUtc; + dynamic updatedOnUtc; + dynamic productType; dynamic parentGroupedProductId; dynamic roleIds; dynamic discountIds; @@ -1127,14 +1157,14 @@ class Review { dynamic productId; dynamic storeId; bool isApproved; - Title title; - ReviewText reviewText; + dynamic title; + dynamic reviewText; dynamic replyText; dynamic rating; dynamic helpfulYesTotal; dynamic helpfulNoTotal; - DateTime createdOnUtc; - ReviewCustomer customer; + dynamic createdOnUtc; + dynamic customer; dynamic product; factory Review.fromJson(Map json) => Review( @@ -1216,7 +1246,7 @@ class ReviewCustomer { dynamic isOutSa; dynamic patientType; dynamic gender; - DateTime birthDate; + dynamic birthDate; dynamic phone; dynamic countryCode; dynamic yahalaAccountno; @@ -1225,7 +1255,7 @@ class ReviewCustomer { List addresses; String id; String username; - PurpleEmail email; + dynamic email; dynamic firstName; dynamic lastName; dynamic languageId; @@ -1345,7 +1375,7 @@ final titleValues = EnumValues({ "ممتاز": Title.TITLE }); -enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } +enum OrderStatus { ORDER_SUBMITTED, PENDING, ORDER_IN_PROGRESS,ORDER_SENT_FOR_DELIVERY, ORDER_COMPLETED, CANCELLED, PROCESSING, ORDER_REFUNDED, COMPLETE } final orderStatusValues = EnumValues({ "Cancelled": OrderStatus.CANCELLED, @@ -1355,7 +1385,8 @@ final orderStatusValues = EnumValues({ "OrderRefunded": OrderStatus.ORDER_REFUNDED, "OrderSubmitted": OrderStatus.ORDER_SUBMITTED, "Pending": OrderStatus.PENDING, - "Processing": OrderStatus.PROCESSING + "Processing": OrderStatus.PROCESSING, + "orderSentForDelivery": OrderStatus.ORDER_SENT_FOR_DELIVERY }); enum OrderStatusn { ORDER_SUBMITTED, EMPTY, ORDER_IN_PROGRESS, ORDER_COMPLETED, ORDER_STATUSN, PURPLE, FLUFFY, TENTACLED } @@ -1368,6 +1399,7 @@ final orderStatusnValues = EnumValues({ "ملغي": OrderStatusn.ORDER_STATUSN, "Order Submitted": OrderStatusn.ORDER_SUBMITTED, "قيد التنفيذ": OrderStatusn.PURPLE, + "مكتمل": OrderStatusn.TENTACLED, "مكتمل": OrderStatusn.TENTACLED }); @@ -1450,7 +1482,4 @@ class EnumValues { } return reverseMap; } -} - - - +} \ No newline at end of file diff --git a/lib/core/model/pharmacies/orders_model.dart b/lib/core/model/pharmacies/orders_model.dart new file mode 100644 index 00000000..0ad94767 --- /dev/null +++ b/lib/core/model/pharmacies/orders_model.dart @@ -0,0 +1,90 @@ +class OrdersModel { + List orders; + + OrdersModel({this.orders}); + + OrdersModel.fromJson(Map json) { + if (json['orders'] != null) { + orders = new List(); + json['orders'].forEach((v) { + orders.add(new Orders.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.orders != null) { + data['orders'] = this.orders.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Orders { + String id; + int productCount; + double orderTotal; + String createdOnUtc; + int orderStatusId; + String orderStatus; + String orderStatusn; + bool canCancel; + bool canRefund; + dynamic customerId; + double orderSubtotalExclTax; + dynamic orderShippingExclTax; + double orderTax; + + + Orders( + {this.id, + this.productCount, + this.orderTotal, + this.createdOnUtc, + this.orderStatusId, + this.orderStatus, + this.orderStatusn, + this.canCancel, + this.canRefund, + this.customerId, + this.orderShippingExclTax, + this.orderSubtotalExclTax, + this.orderTax,}); + + Orders.fromJson(Map json) { + try { + id = json['id']; + productCount = json['product_count']; + orderTotal = json['order_total']; + createdOnUtc = json['created_on_utc']; + orderStatusId = json['order_status_id']; + orderStatus = json['order_status']; + orderStatusn = json['order_statusn']; + canCancel = json['can_cancel']; + canRefund = json['can_refund']; + customerId = json['customer_id']; + orderSubtotalExclTax= json["order_subtotal_excl_tax"].toDouble(); + orderShippingExclTax= json["order_shipping_excl_tax"]; + orderTax= json["order_tax"].toDouble(); + }catch(e){ + print(e); + } + + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['product_count'] = this.productCount; + data['order_total'] = this.orderTotal; + data['created_on_utc'] = this.createdOnUtc; + data['order_status_id'] = this.orderStatusId; + data['order_status'] = this.orderStatus; + data['order_statusn'] = this.orderStatusn; + data ["order_subtotal_excl_tax"] = this.orderSubtotalExclTax; + data ["order_shipping_excl_tax"]= this.orderShippingExclTax; + data ["order_tax"]= this.orderTax; + return data; + } +} diff --git a/lib/core/model/pharmacies/recommendedProduct_model.dart b/lib/core/model/pharmacies/recommendedProduct_model.dart new file mode 100644 index 00000000..e1e88cd8 --- /dev/null +++ b/lib/core/model/pharmacies/recommendedProduct_model.dart @@ -0,0 +1,486 @@ +class RecommendedProductModel { + List products; + + RecommendedProductModel({this.products}); + + RecommendedProductModel.fromJson(Map json) { + if (json['products'] != null) { + products = new List(); + json['products'].forEach((v) { + products.add(new Products.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + if (this.products != null) { + data['products'] = this.products.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class Products { + String id; + bool visibleIndividually; + String name; + String namen; + String shortDescription; + String shortDescriptionn; + String fullDescription; + String fullDescriptionn; + bool markasNew; + bool showOnHomePage; + dynamic metaKeywords; + dynamic metaDescription; + dynamic metaTitle; + bool allowCustomerReviews; + dynamic approvedRatingSum; + dynamic notApprovedRatingSum; + dynamic approvedTotalReviews; + dynamic notApprovedTotalReviews; + String sku; + bool isRx; + bool prescriptionRequired; + dynamic rxMessage; + dynamic rxMessagen; + dynamic manufacturerPartNumber; + dynamic gtin; + bool isGiftCard; + bool requireOtherProducts; + bool automaticallyAddRequiredProducts; + bool isDownload; + bool unlimitedDownloads; + dynamic maxNumberOfDownloads; + dynamic downloadExpirationDays; + bool hasSampleDownload; + bool hasUserAgreement; + bool isRecurring; + dynamic recurringCycleLength; + dynamic recurringTotalCycles; + bool isRental; + dynamic rentalPriceLength; + bool isShipEnabled; + bool isFreeShipping; + bool shipSeparately; + dynamic additionalShippingCharge; + bool isTaxExempt; + bool isTelecommunicationsOrBroadcastingOrElectronicServices; + bool useMultipleWarehouses; + dynamic manageInventoryMethodId; + dynamic stockQuantity; + String stockAvailability; + String stockAvailabilityn; + bool displayStockAvailability; + bool displayStockQuantity; + dynamic minStockQuantity; + dynamic notifyAdminForQuantityBelow; + bool allowBackInStockSubscriptions; + dynamic orderMinimumQuantity; + dynamic orderMaximumQuantity; + dynamic allowedQuantities; + bool allowAddingOnlyExistingAttributeCombinations; + bool disableBuyButton; + bool disableWishlistButton; + bool availableForPreOrder; + dynamic preOrderAvailabilityStartDateTimeUtc; + bool callForPrice; + dynamic price; + dynamic oldPrice; + dynamic productCost; + dynamic specialPrice; + dynamic specialPriceStartDateTimeUtc; + dynamic specialPriceEndDateTimeUtc; + bool customerEntersPrice; + dynamic minimumCustomerEnteredPrice; + dynamic maximumCustomerEnteredPrice; + bool basepriceEnabled; + dynamic basepriceAmount; + dynamic basepriceBaseAmount; + bool hasTierPrices; + bool hasDiscountsApplied; + dynamic discountName; + dynamic discountNamen; + dynamic discountDescription; + dynamic discountDescriptionn; + dynamic discountPercentage; + String currency; + String currencyn; + double weight; + dynamic length; + dynamic width; + dynamic height; + dynamic availableStartDateTimeUtc; + dynamic availableEndDateTimeUtc; + dynamic displayOrder; + bool published; + bool deleted; + String createdOnUtc; + String updatedOnUtc; + String productType; + dynamic parentGroupedProductId; + dynamic vendorId; + String seName; + List images; + + Products({ + this.id, + this.visibleIndividually, + this.name, + this.namen, + this.shortDescription, + this.shortDescriptionn, + this.fullDescription, + this.fullDescriptionn, + this.markasNew, + this.showOnHomePage, + this.metaKeywords, + this.metaDescription, + this.metaTitle, + this.allowCustomerReviews, + this.approvedRatingSum, + this.notApprovedRatingSum, + this.approvedTotalReviews, + this.notApprovedTotalReviews, + this.sku, + this.isRx, + this.prescriptionRequired, + this.rxMessage, + this.rxMessagen, + this.manufacturerPartNumber, + this.gtin, + this.isGiftCard, + this.requireOtherProducts, + this.automaticallyAddRequiredProducts, + this.isDownload, + this.unlimitedDownloads, + this.maxNumberOfDownloads, + this.downloadExpirationDays, + this.hasSampleDownload, + this.hasUserAgreement, + this.isRecurring, + this.recurringCycleLength, + this.recurringTotalCycles, + this.isRental, + this.rentalPriceLength, + this.isShipEnabled, + this.isFreeShipping, + this.shipSeparately, + this.additionalShippingCharge, + this.isTaxExempt, + this.isTelecommunicationsOrBroadcastingOrElectronicServices, + this.useMultipleWarehouses, + this.manageInventoryMethodId, + this.stockQuantity, + this.stockAvailability, + this.stockAvailabilityn, + this.displayStockAvailability, + this.displayStockQuantity, + this.minStockQuantity, + this.notifyAdminForQuantityBelow, + this.allowBackInStockSubscriptions, + this.orderMinimumQuantity, + this.orderMaximumQuantity, + this.allowedQuantities, + this.allowAddingOnlyExistingAttributeCombinations, + this.disableBuyButton, + this.disableWishlistButton, + this.availableForPreOrder, + this.preOrderAvailabilityStartDateTimeUtc, + this.callForPrice, + this.price, + this.oldPrice, + this.productCost, + this.specialPrice, + this.specialPriceStartDateTimeUtc, + this.specialPriceEndDateTimeUtc, + this.customerEntersPrice, + this.minimumCustomerEnteredPrice, + this.maximumCustomerEnteredPrice, + this.basepriceEnabled, + this.basepriceAmount, + this.basepriceBaseAmount, + this.hasTierPrices, + this.hasDiscountsApplied, + this.discountName, + this.discountNamen, + this.discountDescription, + this.discountDescriptionn, + this.discountPercentage, + this.currency, + this.currencyn, + this.weight, + this.length, + this.width, + this.height, + this.availableStartDateTimeUtc, + this.availableEndDateTimeUtc, + this.displayOrder, + this.published, + this.deleted, + this.createdOnUtc, + this.updatedOnUtc, + this.productType, + this.parentGroupedProductId, + this.vendorId, + this.seName, + this.images, + }); + + Products.fromJson(Map json) { + id = json['id']; + visibleIndividually = json['visible_individually']; + name = json['name']; + namen = json['namen']; + shortDescription = json['short_description']; + shortDescriptionn = json['short_descriptionn']; + fullDescription = json['full_description']; + fullDescriptionn = json['full_descriptionn']; + markasNew = json['markas_new']; + showOnHomePage = json['show_on_home_page']; + metaKeywords = json['meta_keywords']; + metaDescription = json['meta_description']; + metaTitle = json['meta_title']; + allowCustomerReviews = json['allow_customer_reviews']; + approvedRatingSum = json['approved_rating_sum']; + notApprovedRatingSum = json['not_approved_rating_sum']; + approvedTotalReviews = json['approved_total_reviews']; + notApprovedTotalReviews = json['not_approved_total_reviews']; + sku = json['sku']; + isRx = json['is_rx']; + prescriptionRequired = json['prescription_required']; + rxMessage = json['rx_message']; + rxMessagen = json['rx_messagen']; + manufacturerPartNumber = json['manufacturer_part_number']; + gtin = json['gtin']; + isGiftCard = json['is_gift_card']; + requireOtherProducts = json['require_other_products']; + automaticallyAddRequiredProducts = + json['automatically_add_required_products']; + isDownload = json['is_download']; + unlimitedDownloads = json['unlimited_downloads']; + maxNumberOfDownloads = json['max_number_of_downloads']; + downloadExpirationDays = json['download_expiration_days']; + hasSampleDownload = json['has_sample_download']; + hasUserAgreement = json['has_user_agreement']; + isRecurring = json['is_recurring']; + recurringCycleLength = json['recurring_cycle_length']; + recurringTotalCycles = json['recurring_total_cycles']; + isRental = json['is_rental']; + rentalPriceLength = json['rental_price_length']; + isShipEnabled = json['is_ship_enabled']; + isFreeShipping = json['is_free_shipping']; + shipSeparately = json['ship_separately']; + additionalShippingCharge = json['additional_shipping_charge']; + isTaxExempt = json['is_tax_exempt']; + isTelecommunicationsOrBroadcastingOrElectronicServices = + json['is_telecommunications_or_broadcasting_or_electronic_services']; + useMultipleWarehouses = json['use_multiple_warehouses']; + manageInventoryMethodId = json['manage_inventory_method_id']; + stockQuantity = json['stock_quantity']; + stockAvailability = json['stock_availability']; + stockAvailabilityn = json['stock_availabilityn']; + displayStockAvailability = json['display_stock_availability']; + displayStockQuantity = json['display_stock_quantity']; + minStockQuantity = json['min_stock_quantity']; + notifyAdminForQuantityBelow = json['notify_admin_for_quantity_below']; + allowBackInStockSubscriptions = json['allow_back_in_stock_subscriptions']; + orderMinimumQuantity = json['order_minimum_quantity']; + orderMaximumQuantity = json['order_maximum_quantity']; + allowedQuantities = json['allowed_quantities']; + allowAddingOnlyExistingAttributeCombinations = + json['allow_adding_only_existing_attribute_combinations']; + disableBuyButton = json['disable_buy_button']; + disableWishlistButton = json['disable_wishlist_button']; + availableForPreOrder = json['available_for_pre_order']; + preOrderAvailabilityStartDateTimeUtc = + json['pre_order_availability_start_date_time_utc']; + callForPrice = json['call_for_price']; + price = json['price']; + oldPrice = json['old_price']; + productCost = json['product_cost']; + specialPrice = json['special_price']; + specialPriceStartDateTimeUtc = json['special_price_start_date_time_utc']; + specialPriceEndDateTimeUtc = json['special_price_end_date_time_utc']; + customerEntersPrice = json['customer_enters_price']; + minimumCustomerEnteredPrice = json['minimum_customer_entered_price']; + maximumCustomerEnteredPrice = json['maximum_customer_entered_price']; + basepriceEnabled = json['baseprice_enabled']; + basepriceAmount = json['baseprice_amount']; + basepriceBaseAmount = json['baseprice_base_amount']; + hasTierPrices = json['has_tier_prices']; + hasDiscountsApplied = json['has_discounts_applied']; + discountName = json['discount_name']; + discountNamen = json['discount_namen']; + discountDescription = json['discount_description']; + discountDescriptionn = json['discount_Descriptionn']; + discountPercentage = json['discount_percentage']; + currency = json['currency']; + currencyn = json['currencyn']; + weight = json['weight']; + length = json['length']; + width = json['width']; + height = json['height']; + availableStartDateTimeUtc = json['available_start_date_time_utc']; + availableEndDateTimeUtc = json['available_end_date_time_utc']; + displayOrder = json['display_order']; + published = json['published']; + deleted = json['deleted']; + createdOnUtc = json['created_on_utc']; + updatedOnUtc = json['updated_on_utc']; + productType = json['product_type']; + parentGroupedProductId = json['parent_grouped_product_id']; + vendorId = json['vendor_id']; + seName = json['se_name']; + if (json['images'] != null) { + images = new List(); + json['images'].forEach((v) { + images.add(new Images.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['visible_individually'] = this.visibleIndividually; + data['name'] = this.name; + data['namen'] = this.namen; + data['short_description'] = this.shortDescription; + data['short_descriptionn'] = this.shortDescriptionn; + data['full_description'] = this.fullDescription; + data['full_descriptionn'] = this.fullDescriptionn; + data['markas_new'] = this.markasNew; + data['show_on_home_page'] = this.showOnHomePage; + data['meta_keywords'] = this.metaKeywords; + data['meta_description'] = this.metaDescription; + data['meta_title'] = this.metaTitle; + data['allow_customer_reviews'] = this.allowCustomerReviews; + data['approved_rating_sum'] = this.approvedRatingSum; + data['not_approved_rating_sum'] = this.notApprovedRatingSum; + data['approved_total_reviews'] = this.approvedTotalReviews; + data['not_approved_total_reviews'] = this.notApprovedTotalReviews; + data['sku'] = this.sku; + data['is_rx'] = this.isRx; + data['prescription_required'] = this.prescriptionRequired; + data['rx_message'] = this.rxMessage; + data['rx_messagen'] = this.rxMessagen; + data['manufacturer_part_number'] = this.manufacturerPartNumber; + data['gtin'] = this.gtin; + data['is_gift_card'] = this.isGiftCard; + data['require_other_products'] = this.requireOtherProducts; + data['automatically_add_required_products'] = + this.automaticallyAddRequiredProducts; + data['is_download'] = this.isDownload; + data['unlimited_downloads'] = this.unlimitedDownloads; + data['max_number_of_downloads'] = this.maxNumberOfDownloads; + data['download_expiration_days'] = this.downloadExpirationDays; + data['has_sample_download'] = this.hasSampleDownload; + data['has_user_agreement'] = this.hasUserAgreement; + data['is_recurring'] = this.isRecurring; + data['recurring_cycle_length'] = this.recurringCycleLength; + data['recurring_total_cycles'] = this.recurringTotalCycles; + data['is_rental'] = this.isRental; + data['rental_price_length'] = this.rentalPriceLength; + data['is_ship_enabled'] = this.isShipEnabled; + data['is_free_shipping'] = this.isFreeShipping; + data['ship_separately'] = this.shipSeparately; + data['additional_shipping_charge'] = this.additionalShippingCharge; + data['is_tax_exempt'] = this.isTaxExempt; + data['is_telecommunications_or_broadcasting_or_electronic_services'] = + this.isTelecommunicationsOrBroadcastingOrElectronicServices; + data['use_multiple_warehouses'] = this.useMultipleWarehouses; + data['manage_inventory_method_id'] = this.manageInventoryMethodId; + data['stock_quantity'] = this.stockQuantity; + data['stock_availability'] = this.stockAvailability; + data['stock_availabilityn'] = this.stockAvailabilityn; + data['display_stock_availability'] = this.displayStockAvailability; + data['display_stock_quantity'] = this.displayStockQuantity; + data['min_stock_quantity'] = this.minStockQuantity; + data['notify_admin_for_quantity_below'] = this.notifyAdminForQuantityBelow; + data['allow_back_in_stock_subscriptions'] = + this.allowBackInStockSubscriptions; + data['order_minimum_quantity'] = this.orderMinimumQuantity; + data['order_maximum_quantity'] = this.orderMaximumQuantity; + data['allowed_quantities'] = this.allowedQuantities; + data['allow_adding_only_existing_attribute_combinations'] = + this.allowAddingOnlyExistingAttributeCombinations; + data['disable_buy_button'] = this.disableBuyButton; + data['disable_wishlist_button'] = this.disableWishlistButton; + data['available_for_pre_order'] = this.availableForPreOrder; + data['pre_order_availability_start_date_time_utc'] = + this.preOrderAvailabilityStartDateTimeUtc; + data['call_for_price'] = this.callForPrice; + data['price'] = this.price; + data['old_price'] = this.oldPrice; + data['product_cost'] = this.productCost; + data['special_price'] = this.specialPrice; + data['special_price_start_date_time_utc'] = + this.specialPriceStartDateTimeUtc; + data['special_price_end_date_time_utc'] = this.specialPriceEndDateTimeUtc; + data['customer_enters_price'] = this.customerEntersPrice; + data['minimum_customer_entered_price'] = this.minimumCustomerEnteredPrice; + data['maximum_customer_entered_price'] = this.maximumCustomerEnteredPrice; + data['baseprice_enabled'] = this.basepriceEnabled; + data['baseprice_amount'] = this.basepriceAmount; + data['baseprice_base_amount'] = this.basepriceBaseAmount; + data['has_tier_prices'] = this.hasTierPrices; + data['has_discounts_applied'] = this.hasDiscountsApplied; + data['discount_name'] = this.discountName; + data['discount_namen'] = this.discountNamen; + data['discount_description'] = this.discountDescription; + data['discount_Descriptionn'] = this.discountDescriptionn; + data['discount_percentage'] = this.discountPercentage; + data['currency'] = this.currency; + data['currencyn'] = this.currencyn; + data['weight'] = this.weight; + data['length'] = this.length; + data['width'] = this.width; + data['height'] = this.height; + data['available_start_date_time_utc'] = this.availableStartDateTimeUtc; + data['available_end_date_time_utc'] = this.availableEndDateTimeUtc; + data['display_order'] = this.displayOrder; + data['published'] = this.published; + data['deleted'] = this.deleted; + data['created_on_utc'] = this.createdOnUtc; + data['updated_on_utc'] = this.updatedOnUtc; + data['product_type'] = this.productType; + data['parent_grouped_product_id'] = this.parentGroupedProductId; + data['vendor_id'] = this.vendorId; + data['se_name'] = this.seName; + if (this.images != null) { + data['images'] = this.images.map((v) => v.toJson()).toList(); + } + + return data; + } +} + +class Images { + int id; + int position; + String src; + String thumb; + String attachment; + + Images({this.id, this.position, this.src, this.thumb, this.attachment}); + + Images.fromJson(Map json) { + id = json['id']; + position = json['position']; + src = json['src']; + thumb = json['thumb']; + attachment = json['attachment']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['position'] = this.position; + data['src'] = this.src; + data['thumb'] = this.thumb; + data['attachment'] = this.attachment; + return data; + } +} diff --git a/lib/core/model/prescriptions/prescription_report.dart b/lib/core/model/prescriptions/prescription_report.dart index 51f5750f..8c18df62 100644 --- a/lib/core/model/prescriptions/prescription_report.dart +++ b/lib/core/model/prescriptions/prescription_report.dart @@ -1,127 +1,193 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; class PrescriptionReport { + String address; + int appointmentNo; + String clinic; + String companyName; + int days; + String doctorName; + var doseDailyQuantity; + String frequency; + int frequencyNumber; + String image; + String imageExtension; + String imageSRCUrl; + String imageString; + String imageThumbUrl; + String isCovered; + String itemDescription; + int itemID; + String orderDate; int patientID; String patientName; + String phoneOffice1; + String prescriptionQR; + int prescriptionTimes; + String productImage; + String productImageBase64; + String productImageString; + int projectID; + String projectName; + String remarks; + String route; + String sKU; + int scaleOffset; + String startDate; + String patientAge; String patientGender; - String address; String phoneOffice; - String itemDescription; int doseTimingID; int frequencyID; int routeID; - String clinic; - String doctorName; - String route; - String frequency; - String remarks; String name; - int days; - String startDate; - String orderDate; - int doseDailyQuantity; - int itemID; - Null productImage; - String sKU; String itemDescriptionN; String routeN; String frequencyN; - String imageSRCUrl; - String imageThumbUrl; - PrescriptionReport( - {this.patientID, - this.patientName, - this.patientAge, - this.patientGender, - this.address, - this.phoneOffice, - this.itemDescription, - this.doseTimingID, - this.frequencyID, - this.routeID, - this.clinic, - this.doctorName, - this.route, - this.frequency, - this.remarks, - this.name, - this.days, - this.startDate, - this.orderDate, - this.doseDailyQuantity, - this.itemID, - this.productImage, - this.sKU, - this.itemDescriptionN, - this.routeN, - this.frequencyN, - this.imageSRCUrl, - this.imageThumbUrl}); + PrescriptionReport({ + this.address, + this.appointmentNo, + this.clinic, + this.companyName, + this.days, + this.doctorName, + this.doseDailyQuantity, + this.frequency, + this.frequencyNumber, + this.image, + this.imageExtension, + this.imageSRCUrl, + this.imageString, + this.imageThumbUrl, + this.isCovered, + this.itemDescription, + this.itemID, + this.orderDate, + this.patientID, + this.patientName, + this.phoneOffice1, + this.prescriptionQR, + this.prescriptionTimes, + this.productImage, + this.productImageBase64, + this.productImageString, + this.projectID, + this.projectName, + this.remarks, + this.route, + this.sKU, + this.scaleOffset, + this.startDate, + this.patientAge, + this.patientGender, + this.phoneOffice, + this.doseTimingID, + this.frequencyID, + this.routeID, + this.name, + this.itemDescriptionN, + this.routeN, + this.frequencyN, + }); PrescriptionReport.fromJson(Map json) { - patientID = json['PatientID']; - patientName = json['PatientName']; - patientAge = json['PatientAge']; - patientGender = json['PatientGender']; address = json['Address']; - phoneOffice = json['PhoneOffice']; - itemDescription = json['ItemDescription']; - doseTimingID = json['DoseTimingID']; - frequencyID = json['FrequencyID']; - routeID = json['RouteID']; + appointmentNo = json['AppointmentNo']; clinic = json['Clinic']; - doctorName = json['DoctorName']; - route = json['Route']; - frequency = json['Frequency']; - remarks = json['Remarks']; - name = json['Name']; + companyName = json['CompanyName']; days = json['Days']; - startDate = json['StartDate']; - orderDate = json['OrderDate']; + doctorName = json['DoctorName']; doseDailyQuantity = json['DoseDailyQuantity']; + frequency = json['Frequency']; + frequencyNumber = json['FrequencyNumber']; + image = json['Image']; + imageExtension = json['ImageExtension']; + imageSRCUrl = json['ImageSRCUrl']; + imageString = json['ImageString']; + imageThumbUrl = json['ImageThumbUrl']; + isCovered = json['IsCovered']; + itemDescription = json['ItemDescription']; itemID = json['ItemID']; + orderDate = json['OrderDate']; + patientID = json['PatientID']; + patientName = json['PatientName']; + phoneOffice1 = json['PhoneOffice1']; + prescriptionQR = json['PrescriptionQR']; + prescriptionTimes = json['PrescriptionTimes']; productImage = json['ProductImage']; + productImageBase64 = json['ProductImageBase64']; + productImageString = json['ProductImageString']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + remarks = json['Remarks']; + route = json['Route']; sKU = json['SKU']; - itemDescriptionN = json['ItemDescriptionN']; - routeN = json['RouteN']; - frequencyN = json['FrequencyN']; - imageSRCUrl = json['ImageSRCUrl']; - imageThumbUrl = json['ImageThumbUrl']; + scaleOffset = json['ScaleOffset']; + startDate = json['StartDate']; + + patientAge = json['patientAge']; + patientGender = json['patientGender']; + phoneOffice = json['phoneOffice']; + doseTimingID = json['doseTimingID']; + frequencyID = json['frequencyID']; + routeID = json['routeID']; + name = json['name']; + itemDescriptionN = json['itemDescriptionN']; + routeN = json['routeN']; + frequencyN = json['frequencyN']; } Map toJson() { final Map data = new Map(); + + data['Address'] = this.address; + data['AppointmentNo'] = this.appointmentNo; + data['Clinic'] = this.clinic; + data['CompanyName'] = this.companyName; + data['Days'] = this.days; + data['DoctorName'] = this.doctorName; + data['DoseDailyQuantity'] = this.doseDailyQuantity; + data['Frequency'] = this.frequency; + data['FrequencyNumber'] = this.frequencyNumber; + data['Image'] = this.image; + data['ImageExtension'] = this.imageExtension; + data['ImageSRCUrl'] = this.imageSRCUrl; + data['ImageString'] = this.imageString; + data['ImageThumbUrl'] = this.imageThumbUrl; + data['IsCovered'] = this.isCovered; + data['ItemDescription'] = this.itemDescription; + data['ItemID'] = this.itemID; + data['OrderDate'] = this.orderDate; data['PatientID'] = this.patientID; data['PatientName'] = this.patientName; + data['PhoneOffice1'] = this.phoneOffice1; + data['PrescriptionQR'] = this.prescriptionQR; + data['PrescriptionTimes'] = this.prescriptionTimes; + data['ProductImage'] = this.productImage; + data['ProductImageBase64'] = this.productImageBase64; + data['ProductImageString'] = this.productImageString; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['Remarks'] = this.remarks; + data['Route'] = this.route; + data['SKU'] = this.sKU; + data['ScaleOffset'] = this.scaleOffset; + data['StartDate'] = this.startDate; + data['PatientAge'] = this.patientAge; data['PatientGender'] = this.patientGender; - data['Address'] = this.address; data['PhoneOffice'] = this.phoneOffice; - data['ItemDescription'] = this.itemDescription; data['DoseTimingID'] = this.doseTimingID; data['FrequencyID'] = this.frequencyID; data['RouteID'] = this.routeID; - data['Clinic'] = this.clinic; - data['DoctorName'] = this.doctorName; - data['Route'] = this.route; - data['Frequency'] = this.frequency; - data['Remarks'] = this.remarks; data['Name'] = this.name; - data['Days'] = this.days; - data['StartDate'] = this.startDate; - data['OrderDate'] = this.orderDate; - data['DoseDailyQuantity'] = this.doseDailyQuantity; - data['ItemID'] = this.itemID; - data['ProductImage'] = this.productImage; - data['SKU'] = this.sKU; data['ItemDescriptionN'] = this.itemDescriptionN; data['RouteN'] = this.routeN; data['FrequencyN'] = this.frequencyN; - data['ImageSRCUrl'] = this.imageSRCUrl; - data['ImageThumbUrl'] = this.imageThumbUrl; data['hasPlan'] = false; + return data; } } diff --git a/lib/core/model/reports/Reports.dart b/lib/core/model/reports/Reports.dart index a8a5869d..6791a3d4 100644 --- a/lib/core/model/reports/Reports.dart +++ b/lib/core/model/reports/Reports.dart @@ -11,24 +11,24 @@ class Reports { String setupId; int patientID; int doctorID; - Null clinicID; + dynamic clinicID; DateTime requestDate; bool isRead; DateTime isReadOn; int actualDoctorRate; String clinicDescription; - Null clinicDescriptionN; + dynamic clinicDescriptionN; String docName; Null docNameN; String doctorImageURL; - Null doctorName; - Null doctorNameN; + dynamic doctorName; + dynamic doctorNameN; int doctorRate; bool isDoctorAllowVedioCall; bool isExecludeDoctor; int noOfPatientsRate; String projectName; - Null projectNameN; + dynamic projectNameN; Reports( {this.status, @@ -61,37 +61,41 @@ class Reports { this.projectNameN}); Reports.fromJson(Map json) { - status = json['Status']; - encounterDate = DateUtil.convertStringToDate( - json['EncounterDate']); //json['EncounterDate']; - projectID = json['ProjectID']; - invoiceNo = json['InvoiceNo']; - encounterNo = json['EncounterNo']; - procedureId = json['ProcedureId']; - requestType = json['RequestType']; - setupId = json['SetupId']; - patientID = json['PatientID']; - doctorID = json['DoctorID']; - clinicID = json['ClinicID']; - requestDate = DateUtil.convertStringToDate( - json['RequestDate']); //json['RequestDate']; - isRead = json['IsRead']; - isReadOn = - DateUtil.convertStringToDate(json['IsReadOn']); //json['IsReadOn']; - actualDoctorRate = json['ActualDoctorRate']; - clinicDescription = json['ClinicDescription']; - clinicDescriptionN = json['ClinicDescriptionN']; - docName = json['DocName']; - docNameN = json['DocNameN']; - doctorImageURL = json['DoctorImageURL']; - doctorName = json['DoctorName']; - doctorNameN = json['DoctorNameN']; - doctorRate = json['DoctorRate']; - isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; - isExecludeDoctor = json['IsExecludeDoctor']; - noOfPatientsRate = json['NoOfPatientsRate']; - projectName = json['ProjectName']; - projectNameN = json['ProjectNameN']; + try { + status = json['Status']; + encounterDate = DateUtil.convertStringToDate( + json['EncounterDate']); //json['EncounterDate']; + projectID = json['ProjectID']; + invoiceNo = json['InvoiceNo']; + encounterNo = json['EncounterNo']; + procedureId = json['ProcedureId']; + requestType = json['RequestType']; + setupId = json['SetupId']; + patientID = json['PatientID']; + doctorID = json['DoctorID']; + clinicID = json['ClinicID']; + requestDate = DateUtil.convertStringToDate( + json['RequestDate']); //json['RequestDate']; + isRead = json['IsRead']; + isReadOn = + DateUtil.convertStringToDate(json['IsReadOn']); //json['IsReadOn']; + actualDoctorRate = json['ActualDoctorRate']; + clinicDescription = json['ClinicDescription']; + clinicDescriptionN = json['ClinicDescriptionN']; + docName = json['DocName']; + docNameN = json['DocNameN']; + doctorImageURL = json['DoctorImageURL']; + doctorName = json['DoctorName']; + doctorNameN = json['DoctorNameN']; + doctorRate = json['DoctorRate']; + isDoctorAllowVedioCall = json['IsDoctorAllowVedioCall']; + isExecludeDoctor = json['IsExecludeDoctor']; + noOfPatientsRate = json['NoOfPatientsRate']; + projectName = json['ProjectName']; + projectNameN = json['ProjectNameN']; + }catch(e){ + print(e); + } } Map toJson() { diff --git a/lib/core/service/AlHabibMedicalService/H2O_service.dart b/lib/core/service/AlHabibMedicalService/H2O_service.dart index c65221c5..9483bc31 100644 --- a/lib/core/service/AlHabibMedicalService/H2O_service.dart +++ b/lib/core/service/AlHabibMedicalService/H2O_service.dart @@ -1,5 +1,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_today_data_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart'; @@ -10,8 +12,66 @@ class H2OService extends BaseService { List userProgressForTodayDataList = List(); List userProgressForWeekDataList = List(); List userProgressForMonthDataList = List(); - UserProgressRequestModel userProgressRequestModel = - UserProgressRequestModel(); + UserProgressRequestModel userProgressRequestModel = UserProgressRequestModel(); + + UserDetailModel userDetailModel = UserDetailModel(); + + Future getUserDetail() async { + userProgressRequestModel.progress = 1; + userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.identificationNo = user.patientIdentificationNo; + + hasError = false; + await baseAppClient.post(H2O_GET_USER_DETAIL, onSuccess: (dynamic response, int statusCode) { + userDetailModel = UserDetailModel.fromJson(response["UserDetailData_New"]); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: userProgressRequestModel.toJson()); + } + + Future updateUserDetail(UserDetailModel userDetail) async { + userProgressRequestModel.progress = 1; + userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.identificationNo = user.patientIdentificationNo; + + UserDetailRequestModel _requestModel = UserDetailRequestModel(); + + _requestModel.activityID = userDetail.activityID.toString(); + _requestModel.channel = userProgressRequestModel.channel; + _requestModel.dOB = userDetail.dOB; + _requestModel.deviceTypeID = userProgressRequestModel.deviceTypeID; + _requestModel.email = userDetail.emailID; + _requestModel.firstName = userDetail.firstName; + _requestModel.gender = userDetail.gender; + _requestModel.height = userDetail.height; + _requestModel.iPAdress = userProgressRequestModel.iPAdress; + _requestModel.identificationNo = userProgressRequestModel.identificationNo; + _requestModel.isHeightInCM = userDetail.isHeightInCM; + _requestModel.isWeightInKG = userDetail.isWeightInKG; + _requestModel.languageID = userProgressRequestModel.languageID; + _requestModel.mobileNumber = userProgressRequestModel.mobileNumber; + _requestModel.patientID = userProgressRequestModel.patientID; + _requestModel.patientOutSA = userProgressRequestModel.patientOutSA; + _requestModel.patientType = userProgressRequestModel.patientType; + _requestModel.patientTypeID = userProgressRequestModel.patientOutSA; + _requestModel.sessionID = userProgressRequestModel.sessionID; + _requestModel.tokenID = userProgressRequestModel.tokenID; + _requestModel.versionID = userProgressRequestModel.versionID; + _requestModel.zipCode = userDetail.zipCode; + _requestModel.weight = userDetail.weight; + _requestModel.generalid = userProgressRequestModel.generalid; + _requestModel.isDentalAllowedBackend = userProgressRequestModel.isDentalAllowedBackend; + _requestModel.isNotificationOn = userDetail.isNotificationON; + + hasError = false; + await baseAppClient.post(H2O_UPDATE_USER_DETAIL, onSuccess: (dynamic response, int statusCode) { + userDetailModel = userDetail; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: _requestModel.toJson()); + } Future getUserProgressForTodayData() async { userProgressRequestModel.progress = 1; @@ -19,12 +79,10 @@ class H2OService extends BaseService { userProgressRequestModel.identificationNo = user.patientIdentificationNo; hasError = false; - await baseAppClient.post(H2O_GET_USER_PROGRESS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(H2O_GET_USER_PROGRESS, onSuccess: (dynamic response, int statusCode) { userProgressForTodayDataList.clear(); response['UserProgressForTodayData'].forEach((progressData) { - userProgressForTodayDataList - .add(UserProgressForTodayDataModel.fromJson(progressData)); + userProgressForTodayDataList.add(UserProgressForTodayDataModel.fromJson(progressData)); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -38,16 +96,15 @@ class H2OService extends BaseService { userProgressRequestModel.identificationNo = super.user.patientIdentificationNo; hasError = false; - await baseAppClient.post(H2O_GET_USER_PROGRESS, - onSuccess: (dynamic response, int statusCode) { - userProgressForTodayDataList.clear(); - response['UserProgressForWeekData'].forEach((hospital) { - userProgressForWeekDataList.add(UserProgressForWeekDataModel.fromJson(hospital)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: userProgressRequestModel.toJson()); + await baseAppClient.post(H2O_GET_USER_PROGRESS, onSuccess: (dynamic response, int statusCode) { + userProgressForWeekDataList.clear(); + response['UserProgressForWeekData'].forEach((hospital) { + userProgressForWeekDataList.add(UserProgressForWeekDataModel.fromJson(hospital)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: userProgressRequestModel.toJson()); } Future getUserProgressForMonthData() async { @@ -56,8 +113,7 @@ class H2OService extends BaseService { userProgressRequestModel.identificationNo = super.user.patientIdentificationNo; hasError = false; - await baseAppClient.post(H2O_GET_USER_PROGRESS, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.post(H2O_GET_USER_PROGRESS, onSuccess: (dynamic response, int statusCode) { userProgressForMonthDataList.clear(); response['UserProgressForMonthData'].forEach((hospital) { userProgressForMonthDataList.add(UserProgressForMonthDataModel.fromJson(hospital)); @@ -68,22 +124,33 @@ class H2OService extends BaseService { }, body: userProgressRequestModel.toJson()); } - - - Future insertUserActivity(InsertUserActivityRequestModel insertUserActivityRequestModel) async { + hasError = false; + await baseAppClient.post(H2O_INSERT_USER_ACTIVITY, onSuccess: (dynamic response, int statusCode) { + userProgressForTodayDataList.clear(); + response['UserProgressForTodayData'].forEach((progressData) { + userProgressForTodayDataList.add(UserProgressForTodayDataModel.fromJson(progressData)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: insertUserActivityRequestModel.toJson()); + } + + Future undoUserActivity() async { + userProgressRequestModel.progress = 1; + userProgressRequestModel.mobileNumber = user.mobileNumber.substring(1); + userProgressRequestModel.identificationNo = user.patientIdentificationNo; hasError = false; - await baseAppClient.post(H2O_INSERT_USER_ACTIVITY, - onSuccess: (dynamic response, int statusCode) { - userProgressForTodayDataList.clear(); - response['UserProgressForTodayData'].forEach((progressData) { - userProgressForTodayDataList - .add(UserProgressForTodayDataModel.fromJson(progressData)); - }); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: insertUserActivityRequestModel.toJson()); + await baseAppClient.post(H2O_UNDO_USER_ACTIVITY, onSuccess: (dynamic response, int statusCode) { + userProgressForTodayDataList.clear(); + response['UserProgressForTodayData'].forEach((progressData) { + userProgressForTodayDataList.add(UserProgressForTodayDataModel.fromJson(progressData)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: userProgressRequestModel.toJson()); } } diff --git a/lib/core/service/AlHabibMedicalService/cmc_service.dart b/lib/core/service/AlHabibMedicalService/cmc_service.dart index dffa6683..9e99f3ad 100644 --- a/lib/core/service/AlHabibMedicalService/cmc_service.dart +++ b/lib/core/service/AlHabibMedicalService/cmc_service.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; @@ -47,8 +48,9 @@ class CMCService extends BaseService { await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, onSuccess: (dynamic response, int statusCode) { cmcAllPresOrdersList.clear(); + cmcAllOrderDetail.clear(); response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { - if (data['ServiceID'] == 3) + if (data['ServiceID'] == OrderService.Comprehensive_Medical_Checkup.getIdOrderService()) cmcAllPresOrdersList .add(GetHHCAllPresOrdersResponseModel.fromJson(data)); }); @@ -104,7 +106,7 @@ class CMCService extends BaseService { Future insertPresPresOrder({CMCInsertPresOrderRequestModel order}) async { hasError = false; - await baseAppClient.post(PATIENT_ER_UPDATE_PRES_ORDER, + await baseAppClient.post(PATIENT_ER_INSERT_PRES_ORDER, onSuccess: (dynamic response, int statusCode) { isOrderUpdated = true; }, onFailure: (String error, int statusCode) { diff --git a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart index da12b48b..ea5d03ca 100644 --- a/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart +++ b/lib/core/service/AlHabibMedicalService/customer_addresses_service.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:intl/intl.dart'; +import '../../../locator.dart'; import '../base_service.dart'; class CustomerAddressesService extends BaseService { @@ -9,6 +11,7 @@ class CustomerAddressesService extends BaseService { List addressesList = List(); CustomerInfo customerInfo; + Future addAddressInfo({ AddNewAddressRequestModel addNewAddressRequestModel }) async { @@ -25,7 +28,7 @@ class CustomerAddressesService extends BaseService { var date = f.format(DateTime.now().toUtc()) + " GMT"; addNewAddressRequestModel.customer.addresses[0].createdOnUtc = date; hasError = false; - await baseAppClient.post(ADD_ADDRESS_INFO, + await baseAppClient.post(ADD_CUSTOMER_ADDRESS, onSuccess: (dynamic response, int statusCode) { addressesList.clear(); response["customers"][0]["addresses"].forEach((data) { @@ -35,7 +38,7 @@ class CustomerAddressesService extends BaseService { }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; - }, body: addNewAddressRequestModel.toJson(), isExternal: true, isAllowAny: true); + }, body: addNewAddressRequestModel.toJson(), isAllowAny: true); } Future getCustomerAddresses() async { @@ -43,7 +46,7 @@ class CustomerAddressesService extends BaseService { 'fields':'addresses' }; hasError = false; - await baseAppClient.get("$GET_CUSTOMER_ADDRESSES${customerInfo.customerId}", + await baseAppClient.getPharmacy("$BASE_PHARMACY_URL$GET_CUSTOMER_ADDRESSES${customerInfo.customerId}", onSuccess: (dynamic response, int statusCode) { addressesList.clear(); response["customers"][0]["addresses"].forEach((data) { @@ -63,7 +66,7 @@ class CustomerAddressesService extends BaseService { }; hasError = false; - await baseAppClient.get(GET_CUSTOMER_INFO, + await baseAppClient.getPharmacy(BASE_PHARMACY_URL+GET_CUSTOMER_INFO, onSuccess: (dynamic response, int statusCode) { customerInfo= CustomerInfo.fromJson(response); }, onFailure: (String error, int statusCode) { @@ -77,9 +80,9 @@ class CustomerAddressesService extends BaseService { class CustomerInfo { bool isRegistered; String userName; - Null password; + dynamic password; String email; - Null errorMessage; + dynamic errorMessage; String mobileNumber; int customerId; @@ -121,19 +124,19 @@ class AddressInfo { String firstName; String lastName; String email; - Null company; + dynamic company; int countryId; String country; - Null stateProvinceId; + dynamic stateProvinceId; String city; String address1; String address2; String zipPostalCode; String phoneNumber; - Null faxNumber; + dynamic faxNumber; String customerAttributes; String createdOnUtc; - Null province; + dynamic province; String latLong; AddressInfo( diff --git a/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart new file mode 100644 index 00000000..b59eadac --- /dev/null +++ b/lib/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart @@ -0,0 +1,76 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class BariatricsService extends BaseService { + List clinicCategoryList = []; + List diseasesList = []; + + Future getClinicCategory() async { + hasError = false; + Map body = Map(); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + + body['ClinicID'] = 108; // hint: it is static depend on IONIC project + body['isDentalAllowedBackend'] = false; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + + await baseAppClient.post(GET_CLINIC_CATEGORY, + onSuccess: (dynamic response, int statusCode) { + clinicCategoryList.clear(); + if (response['ClinicCategoryList'] != null) + response['ClinicCategoryList'].forEach((city) { + clinicCategoryList.add(ClinicCategory.fromJson(city)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getDiseaseByClinicId() async { + hasError = false; + Map body = Map(); + body['ClinicID'] = 108; // hint: it is static depend on IONIC project + + await baseAppClient.post(GET_DISEASE_BY_CLINIC_ID, + onSuccess: (dynamic response, int statusCode) { + diseasesList.clear(); + if (response['DiseasesByClinicList'] != null) + response['DiseasesByClinicList'].forEach((city) { + diseasesList.add(DiseasesByClinic.fromJson(city)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future searchDoctorsByTime(DiseasesByClinic disease) async { + hasError = false; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + + Map body = Map(); + body['ClinicID'] = 108; // hint: it is static depend on IONIC project + body['ContinueDentalPlan'] = false; + body['DiseaseID'] = disease.diseasesID; + body['IsGetNearAppointment'] = false; + body['IsSearchAppointmnetByClinicID'] = true; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + body['Latitude'] = 0; + body['License'] = true; + body['Longitude'] = 0; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(SEARCH_DOCTOR_BY_TIME, + onSuccess: (dynamic response, int statusCode) { + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } +} diff --git a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart index e636321b..2ec1e310 100644 --- a/lib/core/service/AlHabibMedicalService/home_health_care_service.dart +++ b/lib/core/service/AlHabibMedicalService/home_health_care_service.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_request_modle.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/HHC_get_all_services_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hHC_all_pres_orders_request_model.dart'; @@ -7,6 +8,8 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealth import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; import '../base_service.dart'; @@ -15,9 +18,10 @@ class HomeHealthCareService extends BaseService { List hhcAllPresOrdersList = List(); List hhcAllOrderDetail = List(); + List addressesList = List(); bool isOrderUpdated; - + CustomerInfo customerInfo; Future getHHCAllServices( HHCGetAllServicesRequestModel hHCGetAllServicesRequestModel) async { hasError = false; @@ -37,11 +41,11 @@ class HomeHealthCareService extends BaseService { GetHHCAllPresOrdersRequestModel getHHCAllPresOrdersRequestModel = GetHHCAllPresOrdersRequestModel(); hasError = false; - await baseAppClient.post(GET_PATIENT_ALL_PRES_ORDERS, + await baseAppClient.post(GET_PATIENT_ALL_PRES_ORD, onSuccess: (dynamic response, int statusCode) { hhcAllPresOrdersList.clear(); response['PatientER_GetPatientAllPresOrdersList'].forEach((data) { - if (data['ServiceID'] == 2) + if (data['ServiceID'] == OrderService.HOME_HEALTH_CARE.getIdOrderService()) hhcAllPresOrdersList .add(GetHHCAllPresOrdersResponseModel.fromJson(data)); }); @@ -91,3 +95,5 @@ class HomeHealthCareService extends BaseService { }, body: order.toJson()); } } + + diff --git a/lib/core/service/PrescriptionDeliveryService.dart b/lib/core/service/PrescriptionDeliveryService.dart new file mode 100644 index 00000000..c36efe89 --- /dev/null +++ b/lib/core/service/PrescriptionDeliveryService.dart @@ -0,0 +1,30 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class PrescriptionDeliveryService extends BaseService { + Future insertDeliveryOrder( + {int lineItemNo, + double latitude, + double longitude, + int appointmentNo, + int createdBy, + int dischargeID}) async { + hasError = false; + Map body = Map(); + body['LineItemNo'] = lineItemNo; + body['Latitude'] = latitude; + body['Longitude'] = longitude; + body['AppointmentNo'] = appointmentNo; + body['CreatedBy'] = createdBy; + body['DischargeID'] = dischargeID; + await baseAppClient.post(INSERT_ER_INERT_PRES_ORDER, + onSuccess: (dynamic response, int statusCode) { + var asd=""; + }, + onFailure: (String error, int statusCode) { + hasError = true; + print(error); + super.error = error; + }, body: body); + } +} diff --git a/lib/core/service/ancillary_orders_service.dart b/lib/core/service/ancillary_orders_service.dart new file mode 100644 index 00000000..b9d14a06 --- /dev/null +++ b/lib/core/service/ancillary_orders_service.dart @@ -0,0 +1,204 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; + +class AncillaryOrdersService extends BaseService { + List _ancillaryLists = List(); + List get ancillaryLists => _ancillaryLists; + List _ancillaryProcLists = List(); + List get ancillaryProcLists => + _ancillaryProcLists; + + Future getOrders() async { + Map body = Map(); + + hasError = false; + + await baseAppClient.post(GET_ANCILLARY_ORDERS, + onSuccess: (dynamic response, int statusCode) { + _ancillaryLists = []; + response['AncillaryOrderList'].forEach((item) { + ancillaryLists.add(AncillaryOrdersListModel.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future getOrdersDetails(appointmentNo, orderNo) async { + Map body = Map(); + + hasError = false; + + await baseAppClient.post(GET_ANCILLARY_ORDERS_DETAILS, + onSuccess: (dynamic response, int statusCode) { + _ancillaryProcLists = []; + response['AncillaryOrderProcList'] = [ + { + "AncillaryOrderProcList": [ + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 501.3, + "CompanyShareWithTax": 576.5, + "CompanyTaxAmount": 75.19, + "DiscountAmount": 55.7, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": false, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 1, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 557, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02013001", + "ProcedureName": "11-DESOXYCORTISOL (COMPOUND S) - S.O", + "TaxAmount": 75.19, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 90, + "CompanyShareWithTax": 103.5, + "CompanyTaxAmount": 13.5, + "DiscountAmount": 10, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": true, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 4, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 100, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02014011", + "ProcedureName": "CBC (COMPLETE BLOOD COUNT PROFILE)", + "TaxAmount": 13.5, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 347.76, + "CompanyShareWithTax": 399.92, + "CompanyTaxAmount": 52.16, + "DiscountAmount": 38.64, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": false, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 3, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 386.4, + "ProcedureCategoryID": 2, + "ProcedureCategoryName": "LABORATORY", + "ProcedureID": "02019302", + "ProcedureName": "21-HYDROXYLASE ABS - S.O", + "TaxAmount": 52.16, + "TaxPct": 15 + }, + { + "ApprovalLineItemNo": 0, + "ApprovalNo": 0, + "ApprovalStatus": "", + "ApprovalStatusID": 0, + "CompanyShare": 1323, + "CompanyShareWithTax": 1521.45, + "CompanyTaxAmount": 198.45, + "DiscountAmount": 147, + "DiscountCategory": 1, + "DiscountType": "P", + "DiscountTypeValue": 10, + "IsApprovalCreated": false, + "IsApprovalRequired": true, + "IsCovered": false, + "OrderDate": "/Date(1601758800000+0300)/", + "OrderLineItemNo": 5, + "OrderNo": 2020000001, + "PartnerID": 0, + "PartnerShare": 0, + "PartnerShareType": "P", + "PatientShare": 0, + "PatientShareWithTax": 0, + "PatientTaxAmount": 0, + "ProcPrice": 1470, + "ProcedureCategoryID": 3, + "ProcedureCategoryName": "RADIOLOGY", + "ProcedureID": "03033065", + "ProcedureName": "CT SCAN - ABDOMEN (WITH CONTRAST)", + "TaxAmount": 198.45, + "TaxPct": 15 + } + ], + "AppointmentDate": "/Date(1601499600000+0300)/", + "AppointmentNo": 2016053756, + "ClinicID": 1, + "ClinicName": "INTERNAL MEDICINE CLINIC", + "CompanyID": 0, + "CompanyName": "Blood Donation Investigation", + "DoctorID": 1485, + "DoctorName": "ANAS ABDULLAH", + "ErrCode": null, + "GroupID": 2, + "InsurancePolicyNo": "45976500", + "Message": "Success", + "PatientCardID": "232332323", + "PatientID": 3072055, + "PatientName": "MAYA KHALED SADDIQ", + "PatientType": 1, + "PolicyID": 2, + "PolicyName": "Test", + "ProjectID": 15, + "SetupID": "010266", + "StatusCode": 1, + "SubCategoryID": 2, + "SubPolicyNo": "234234" + } + ]; + + response['AncillaryOrderProcList'].forEach((item) { + ancillaryProcLists.add(AncillaryOrdersListProcListModel.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } +} diff --git a/lib/core/service/blood/blood_donation_service.dart b/lib/core/service/blood/blood_donation_service.dart index 326407a3..9fc11c04 100644 --- a/lib/core/service/blood/blood_donation_service.dart +++ b/lib/core/service/blood/blood_donation_service.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; import '../base_service.dart'; @@ -25,4 +26,52 @@ class BloodDonationService extends BaseService { super.error = error; }, body: body); } + Future bloodDonationSave(request) async { + var localRes; + try { + await baseAppClient.post(SAVE_BLOOD_REQUEST, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + Future getAgreement() async { + var localRes; + try { + await baseAppClient.post(GET_BLOOD_AGREEMENT, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: {}); + return Future.value(localRes); + } catch (error) { + throw error; + } + } + + + Future saveAgreement(request) async { + var localRes; + try { + await baseAppClient.post(SAVE_BLOOD_AGREEMENT, + onSuccess: (dynamic response, int statusCode) { + localRes = response; + }, onFailure: (String error, int statusCode) { + localRes = error; + return Future.value(error); + }, body: request); + return Future.value(localRes); + } catch (error) { + throw error; + } + } } diff --git a/lib/core/service/childvaccines/vaccination_table_service.dart b/lib/core/service/childvaccines/vaccination_table_service.dart index 7f987b76..fc2b40e9 100644 --- a/lib/core/service/childvaccines/vaccination_table_service.dart +++ b/lib/core/service/childvaccines/vaccination_table_service.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/user_information_model.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import '../base_service.dart'; class VaccinationTableService extends BaseService { @@ -10,19 +12,18 @@ class VaccinationTableService extends BaseService { - Future getCreateVaccinationTableOrders() async { + Future getCreateVaccinationTableOrders(List_BabyInformationModel babyInfo, bool sendEmail) async { + String babyBDFormatted = "${DateUtil.convertDateToString(babyInfo.dOB)}/"; + hasError = false; await getUser(); - body['BabyName']="fffffffffff eeeeeeeeeeeeee"; - body['DOB'] = "/Date(1585774800000+0300)/"; + body['BabyName']= babyInfo.babyName; + body['DOB'] = babyBDFormatted; body['EmailAddress'] = user.emailAddress; body['isDentalAllowedBackend'] = false; - body['SendEmail'] = false; + body['SendEmail'] = sendEmail; body['IsLogin'] =true; - - - await baseAppClient.post(GET_TABLE_REQUEST, onSuccess: (dynamic response, int statusCode) { createVaccinationTableModelList.clear(); diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 04f599f1..8e410819 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -5,9 +5,12 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; @@ -16,6 +19,7 @@ import 'package:provider/provider.dart'; import '../../../locator.dart'; import '../../../routes.dart'; import '../AuthenticatedUserObject.dart'; +import 'dart:io' show Platform; AppSharedPreferences sharedPref = new AppSharedPreferences(); @@ -44,10 +48,16 @@ class BaseAppClient { } try { //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); + var pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + Map headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }; if (!isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = await sharedPref.getString(APP_LANGUAGE); - var user = await sharedPref.getObject(USER_PROFILE); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') ? body['SetupID'] != null @@ -58,15 +68,7 @@ class BaseAppClient { body['VersionID'] = VERSION_ID; body['Channel'] = CHANNEL; - body['LanguageID'] = body.containsKey('LanguageID') - ? body['LanguageID'] != null - ? body['LanguageID'] - : languageID == 'ar' - ? 1 - : 2 - : languageID == 'en' - ? 2 - : 1; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; body['IPAdress'] = IP_ADDRESS; body['generalid'] = GENERAL_ID; @@ -85,7 +87,7 @@ class BaseAppClient { : IS_DENTAL_ALLOWED_BACKEND; } - body['DeviceTypeID'] = DeviceTypeID; + body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; if (!body.containsKey('IsPublicRequest')) { body['PatientType'] = body.containsKey('PatientType') @@ -109,28 +111,34 @@ class BaseAppClient { ? body['PatientID'] : user['PatientID']; body['PatientOutSA'] = user['OutSA']; - body['SessionID'] = SESSION_ID; //getSessionId(token); + body['SessionID'] = SESSION_ID; //getSe + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': pharmacyToken, + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user['PatientID'].toString(), + }; } } } print("URL : $url"); print("Body : ${json.encode(body)}"); - var ss = json.encode(body); if (await Utils.checkConnection()) { final response = await http.post(url.trim(), - body: json.encode(body), - headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' - }); + body: json.encode(body), headers: headers); final int statusCode = response.statusCode; print("statusCode :$statusCode"); if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); if (parsed['Response_Message'] != null) { onSuccess(parsed, statusCode); } else { @@ -160,14 +168,219 @@ class BaseAppClient { } else if (parsed['MessageStatus'] == 1 || parsed['SMSLoginRequired'] == true) { onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && + parsed['IsAuthenticated']) { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] == null && + parsed['ErrorEndUserMessage'] == null) { + if (parsed['ErrorSearchMsg'] == null) { + onFailure("Server Error found with no available message", + statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); + } + } else { + onFailure( + parsed['message'] ?? + parsed['ErrorEndUserMessage'] ?? + parsed['ErrorMessage'], + statusCode); + } + } + } else if (!parsed['IsAuthenticated']) { + await logout(); + + //helpers.showErrorToast('Your session expired Please login agian'); + } else { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] != null) { + onFailure(parsed['message'] ?? parsed['message'], statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + } + } } - else if(parsed['MessageStatus'] == 2 && parsed['IsAuthenticated']){ - onFailure( - parsed['message'] ?? parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], - statusCode); + } + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } catch (e) { + print(e); + onFailure(e.toString(), -1); + } + } + + postPharmacy(String endPoint, + {Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false}) async { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + String url; + if (isExternal) { + url = endPoint; + } else { + url = PHARMACY_BASE_URL + endPoint; + } + try { + //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); + var pharmacyToken = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + Map headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': token ?? '', + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user != null ? user['PatientID'].toString() : "", + }; + if (!isExternal) { + String token = await sharedPref.getString(TOKEN); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + if (body.containsKey('SetupID')) { + body['SetupID'] = body.containsKey('SetupID') + ? body['SetupID'] != null + ? body['SetupID'] + : SETUP_ID + : SETUP_ID; + } + + body['VersionID'] = VERSION_ID; + body['Channel'] = CHANNEL; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + + body['IPAdress'] = IP_ADDRESS; + body['generalid'] = GENERAL_ID; + body['PatientOutSA'] = body.containsKey('PatientOutSA') + ? body['PatientOutSA'] != null + ? body['PatientOutSA'] + : PATIENT_OUT_SA + : PATIENT_OUT_SA; + + if (body.containsKey('isDentalAllowedBackend')) { + body['isDentalAllowedBackend'] = + body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; + } + + + body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; + + if (!body.containsKey('IsPublicRequest')) { + body['PatientType'] = body.containsKey('PatientType') + ? body['PatientType'] != null + ? body['PatientType'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE + : PATIENT_TYPE; + + body['PatientTypeID'] = body.containsKey('PatientTypeID') + ? body['PatientTypeID'] != null + ? body['PatientTypeID'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE_ID + : PATIENT_TYPE_ID; + if (user != null) { + body['TokenID'] = token; + body['PatientID'] = body['PatientID'] != null + ? body['PatientID'] + : user['PatientID']; + body['PatientOutSA'] = user['OutSA']; + body['SessionID'] = SESSION_ID; //getSe + headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': pharmacyToken, + 'Mobilenumber': user['MobileNumber'].toString(), + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user['PatientID'].toString(), + }; + } + } + } + + print("URL : $url"); + print("Body : ${json.encode(body)}"); + + if (await Utils.checkConnection()) { + final response = await http.post(url.trim(), + body: json.encode(body), headers: headers); + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); + if (parsed['Response_Message'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['ErrorType'] == 4) { + navigateToAppUpdate( + AppGlobal.context, parsed['ErrorEndUserMessage']); } - else if (!parsed['IsAuthenticated']) { - await logout(); + if (isAllowAny) { + onSuccess(parsed, statusCode); + } else if (parsed['IsAuthenticated'] == null) { + if (parsed['isSMSSent'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 1) { + onSuccess(parsed, statusCode); + } else if (parsed['Result'] == 'OK') { + onSuccess(parsed, statusCode); + } else { + if (parsed != null) { + onSuccess(parsed, statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + logout(); + } + } + } else if (parsed['MessageStatus'] == 1 || + parsed['SMSLoginRequired'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && + parsed['IsAuthenticated']) { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] == null && + parsed['ErrorEndUserMessage'] == null) { + if (parsed['ErrorSearchMsg'] == null) { + onFailure("Server Error found with no available message", + statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); + } + } else { + onFailure( + parsed['message'] ?? + parsed['ErrorEndUserMessage'] ?? + parsed['ErrorMessage'], + statusCode); + } + } + } else if (!parsed['IsAuthenticated']) { + await logout(); //helpers.showErrorToast('Your session expired Please login agian'); } else { @@ -193,18 +406,17 @@ class BaseAppClient { onFailure(e.toString(), -1); } } + Future navigateToAppUpdate(context, String text) async { Navigator.pushReplacement( - context, - MaterialPageRoute( - builder: (context) => AppUpdatePage(appUpdateText: text))); + context, FadePage(page: AppUpdatePage(appUpdateText: text))); } get(String endPoint, {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - Map queryParams, - bool isExternal = false}) async { + Function(String error, int statusCode) onFailure, + Map queryParams, + bool isExternal = false}) async { String url; if (isExternal) { url = endPoint; @@ -232,7 +444,8 @@ class BaseAppClient { if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); onSuccess(parsed, statusCode); } } else { @@ -242,10 +455,19 @@ class BaseAppClient { getPharmacy(String endPoint, {Function(dynamic response, int statusCode) onSuccess, - Function(String error, int statusCode) onFailure, - bool isAllowAny = false, - Map queryParams}) async { - String url = PHARMACY_BASE_URL + endPoint; + Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false, + Map queryParams}) async { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + + String url; + if (isExternal) { + url = endPoint; + } else { + url = PHARMACY_BASE_URL + endPoint; + } if (queryParams != null) { String queryString = Uri(queryParameters: queryParams).query; url += '?' + queryString; @@ -255,25 +477,74 @@ class BaseAppClient { if (await Utils.checkConnection()) { final response = await http.get(url.trim(), headers: { - 'Content-Type': 'application/json', - 'Accept': 'application/json' + 'Content-Type': 'text/html; charset=utf-8', + 'Accept': 'application/json', + 'Authorization': token ?? '', + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user != null ? user['PatientID'].toString() : "", }); final int statusCode = response.statusCode; print("statusCode :$statusCode"); + if (statusCode < 200 || statusCode >= 400 || json == null) { + if (statusCode == 401) { + AppToast.showErrorToast( + message: TranslationBase.of(AppGlobal.context).pharmacyRelogin); + Navigator.of(AppGlobal.context).pushNamed(HOME); + } else { + onFailure('Error While Fetching data', statusCode); + } + } else { + // var parsed = json.decode(response.body.toString()); + var bodyUtf = json.decode(utf8.decode(response.bodyBytes)); + onSuccess(bodyUtf, statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } + + simplePost(String fullUrl, + { Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure,}) async { + String url = fullUrl; + print("URL Query String: $url"); + + if (await Utils.checkConnection()) { + final response = await http.post( + url.trim(), + body: json.encode(body), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + if (statusCode < 200 || statusCode >= 400 || json == null) { onFailure('Error While Fetching data', statusCode); } else { - var parsed = json.decode(response.body.toString()); - onSuccess(parsed, statusCode); + onSuccess(response.body.toString(), statusCode); } } else { onFailure('Please Check The Internet Connection', -1); } } - simpleGet(String fullUrl, {Function(dynamic response, int statusCode) onSuccess, Function(String error, int statusCode) onFailure, Map queryParams}) async { + simpleGet(String fullUrl, + {Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + Map queryParams}) async { + String url = fullUrl; + print("URL Query String: $url"); + var haveParams = (queryParams != null); if (haveParams) { String queryString = Uri(queryParameters: queryParams).query; @@ -284,7 +555,79 @@ class BaseAppClient { if (await Utils.checkConnection()) { final response = await http.get( url.trim(), - headers: {'Content-Type': 'application/json', 'Accept': 'application/json'}, + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body.toString(), statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } + + + simplePut(String fullUrl, + { Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure}) async { + + String url = fullUrl; + print("URL Query String: $url"); + + if (await Utils.checkConnection()) { + final response = await http.put( + url.trim(), + body: json.encode(body), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + ); + + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + onSuccess(response.body.toString(), statusCode); + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } + + simpleDelete(String fullUrl, + {Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + Map queryParams}) async { + + String url = fullUrl; + print("URL Query String: $url"); + + var haveParams = (queryParams != null); + if (haveParams) { + String queryString = Uri(queryParameters: queryParams).query; + url += '?' + queryString; + print("URL Query String: $url"); + } + + if (await Utils.checkConnection()) { + final response = await http.delete( + url.trim(), + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, ); final int statusCode = response.statusCode; @@ -306,7 +649,8 @@ class BaseAppClient { await authenticatedUserObject.getUser(); Provider.of(AppGlobal.context, listen: false).isLogin = false; - var model = Provider.of(AppGlobal.context,listen: false); + var model = + Provider.of(AppGlobal.context, listen: false); _vitalSignService.weightKg = ""; _vitalSignService.heightCm = ""; model.setState(0, false); @@ -315,12 +659,13 @@ class BaseAppClient { String getSessionId(String id) { ///return id.replaceAll(RegExp('/[^\w\s]/'), ''); - return id.replaceAll(RegExp('/[^a-zA-Z ]'), ''); + return id.replaceAll(RegExp('/[^a-zA-Z ]'), ''); } static defaultHttpParameters() async { String token = await sharedPref.getString(TOKEN); - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); var user = await sharedPref.getObject(USER_PROFILE); var params = {}; if (user != null) { @@ -338,4 +683,182 @@ class BaseAppClient { return params; } -} \ No newline at end of file + + pharmacyPost(String endPoint, + {Map body, + Function(dynamic response, int statusCode) onSuccess, + Function(String error, int statusCode) onFailure, + bool isAllowAny = false, + bool isExternal = false}) async { + var token = await sharedPref.getString(PHARMACY_AUTORZIE_TOKEN); + var user = await sharedPref.getObject(USER_PROFILE); + String url; + if (isExternal) { + url = endPoint; + } else { + url = BASE_PHARMACY_URL + endPoint; + } + try { + if (isExternal) { + String token = await sharedPref.getString(TOKEN); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var user = await sharedPref.getObject(USER_PROFILE); + if (body.containsKey('SetupID')) { + body['SetupID'] = body.containsKey('SetupID') + ? body['SetupID'] != null + ? body['SetupID'] + : SETUP_ID + : SETUP_ID; + } + + body['VersionID'] = VERSION_ID; + body['Channel'] = CHANNEL; + body['LanguageID'] = languageID == 'ar' ? 1 : 2; + + body['IPAdress'] = IP_ADDRESS; + body['generalid'] = GENERAL_ID; + body['PatientOutSA'] = body.containsKey('PatientOutSA') + ? body['PatientOutSA'] != null + ? body['PatientOutSA'] + : PATIENT_OUT_SA + : PATIENT_OUT_SA; + + if (body.containsKey('isDentalAllowedBackend')) { + body['isDentalAllowedBackend'] = + body.containsKey('isDentalAllowedBackend') + ? body['isDentalAllowedBackend'] != null + ? body['isDentalAllowedBackend'] + : IS_DENTAL_ALLOWED_BACKEND + : IS_DENTAL_ALLOWED_BACKEND; + } + + body['DeviceTypeID'] = Platform.isAndroid ? 1: 2; + + if (!body.containsKey('IsPublicRequest')) { + body['PatientType'] = body.containsKey('PatientType') + ? body['PatientType'] != null + ? body['PatientType'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE + : PATIENT_TYPE; + + body['PatientTypeID'] = body.containsKey('PatientTypeID') + ? body['PatientTypeID'] != null + ? body['PatientTypeID'] + : user['PatientType'] != null + ? user['PatientType'] + : PATIENT_TYPE_ID + : PATIENT_TYPE_ID; + if (user != null) { + body['TokenID'] = token; + body['PatientID'] = body['PatientID'] != null + ? body['PatientID'] + : user['PatientID']; + body['PatientOutSA'] = user['OutSA']; + body['SessionID'] = SESSION_ID; //getSessionId(token); + } + } + } + + print("URL : $url"); + print("Body : ${json.encode(body)}"); + var ss = json.encode(body); + + if (await Utils.checkConnection()) { + final response = + await http.post(url.trim(), body: json.encode(body), headers: { + // 'Content-Type': 'application/json', + // 'Accept': 'application/json', + // 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'Authorization': token ?? '', + 'Mobilenumber': user != null + ? Utils.getPhoneNumberWithoutZero(user['MobileNumber'].toString()) + : "", + 'Statictoken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9', + 'Username': user != null ? user['PatientID'].toString() : "", + }); + final int statusCode = response.statusCode; + print("statusCode :$statusCode"); + if (statusCode < 200 || statusCode >= 400 || json == null) { + onFailure('Error While Fetching data', statusCode); + } else { + // var parsed = json.decode(response.body.toString()); + var parsed = json.decode(utf8.decode(response.bodyBytes)); + if (parsed['Response_Message'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['ErrorType'] == 4) { + navigateToAppUpdate( + AppGlobal.context, parsed['ErrorEndUserMessage']); + } + if (isAllowAny) { + onSuccess(parsed, statusCode); + } else if (parsed['IsAuthenticated'] == null) { + if (parsed['isSMSSent'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 1) { + onSuccess(parsed, statusCode); + } else if (parsed['Result'] == 'OK') { + onSuccess(parsed, statusCode); + } else { + if (parsed != null) { + onSuccess(parsed, statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + logout(); + } + } + } else if (parsed['MessageStatus'] == 1 || + parsed['SMSLoginRequired'] == true) { + onSuccess(parsed, statusCode); + } else if (parsed['MessageStatus'] == 2 && + parsed['IsAuthenticated']) { + if (parsed['message'] == null && + parsed['ErrorEndUserMessage'] == null) { + if (parsed['ErrorSearchMsg'] == null) { + onFailure("Server Error found with no available message", + statusCode); + } else { + onFailure(parsed['ErrorSearchMsg'], statusCode); + } + } else { + onFailure( + parsed['message'] ?? + parsed['ErrorEndUserMessage'] ?? + parsed['ErrorMessage'], + statusCode); + } + } else if (!parsed['IsAuthenticated']) { + await logout(); + + //helpers.showErrorToast('Your session expired Please login agian'); + } else { + if (parsed['SameClinicApptList'] != null) { + onSuccess(parsed, statusCode); + } else { + if (parsed['message'] != null) { + onFailure(parsed['message'] ?? parsed['message'], statusCode); + } else { + onFailure( + parsed['ErrorEndUserMessage'] ?? parsed['ErrorMessage'], + statusCode); + } + } + } + } + } + } else { + onFailure('Please Check The Internet Connection', -1); + } + } catch (e) { + print(e); + onFailure(e.toString(), -1); + } + } +} diff --git a/lib/core/service/er/EdOnlineServices.dart b/lib/core/service/er/EdOnlineServices.dart new file mode 100644 index 00000000..2df92d8a --- /dev/null +++ b/lib/core/service/er/EdOnlineServices.dart @@ -0,0 +1,96 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/er/ErPatientShareModel.dart'; +import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class EdOnlineServices extends BaseService { + List triageQuestionsModelList = List(); + ErPatientShareModel erPatientShareModel; + + Future getQuestions() async { + hasError =false; + triageQuestionsModelList.clear(); + Map body = Map(); + body['ProjectID'] = 15; + await baseAppClient.post(ER_GET_VISUAL_TRIAGE_QUESTIONS, + onSuccess: (dynamic response, int statusCode) { + triageQuestionsModelList.clear(); + response['ER_TriageQuestionsList'].forEach((questions) { + triageQuestionsModelList.add(TriageQuestionsModel.fromJson(questions)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + + Future getPatientPaymentInformation({var id}) async { + hasError =false; + await baseAppClient.post(ER_GetPatientPaymentInformationForERClinic, + onSuccess: (dynamic response, int statusCode) { + erPatientShareModel = + ErPatientShareModel.fromJson(response['ER_PatientShare']); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: Map.from({"ProjectID":15,"ClinicID":10})); + } + + Future saveQuestionsInformation( + {String notes, + String chiefComplaint, + int projectId, + DateTime selectedTime, + List selectedQuestions}) async { + hasError =false; + Map body = Map(); + List checklist = List(); + + body['ProjectID'] = 15; + body['ProjectId'] = projectId; + int riskScore = 0; + + if (user.age > 14) { + selectedQuestions.forEach((element) { + int score = int.parse(element.adultPoints); + riskScore += score; + checklist.add(Map.from({ + "IsSelected": 1, + "ParameterCode": element.parameterCode, + "ParameterGroup": element.parameterGroup, + "ParameterType": element.parameterType, + "Score": score + })); + }); + } else { + selectedQuestions.forEach((element) { + int score = int.parse(element.pediaPoints); + riskScore += score; + checklist.add(Map.from({ + "IsSelected": 1, + "ParameterCode": element.parameterCode, + "ParameterGroup": element.parameterGroup, + "ParameterType": element.parameterType, + "Score": score + })); + }); + } + + body['ERTriageInformation'] = { + "Notes": notes, + "ChiefComplaint": chiefComplaint, + "PatientId": user.patientID, + "ProjectId": 15, + "RiskScore": riskScore, + "checklist": checklist.map((e) => e).toList() + }; + + await baseAppClient.post(ER_SAVE_TRIAGE_INFORMATION, + onSuccess: (dynamic response, int statusCode) {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } +} diff --git a/lib/core/service/health-weather/health_weather_indicator.dart b/lib/core/service/health-weather/health_weather_indicator.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/core/service/hospital_service.dart b/lib/core/service/hospital_service.dart index 312d7fd7..6e32d8e6 100644 --- a/lib/core/service/hospital_service.dart +++ b/lib/core/service/hospital_service.dart @@ -22,12 +22,13 @@ class HospitalService extends BaseService { }); } - Future getHospitals() async { + Future getHospitals({bool isResBasedOnLoc = true}) async { + if(isResBasedOnLoc) await _getCurrentLocation(); Map body = Map(); - body['Latitude'] = _latitude; - body['Longitude'] = _longitude; - body['IsOnlineCheckIn'] = true; + body['Latitude'] = isResBasedOnLoc?_latitude:0; + body['Longitude'] = isResBasedOnLoc?_longitude:0; + body['IsOnlineCheckIn'] = isResBasedOnLoc; body['PatientOutSA'] = 0; await baseAppClient.post(GET_PROJECT, diff --git a/lib/core/service/medical/BloodPressureService.dart b/lib/core/service/medical/BloodPressureService.dart index f2681191..82130750 100644 --- a/lib/core/service/medical/BloodPressureService.dart +++ b/lib/core/service/medical/BloodPressureService.dart @@ -68,6 +68,19 @@ class BloodPressureService extends BaseService { super.error = error; }, body: Map()); } + Future sendReportByEmail() async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['to'] = user.emailAddress; + await baseAppClient.post(SEND_AVERAGE_BLOOD_PRESSURE_REPORT, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } addDiabtecResult( {String bloodPressureDate, @@ -93,4 +106,43 @@ class BloodPressureService extends BaseService { super.error = error; }, body: body); } + + updateDiabtecResult( + {String bloodPressureDate, + String diastolicPressure, + String systolicePressure, + int measuredArm}) async { + hasError = false; + super.error = ""; + + Map body = Map(); + body['BloodPressureDate'] = bloodPressureDate; + body['DiastolicPressure'] = diastolicPressure; + body['SystolicePressure'] = systolicePressure; + body['MeasuredArm'] ='$measuredArm'; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(UPDATE_BLOOD_PRESSURE_RESULT, + onSuccess: (response, statusCode) async { + + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future deactivateDiabeticStatus({int lineItemNo }) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['LineItemNo'] =lineItemNo; + await baseAppClient.post(DEACTIVATE_BLOOD_PRESSURES_STATUS, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/medical/BloodSugarService.dart b/lib/core/service/medical/BloodSugarService.dart index 09fe9fe9..e8e2fabf 100644 --- a/lib/core/service/medical/BloodSugarService.dart +++ b/lib/core/service/medical/BloodSugarService.dart @@ -24,6 +24,11 @@ class BloodSugarService extends BaseService { monthDiabtectResultAverageList.clear(); weekDiabtectResultAverageList.clear(); yearDiabtecResultAverageList.clear(); + + monthDiabtecPatientResult.clear(); + weekDiabtecPatientResult.clear(); + yearDiabtecPatientResult.clear(); + response['List_MonthDiabtectResultAverage'].forEach((item) { monthDiabtectResultAverageList .add(MonthDiabtectResultAverage.fromJson(item)); @@ -69,28 +74,66 @@ class BloodSugarService extends BaseService { }, body: Map()); } - addDiabtecResult( - {String bloodSugerDateChart, - String bloodSugerResult, - String diabtecUnit, - int measuredTime}) async { + addDiabtecResult({String bloodSugerDateChart, String bloodSugerResult, String diabtecUnit, int measuredTime}) async { hasError = false; super.error = ""; - Map body = Map(); body['BloodSugerDateChart'] = bloodSugerDateChart; body['BloodSugerResult'] = bloodSugerResult; body['DiabtecUnit'] = diabtecUnit; - body['MeasuredTime'] =2;// measuredTime; + body['MeasuredTime'] = measuredTime+1; body['isDentalAllowedBackend'] = false; + await baseAppClient.post(ADD_DIABTEC_RESULT, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } - await baseAppClient.post(ADD_BLOOD_PRESSURE_RESULT, - onSuccess: (response, statusCode) async { - var asd =""; - }, + updateDiabtecResult({DateTime month,DateTime hour,String bloodSugerResult,String diabtecUnit, int measuredTime,int lineItemNo}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['BloodSugerResult'] = bloodSugerResult; + body['DiabtecUnit'] = diabtecUnit; + body['BloodSugerDateChart'] = '${month.year}-${month.month}-${month.day} ${hour.hour}:${hour.minute}:00'; + body['isDentalAllowedBackend'] = false; + body['MeasuredTime'] = measuredTime+1; + body['LineItemNo'] = lineItemNo; + await baseAppClient.post(UPDATE_DIABETIC_RESULT, + onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, body: body); } + + Future sendReportByEmail() async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['to'] = user.emailAddress; + await baseAppClient.post(SEND_AVERAGE_BLOOD_SUGAR_REPORT, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + Future deactivateDiabeticStatus({int lineItemNo }) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['LineItemNo'] =lineItemNo; + await baseAppClient.post(DEACTIVATE_DIABETIC_STATUS, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/medical/EyeService.dart b/lib/core/service/medical/EyeService.dart index 879acbbf..937f89e3 100644 --- a/lib/core/service/medical/EyeService.dart +++ b/lib/core/service/medical/EyeService.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; class EyeService extends BaseService { List appoimentAllHistoryResultList = List(); @@ -23,4 +24,53 @@ class EyeService extends BaseService { super.error = error; }, body: body); } + + sendGlassesPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['PatientIditificationNum'] = user.patientIdentificationNo; + body['PatientName'] = user.firstName+" "+user.lastName; + body['To'] = user.emailAddress; + body['SetupID'] = user.setupID; + body['DateofBirth'] = user.dateofBirth; + body['ProjectID'] = projectID; + body['AppointmentNo'] = appointmentNo; + body['ProjectName'] = projectName; + body['PatientID'] = user.patientID; + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); + await baseAppClient.post(SEND_REPORT_EYE_EMAIL, + onSuccess: (response, statusCode) async { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + sendContactLensPrescriptionEmail({int appointmentNo,String projectName,int projectID}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['AppointmentNo'] = appointmentNo; + body['PatientIditificationNum'] = user.patientIdentificationNo; + body['PatientName'] = user.firstName+" "+user.lastName; + body['To'] = user.emailAddress; + body['SetupID'] = user.setupID; + body['DateofBirth'] = user.dateofBirth; + body['ProjectID'] = projectID; + body['AppointmentNo'] = appointmentNo; + body['ProjectName'] = projectName; + body['PatientID'] = user.patientID; + body['PatientMobileNumber'] = Utils.getPhoneNumberWithoutZero(user.mobileNumber); + await baseAppClient.post(SEND_CONTACT_LENS_PRESCRIPTION_EMAIL, + onSuccess: (response, statusCode) async { + + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/medical/WeightPressureService.dart b/lib/core/service/medical/WeightPressureService.dart index 27048dc8..b48c4795 100644 --- a/lib/core/service/medical/WeightPressureService.dart +++ b/lib/core/service/medical/WeightPressureService.dart @@ -6,11 +6,13 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/weight/YearWeightMeas import 'package:diplomaticquarterapp/core/service/base_service.dart'; class WeightService extends BaseService { - ///Average - List monthWeightMeasurementResultAverage = List(); - List weekWeightMeasurementResultAverage = List(); - List yearWeightMeasurementResultAverage = List(); + List + monthWeightMeasurementResultAverage = List(); + List weekWeightMeasurementResultAverage = + List(); + List yearWeightMeasurementResultAverage = + List(); ///Result List monthWeightMeasurementResult = List(); @@ -59,7 +61,8 @@ class WeightService extends BaseService { }); response['List_MonthWeightMeasurementResult'].forEach((item) { - monthWeightMeasurementResult.add(WeightMeasurementResult.fromJson(item)); + monthWeightMeasurementResult + .add(WeightMeasurementResult.fromJson(item)); }); response['List_YearWeightMeasurementResult'].forEach((item) { @@ -72,9 +75,7 @@ class WeightService extends BaseService { } addWeightResult( - {String weightDate, - String weightMeasured, - int weightUnit}) async { + {String weightDate, String weightMeasured, int weightUnit}) async { hasError = false; super.error = ""; @@ -85,9 +86,53 @@ class WeightService extends BaseService { body['isDentalAllowedBackend'] = false; await baseAppClient.post(ADD_WEIGHT_PRESSURE_RESULT, - onSuccess: (response, statusCode) async { + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + updateWeightResult({int lineItemNo, int weightUnit,String weightMeasured,String weightDate}) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['LineItemNo'] = lineItemNo; + body['weightUnit'] = '$weightUnit'; + body['WeightMeasured'] = weightMeasured; + body['WeightDate'] = weightDate; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(UPDATE_WEIGHT_PRESSURE_RESULT, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + Future sendReportByEmail() async { + hasError = false; + super.error = ""; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + body['to'] = user.emailAddress; + await baseAppClient.post(SEND_AVERAGE_BLOOD_WEIGHT_REPORT, + onSuccess: (response, statusCode) async {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + + deleteWeightResult({int lineItemNo, }) async { + hasError = false; + super.error = ""; + Map body = Map(); + body['LineItemNo'] = lineItemNo; + body['isDentalAllowedBackend'] = false; - }, + await baseAppClient.post(DEACTIVATE_WEIGHT_PRESSURE_RESULT, + onSuccess: (response, statusCode) async {}, onFailure: (String error, int statusCode) { hasError = true; super.error = error; diff --git a/lib/core/service/medical/my_balance_service.dart b/lib/core/service/medical/my_balance_service.dart index 86e925b8..e2744250 100644 --- a/lib/core/service/medical/my_balance_service.dart +++ b/lib/core/service/medical/my_balance_service.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_advance_balance_amount.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; @@ -23,11 +24,11 @@ class MyBalanceService extends BaseService { PatientInfoAndMobileNumber patientInfoAndMobileNumber; String logInTokenID; String verificationCode; - + String updatedRegisterBloodMessage = ""; AuthenticatedUserObject authenticatedUserObject = locator(); - MyBalanceService(){ + MyBalanceService() { getFamilyFiles(); } @@ -156,4 +157,49 @@ class MyBalanceService extends BaseService { return await getSharedRecordByStatus(); } } + + Future updateBloodGroup(List_BloodGroupDetailsModel detailsModel) async { + hasError = false; + await getUser(); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Map body = Map(); + body['City'] = detailsModel.city; + body['cityCode'] = detailsModel.cityCode; + body['Gender'] = detailsModel.gender; + body['BloodGroup'] = detailsModel.bloodGroup; + body['CellNumber'] = user.mobileNumber; + body['LanguageID'] = languageID; + body['NationalID'] = user.nationalityID; + body['ZipCode'] = user.zipCode ?? "+966"; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(BLOOD_DONATION_REGISTER_BLOOD_TYPE, + onSuccess: (dynamic response, int statusCode) { + updatedRegisterBloodMessage = response['ErrorEndUserMessage']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + if(error == null){ + super.error = "Something went wrong"; + } + }, body: body); + } + + Future addUserAgreementForBloodDonation() async { + hasError = false; + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Map body = Map(); + body['IsAgreed'] = true; + body['LanguageID'] = languageID; + body['isDentalAllowedBackend'] = false; + + await baseAppClient.post(ADD_USER_AGREEMENT_FOR_BLOOD_DONATION, + onSuccess: (dynamic response, int statusCode) { + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } } diff --git a/lib/core/service/medical/radiology_service.dart b/lib/core/service/medical/radiology_service.dart index 965fa752..b0b96e71 100644 --- a/lib/core/service/medical/radiology_service.dart +++ b/lib/core/service/medical/radiology_service.dart @@ -11,7 +11,7 @@ class RadiologyService extends BaseService { hasError = false; final Map body = new Map(); body['InvoiceNo'] = invoiceNo; - body['LineItemNo'] = lineItem; + body['LineIt emNo'] = lineItem; body['ProjectID'] = projectId; await baseAppClient.post(GET_RAD_IMAGE_URL, diff --git a/lib/core/service/medical/reports_service.dart b/lib/core/service/medical/reports_service.dart index b2f90e61..bf340814 100644 --- a/lib/core/service/medical/reports_service.dart +++ b/lib/core/service/medical/reports_service.dart @@ -68,6 +68,19 @@ class ReportsService extends BaseService { }, body: body); } + Future updateEmail({String email}) async { + Map body = Map(); + body['EmailAddress'] = email; + body['isDentalAllowedBackend'] = false; + hasError = false; + await baseAppClient.post(UPDATE_PATENT_EMAIL, + onSuccess: (dynamic response, int statusCode) {}, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } + Future insertRequestForMedicalReport( AppointmentHistory appointmentHistory) async { Map body = new Map(); diff --git a/lib/core/service/offers_service.dart b/lib/core/service/offers_service.dart index 2247c833..8007007b 100644 --- a/lib/core/service/offers_service.dart +++ b/lib/core/service/offers_service.dart @@ -21,7 +21,7 @@ class OffersCategoriseService extends BaseService { Future getOffersCategorise() async { hasError = false; _offersList.clear(); - await baseAppClient.get( + await baseAppClient.getPharmacy( GET_OFFERS_CATEGORISE, onSuccess: (dynamic response, int statusCode) { response['categories'].forEach((item) { @@ -40,7 +40,7 @@ class OffersCategoriseService extends BaseService { _offerProducts.clear(); String endPoint = id != null ? GET_OFFERS_PRODUCTS + "$id" : GET_OFFERS_PRODUCTS + "1"; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { diff --git a/lib/core/service/packages_offers/PackagesOffersServices.dart b/lib/core/service/packages_offers/PackagesOffersServices.dart index e58c3fa3..15811b82 100644 --- a/lib/core/service/packages_offers/PackagesOffersServices.dart +++ b/lib/core/service/packages_offers/PackagesOffersServices.dart @@ -1,27 +1,46 @@ import 'dart:convert'; import 'dart:developer'; +import 'dart:ui'; import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/order_response_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:flutter/cupertino.dart'; import '../../../locator.dart'; class OffersAndPackagesServices extends BaseService { - List categoryList = List(); + List categoryList = List(); + List productList = List(); + List latestOffersList = List(); + List bestSellerList = List(); + List bannersList = List(); + List cartItemList = List(); + String cartItemCount = ""; + + PackagesCustomerResponseModel customer; + + Future> getAllCategories(OffersCategoriesRequestModel request) async { + Future errorThrow; - Future> getAllCategories(OffersCategoriesRequestModel request) async { - hasError = false; var url = EXA_CART_API_BASE_URL + PACKAGES_CATEGORIES; await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['categories'].forEach((json) { - categoryList.add(OfferCategoriesResponseModel().fromJson(json)); + categoryList.add(PackagesCategoriesResponseModel().fromJson(json)); }); } }, onFailure: (String error, int statusCode) { @@ -31,15 +50,18 @@ class OffersAndPackagesServices extends BaseService { return categoryList; } - List productList = List(); - Future> getAllProducts(OffersProductsRequestModel request) async { - hasError = false; + Future> getAllProducts({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + Future errorThrow; + + request.sinceId = (productList.isNotEmpty) ? productList.last.id : 0; + + productList = List(); var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { if (statusCode == 200) { var jsonResponse = json.decode(stringResponse); jsonResponse['products'].forEach((json) { - productList.add(OfferProductsResponseModel().fromJson(json)); + productList.add(PackagesResponseModel().fromJson(json)); }); } }, onFailure: (String error, int statusCode) { @@ -48,4 +70,276 @@ class OffersAndPackagesServices extends BaseService { return productList; } + + Future> getLatestOffers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + latestOffersList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return latestOffersList; + } + + Future> getBestSellers({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + bestSellerList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return bestSellerList; + } + + + Future> getBanners({@required OffersProductsRequestModel request, @required BuildContext context, @required bool showLoading = true}) async { + var url = EXA_CART_API_BASE_URL + PACKAGES_PRODUCTS; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + if (statusCode == 200) { + var jsonResponse = json.decode(stringResponse); + jsonResponse['products'].forEach((json) { + bannersList.add(PackagesResponseModel().fromJson(json)); + }); + } + }, onFailure: (String error, int statusCode) { + log(error); + }, queryParams: request.toFlatMap()); + + return bannersList; + } + + Future loadOffersPackagesDataForMainPage({@required BuildContext context, bool showLoading = true, Function completion }) async { + var finished = 0; + var totalCalls = 3; + + completedAll(){ + + finished++; + if(completion != null && finished == totalCalls) { + _hideLoading(context, showLoading); + completion(); + } + } + + _showLoading(context, showLoading); + + // Performing Parallel Request on same time + // # 1 + getBestSellers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + // # 2 + getLatestOffers(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + // # 3 + getBanners(request: OffersProductsRequestModel(), context: context, showLoading: false).then((value){ + completedAll(); + }); + + } + + // -------------------- + // Create Customer + // -------------------- + Future createCustomer(PackagesCustomerRequestModel request, {@required BuildContext context, bool showLoading = true, Function(bool) completion }) async{ + if(customer != null) + return Future.value(customer); + + customer = null; + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_CUSTOMER; + await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var customerJson = jsonResponse['customers'].first; + customer = PackagesCustomerResponseModel.fromJson(customerJson); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + errorThrow = Future.error(error); + log(error); + }); + + await Future.delayed(Duration(seconds: 1)); + + return errorThrow ?? customer; + } + + + + // -------------------- + // Shopping Cart + // -------------------- + Future> cartItems({@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + cartItemList.clear(); + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/${customer.id}'; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + jsonResponse['shopping_carts'].forEach((json) { + cartItemList.add(PackagesCartItemsResponseModel.fromJson(json)); + }); + + }, onFailure: (String error, int statusCode) { + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }, queryParams: null); + + return errorThrow ?? cartItemList; + } + + Future> addProductToCart(AddProductToCartRequestModel request, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + ResponseModel response; + + request.customer_id = customer.id; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART; + await baseAppClient.simplePost(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var jsonCartItem = jsonResponse["shopping_carts"][0]; + response = ResponseModel(status: true, data: PackagesCartItemsResponseModel.fromJson(jsonCartItem), error: null); + cartItemCount = response.data.quantity.toString(); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + errorThrow = Future.error(ResponseModel(status: true, data: null, error: error)); + }); + + return errorThrow ?? response; + } + + Future updateProductToCart(int cartItemID, {UpdateProductToCartRequestModel request, @required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; + await baseAppClient.simplePut(url, body: request.json(), onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }); + + return errorThrow ?? bannersList; + } + + + Future deleteProductFromCart(int cartItemID, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_SHOPPING_CART + '/$cartItemID'; + await baseAppClient.simpleDelete(url, onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + // var jsonResponse = json.decode(stringResponse); + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error({"error":error, "statusCode":statusCode}); + }); + + return errorThrow ?? true; + } + + // -------------------- + // Place Order + // -------------------- + Future placeOrder({@required String paymentOption, @required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + + var jsonBody = { + "order": { + "customer_id" : customer.id, + "billing_address": { + "email": customer.email, + "phone_number": customer.addresses.first.phoneNumber + }, + "payment_method_system_name": "Payments.PayFort", + "payment_option": paymentOption + } + }; + + int order_id; + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS; + await baseAppClient.simplePost(url, body: jsonBody, onSuccess: (dynamic stringResponse, int statusCode){ + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + order_id = jsonResponse['orders'][0]['id']; + + }, onFailure: (String error, int statusCode){ + _hideLoading(context, showLoading); + log(error); + errorThrow = Future.error(error); + }); + + return errorThrow ?? order_id; + } + + Future> getOrderById(int id, {@required BuildContext context, bool showLoading = true}) async{ + Future errorThrow; + ResponseModel response; + + _showLoading(context, showLoading); + var url = EXA_CART_API_BASE_URL + PACKAGES_ORDERS + '/$id'; + await baseAppClient.simpleGet(url, onSuccess: (dynamic stringResponse, int statusCode) { + _hideLoading(context, showLoading); + + var jsonResponse = json.decode(stringResponse); + var jsonOrder = jsonResponse['orders'][0]; + response = ResponseModel(status: true, data: PackagesOrderResponseModel.fromJson(jsonOrder)); + + }, onFailure: (String error, int statusCode) { + _hideLoading(context, showLoading); + errorThrow = Future.error(ResponseModel(status: false,error: error)); + }, queryParams: null); + + return errorThrow ?? response; + } + } + +_showLoading(BuildContext context, bool flag){ + if(flag) + GifLoaderDialogUtils.showMyDialog(context); +} + +_hideLoading(BuildContext context, bool flag){ + if(flag) + GifLoaderDialogUtils.hideDialog(context); +} \ No newline at end of file diff --git a/lib/core/service/parmacyModule/order-preview-service.dart b/lib/core/service/parmacyModule/order-preview-service.dart index 5648ff6d..0ada84e7 100644 --- a/lib/core/service/parmacyModule/order-preview-service.dart +++ b/lib/core/service/parmacyModule/order-preview-service.dart @@ -3,9 +3,12 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; class OrderPreviewService extends BaseService { bool isFinished = true; @@ -15,13 +18,14 @@ class OrderPreviewService extends BaseService { List addresses = List(); LacumAccountInformation lacumInformation; LacumAccountInformation lacumGroupInformation; + List orderList = List(); Future getAddresses() async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); Map queryParams = {'fields': 'addresses'}; hasError = false; try { - await baseAppClient.get("$GET_CUSTOMERS_ADDRESSES$customerId", + await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId", onSuccess: (dynamic response, int statusCode) { addresses.clear(); response['customers'][0]['addresses'].forEach((item) { @@ -42,13 +46,14 @@ class OrderPreviewService extends BaseService { dynamic localRes; hasError = false; try { - await baseAppClient.get("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", - onSuccess: (dynamic response, int statusCode) { - localRes = response['shipping_option'][0]; - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, queryParams: queryParams); + await baseAppClient + .getPharmacy("$GET_SHIPPING_OPTIONS$customerId/${selectedAddress.id}", + onSuccess: (dynamic response, int statusCode) { + localRes = response['shipping_option'][0]; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); } catch (error) { throw error; } @@ -61,7 +66,7 @@ class OrderPreviewService extends BaseService { dynamic localRes; hasError = false; try { - await baseAppClient.get("$GET_SHOPPING_CART$customerId", + await baseAppClient.getPharmacy("$GET_SHOPPING_CART$customerId", onSuccess: (dynamic response, int statusCode) { localRes = response; }, onFailure: (String error, int statusCode) { @@ -89,7 +94,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); body["shopping_cart_item"] = choppingCartObject; - await baseAppClient.post("$GET_SHOPPING_CART$productId", + await baseAppClient.pharmacyPost("$GET_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { @@ -107,7 +112,7 @@ class OrderPreviewService extends BaseService { Map body = Map(); - await baseAppClient.post("$DELETE_SHOPPING_CART$productId", + await baseAppClient.pharmacyPost("$DELETE_SHOPPING_CART$productId", isExternal: false, onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { @@ -125,8 +130,9 @@ class OrderPreviewService extends BaseService { super.error = ""; dynamic localRes; - await baseAppClient.get("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", - onSuccess: (response, statusCode) async { + await baseAppClient + .getPharmacy("$DELETE_SHOPPING_CART_ALL$customerId/ShoppingCart", + onSuccess: (response, statusCode) async { localRes = response; }, onFailure: (String error, int statusCode) { hasError = true; @@ -167,23 +173,24 @@ class OrderPreviewService extends BaseService { try { await baseAppClient.post(GET_LACUM_GROUP_INFORMATION, onSuccess: (response, statusCode) async { - lacumGroupInformation = LacumAccountInformation.fromJson(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + lacumGroupInformation = LacumAccountInformation.fromJson(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } catch (error) { throw error; } } - Future makeOrder(PaymentCheckoutData paymentCheckoutData, List shoppingCarts) async { + Future makeOrder(PaymentCheckoutData paymentCheckoutData, + List shoppingCarts) async { paymentCheckoutData.address.isChecked = true; hasError = false; super.error = ""; var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'en'); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); Map orderBody = Map(); @@ -192,10 +199,15 @@ class OrderPreviewService extends BaseService { orderBody['billing_address'] = paymentCheckoutData.address; orderBody['pick_up_in_store'] = false; orderBody['payment_method_system_name'] = "Payments.PayFort"; - orderBody['shipping_method'] = languageID == 'ar' ? paymentCheckoutData.shippingOption.namen : paymentCheckoutData.shippingOption.name ; - orderBody['shipping_rate_computation_method_system_name'] = paymentCheckoutData.shippingOption.shippingRateComputationMethodSystemName; - orderBody['customer_id'] = customerId; - orderBody['custom_values_xml'] = "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption)}"; + orderBody['shipping_method'] = languageID == 'ar' + ? paymentCheckoutData.shippingOption.namen + : paymentCheckoutData.shippingOption.name; + orderBody['shipping_rate_computation_method_system_name'] = + paymentCheckoutData + .shippingOption.shippingRateComputationMethodSystemName; + orderBody['customer_id'] = int.parse(customerId); + orderBody['custom_values_xml'] = + "PaymentOption:${getPaymentOptionName(paymentCheckoutData.paymentOption)}"; orderBody['shippingOption'] = paymentCheckoutData.shippingOption; orderBody['shipping_address'] = paymentCheckoutData.address; orderBody['lakum_amount'] = paymentCheckoutData.usedLakumPoints; @@ -213,12 +225,17 @@ class OrderPreviewService extends BaseService { body['order'] = orderBody; try { - await baseAppClient.post(ORDER_SHOPPING_CART, + await baseAppClient.pharmacyPost(ORDER_SHOPPING_CART, isExternal: false, isAllowAny: true, onSuccess: (response, statusCode) async { - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }, body: body); + orderList.clear(); + response['orders'].forEach((item) { + orderList.add(OrderDetailModel.fromJson(item)); + print(response); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); } catch (error) { throw error; } @@ -245,4 +262,26 @@ class OrderPreviewService extends BaseService { return ""; } } + + Future getDriverLocation(dynamic driverId) async{ + Map jsonBody = Map(); + jsonBody['DriverID'] = driverId; + + LatLng coordinates; + await baseAppClient.post(DRIVER_LOCATION, + onSuccess: (response, statusCode) async { + if(statusCode == 200){ + dynamic locationObject = response['PatientER_GetDriverLocationList'][0]; + double lat = locationObject['Latitude']; + double lon = locationObject['Longitude']; + if(lat != null && lon != null){ + coordinates = LatLng(lat,lon); + } + } + }, onFailure: (String error, int statusCode) { + + }, body: jsonBody); + + return coordinates; + } } diff --git a/lib/core/service/parmacyModule/parmacy_module_service.dart b/lib/core/service/parmacyModule/parmacy_module_service.dart index c3bce324..7fa095ca 100644 --- a/lib/core/service/parmacyModule/parmacy_module_service.dart +++ b/lib/core/service/parmacyModule/parmacy_module_service.dart @@ -5,12 +5,14 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.d import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; class PharmacyModuleService extends BaseService { final AppSharedPreferences sharedPref = AppSharedPreferences(); bool isFinished = true; bool hasError = false; String errorMsg = ''; + String url = ""; List bannerItems = List(); List manufacturerList = List(); @@ -18,16 +20,19 @@ class PharmacyModuleService extends BaseService { List lastVisitedProducts = List(); Future makeVerifyCustomer(dynamic data) async { - Map queryParams = {'FileNumber': data['PatientID'].toString()}; + Map queryParams = { + 'FileNumber': data['PatientID'].toString() + }; hasError = false; try { - await baseAppClient.get(PHARMACY_VERIFY_CUSTOMER, - onSuccess: (dynamic response, int statusCode) { + await baseAppClient.getPharmacy(PHARMACY_VERIFY_CUSTOMER, + onSuccess: (dynamic response, int statusCode) async { if (response['UserName'] != null) { - sharedPref.setString(PHARMACY_CUSTOMER_ID, response['CustomerId'].toString()); + sharedPref.setString( + PHARMACY_CUSTOMER_ID, response['CustomerId'].toString()); print(response); } else { - createUser(); + await createUser(); } }, onFailure: (String error, int statusCode) { hasError = true; @@ -55,8 +60,32 @@ class PharmacyModuleService extends BaseService { hasError = false; try { await baseAppClient.get(PHARMACY_CREATE_CUSTOMER, - onSuccess: (dynamic response, int statusCode) { + onSuccess: (dynamic response, int statusCode) async { if (!response['IsRegistered']) {} + await generatePharmacyToken(); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } + + Future generatePharmacyToken() async { + await getUser(); + Map queryParams = { + 'Filenumber': user.patientID.toString(), + 'MobileNumber': Utils.getPhoneNumberWithoutZero(user.mobileNumber), + }; + hasError = false; + try { + await baseAppClient.getPharmacy(PHARMACY_AUTORZIE_CUSTOMER, + onSuccess: (dynamic response, int statusCode) async { + if (response['Status'] == 200) { + await sharedPref.setString( + PHARMACY_AUTORZIE_TOKEN, response['token'].toString()); + } }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; @@ -69,7 +98,7 @@ class PharmacyModuleService extends BaseService { Future getBannerListList() async { hasError = false; try { - await baseAppClient.get(GET_PHARMACY_BANNER, + await baseAppClient.getPharmacy(GET_PHARMACY_BANNER, onSuccess: (dynamic response, int statusCode) { bannerItems.clear(); response['images'].forEach((item) { @@ -87,12 +116,12 @@ class PharmacyModuleService extends BaseService { Future getTopManufacturerList() async { Map queryParams = {'page': '1', 'limit': '8'}; try { - await baseAppClient.get(GET_PHARMACY_TOP_MANUFACTURER, + await baseAppClient.getPharmacy(GET_PHARMACY_TOP_MANUFACTURER, onSuccess: (dynamic response, int statusCode) { manufacturerList.clear(); response['manufacturer'].forEach((item) { Manufacturer manufacturer = Manufacturer.fromJson(item); - if(manufacturer.image != null){ + if (manufacturer.image != null) { manufacturerList.add(Manufacturer.fromJson(item)); } }); @@ -111,7 +140,7 @@ class PharmacyModuleService extends BaseService { 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews', }; try { - await baseAppClient.get(GET_PHARMACY_BEST_SELLER_PRODUCT, + await baseAppClient.getPharmacy(GET_PHARMACY_BEST_SELLER_PRODUCT, onSuccess: (dynamic response, int statusCode) { bestSellerProducts.clear(); response['products'].forEach((item) { @@ -133,8 +162,9 @@ class PharmacyModuleService extends BaseService { lastVisited = await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS); try { - await baseAppClient.get("$GET_PHARMACY_PRODUCTs_BY_IDS$lastVisited", - onSuccess: (dynamic response, int statusCode) { + await baseAppClient + .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_IDS$lastVisited", + onSuccess: (dynamic response, int statusCode) { lastVisitedProducts.clear(); response['products'].forEach((item) { lastVisitedProducts.add(PharmacyProduct.fromJson(item)); diff --git a/lib/core/service/parmacyModule/prescription_service.dart b/lib/core/service/parmacyModule/prescription_service.dart new file mode 100644 index 00000000..c2312890 --- /dev/null +++ b/lib/core/service/parmacyModule/prescription_service.dart @@ -0,0 +1,55 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; + +class PrescriptionService extends BaseService { + final AppSharedPreferences sharedPref = AppSharedPreferences(); + bool isFinished = true; + bool hasError = false; + String errorMsg = ''; + String url = ""; + + List _prescriptionsList = List(); + List get prescriptionsList => _prescriptionsList; + +// Future getPrescription() async { +// hasError = false; +// url = PRESCRIPTION; +// print("Print PRESCRIPTION url" + url); +// await baseAppClient.get(url, +// onSuccess: (dynamic response, int statusCode) { +// _prescriptionsList.clear(); +// response['PatientPrescriptionList'].forEach((item) { +// _prescriptionsList.add(Prescriptions.fromJson(item)); +// }); +// print(_prescriptionsList.length); +// print(response); +// }, onFailure: (String error, int statusCode) { +// hasError = true; +// super.error = error; +// }); +// } + Future getPrescription() async { + url = PRESCRIPTION; + print("Print PRESCRIPTION url" + url); + hasError = false; + Map body = Map(); + body['isDentalAllowedBackend'] = false; + print("Print PRESCRIPTION url" + url); + await baseAppClient.post(url, + onSuccess: (dynamic response, int statusCode) { + _prescriptionsList.clear(); + response['PatientPrescriptionList'].forEach((prescriptions) { + _prescriptionsList.add(Prescriptions.fromJson(prescriptions)); + }); + print(_prescriptionsList.length); + print("response is -------------"+response); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: body); + } +} diff --git a/lib/core/service/pharmacy_categorise_service.dart b/lib/core/service/pharmacy_categorise_service.dart index b55a755d..58f58ddb 100644 --- a/lib/core/service/pharmacy_categorise_service.dart +++ b/lib/core/service/pharmacy_categorise_service.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; @@ -21,34 +23,36 @@ class PharmacyCategoriseService extends BaseService { List get parentCategoriseList => _parentCategoriseList; //service three - List _parentProductsList = List(); - List get parentProductsList => _parentProductsList; + List _parentProductsList = List(); + List get parentProductsList => _parentProductsList; //service four - List _subCategoriseList = List(); - List get subCategoriseList => _subCategoriseList; + List _subCategoriseList = List(); + List get subCategoriseList => _subCategoriseList; //service five - List _subProductsList = List(); - List get subProductsList => _subProductsList; + List _subProductsList = List(); + List get subProductsList => _subProductsList; //service six - List _finalProducts = List(); - List get finalProducts => _finalProducts; + List _finalProducts = List(); + List get finalProducts => _finalProducts; //service 7 - List _brandsList = List(); - List get brandsList => _brandsList; + List _brandsList = List(); + List get brandsList => _brandsList; // service 8 - List _searchList = List(); - List get searchList => _searchList; + List _searchList = List(); + List get searchList => _searchList; List _scanList = List(); List get scanList => _scanList; + List manufacturerProducts = List(); + clearSearchList() { _searchList.clear(); } @@ -56,7 +60,7 @@ class PharmacyCategoriseService extends BaseService { Future getCategorise() async { hasError = false; _categoriseList.clear(); - await baseAppClient.get( + await baseAppClient.getPharmacy( GET_PHARMACY_CATEGORISE, onSuccess: (dynamic response, int statusCode) { response['categories'].forEach((item) { @@ -74,7 +78,7 @@ class PharmacyCategoriseService extends BaseService { hasError = false; _scanList.clear(); String endPoint = id != null ? SCAN_QR_CODE + "$id" : SCAN_QR_CODE + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { @@ -94,11 +98,11 @@ class PharmacyCategoriseService extends BaseService { String endPoint = productName != null ? GET_SEARCH_PRODUCTS + "$productName" + '&language_id=1' : GET_SEARCH_PRODUCTS + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { - _searchList.add(SearchProductsModel.fromJson(item)); + _searchList.add(PharmacyProduct.fromJson(item)); }); }, onFailure: (String error, int statusCode) { @@ -108,14 +112,14 @@ class PharmacyCategoriseService extends BaseService { ); } - Future getBrands() async { + Future getBrands({String id}) async { hasError = false; _brandsList.clear(); - await baseAppClient.get( - GET_BRANDS_LIST, + await baseAppClient.getPharmacy( + GET_BRANDS_LIST + "$id" + "&fields=id,name,image,namen", onSuccess: (dynamic response, int statusCode) { response['manufacturer'].forEach((item) { - _brandsList.add(BrandsModel.fromJson(item)); + _brandsList.add(CategoriseParentModel.fromJson(item)); }); }, onFailure: (String error, int statusCode) { @@ -130,7 +134,7 @@ class PharmacyCategoriseService extends BaseService { _parentCategoriseList.clear(); String endPoint = id != null ? GET_CATEGORISE_PARENT + "$id" : GET_CATEGORISE_PARENT + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['categories'].forEach((item) { @@ -150,11 +154,11 @@ class PharmacyCategoriseService extends BaseService { String endPoint = id != null ? GET_PARENT_PRODUCTS + "$id" + '&page=1&limit=50' : GET_PARENT_PRODUCTS + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { - _parentProductsList.add(ParentProductsModel.fromJson(item)); + _parentProductsList.add(PharmacyProduct.fromJson(item)); }); }, onFailure: (String error, int statusCode) { @@ -170,11 +174,11 @@ class PharmacyCategoriseService extends BaseService { String endPoint = id != null ? GET_SUB_CATEGORISE + "$id" : GET_SUB_CATEGORISE + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['categories'].forEach((item) { - _subCategoriseList.add(SubCategoriesModel.fromJson(item)); + _subCategoriseList.add(CategoriseParentModel.fromJson(item)); }); }, onFailure: (String error, int statusCode) { @@ -190,11 +194,11 @@ class PharmacyCategoriseService extends BaseService { String endPoint = id != null ? GET_SUB_PRODUCTS + "$id" + '&page=1&limit=50' : GET_SUB_PRODUCTS + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { - _subProductsList.add(SubProductsModel.fromJson(item)); + _subProductsList.add(PharmacyProduct.fromJson(item)); }); }, onFailure: (String error, int statusCode) { @@ -209,17 +213,153 @@ class PharmacyCategoriseService extends BaseService { _finalProducts.clear(); String endPoint = id != null ? GET_FINAL_PRODUCTS + "$id" : GET_FINAL_PRODUCTS + ""; - await baseAppClient.get( + await baseAppClient.getPharmacy( endPoint, onSuccess: (dynamic response, int statusCode) { response['products'].forEach((item) { - _finalProducts.add(FinalProductsModel.fromJson(item)); + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + + Future getManufacturerProducts(String id) async { + hasError = false; + Map queryParams = {'ManufacturerId': id}; + + _finalProducts.clear(); + await baseAppClient.getPharmacy( + GET_BRAND_ITEMS, + onSuccess: (dynamic response, int statusCode) { + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); }); }, onFailure: (String error, int statusCode) { hasError = true; super.error = error; }, + queryParams: queryParams, ); } + + Future getLastVisitedProducts() async { + String lastVisited = ""; + if (await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS) != + null) { + lastVisited = + await this.sharedPref.getString(PHARMACY_LAST_VISITED_PRODUCTS); + try { + await baseAppClient + .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_IDS$lastVisited", + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); + } catch (error) { + throw error; + } + } + } + + Future getBestSellerProducts() async { + Map queryParams = { + 'fields': + 'id,discount_ids,name,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage,reviews', + }; + try { + await baseAppClient.getPharmacy(GET_PHARMACY_BEST_SELLER_PRODUCT, + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } + + Future getFilteredProducts( + {String categoryId, String brandId, String min, String max}) async { + hasError = false; + String endPoint; + + _parentProductsList.clear(); + endPoint = FILTERED_PRODUCTS + + "$categoryId" + + "&manufacturerids=$brandId" + + "&price_min=$min" + + "&price_max=$max&page=1&limit=50"; + await baseAppClient.getPharmacy( + endPoint, + onSuccess: (dynamic response, int statusCode) { + response['products'].forEach((item) { + _parentProductsList.add(PharmacyProduct.fromJson(item)); + }); + }, + onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, + ); + } + + Future getMostViewedProducts() async { + Map queryParams = { + 'fields': + 'id,discount_ids,name,reviews,namen,localized_names,display_order,short_description,full_description,full_descriptionn,sku,order_minimum_quantity,order_maximum_quantity,price,old_price,images,is_rx,rx_message,rx_messagen,discount_name,discount_namen,approved_rating_sum,approved_total_reviews,allow_back_in_stock_subscriptions,stock_quantity,stock_availability,stock_availabilityn,discount_percentage', + }; + try { + await baseAppClient.getPharmacy(GET_MOST_VIEWED_PRODUCTS, + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("most viewed products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } + + Future getNewProducts() async { + Map queryParams = { + 'fields': + 'Id,name,namen,localized_names,price,images,sku,stock_availability,published', + }; + try { + await baseAppClient.getPharmacy(GET_NEW_PRODUCTS, + onSuccess: (dynamic response, int statusCode) { + _finalProducts.clear(); + response['products'].forEach((item) { + _finalProducts.add(PharmacyProduct.fromJson(item)); + }); + print("new products ---------"); + print(response); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, queryParams: queryParams); + } catch (error) { + throw error; + } + } } diff --git a/lib/core/service/termsConditionsService.dart b/lib/core/service/termsConditionsService.dart new file mode 100644 index 00000000..1f806e22 --- /dev/null +++ b/lib/core/service/termsConditionsService.dart @@ -0,0 +1,18 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; + +class TermsConditionsService extends BaseService { + + String userAgreementContent = ""; + + Future getUserTermsAndConditions() async { + hasError = false; + await baseAppClient.post(GET_USER_TERMS, + onSuccess: (dynamic response, int statusCode) { + userAgreementContent = response['UserAgreementContent']; + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }, body: Map()); + } +} \ No newline at end of file diff --git a/lib/core/service/weather_service.dart b/lib/core/service/weather_service.dart index 10ab1adf..ea7d65bf 100644 --- a/lib/core/service/weather_service.dart +++ b/lib/core/service/weather_service.dart @@ -18,10 +18,9 @@ class WeatherService extends BaseService { var long = await sharedPref.getDouble(USER_LONG); body['Latitude'] = lat ?? 0; body['Longitude'] = long ?? 0; - + weatherIndicatorData = []; await baseAppClient.post(WEATHER_INDICATOR, onSuccess: (dynamic response, int statusCode) { - weatherIndicatorData = []; response['GetCityInfo_List'].forEach((data) { weatherIndicatorData.add(GetCityInfoList.fromJson(data)); }); diff --git a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart index 15b00e37..a89ec799 100644 --- a/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/H2O_view_model.dart @@ -1,26 +1,54 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert_user_activity_request_model.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_month_data_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_today_data_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_progress_for_week_data_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:charts_flutter/flutter.dart' as charts; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import '../../../locator.dart'; class H2OViewModel extends BaseViewModel { - H2OService _h2OService = locator(); List userProgressForWeekDataSeries; List userProgressForMonthDataSeries; + UserDetailModel get userDetail => _h2OService.userDetailModel; + UserProgressForTodayDataModel get userProgressData { - if (_h2OService.userProgressForTodayDataList.length != 0) - return _h2OService.userProgressForTodayDataList[0]; - return null; + if (_h2OService.userProgressForTodayDataList.length != 0) return _h2OService.userProgressForTodayDataList[0]; + return null; } + Future getUserDetail() async { + // if(_h2OService.userProgressForTodayDataList.length==0){ + setState(ViewState.Busy); + await _h2OService.getUserDetail(); + if (_h2OService.hasError) { + error = _h2OService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future updateUserDetail(UserDetailModel userDetailModel, Function(bool) onResponse) async { + setState(ViewState.Busy); + + await _h2OService.updateUserDetail(userDetailModel); + if (_h2OService.hasError) { + error = _h2OService.error; + setState(ViewState.Error); + onResponse(false); + } else { + _h2OService.userDetailModel = userDetailModel; + setState(ViewState.Idle); + onResponse(true); + } + } Future getUserProgressForTodayData() async { // if(_h2OService.userProgressForTodayDataList.length==0){ @@ -58,13 +86,9 @@ class H2OViewModel extends BaseViewModel { } } - - List> createUserProgressForWeekDataSeries() { - List globalData = [ - ]; - _h2OService.userProgressForWeekDataList.forEach(( - UserProgressForWeekDataModel data) { + List> createUserProgressForWeekDataSeries() { + List globalData = []; + _h2OService.userProgressForWeekDataList.forEach((UserProgressForWeekDataModel data) { globalData.add(new ChartSeries(data.dayName, data.percentageConsumed)); }); return [ @@ -77,12 +101,9 @@ class H2OViewModel extends BaseViewModel { ]; } - List> createUserProgressForMonthDataSeries() { - List globalData = [ - ]; - _h2OService.userProgressForMonthDataList.forEach(( - UserProgressForMonthDataModel data) { + List> createUserProgressForMonthDataSeries() { + List globalData = []; + _h2OService.userProgressForMonthDataList.forEach((UserProgressForMonthDataModel data) { globalData.add(new ChartSeries(data.monthName, data.percentageConsumed)); }); return [ @@ -95,14 +116,10 @@ class H2OViewModel extends BaseViewModel { ]; } - - Future insertUserActivity( - InsertUserActivityRequestModel insertUserActivityRequestModel) async { + Future insertUserActivity(InsertUserActivityRequestModel insertUserActivityRequestModel) async { setState(ViewState.BusyLocal); - insertUserActivityRequestModel.mobileNumber = - user.mobileNumber.substring(1); - insertUserActivityRequestModel.identificationNo = - user.patientIdentificationNo; + insertUserActivityRequestModel.mobileNumber = user.mobileNumber.substring(1); + insertUserActivityRequestModel.identificationNo = user.patientIdentificationNo; await _h2OService.insertUserActivity(insertUserActivityRequestModel); if (_h2OService.hasError) { @@ -113,9 +130,18 @@ class H2OViewModel extends BaseViewModel { } } + Future undoUserActivity() async { + setState(ViewState.BusyLocal); + await _h2OService.undoUserActivity(); + if (_h2OService.hasError) { + error = _h2OService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } } - /// Sample ordinal data type. class ChartSeries { final String y; diff --git a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart index 5bde5a5f..23329a89 100644 --- a/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart @@ -55,7 +55,7 @@ class Addresses { String firstName; String lastName; String email; - Null company; + dynamic company; int countryId; String country; Null stateProvinceId; @@ -64,7 +64,7 @@ class Addresses { String address2; String zipPostalCode; String phoneNumber; - Null faxNumber; + dynamic faxNumber; String customerAttributes; String createdOnUtc; Null province; diff --git a/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart index f2c81956..65fffe33 100644 --- a/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/cmc_view_model.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealth import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/cmc_service.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import '../../../locator.dart'; @@ -34,6 +35,8 @@ class CMCViewModel extends BaseViewModel { List get checkupItems => _cMCService.checkupItemsList; + PharmacyModuleService _pharmacyModuleService = locator(); + bool get isOrderUpdated => _cMCService.isOrderUpdated; Future getCMCAllServices() async { @@ -115,8 +118,7 @@ class CMCViewModel extends BaseViewModel { Future getCustomerAddresses() async { setState(ViewState.Busy); - await _customerAddressesService.getCustomerAddresses( - ); + await _customerAddressesService.getCustomerAddresses(); if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); @@ -127,8 +129,9 @@ class CMCViewModel extends BaseViewModel { Future getCustomerInfo() async { setState(ViewState.Busy); - await _customerAddressesService.getCustomerInfo( - ); + await _pharmacyModuleService.generatePharmacyToken().then((value) async{ + await _customerAddressesService.getCustomerInfo(); + }); if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart b/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart new file mode 100644 index 00000000..5853cc8f --- /dev/null +++ b/lib/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart @@ -0,0 +1,49 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/ClinicCategory.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../../locator.dart'; + +class BariatricsViewModel extends BaseViewModel { + BariatricsService _service = locator(); + + List get clinicCategoryList => _service.clinicCategoryList; + + List get diseasesList => _service.diseasesList; + + void getClinicCategory() async { + setState(ViewState.Busy); + await _service.getClinicCategory(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else { + getDiseaseByClinicId(); + } + } + + void getDiseaseByClinicId() async { + setState(ViewState.Busy); + await _service.getDiseaseByClinicId(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future searchDoctorsByTime(DiseasesByClinic disease) async { + setState(ViewState.Busy); + await _service.searchDoctorsByTime(disease); + if (_service.hasError) { + error = _service.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } +} diff --git a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart index 20a19b23..32644fd4 100644 --- a/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart +++ b/lib/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealth import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/home_health_care_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:intl/intl.dart'; @@ -36,6 +37,11 @@ class HomeHealthCareViewModel extends BaseViewModel { List get hhcAllOrderDetail => _homeHealthCareService.hhcAllOrderDetail; + PharmacyModuleService _pharmacyModuleService = locator(); + + + + bool get isOrderUpdated => _homeHealthCareService.isOrderUpdated; GetHHCAllPresOrdersResponseModel pendingOrder; @@ -117,8 +123,9 @@ class HomeHealthCareViewModel extends BaseViewModel { Future getCustomerInfo() async { setState(ViewState.Busy); - await _customerAddressesService.getCustomerInfo( - ); + await _pharmacyModuleService.generatePharmacyToken().then((value) async{ + await _customerAddressesService.getCustomerInfo(); + }); if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); @@ -131,9 +138,13 @@ class HomeHealthCareViewModel extends BaseViewModel { {AddNewAddressRequestModel addNewAddressRequestModel}) async { setState(ViewState.Busy); - await _customerAddressesService.addAddressInfo( - addNewAddressRequestModel: addNewAddressRequestModel - ); + + await _pharmacyModuleService.generatePharmacyToken().then((value) async{ + await _customerAddressesService.addAddressInfo( + addNewAddressRequestModel: addNewAddressRequestModel + ); + }); + if (_customerAddressesService.hasError) { error = _customerAddressesService.error; setState(ViewState.ErrorLocal); diff --git a/lib/core/viewModels/TermsConditionsViewModel.dart b/lib/core/viewModels/TermsConditionsViewModel.dart new file mode 100644 index 00000000..0cd667cf --- /dev/null +++ b/lib/core/viewModels/TermsConditionsViewModel.dart @@ -0,0 +1,29 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/service/termsConditionsService.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../locator.dart'; + +class TermsConditionsViewModel extends BaseViewModel{ + + TermsConditionsService _service = locator(); + + String get userAgreementContent => _service.userAgreementContent; + + getUserTermsAndConditions() async { + setState(ViewState.Busy); + await _service.getUserTermsAndConditions(); + if (_service.hasError) { + error = _service.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + @override + void dispose() { + super.dispose(); + } + +} \ No newline at end of file diff --git a/lib/core/viewModels/ancillary_orders_view_model.dart b/lib/core/viewModels/ancillary_orders_view_model.dart new file mode 100644 index 00000000..77eb4237 --- /dev/null +++ b/lib/core/viewModels/ancillary_orders_view_model.dart @@ -0,0 +1,38 @@ +import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_list_model.dart'; +import 'package:diplomaticquarterapp/models/anicllary-orders/ancillary_order_proc_model.dart'; + +import 'base_view_model.dart'; +import '../../locator.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; + +class AnciallryOrdersViewModel extends BaseViewModel { + bool hasError = false; + + AncillaryOrdersService _ancillaryService = locator(); + List get ancillaryLists => + _ancillaryService.ancillaryLists; + List get ancillaryListsDetails => + _ancillaryService.ancillaryProcLists; + Future getOrders() async { + hasError = false; + setState(ViewState.Busy); + await _ancillaryService.getOrders(); + if (_ancillaryService.hasError) { + error = _ancillaryService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future getOrdersDetails(appointmentNo, orderNo) async { + hasError = false; + setState(ViewState.Busy); + await _ancillaryService.getOrdersDetails(appointmentNo, orderNo); + if (_ancillaryService.hasError) { + error = _ancillaryService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/core/viewModels/appointment_rate_view_model.dart b/lib/core/viewModels/appointment_rate_view_model.dart index 23d00366..e1bdfc9e 100644 --- a/lib/core/viewModels/appointment_rate_view_model.dart +++ b/lib/core/viewModels/appointment_rate_view_model.dart @@ -40,7 +40,7 @@ class AppointmentRateViewModel extends BaseViewModel { Future sendAppointmentRate(int rate, int appointmentNo, int projectID, int doctorID, int clinicID, String note) async { - setState(ViewState.BusyLocal); + setState(ViewState.Busy); await _appointmentRateService.sendAppointmentRate( rate, appointmentNo, projectID, doctorID, clinicID, note); if (_appointmentRateService.hasError) { diff --git a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart index 3b72dd50..d0ccb8a1 100644 --- a/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart +++ b/lib/core/viewModels/child_vaccines/vaccination_table_view_model.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/add_newchild_model.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/create_vaccination_table.dart'; import 'package:diplomaticquarterapp/core/service/childvaccines/add_new_child_service.dart'; @@ -11,14 +12,12 @@ import '../base_view_model.dart'; class VaccinationTableViewModel extends BaseViewModel{ VaccinationTableService _creteVaccinationTableService = locator(); + List get creteVaccinationTableModelList=> _creteVaccinationTableService.createVaccinationTableModelList; - // String get creteVaccinationTableContent => _creteVaccinationTableService.userAgreementContent; - //String get userAgreementContent => _creteNewBabyService.v//_reportsService.userAgreementContent; - List get creteVaccinationTableModelList=> _creteVaccinationTableService.createVaccinationTableModelList;//.createNewBabyModelList; - getCreateVaccinationTable() async { + getCreateVaccinationTable(List_BabyInformationModel babyInfo, bool sendEmail) async { setState(ViewState.Busy); - await _creteVaccinationTableService.getCreateVaccinationTableOrders();//getCreateNewBabyOrders(); + await _creteVaccinationTableService.getCreateVaccinationTableOrders(babyInfo, sendEmail);//getCreateNewBabyOrders(); if ( _creteVaccinationTableService.hasError) { error = _creteVaccinationTableService.error; diff --git a/lib/core/viewModels/er/EdOnlineViewModel.dart b/lib/core/viewModels/er/EdOnlineViewModel.dart new file mode 100644 index 00000000..1970a965 --- /dev/null +++ b/lib/core/viewModels/er/EdOnlineViewModel.dart @@ -0,0 +1,76 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/er/ErPatientShareModel.dart'; +import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/service/er/EdOnlineServices.dart'; +import 'package:diplomaticquarterapp/core/service/hospital_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class EdOnlineViewModel extends BaseViewModel { + HospitalService _hospitalService = locator(); + + EdOnlineServices _edOnlineServices = locator(); + + List get hospitals => _hospitalService.hospitals; + + List get triageQuestionsModelList => + _edOnlineServices.triageQuestionsModelList; + + ErPatientShareModel get erPatientShareModel => _edOnlineServices.erPatientShareModel; + + Future getHospitals() async { + if(_hospitalService.hospitals.isEmpty){ + setState(ViewState.Busy); + await _hospitalService.getHospitals(); + if (_hospitalService.hasError) { + error = _hospitalService.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + } + + Future getQuestions() async { + if(_edOnlineServices.triageQuestionsModelList.isEmpty){ + setState(ViewState.Busy); + await _edOnlineServices.getQuestions(); + if (_edOnlineServices.hasError) { + error = _edOnlineServices.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + } + + Future getPatientPaymentInformation({var id}) async { + setState(ViewState.Busy); + await _edOnlineServices.getPatientPaymentInformation(); + if (_edOnlineServices.hasError) { + error = _edOnlineServices.error; + setState(ViewState.Error); + } else + setState(ViewState.Idle); + } + + Future saveQuestionsInformation( + {String notes, + String chiefComplaint, + int projectId, + DateTime selectedTime, + List selectedQuestions}) async { + setState(ViewState.BusyLocal); + await _edOnlineServices.saveQuestionsInformation( + notes: notes, + projectId: projectId, + chiefComplaint: chiefComplaint, + selectedTime: selectedTime, + selectedQuestions: selectedQuestions); + if (_edOnlineServices.hasError) { + error = _edOnlineServices.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } +} diff --git a/lib/core/viewModels/er/am_request_view_model.dart b/lib/core/viewModels/er/am_request_view_model.dart index 2cf8e877..5f6d40d5 100644 --- a/lib/core/viewModels/er/am_request_view_model.dart +++ b/lib/core/viewModels/er/am_request_view_model.dart @@ -55,7 +55,7 @@ class AmRequestViewModel extends BaseViewModel { Future getHospitals() async { setState(ViewState.Busy); - await _hospitalService.getHospitals(); + await _hospitalService.getHospitals(isResBasedOnLoc: false); if (_hospitalService.hasError) { error = _hospitalService.error; setState(ViewState.Error); diff --git a/lib/core/viewModels/medical/EyeViewModel.dart b/lib/core/viewModels/medical/EyeViewModel.dart index d6c3bf80..ab76b94f 100644 --- a/lib/core/viewModels/medical/EyeViewModel.dart +++ b/lib/core/viewModels/medical/EyeViewModel.dart @@ -43,4 +43,34 @@ class EyeViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + sendGlassesPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + setState(ViewState.Busy); + await _eyeService.sendGlassesPrescriptionEmail( + appointmentNo: appointmentNo, + projectID: projectID, + projectName: projectName); + if (_eyeService.hasError) { + error = _eyeService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + sendContactLensPrescriptionEmail({int appointmentNo, String projectName, int projectID}) async { + setState(ViewState.Busy); + await _eyeService.sendContactLensPrescriptionEmail( + appointmentNo: appointmentNo, + projectID: projectID, + projectName: projectName); + if (_eyeService.hasError) { + error = _eyeService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + } diff --git a/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart new file mode 100644 index 00000000..455b5934 --- /dev/null +++ b/lib/core/viewModels/medical/PrescriptionDeliveryViewModel.dart @@ -0,0 +1,68 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/service/PrescriptionDeliveryService.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; + +import '../../../locator.dart'; + +class PrescriptionDeliveryViewModel extends BaseViewModel { + CustomerAddressesService _customerAddressesService = + locator(); + PharmacyModuleService _pharmacyModuleService = + locator(); + PrescriptionDeliveryService _prescriptionDeliveryService = + locator(); + + List get addressesList => + _customerAddressesService.addressesList; + + Future getCustomerInfo() async { + setState(ViewState.Busy); + await _pharmacyModuleService.generatePharmacyToken().then((value) async { + await _customerAddressesService.getCustomerInfo(); + }); + if (_customerAddressesService.hasError) { + error = _customerAddressesService.error; + setState(ViewState.ErrorLocal); + } else { + await getCustomerAddresses(); + } + } + + Future insertDeliveryOrder( + {int lineItemNo, + double latitude, + double longitude, + int appointmentNo, + int createdBy, + int dischargeID}) async { + + setState(ViewState.BusyLocal); + await _prescriptionDeliveryService.insertDeliveryOrder( + lineItemNo: lineItemNo, + latitude: latitude, + longitude: longitude, + appointmentNo: appointmentNo, + createdBy: createdBy, + dischargeID: dischargeID + ); + if (_prescriptionDeliveryService.hasError) { + error = _prescriptionDeliveryService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + Future getCustomerAddresses() async { + setState(ViewState.Busy); + await _customerAddressesService.getCustomerAddresses(); + if (_customerAddressesService.hasError) { + error = _customerAddressesService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } +} diff --git a/lib/core/viewModels/medical/blood_pressure_view_model.dart b/lib/core/viewModels/medical/blood_pressure_view_model.dart index dfff5b45..ae3abbcb 100644 --- a/lib/core/viewModels/medical/blood_pressure_view_model.dart +++ b/lib/core/viewModels/medical/blood_pressure_view_model.dart @@ -1,33 +1,31 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; import 'package:diplomaticquarterapp/core/service/medical/BloodPressureService.dart'; -import 'package:diplomaticquarterapp/core/service/medical/BloodSugarService.dart'; import 'package:diplomaticquarterapp/locator.dart'; -import 'package:charts_flutter/flutter.dart' as charts; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import '../../../core/viewModels/base_view_model.dart'; class BloodPressureViewMode extends BaseViewModel { BloodPressureService bloodPressureService = locator(); - ///BLOOD - List _bloodDiastolicPressureWeeklyTimeSeriesSalesList = List(); - List _bloodSystolicePressureWeeklyTimeSeriesSalesList = List(); + List get monthDiabtecPatientResult => + bloodPressureService.monthDiabtecPatientResult; - List _bloodDiastolicMonthlyTimeSeriesSalesList = List(); - List _bloodSystolicMonthlyTimeSeriesSalesList = List(); + List get weekDiabtecPatientResult => + bloodPressureService.weekDiabtecPatientResult; - List _bloodSystoliceYearTimeSeriesSalesList = List(); - List _bloodDiastolicYearTimeSeriesSalesList = List(); + List get yearDiabtecPatientResult => + bloodPressureService.yearDiabtecPatientResult; - List get monthDiabtecPatientResult => bloodPressureService.monthDiabtecPatientResult; + List weightWeekTimeSeriesDataTop = []; + List weightWeekTimeSeriesDataLow = []; - List get weekDiabtecPatientResult => bloodPressureService.weekDiabtecPatientResult; + List weighMonthTimeSeriesDataTop = []; + List weighMonthTimeSeriesDataLow = []; - List get yearDiabtecPatientResult => bloodPressureService.yearDiabtecPatientResult; + List weightYearTimeSeriesDataTop = []; + List weightYearTimeSeriesDataLow = []; Future getBloodPressure() async { setState(ViewState.Busy); @@ -35,114 +33,94 @@ class BloodPressureViewMode extends BaseViewModel { await bloodPressureService.getDiabtecResults(); if (bloodPressureService.hasError) { error = bloodPressureService.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else { + clearDate(); bloodPressureService.weekDiabtectResultAverageList.forEach((element) { - _bloodDiastolicPressureWeeklyTimeSeriesSalesList.add(WeekChartDate( - x: element.bloodPressureDate, - y: element.dailyDiastolicPressureAverageResult)); - _bloodSystolicePressureWeeklyTimeSeriesSalesList.add(WeekChartDate( - x: element.bloodPressureDate, - y: element.dailySystolicePressureAverageResult)); - }); + weightWeekTimeSeriesDataTop.add(TimeSeriesSales2( + element.bloodPressureDate, + element.dailyDiastolicPressureAverageResult.toDouble())); + weightWeekTimeSeriesDataLow.add(TimeSeriesSales2( + element.bloodPressureDate, + element.dailySystolicePressureAverageResult.toDouble())); - for (int index = 0; - index < bloodPressureService.monthDiabtectResultAverageList.length; - index++) { - _bloodDiastolicMonthlyTimeSeriesSalesList.add(YearMonthlyChartDate( - x: index, - y: bloodPressureService.monthDiabtectResultAverageList[index] - .weekDiastolicPressureAverageResult)); - _bloodSystolicMonthlyTimeSeriesSalesList.add(YearMonthlyChartDate( - x: index, - y: bloodPressureService.monthDiabtectResultAverageList[index] - .weekSystolicePressureAverageResult)); - } - - bloodPressureService.yearDiabtecResultAverageList.forEach((element) { - _bloodSystoliceYearTimeSeriesSalesList - .add(WeekChartDate(x: element.date, y: element.monthSystolicePressureAverageResult)); - - _bloodDiastolicYearTimeSeriesSalesList - .add(WeekChartDate(x: element.date, y: element.monthDiastolicPressureAverageResult)); - }); + for (int index = 0; index < bloodPressureService.monthDiabtectResultAverageList.length; index++) { + + weighMonthTimeSeriesDataTop.add(TimeSeriesSales3(index, bloodPressureService.monthDiabtectResultAverageList[index].weekDiastolicPressureAverageResult.toDouble())); + + weighMonthTimeSeriesDataLow.add(TimeSeriesSales3(index, bloodPressureService.monthDiabtectResultAverageList[index].weekSystolicePressureAverageResult.toDouble())); + } + bloodPressureService.yearDiabtecResultAverageList.forEach((element) { + weightYearTimeSeriesDataTop.add(TimeSeriesSales2(element.date, + element.monthSystolicePressureAverageResult.toDouble())); + + weightYearTimeSeriesDataLow.add(TimeSeriesSales2(element.date, + element.monthDiastolicPressureAverageResult.toDouble())); + }); + + }); setState(ViewState.Idle); } } - List> getBloodWeeklySeries() { - return [ - charts.Series( - id: 'Diastolic', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodDiastolicPressureWeeklyTimeSeriesSalesList, - ), - charts.Series( - id: 'Systolice', - colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodSystolicePressureWeeklyTimeSeriesSalesList, - ) - ]; - } - List> - getBloodMonthlyTimeSeriesSales() { - return [ - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (YearMonthlyChartDate sales, _) => sales.x, - measureFn: (YearMonthlyChartDate sales, _) => sales.y, - data: _bloodDiastolicMonthlyTimeSeriesSalesList, - ), - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, - domainFn: (YearMonthlyChartDate sales, _) => sales.x, - measureFn: (YearMonthlyChartDate sales, _) => sales.y, - data: _bloodSystolicMonthlyTimeSeriesSalesList, - ), - ]; + void clearDate(){ + weightWeekTimeSeriesDataTop.clear(); + weightWeekTimeSeriesDataLow.clear(); + weighMonthTimeSeriesDataTop.clear(); + weighMonthTimeSeriesDataLow.clear(); + weightYearTimeSeriesDataTop.clear(); + weightYearTimeSeriesDataLow.clear(); } - List> getBloodYearTimeSeriesSales() { - return [ - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodSystoliceYearTimeSeriesSalesList, - ), - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodDiastolicYearTimeSeriesSalesList, - ) - ]; + Future sendReportByEmail() async { + setState(ViewState.BusyLocal); + + await bloodPressureService.sendReportByEmail(); + if (bloodPressureService.hasError) { + error = bloodPressureService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } } - addDiabtecResult( + Future addORUpdateDiabtecResult( {String bloodPressureDate, - String diastolicPressure, - String systolicePressure, - int measuredArm}) async { + String diastolicPressure, + String systolicePressure, + int measuredArm,bool isUpdate = false}) async { setState(ViewState.BusyLocal); + if(!isUpdate) await bloodPressureService.addDiabtecResult( bloodPressureDate: bloodPressureDate, diastolicPressure: diastolicPressure, systolicePressure: systolicePressure, measuredArm: measuredArm); + else + await bloodPressureService.updateDiabtecResult( + bloodPressureDate: bloodPressureDate, + diastolicPressure: diastolicPressure, + systolicePressure: systolicePressure, + measuredArm: measuredArm); + if (bloodPressureService.hasError) { + error = bloodPressureService.error; + setState(ViewState.ErrorLocal); + } else { + await getBloodPressure(); + setState(ViewState.Idle); + } + } + + + Future deactivateDiabeticStatus({int lineItemNo}) async { + setState(ViewState.BusyLocal); + + await bloodPressureService.deactivateDiabeticStatus(lineItemNo: lineItemNo); if (bloodPressureService.hasError) { error = bloodPressureService.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else { await getBloodPressure(); setState(ViewState.Idle); diff --git a/lib/core/viewModels/medical/blood_sugar_view_model.dart b/lib/core/viewModels/medical/blood_sugar_view_model.dart index fb00f80e..8a513992 100644 --- a/lib/core/viewModels/medical/blood_sugar_view_model.dart +++ b/lib/core/viewModels/medical/blood_sugar_view_model.dart @@ -5,17 +5,13 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthly import 'package:diplomaticquarterapp/core/service/medical/BloodSugarService.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:charts_flutter/flutter.dart' as charts; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import '../../../core/viewModels/base_view_model.dart'; class BloodSugarViewMode extends BaseViewModel { BloodSugarService bloodSugarService = locator(); - ///BLOOD - List _bloodWeeklyTimeSeriesSalesList = List(); - List _bloodMonthlyTimeSeriesSalesList = List(); - List _bloodYearTimeSeriesSalesList = List(); - List get monthDiabtecPatientResult => bloodSugarService.monthDiabtecPatientResult; @@ -25,6 +21,10 @@ class BloodSugarViewMode extends BaseViewModel { List get yearDiabtecPatientResult => bloodSugarService.yearDiabtecPatientResult; + List bloodWeekTimeSeriesData = []; + List yearTimeSeriesData = []; + List monthTimeSeriesData = []; + Future getBloodSugar() async { setState(ViewState.Busy); await bloodSugarService.getBloodSugar(); @@ -34,67 +34,35 @@ class BloodSugarViewMode extends BaseViewModel { setState(ViewState.Error); } else { bloodSugarService.weekDiabtectResultAverageList.forEach((element) { - _bloodWeeklyTimeSeriesSalesList.add( - WeekChartDate(x: element.dateChart, y: element.dailyAverageResult)); + bloodWeekTimeSeriesData.add(TimeSeriesSales2( + element.dateChart, + element.dailyAverageResult.toDouble(), + )); }); for (int index = 0; index < bloodSugarService.monthDiabtectResultAverageList.length; index++) { - _bloodMonthlyTimeSeriesSalesList.add(YearMonthlyChartDate( - x: index, - y: bloodSugarService - .monthDiabtectResultAverageList[index].weekAverageResult)); - var asd=""; + monthTimeSeriesData.add(TimeSeriesSales3( + index, + bloodSugarService + .monthDiabtectResultAverageList[index].weekAverageResult + .toDouble(), + )); } bloodSugarService.yearDiabtecResultAverageList.forEach((element) { - _bloodYearTimeSeriesSalesList - .add(WeekChartDate(x: element.date, y: element.monthAverageResult)); + yearTimeSeriesData.add(TimeSeriesSales2( + element.date, + element.monthAverageResult.toDouble(), + )); }); setState(ViewState.Idle); } } - List> getBloodWeeklySeries() { - return [ - new charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodWeeklyTimeSeriesSalesList, - ) - ]; - } - - List> - getBloodMonthlyTimeSeriesSales() { - return [ - new charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (YearMonthlyChartDate sales, _) => sales.x, - measureFn: (YearMonthlyChartDate sales, _) => sales.y, - data: _bloodMonthlyTimeSeriesSalesList, - ) - ]; - } - - List> getBloodYearTimeSeriesSales() { - return [ - new charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _bloodYearTimeSeriesSalesList, - ) - ]; - } - - addDiabtecResult( + Future addDiabtecResult( {String bloodSugerDateChart, String bloodSugerResult, String diabtecUnit, @@ -102,7 +70,7 @@ class BloodSugarViewMode extends BaseViewModel { setState(ViewState.BusyLocal); await bloodSugarService.addDiabtecResult( bloodSugerDateChart: bloodSugerDateChart, - bloodSugerResult: bloodSugerResult , + bloodSugerResult: bloodSugerResult, diabtecUnit: diabtecUnit, measuredTime: measuredTime); if (bloodSugarService.hasError) { @@ -113,7 +81,54 @@ class BloodSugarViewMode extends BaseViewModel { setState(ViewState.Idle); } } - - - + + Future updateDiabtecResult( + {DateTime month, + DateTime hour, + String bloodSugerResult, + String diabtecUnit, + int measuredTime, + int lineItemNo}) async { + setState(ViewState.BusyLocal); + + await bloodSugarService.updateDiabtecResult( + bloodSugerResult: bloodSugerResult, + diabtecUnit: diabtecUnit, + hour: hour, + measuredTime: measuredTime, + lineItemNo: lineItemNo, + month: month); + if (bloodSugarService.hasError) { + error = bloodSugarService.error; + setState(ViewState.ErrorLocal); + } else { + await getBloodSugar(); + setState(ViewState.Idle); + } + } + + Future sendReportByEmail() async { + setState(ViewState.BusyLocal); + + await bloodSugarService.sendReportByEmail(); + if (bloodSugarService.hasError) { + error = bloodSugarService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + + Future deactivateDiabeticStatus({int lineItemNo}) async { + setState(ViewState.BusyLocal); + + await bloodSugarService.deactivateDiabeticStatus(lineItemNo: lineItemNo); + if (bloodSugarService.hasError) { + error = bloodSugarService.error; + setState(ViewState.ErrorLocal); + } else { + await getBloodSugar(); + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModels/medical/my_balance_view_model.dart b/lib/core/viewModels/medical/my_balance_view_model.dart index f9554d94..e33bc86c 100644 --- a/lib/core/viewModels/medical/my_balance_view_model.dart +++ b/lib/core/viewModels/medical/my_balance_view_model.dart @@ -41,6 +41,9 @@ class MyBalanceViewModel extends BaseViewModel { double get totalAdvanceBalanceAmount => _myBalanceService.totalAdvanceBalanceAmount; + String get updatedRegisterBloodMessage => + _myBalanceService.updatedRegisterBloodMessage; + GetAllSharedRecordsByStatusResponse get getAllSharedRecordsByStatusResponse => _myBalanceService.getAllSharedRecordsByStatusResponse; @@ -74,7 +77,6 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getCities() async { setState(ViewState.Busy); await _bloodDonationService.getAllCitiesOrders(); @@ -95,7 +97,6 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getPatientInfoByPatientID({String id}) async { setState(ViewState.Busy); await _myBalanceService.getPatientInfoByPatientID(id: id); @@ -108,7 +109,8 @@ class MyBalanceViewModel extends BaseViewModel { } } - Future getPatientInfoByPatientIDAndMobileNumber(AdvanceModel advanceModel) async { + Future getPatientInfoByPatientIDAndMobileNumber( + AdvanceModel advanceModel) async { setState(ViewState.Busy); await _myBalanceService .getPatientInfoByPatientIDAndMobileNumber(advanceModel); @@ -159,4 +161,16 @@ class MyBalanceViewModel extends BaseViewModel { setState(ViewState.Idle); } } + + Future updateBloodGroup(List_BloodGroupDetailsModel detailsModel) async { + setState(ViewState.Busy); + await _myBalanceService.updateBloodGroup(detailsModel); + if (_myBalanceService.hasError) { + error = _myBalanceService.error; + setState(ViewState.ErrorLocal); + } else { + await _myBalanceService.addUserAgreementForBloodDonation(); + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModels/medical/reports_monthly_view_model.dart b/lib/core/viewModels/medical/reports_monthly_view_model.dart index 3ae196f5..adb7223e 100644 --- a/lib/core/viewModels/medical/reports_monthly_view_model.dart +++ b/lib/core/viewModels/medical/reports_monthly_view_model.dart @@ -13,11 +13,9 @@ class ReportsMonthlyViewModel extends BaseViewModel { ReportsService _reportsService = locator(); - - String get userAgreementContent => _reportsService.userAgreementContent; - getUserTermsAndConditions() async{ + getUserTermsAndConditions() async { setState(ViewState.Busy); await _reportsService.getUserTermsAndConditions(); if (_reportsService.hasError) { @@ -28,19 +26,33 @@ class ReportsMonthlyViewModel extends BaseViewModel { } } - updatePatientHealthSummaryReport({String message, bool isSummary})async{ + updatePatientHealthSummaryReport( + {String message, + bool isSummary, + bool isUpdateEmail = false, + String email}) async { setState(ViewState.BusyLocal); - await _reportsService.updatePatientHealthSummaryReport(isSummary: isSummary); + await _reportsService.updatePatientHealthSummaryReport( + isSummary: isSummary); if (_reportsService.hasError) { error = _reportsService.error; AppToast.showErrorToast(message: error); setState(ViewState.ErrorLocal); } else { - AppToast.showSuccessToast(message: message); - setState(ViewState.Idle); + if (isUpdateEmail) { + await _reportsService.updateEmail(email: email); + if (_reportsService.hasError) { + error = _reportsService.error; + AppToast.showErrorToast(message: error); + setState(ViewState.ErrorLocal); + } else { + AppToast.showSuccessToast(message: message); + setState(ViewState.Idle); + } + } else { + AppToast.showSuccessToast(message: message); + setState(ViewState.Idle); + } } } - - - } diff --git a/lib/core/viewModels/medical/weight_pressure_view_model.dart b/lib/core/viewModels/medical/weight_pressure_view_model.dart index 29095895..42db0a58 100644 --- a/lib/core/viewModels/medical/weight_pressure_view_model.dart +++ b/lib/core/viewModels/medical/weight_pressure_view_model.dart @@ -9,16 +9,13 @@ import 'package:diplomaticquarterapp/core/service/medical/BloodSugarService.dart import 'package:diplomaticquarterapp/core/service/medical/WeightPressureService.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:charts_flutter/flutter.dart' as charts; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import '../../../core/viewModels/base_view_model.dart'; -class WeightPressureViewMode extends BaseViewModel { +class WeightPressureViewModel extends BaseViewModel { WeightService weightService = locator(); - List _weightWeeklyTimeSeriesSalesList = List(); - List _weightMonthlyTimeSeriesSalesList = List(); - List _weightYearTimeSeriesSalesList = List(); - List get monthWeightMeasurementResult => weightService.monthWeightMeasurementResult; @@ -28,6 +25,10 @@ class WeightPressureViewMode extends BaseViewModel { List get yearWeightMeasurementResult => weightService.yearWeightMeasurementResult; + List weightWeekTimeSeriesData = []; + List weighMonthTimeSeriesData = []; + List weightYearTimeSeriesData = []; + Future getWeight() async { setState(ViewState.Busy); await weightService.getWeightAverage(); @@ -37,71 +38,84 @@ class WeightPressureViewMode extends BaseViewModel { setState(ViewState.Error); } else { weightService.weekWeightMeasurementResultAverage.forEach((element) { - _weightWeeklyTimeSeriesSalesList.add(WeekChartDate( - x: element.weightDate, y: element.dailyAverageResult)); + weightWeekTimeSeriesData.add(TimeSeriesSales2( + element.weightDate, + element.dailyAverageResult.toDouble(), + )); }); for (int index = 0; index < weightService.monthWeightMeasurementResultAverage.length; index++) { - _weightMonthlyTimeSeriesSalesList.add(YearMonthlyChartDate( - x: index, - y: weightService.monthWeightMeasurementResultAverage[index].weekAverageResult)); + weighMonthTimeSeriesData.add(TimeSeriesSales3( + index, + weightService + .monthWeightMeasurementResultAverage[index].weekAverageResult + .toDouble(), + )); } weightService.yearWeightMeasurementResultAverage.forEach((element) { - _weightYearTimeSeriesSalesList - .add(WeekChartDate(x: element.date, y: element.monthAverageResult)); + weightYearTimeSeriesData.add(TimeSeriesSales2( + element.date, + element.monthAverageResult.toDouble(), + )); }); setState(ViewState.Idle); } } - List> getWeightWeeklySeries() { - return [ - charts.Series( - id: 'Diastolic', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _weightWeeklyTimeSeriesSalesList, - ), - ]; + addWeightResult( + {String weightDate, String weightMeasured, int weightUnit}) async { + setState(ViewState.BusyLocal); + await weightService.addWeightResult( + weightDate: weightDate, + weightMeasured: weightMeasured, + weightUnit: weightUnit, + ); + if (weightService.hasError) { + error = weightService.error; + setState(ViewState.Error); + } else { + await getWeight(); + setState(ViewState.Idle); + } } + Future sendReportByEmail() async { + setState(ViewState.BusyLocal); - List> - getWeightMonthlyTimeSeriesSales() { - return [ - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (YearMonthlyChartDate sales, _) => sales.x, - measureFn: (YearMonthlyChartDate sales, _) => sales.y, - data: _weightMonthlyTimeSeriesSalesList, - ), - ]; + await weightService.sendReportByEmail(); + if (weightService.hasError) { + error = weightService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } } - List> getWeightYearTimeSeriesSales() { - return [ - charts.Series( - id: 'Sales', - colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, - domainFn: (WeekChartDate sales, _) => sales.x, - measureFn: (WeekChartDate sales, _) => sales.y, - data: _weightYearTimeSeriesSalesList, - ), - ]; + updateWeightResult({int lineItemNo, int weightUnit, String weightMeasured,String weightDate}) async { + setState(ViewState.BusyLocal); + await weightService.updateWeightResult( + lineItemNo: lineItemNo, + weightMeasured: weightMeasured, + weightUnit: weightUnit, + weightDate: weightDate + ); + if (weightService.hasError) { + error = weightService.error; + setState(ViewState.Error); + } else { + await getWeight(); + setState(ViewState.Idle); + } } - addWeightResult( - {String weightDate, String weightMeasured, int weightUnit}) async { + deleteWeightResult({int lineItemNo, }) async { setState(ViewState.BusyLocal); - await weightService.addWeightResult( - weightDate: weightDate, - weightMeasured: weightMeasured, - weightUnit: weightUnit,); + await weightService.deleteWeightResult( + lineItemNo: lineItemNo, + ); if (weightService.hasError) { error = weightService.error; setState(ViewState.Error); diff --git a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart index 21df52bc..1029ed4d 100644 --- a/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart +++ b/lib/core/viewModels/packages_offers/PackagesOffersViewModel.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCartItemsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/service/packages_offers/PackagesOffersServices.dart'; @@ -8,12 +9,29 @@ import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; import 'package:flutter/cupertino.dart'; import 'package:diplomaticquarterapp/locator.dart'; -class OfferCategoriesViewModel extends BaseViewModel { +class OfferCategoriesViewModel extends BaseViewModel{ OffersAndPackagesServices service = locator(); - List get list => service.categoryList; + get categoryList => service.categoryList; + get productList => service.categoryList; + } -class OfferProductsViewModel extends BaseViewModel { +class PackagesViewModel extends BaseViewModel { OffersAndPackagesServices service = locator(); - List get list => service.productList; + List get categoryList => service.categoryList; + List get productList => service.productList; + List get latestOffersList => service.latestOffersList; + List get bestSellerList => service.bestSellerList; + List get bannersList => service.bannersList; + List get cartItemList => service.cartItemList; + + + String _cartItemCount = ""; + + String get cartItemCount => _cartItemCount; + + set cartItemCount(String value) { + _cartItemCount = value; + notifyListeners(); + } } diff --git a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart index 06295188..1fa34ee2 100644 --- a/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart +++ b/lib/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart @@ -5,8 +5,10 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformati import 'package:diplomaticquarterapp/core/model/pharmacies/ShippingOption.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCart.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; @@ -17,6 +19,11 @@ class OrderPreviewViewModel extends BaseViewModel { List get addresses => _orderService.addresses; LacumAccountInformation get lacumInformation => _orderService.lacumInformation; + List get orderListModel => _orderService.orderList; + + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); + ShoppingCartResponse cartResponse = ShoppingCartResponse(); PaymentCheckoutData paymentCheckoutData = PaymentCheckoutData(); double totalAdditionalShippingCharge = 0; @@ -32,7 +39,7 @@ class OrderPreviewViewModel extends BaseViewModel { } } - getShoppingCart() async { + Future getShoppingCart() async { setState(ViewState.Busy); await _orderService.getShoppingCart().then((res) { _handleGetShoppingCartResponse(res); @@ -48,20 +55,20 @@ class OrderPreviewViewModel extends BaseViewModel { } } - changeProductQuantity(ShoppingCart product) async { + Future changeProductQuantity(ShoppingCart product) async { setState(ViewState.Busy); await _orderService.changeProductQuantity(product.id, product).then((res) { _handleGetShoppingCartResponse(res); }); if (_orderService.hasError) { error = _orderService.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } } - deleteProduct(ShoppingCart product) async { + Future deleteProduct(ShoppingCart product) async { setState(ViewState.Busy); await _orderService.deleteProduct(product.id).then((res) { _handleGetShoppingCartResponse(res); @@ -74,7 +81,7 @@ class OrderPreviewViewModel extends BaseViewModel { } } - deleteShoppingCart() async { + Future deleteShoppingCart() async { setState(ViewState.Busy); await _orderService.deleteShoppingCart().then((res) { _handleGetShoppingCartResponse(res); @@ -182,10 +189,12 @@ class OrderPreviewViewModel extends BaseViewModel { Future makeOrder() async { setState(ViewState.Busy); + await pharmacyModuleViewModel.generatePharmacyToken(); + await _orderService.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts); if (_orderService.hasError) { error = _orderService.error; - setState(ViewState.Error); + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); } diff --git a/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart b/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart index f8f5ea05..f2ed5913 100644 --- a/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart +++ b/lib/core/viewModels/pharmacyModule/lacum-registration-viewModel.dart @@ -19,11 +19,13 @@ class LacumRegistrationViewModel extends LacumViewModel { error = _lacumService.error; setState(ViewState.Error); } else { - if(_lacumService.lacumInformation.yahalaAccountNo != 0){ - error = "The account has already been activated"; - setState(ViewState.Error); - } else { - setState(ViewState.Idle); + if(_lacumService.lacumInformation != null){ + if(_lacumService.lacumInformation.yahalaAccountNo == 0){ + error = _lacumService.lacumInformation.errorEndUserMessage; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } } } } diff --git a/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart b/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart index ba8d70d9..1ee1a41c 100644 --- a/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart +++ b/lib/core/viewModels/pharmacyModule/lacum-viewmodel.dart @@ -19,6 +19,9 @@ class LacumViewModel extends BaseViewModel { LacumAccountInformation get lacumGroupInformation => _lacumService.lacumGroupInformation; + String get successMsg => + _lacumService.successMsg; + Future getLacumData() async { await getLacumAccountData(); getLacumGroupData(); @@ -70,16 +73,14 @@ class LacumViewModel extends BaseViewModel { } } - Future createLakumAccount(String name, String phone) async { - setState(ViewState.Busy); + Future createLakumAccount(String name, String phone) async { + setState(ViewState.BusyLocal); await _lacumService.createLakumAccount(name, phone, lacumInformation.yahalaAccountNo, lacumInformation.identificationNo, null); if (_lacumService.hasError) { error = _lacumService.error; - setState(ViewState.Error); - return 404; + setState(ViewState.ErrorLocal); } else { setState(ViewState.Idle); - return 200; } } diff --git a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart index b7ddb528..5b1c67f2 100644 --- a/lib/core/viewModels/pharmacyModule/order_model_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/order_model_view_model.dart @@ -1,32 +1,29 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/order/OrderDetails.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/cancelOrder_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/orderDetails_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; -import 'package:flutter/material.dart'; import '../../../locator.dart'; import '../base_view_model.dart'; class OrderModelViewModel extends BaseViewModel { OrderService _orderService = locator(); - - List get order => _orderService.orderList; + List get orders => _orderService.orderList; OrderDetailsService _orderDetailsService = locator(); - - List get orderDetails => _orderDetailsService.orderDetails; + List get orderListModel => _orderDetailsService.orderList; CancelOrderService _cancelOrderService = locator(); - - List get cancelOrder => _cancelOrderService.cancelOrderList; + List get cancelOrder => _cancelOrderService.cancelOrderList; OrderPreviewService _orderServices = locator(); @@ -52,15 +49,16 @@ class OrderModelViewModel extends BaseViewModel { } } - Future getOrderDetails(orderId) async { + Future getOrderDetails(OrderId) async { setState(ViewState.Busy); - await _orderDetailsService.getOrderDetails(orderId); + await _orderDetailsService.getOrderDetails(OrderId); if (_orderDetailsService.hasError) { error = _orderDetailsService.error; setState(ViewState.Error); } else { setState(ViewState.Idle); } + return _orderDetailsService.orderList.first; } Future getProductReview() async { @@ -100,7 +98,7 @@ class OrderModelViewModel extends BaseViewModel { return res; } - Future makeReview(Product product, double rating, String reviewText) async { + Future makeReview(PharmacyProduct product, double rating, String reviewText) async { setState(ViewState.Busy); await _orderDetailsService.makeReview(product, rating, reviewText); if (_orderDetailsService.hasError) { @@ -113,15 +111,16 @@ class OrderModelViewModel extends BaseViewModel { message: "Your review has been Submitted successfully"); } } + Future makeOrder() async { - setState(ViewState.Busy); + /* setState(ViewState.Busy); await _orderServices.makeOrder(paymentCheckoutData, cartResponse.shoppingCarts); if (_orderServices.hasError) { error = _orderServices.error; setState(ViewState.Error); } else { setState(ViewState.Idle); - } + }*/ } } diff --git a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart index 4dfc6a26..833735bb 100644 --- a/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart @@ -3,14 +3,26 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyImageObject.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/service/medical/prescriptions_service.dart'; +//import 'package:diplomaticquarterapp/core/model/prescriptions/perscription_pharmacy.dart'; import 'package:diplomaticquarterapp/core/service/parmacyModule/parmacy_module_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/base_view_model.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/recommendedProduct_service.dart'; + import '../../../locator.dart'; class PharmacyModuleViewModel extends BaseViewModel { PharmacyModuleService _pharmacyService = locator(); + PrescriptionService _prescriptionService = locator(); + + + RecommendedProductService _recommendedProductService = locator(); + List get bannerList => _pharmacyService.bannerItems; List get manufacturerList => _pharmacyService.manufacturerList; @@ -21,14 +33,26 @@ class PharmacyModuleViewModel extends BaseViewModel { List get lastVisitedProducts => _pharmacyService.lastVisitedProducts; + + List get recommendedProductList => + _recommendedProductService.recommendedList; + + List get prescriptionsList => + _prescriptionService.prescriptionsList; + + bool hasError = false; +// List get pharmacyPrescriptionsList => PharmacyProduct.pharmacyPrescriptionsList ; + Future getPharmacyHomeData() async { - setState(ViewState.Busy); + if(authenticatedUserObject.isLogin) + await generatePharmacyToken(); + var data = await sharedPref.getObject(USER_PROFILE); var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + setState(ViewState.Busy); if (authenticatedUserObject.isLogin && data != null && customerId == null) { await _pharmacyService.makeVerifyCustomer(data); - // here must call getShoppingCard() if (_pharmacyService.hasError) { error = _pharmacyService.error; setState(ViewState.Error); @@ -40,6 +64,27 @@ class PharmacyModuleViewModel extends BaseViewModel { } } + Future createUser() async { + setState(ViewState.Busy); + await _pharmacyService.createUser(); + if (_pharmacyService.hasError) { + error = _pharmacyService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + Future generatePharmacyToken() async { + setState(ViewState.Busy); + await _pharmacyService.generatePharmacyToken(); + if (_pharmacyService.hasError) { + error = _pharmacyService.error; + setState(ViewState.ErrorLocal); + } else { + setState(ViewState.Idle); + } + } + Future getBannerList() async { setState(ViewState.Busy); await _pharmacyService.getBannerListList(); @@ -92,6 +137,19 @@ class PharmacyModuleViewModel extends BaseViewModel { } } + /////////////RecommendedProducts + getRecommendedProducts(productId) async { + hasError = false; + setState(ViewState.Busy); + await _recommendedProductService.getRecommendedProducts(productId); + if (_recommendedProductService.hasError) { + error = _recommendedProductService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + Future checkUserIsActivated() async { if (authenticatedUserObject.isLogin) { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); @@ -105,4 +163,32 @@ class PharmacyModuleViewModel extends BaseViewModel { return false; } } + + getPrescription() async { + print("Print PRESCRIPTION url"); + setState(ViewState.Busy); + await _prescriptionService.getPrescription(); + if (_prescriptionService.hasError) { + error = _prescriptionService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + + ///////////////////////or +// getPrescriptions() async { +// setState(ViewState.Busy); +// await _prescriptionsService.getPrescriptions(); +// if (_prescriptionsService.hasError) { +// error = _prescriptionsService.error; +// setState(ViewState.Error); +// } else { +// _filterList(); +// await _getPrescriptionsOrders(); +// setState(ViewState.Idle); +// } +// } + } diff --git a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart index 47a3bb11..c7ac0a04 100644 --- a/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart +++ b/lib/core/viewModels/pharmacyModule/product_detail_view_model.dart @@ -11,23 +11,19 @@ import '../../../locator.dart'; class ProductDetailViewModel extends BaseViewModel{ ProductDetailService _productDetailService = locator(); - ProductDetailService _productLocationService = locator(); - ProductDetailService _productWishlistService = locator(); - ProductDetailService _productSpecification = locator(); List get productDetailService => _productDetailService.productDetailList; - List get productLocationService => _productLocationService.productLocationList; + List get productLocationService => _productDetailService.productLocationList; - List get wishListItems => _productWishlistService.wishListProducts; + List get wishListItems => _productDetailService.wishListProducts; - List get productSpecification => _productSpecification.productSpecification; + List get productSpecification => _productDetailService.productSpecification; bool hasError = false; Future getProductReviewsData(productID) async { - print('ENAD REview'); hasError = false; setState(ViewState.Busy); await _productDetailService.getProductReviews(productID); @@ -39,12 +35,22 @@ class ProductDetailViewModel extends BaseViewModel{ } Future getProductLocationData() async { - print('ENAD in model view'); hasError = false; setState(ViewState.Busy); - await _productLocationService.getProductAvailabiltyDetail(); - if (_productLocationService.hasError) { - error = _productLocationService.error; + await _productDetailService.getProductAvailabiltyDetail(); + if (_productDetailService.hasError) { + error = _productDetailService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future notifyMe(customerId, itemID) async { + hasError = false; + setState(ViewState.Busy); + await _productDetailService.notifyMe(customerId, itemID); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -53,9 +59,9 @@ class ProductDetailViewModel extends BaseViewModel{ Future addToCartData(quantity, itemID) async { hasError = false; setState(ViewState.Busy); - await _productLocationService.addToCart(quantity, itemID); - if (_productLocationService.hasError) { - error = _productLocationService.error; + await _productDetailService.addToCart(quantity, itemID); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -64,9 +70,9 @@ class ProductDetailViewModel extends BaseViewModel{ Future addToWishlistData(itemID) async { hasError = false; setState(ViewState.Busy); - await _productLocationService.addToWishlist(itemID); - if (_productLocationService.hasError) { - error = _productLocationService.error; + await _productDetailService.addToWishlist(itemID); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -75,9 +81,9 @@ class ProductDetailViewModel extends BaseViewModel{ Future checkWishlistData() async { hasError = false; setState(ViewState.Busy); - await _productWishlistService.getWishlistItems(); - if (_productWishlistService.hasError) { - error = _productWishlistService.error; + await _productDetailService.getWishlistItems(); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -87,9 +93,9 @@ class ProductDetailViewModel extends BaseViewModel{ Future deletWishlistData(itemID) async { hasError = false; setState(ViewState.Busy); - await _productWishlistService.delteItemFromWishlist(itemID); - if (_productWishlistService.hasError) { - error = _productWishlistService.error; + await _productDetailService.delteItemFromWishlist(itemID); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); @@ -99,9 +105,9 @@ class ProductDetailViewModel extends BaseViewModel{ Future productSpecificationData(itemID) async { hasError = false; setState(ViewState.Busy); - await _productWishlistService.productSpecificationData(itemID); - if (_productWishlistService.hasError) { - error = _productWishlistService.error; + await _productDetailService.productSpecificationData(itemID); + if (_productDetailService.hasError) { + error = _productDetailService.error; setState(ViewState.ErrorLocal); } else setState(ViewState.Idle); diff --git a/lib/core/viewModels/pharmacy_categorise_view_model.dart b/lib/core/viewModels/pharmacy_categorise_view_model.dart index 5e1f4f9f..e48329ba 100644 --- a/lib/core/viewModels/pharmacy_categorise_view_model.dart +++ b/lib/core/viewModels/pharmacy_categorise_view_model.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/brands_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/model/pharmacy/final_products_model.dart'; @@ -17,7 +18,7 @@ import 'base_view_model.dart'; class PharmacyCategoriseViewModel extends BaseViewModel { bool hasError = false; PharmacyCategoriseService _pharmacyCategoriseService = - locator(); + locator(); List get categorise => _pharmacyCategoriseService.categoriseList; @@ -25,21 +26,21 @@ class PharmacyCategoriseViewModel extends BaseViewModel { List get categoriseParent => _pharmacyCategoriseService.parentCategoriseList; - List get parentProducts => + List get parentProducts => _pharmacyCategoriseService.parentProductsList; - List get subCategorise => + List get subCategorise => _pharmacyCategoriseService.subCategoriseList; - List get subProducts => + List get subProducts => _pharmacyCategoriseService.subProductsList; - List get finalProducts => + List get finalProducts => _pharmacyCategoriseService.finalProducts; - List get brandsList => _pharmacyCategoriseService.brandsList; + List get brandsList => + _pharmacyCategoriseService.brandsList; - List get searchList => - _pharmacyCategoriseService.searchList; + List get searchList => _pharmacyCategoriseService.searchList; List get scanList => _pharmacyCategoriseService.scanList; @@ -55,11 +56,11 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.Idle); } - Future getBrands() async { + Future getBrands({String id}) async { hasError = false; // _insuranceCardService.clearInsuranceCard(); setState(ViewState.Busy); - await _pharmacyCategoriseService.getBrands(); + await _pharmacyCategoriseService.getBrands(id: id); if (_pharmacyCategoriseService.hasError) { error = _pharmacyCategoriseService.error; setState(ViewState.ErrorLocal); @@ -105,7 +106,7 @@ class PharmacyCategoriseViewModel extends BaseViewModel { setState(ViewState.ErrorLocal); } else await getParentProducts(i: i); - await getBrands(); + await getBrands(id: i); } Future getParentProducts({String i}) async { @@ -155,4 +156,73 @@ class PharmacyCategoriseViewModel extends BaseViewModel { } else setState(ViewState.Idle); } + + Future getFilteredProducts( + {String categoryId, String brandId, String min, String max}) async { + hasError = false; + // _insuranceCardService.clearInsuranceCard(); + setState(ViewState.Busy); + await _pharmacyCategoriseService.getFilteredProducts( + categoryId: categoryId, brandId: brandId, max: max, min: min); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.ErrorLocal); + } else + setState(ViewState.Idle); + } + + Future getManufacturerProducts(String id) async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getManufacturerProducts(id); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future getLastVisitedProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getLastVisitedProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future getBestSellerProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getBestSellerProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future getMostViewedProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getMostViewedProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } + + Future getNewProducts() async { + setState(ViewState.Busy); + await _pharmacyCategoriseService.getNewProducts(); + if (_pharmacyCategoriseService.hasError) { + error = _pharmacyCategoriseService.error; + setState(ViewState.Error); + } else { + setState(ViewState.Idle); + } + } } diff --git a/lib/core/viewModels/project_view_model.dart b/lib/core/viewModels/project_view_model.dart index baaf6b5b..2bb75305 100644 --- a/lib/core/viewModels/project_view_model.dart +++ b/lib/core/viewModels/project_view_model.dart @@ -32,7 +32,7 @@ class ProjectViewModel extends BaseViewModel { Locale get appLocal => _appLocale; - LocaleType get localeType => isArabic ? LocaleType.en : LocaleType.ar; + LocaleType get localeType => isArabic ? LocaleType.ar : LocaleType.en; bool get isArabic => _isArabic; diff --git a/lib/d_q_icons_icons.dart b/lib/d_q_icons_icons.dart index c3b64559..5d1ff3c6 100644 --- a/lib/d_q_icons_icons.dart +++ b/lib/d_q_icons_icons.dart @@ -39,4 +39,5 @@ class DQIcons { static const IconData my_medical_file = IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData family = IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg); static const IconData calendar__2_ = IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg); + static const IconData roboticon = IconData(0xe812, fontFamily: _kFontFam, fontPackage: _kFontPkg); } diff --git a/lib/generated/json/OfferCategoriesResponseModel_helper.dart b/lib/generated/json/OfferCategoriesResponseModel_helper.dart index e5ebc914..1a28d179 100644 --- a/lib/generated/json/OfferCategoriesResponseModel_helper.dart +++ b/lib/generated/json/OfferCategoriesResponseModel_helper.dart @@ -1,8 +1,8 @@ -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; -offerCategoriesResponseModelFromJson(OfferCategoriesResponseModel data, Map json) { +offerCategoriesResponseModelFromJson(PackagesCategoriesResponseModel data, Map json) { if (json['id'] != null) { - data.id = json['id']?.toString(); + data.id = json['id']; } if (json['name'] != null) { data.name = json['name']?.toString(); @@ -91,7 +91,7 @@ offerCategoriesResponseModelFromJson(OfferCategoriesResponseModel data, Map offerCategoriesResponseModelToJson(OfferCategoriesResponseModel entity) { +Map offerCategoriesResponseModelToJson(PackagesCategoriesResponseModel entity) { final Map data = new Map(); data['id'] = entity.id; data['name'] = entity.name; diff --git a/lib/generated/json/OfferProductsResponseModel_helper.dart b/lib/generated/json/OfferProductsResponseModel_helper.dart index dc0edeca..d180af67 100644 --- a/lib/generated/json/OfferProductsResponseModel_helper.dart +++ b/lib/generated/json/OfferProductsResponseModel_helper.dart @@ -1,8 +1,8 @@ -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; -offerProductsResponseModelFromJson(OfferProductsResponseModel data, Map json) { +offerProductsResponseModelFromJson(PackagesResponseModel data, Map json) { if (json['id'] != null) { - data.id = json['id']?.toString(); + data.id = json['id']; } if (json['visible_individually'] != null) { data.visibleIndividually = json['visible_individually']; @@ -353,7 +353,7 @@ offerProductsResponseModelFromJson(OfferProductsResponseModel data, Map offerProductsResponseModelToJson(OfferProductsResponseModel entity) { +Map offerProductsResponseModelToJson(PackagesResponseModel entity) { final Map data = new Map(); data['id'] = entity.id; data['visible_individually'] = entity.visibleIndividually; diff --git a/lib/generated/json/base/json_convert_content.dart b/lib/generated/json/base/json_convert_content.dart index 9fab946e..ae4eadeb 100644 --- a/lib/generated/json/base/json_convert_content.dart +++ b/lib/generated/json/base/json_convert_content.dart @@ -3,11 +3,11 @@ // ignore_for_file: prefer_single_quotes // This file is automatically generated. DO NOT EDIT, all your changes would be lost. -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/OfferCategoriesResponseModel_helper.dart'; import 'package:diplomaticquarterapp/core/model/geofencing/responses/LogGeoZoneResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/log_geo_zone_response_model_entity_helper.dart'; -import 'package:diplomaticquarterapp/core/model/packages_offers/responses/OfferProductsResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/OfferProductsResponseModel_helper.dart'; import 'package:diplomaticquarterapp/core/model/geofencing/responses/GeoZonesResponseModel.dart'; import 'package:diplomaticquarterapp/generated/json/GeoZonesResponseModel_helper.dart'; @@ -23,16 +23,16 @@ class JsonConvert { static _getFromJson(Type type, data, json) { switch (type) { - case OfferCategoriesResponseModel: - return offerCategoriesResponseModelFromJson(data as OfferCategoriesResponseModel, json) as T; + case PackagesCategoriesResponseModel: + return offerCategoriesResponseModelFromJson(data as PackagesCategoriesResponseModel, json) as T; case OfferCategoriesResponseModelLocalizedName: return offerCategoriesResponseModelLocalizedNameFromJson(data as OfferCategoriesResponseModelLocalizedName, json) as T; case OfferCategoriesResponseModelImage: return offerCategoriesResponseModelImageFromJson(data as OfferCategoriesResponseModelImage, json) as T; case LogGeoZoneResponseModel: return logGeoZoneResponseModelEntityFromJson(data as LogGeoZoneResponseModel, json) as T; - case OfferProductsResponseModel: - return offerProductsResponseModelFromJson(data as OfferProductsResponseModel, json) as T; + case PackagesResponseModel: + return offerProductsResponseModelFromJson(data as PackagesResponseModel, json) as T; case OfferProductsResponseModelLocalizedName: return offerProductsResponseModelLocalizedNameFromJson(data as OfferProductsResponseModelLocalizedName, json) as T; case OfferProductsResponseModelImage: @@ -47,16 +47,16 @@ class JsonConvert { static _getToJson(Type type, data) { switch (type) { - case OfferCategoriesResponseModel: - return offerCategoriesResponseModelToJson(data as OfferCategoriesResponseModel); + case PackagesCategoriesResponseModel: + return offerCategoriesResponseModelToJson(data as PackagesCategoriesResponseModel); case OfferCategoriesResponseModelLocalizedName: return offerCategoriesResponseModelLocalizedNameToJson(data as OfferCategoriesResponseModelLocalizedName); case OfferCategoriesResponseModelImage: return offerCategoriesResponseModelImageToJson(data as OfferCategoriesResponseModelImage); case LogGeoZoneResponseModel: return logGeoZoneResponseModelEntityToJson(data as LogGeoZoneResponseModel); - case OfferProductsResponseModel: - return offerProductsResponseModelToJson(data as OfferProductsResponseModel); + case PackagesResponseModel: + return offerProductsResponseModelToJson(data as PackagesResponseModel); case OfferProductsResponseModelLocalizedName: return offerProductsResponseModelLocalizedNameToJson(data as OfferProductsResponseModelLocalizedName); case OfferProductsResponseModelImage: @@ -72,16 +72,16 @@ class JsonConvert { //Go back to a single instance by type static _fromJsonSingle(json) { String type = M.toString(); - if (type == (OfferCategoriesResponseModel).toString()) { - return OfferCategoriesResponseModel().fromJson(json); + if (type == (PackagesCategoriesResponseModel).toString()) { + return PackagesCategoriesResponseModel().fromJson(json); } else if (type == (OfferCategoriesResponseModelLocalizedName).toString()) { return OfferCategoriesResponseModelLocalizedName().fromJson(json); } else if (type == (OfferCategoriesResponseModelImage).toString()) { return OfferCategoriesResponseModelImage().fromJson(json); } else if (type == (LogGeoZoneResponseModel).toString()) { return LogGeoZoneResponseModel().fromJson(json); - } else if (type == (OfferProductsResponseModel).toString()) { - return OfferProductsResponseModel().fromJson(json); + } else if (type == (PackagesResponseModel).toString()) { + return PackagesResponseModel().fromJson(json); } else if (type == (OfferProductsResponseModelLocalizedName).toString()) { return OfferProductsResponseModelLocalizedName().fromJson(json); } else if (type == (OfferProductsResponseModelImage).toString()) { @@ -96,16 +96,16 @@ class JsonConvert { //list is returned by type static M _getListChildType(List data) { - if (List() is M) { - return data.map((e) => OfferCategoriesResponseModel().fromJson(e)).toList() as M; + if (List() is M) { + return data.map((e) => PackagesCategoriesResponseModel().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferCategoriesResponseModelLocalizedName().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferCategoriesResponseModelImage().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => LogGeoZoneResponseModel().fromJson(e)).toList() as M; - } else if (List() is M) { - return data.map((e) => OfferProductsResponseModel().fromJson(e)).toList() as M; + } else if (List() is M) { + return data.map((e) => PackagesResponseModel().fromJson(e)).toList() as M; } else if (List() is M) { return data.map((e) => OfferProductsResponseModelLocalizedName().fromJson(e)).toList() as M; } else if (List() is M) { diff --git a/lib/locator.dart b/lib/locator.dart index cfdad053..1acaf1af 100644 --- a/lib/locator.dart +++ b/lib/locator.dart @@ -1,9 +1,17 @@ import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; +import 'package:diplomaticquarterapp/core/service/ancillary_orders_service.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/prescription_service.dart'; import 'package:diplomaticquarterapp/core/service/qr_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/services/pharmacy_services/recommendedProduct_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/weather/weather_view_model.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; +// import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +// import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/review_service.dart'; import 'package:diplomaticquarterapp/services/pharmacy_services/wishList_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/PharmacyAddressesViewModel.dart'; @@ -17,8 +25,10 @@ import 'package:get_it/get_it.dart'; import 'core/service/AlHabibMedicalService/cmc_service.dart'; import 'core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'core/service/AlHabibMedicalService/e_referral_service.dart'; +import 'core/service/AlHabibMedicalService/health-calculator/bariatrics-service.dart'; import 'core/service/AlHabibMedicalService/home_health_care_service.dart'; import 'core/service/AuthenticatedUserObject.dart'; +import 'core/service/PrescriptionDeliveryService.dart'; import 'core/service/appointment_rate_service.dart'; import 'core/service/blood/blood_details_servies.dart'; import 'core/service/blood/blood_donation_service.dart'; @@ -30,6 +40,7 @@ import 'core/service/childvaccines/vaccination_table_service.dart'; import 'core/service/contactus/finadus_service.dart'; import 'core/service/contactus/livechat_service.dart'; import 'core/service/dashboard_service.dart'; +import 'core/service/er/EdOnlineServices.dart'; import 'core/service/er/am_service.dart'; import 'core/service/er/er_service.dart'; import 'core/service/feedback/feedback_service.dart'; @@ -59,12 +70,17 @@ import 'core/service/parmacyModule/order-preview-service.dart'; import 'core/service/notifications_service.dart'; import 'core/service/parmacyModule/terms-condition-service.dart'; import 'core/service/privilege_service.dart'; +import 'core/service/termsConditionsService.dart'; import 'core/service/weather_service.dart'; import 'core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'core/service/parmacyModule/parmacy_module_service.dart'; import 'core/service/offers_service.dart'; import 'core/service/pharmacy_categorise_service.dart'; +import 'core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart'; +import 'core/viewModels/er/EdOnlineViewModel.dart'; +import 'core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; +import 'core/viewModels/TermsConditionsViewModel.dart'; import 'core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'core/viewModels/appointment_rate_view_model.dart'; import 'core/viewModels/blooddonation/blood_details_view_model.dart'; @@ -180,8 +196,12 @@ void setupLocator() { locator.registerLazySingleton(() => DeleteBabyService()); locator.registerLazySingleton(() => VaccinationTableService()); + locator.registerLazySingleton(() => AncillaryOrdersService()); + locator.registerLazySingleton(() => EdOnlineServices()); //pharmacy + // locator.registerLazySingleton(() => PharmacyCategoriseService()); + // locator.registerLazySingleton(() => OffersCategoriseService()); locator.registerLazySingleton(() => PharmacyCategoriseService()); locator.registerLazySingleton(() => OffersCategoriseService()); @@ -200,10 +220,17 @@ void setupLocator() { locator.registerLazySingleton(() => PharmacyAddressService()); locator.registerLazySingleton(() => OrderDetailsService()); locator.registerLazySingleton(() => CustomerAddressesService()); + // locator.registerLazySingleton(() => TermsConditionService()); locator.registerLazySingleton(() => TermsConditionService()); locator.registerLazySingleton(() => CancelOrderService()); + locator.registerLazySingleton(() => PrescriptionService()); + locator.registerLazySingleton(() => RecommendedProductService()); + locator.registerLazySingleton(() => PrivilegeService()); locator.registerLazySingleton(() => WeatherService()); + locator.registerLazySingleton(() => TermsConditionsService()); + locator.registerLazySingleton(() => BariatricsService()); + locator.registerLazySingleton(() => PrescriptionDeliveryService()); /// View Model locator.registerFactory(() => HospitalViewModel()); @@ -242,10 +269,11 @@ void setupLocator() { locator.registerFactory(() => H2OViewModel()); locator.registerFactory(() => BloodSugarViewMode()); locator.registerFactory(() => BloodPressureViewMode()); - locator.registerFactory(() => WeightPressureViewMode()); + locator.registerFactory(() => WeightPressureViewModel()); locator.registerFactory(() => EyeViewModel()); locator.registerFactory(() => ActiveMedicationsViewModel()); locator.registerFactory(() => AskDoctorViewModel()); + locator.registerFactory(() => PrescriptionDeliveryViewModel()); locator.registerFactory(() => AllergiesViewModel()); locator.registerFactory(() => HomeHealthCareViewModel()); @@ -259,23 +287,30 @@ void setupLocator() { locator.registerFactory(() => ProductDetailViewModel()); locator.registerFactory(() => WeatherViewModel()); - locator.registerFactory(() => OrderPreviewViewModel()); locator.registerFactory(() => LacumViewModel()); locator.registerFactory(() => LacumTranferViewModel()); locator.registerFactory(() => LacumRegistrationViewModel()); + locator.registerFactory(() => EdOnlineViewModel()); //pharmacy locator.registerFactory(() => PharmacyCategoriseViewModel()); locator.registerFactory(() => OffersCategoriseViewModel()); + locator.registerFactory(() => BariatricsViewModel()); // Offer And Packages //---------------------- locator.registerLazySingleton(() => OffersAndPackagesServices()); // offerPackagesServices Service locator.registerFactory(() => OfferCategoriesViewModel()); // Categories View Model - locator.registerFactory(() => OfferProductsViewModel()); // Products View Model + locator.registerFactory(() => PackagesViewModel()); // Products View Model + //pharmacy + // locator.registerFactory(() => PharmacyCategoriseViewModel()); + // locator.registerFactory(() => OffersCategoriseViewModel()); // Geofencing // --------------------- - locator.registerLazySingleton(() => GeofencingServices()); // Geofencing Services + locator.registerLazySingleton( + () => GeofencingServices()); // Geofencing Services + locator.registerFactory(() => TermsConditionsViewModel()); + locator.registerFactory(() => AnciallryOrdersViewModel()); } diff --git a/lib/main.dart b/lib/main.dart index fe129e01..2412e4d1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,13 +7,16 @@ import 'package:diplomaticquarterapp/theme/theme_value.dart'; import 'package:diplomaticquarterapp/uitl/HMG_Geofence.dart'; import 'package:diplomaticquarterapp/uitl/LocalNotification.dart'; import 'package:diplomaticquarterapp/uitl/PlatformBridge.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; import 'Constants.dart'; +import 'config/shared_pref_kay.dart'; import 'config/size_config.dart'; import 'core/model/geofencing/requests/GeoZonesRequestModel.dart'; import 'core/service/geofencing/GeofencingServices.dart'; @@ -23,18 +26,33 @@ import 'pages/pharmacies/compare-list.dart'; void main() async { setupLocator(); - runApp(ChangeNotifierProvider(create: (context) => ThemeNotifier(defaultTheme), child: MyApp())); + runApp(MyApp()); } -class MyApp extends StatelessWidget { +class MyApp extends StatefulWidget { + @override + _MyApp createState() => new _MyApp(); +} + +class _MyApp extends State { + @override + void initState(){ + // ProjectViewModel projectProvider; + // projectProvider = Provider.of(context); + // var font = projectProvider.isArabic ? 'Cairo' : 'WorkSans'; + ThemeNotifier(defaultTheme()); + super.initState(); + } + @override Widget build(BuildContext context) { PlatformBridge.init(context); - LocalNotification.init(onNotificationClick: (payload){ - LocalNotification.getInstance().showNow(title: "Payload", subtitle: payload, payload: payload); + LocalNotification.init(onNotificationClick: (payload) { + LocalNotification.getInstance() + .showNow(title: "Payload", subtitle: payload, payload: payload); }); - final themeNotifier = Provider.of(context); + // final themeNotifier = Provider.of(context); precacheImage(AssetImage('assets/images/powerd-by.jpg'), context); return LayoutBuilder( builder: (context, constraints) { @@ -46,11 +64,18 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider( create: (context) => ProjectViewModel(), ), - ChangeNotifierProvider(create: (context) => ToDoCountProviderModel()), - ChangeNotifierProvider(create: (context) => SearchProvider()), + ChangeNotifierProvider( + create: (context) => ToDoCountProviderModel()), + ChangeNotifierProvider( + create: (context) => SearchProvider()), ChangeNotifierProvider.value( value: SearchProvider(), ), + ChangeNotifierProvider( + create: (context) => ThemeNotifier( + defaultTheme() + ) + ), StreamProvider.value( value: RobotProvider().intStream(), initialData: RobotProvider().setValue({}), @@ -60,7 +85,6 @@ class MyApp extends StatelessWidget { ], child: Consumer( builder: (context, projectProvider, child) => MaterialApp( - showSemanticsDebugger: false, title: 'Diplomatic Quarter App', locale: projectProvider.appLocal, @@ -74,48 +98,53 @@ class MyApp extends StatelessWidget { const Locale('ar', ''), // Arabic const Locale('en', ''), // English ], - theme: ThemeData( - fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - }, - ), - hintColor: Colors.grey[400], - textTheme: TextTheme( - headline1: TextStyle( - color: Color(0xffB8382C), - ), - ), - disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xffE9E9E9), // Colors.grey[100], - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Color.fromRGBO(255, 255, 255, 1), - highlightColor: Colors.grey[100].withOpacity(0.4), - splashColor: Colors.transparent, - primaryColor: Colors.grey, - toggleableActiveColor: secondaryColor, - indicatorColor: secondaryColor, - bottomSheetTheme: BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), - cursorColor: Colors.grey, - iconTheme: IconThemeData(), - appBarTheme: AppBarTheme( - color: Colors.grey[700], - brightness: Brightness.light, - elevation: 0.0, - actionsIconTheme: IconThemeData( - color: Colors.grey[800], - ), - ), - ), + theme: Provider.of(context).getTheme(), + // theme: ThemeData( + // fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', + // primarySwatch: Colors.blue, + // visualDensity: VisualDensity.adaptivePlatformDensity, + // brightness: Brightness.light, + // pageTransitionsTheme: const PageTransitionsTheme( + // builders: { + // TargetPlatform.android: ZoomPageTransitionsBuilder(), + // TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + // }, + // ), + // hintColor: Colors.grey[400], + // textTheme: TextTheme( + // headline1: TextStyle( + // color: Color(0xffB8382C), + // ), + // ), + // disabledColor: Colors.grey[300], + // errorColor: Color.fromRGBO(235, 80, 60, 1.0), + // scaffoldBackgroundColor: + // Color(0xffE9E9E9), // Colors.grey[100], + // textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), + // textSelectionHandleColor: Colors.grey, + // canvasColor: Colors.white, + // backgroundColor: Color.fromRGBO(255, 255, 255, 1), + // highlightColor: Colors.grey[100].withOpacity(0.4), + // splashColor: Colors.transparent, + // primaryColor: Color(0xff515A5D), + // toggleableActiveColor: secondaryColor, + // indicatorColor: secondaryColor, + // bottomSheetTheme: BottomSheetThemeData( + // backgroundColor: HexColor('#E0E0E0')), + // cursorColor: Colors.grey, + // iconTheme: IconThemeData(), + // appBarTheme: AppBarTheme( + // color: Color(0xff515A5D), + // brightness: Brightness.light, + // elevation: 0.0, + // actionsIconTheme: IconThemeData( + // color: Colors.grey[800], + // ), + // ), + // ), initialRoute: SPLASH, + // initialRoute: PACKAGES_OFFERS, + // initialRoute: PACKAGES_ORDER_COMPLETED, routes: routes, debugShowCheckedModeBanner: false, ), diff --git a/lib/models/Authentication/send_activation_request.dart b/lib/models/Authentication/send_activation_request.dart index b53e19b8..f9b386c6 100644 --- a/lib/models/Authentication/send_activation_request.dart +++ b/lib/models/Authentication/send_activation_request.dart @@ -21,7 +21,7 @@ class SendActivationRequest { Null sessionID; bool isDentalAllowedBackend; int deviceTypeID; - + String sMSSignature; SendActivationRequest( {this.patientMobileNumber, this.mobileNo, @@ -44,7 +44,8 @@ class SendActivationRequest { this.patientOutSA, this.sessionID, this.isDentalAllowedBackend, - this.deviceTypeID}); + this.deviceTypeID, + this.sMSSignature}); SendActivationRequest.fromJson(Map json) { patientMobileNumber = json['PatientMobileNumber']; @@ -69,6 +70,7 @@ class SendActivationRequest { sessionID = json['SessionID']; isDentalAllowedBackend = json['isDentalAllowedBackend']; deviceTypeID = json['DeviceTypeID']; + sMSSignature = json['SMSSignature']; } Map toJson() { @@ -95,6 +97,7 @@ class SendActivationRequest { data['SessionID'] = this.sessionID; data['isDentalAllowedBackend'] = this.isDentalAllowedBackend; data['DeviceTypeID'] = this.deviceTypeID; + data['SMSSignature'] = sMSSignature; return data; } } diff --git a/lib/models/SmartWatch/HealthData.dart b/lib/models/SmartWatch/HealthData.dart new file mode 100644 index 00000000..f01c3bf8 --- /dev/null +++ b/lib/models/SmartWatch/HealthData.dart @@ -0,0 +1,8 @@ +class healthData { + int MedCategoryID; + int MedSubCategoryID; + String Value; + String Notes; + String MachineDate; + int TransactionsListID; +} diff --git a/lib/models/SmartWatch/YearlyStepsResModel.dart b/lib/models/SmartWatch/YearlyStepsResModel.dart new file mode 100644 index 00000000..728633d9 --- /dev/null +++ b/lib/models/SmartWatch/YearlyStepsResModel.dart @@ -0,0 +1,36 @@ +class YearlyStepsResModel { + double valueSum; + int medCategoryID; + int month; + String monthName; + int patientID; + int year; + + YearlyStepsResModel( + {this.valueSum, + this.medCategoryID, + this.month, + this.monthName, + this.patientID, + this.year}); + + YearlyStepsResModel.fromJson(Map json) { + valueSum = json['ValueSum']; + medCategoryID = json['MedCategoryID']; + month = json['Month']; + monthName = json['MonthName']; + patientID = json['PatientID']; + year = json['Year']; + } + + Map toJson() { + final Map data = new Map(); + data['ValueSum'] = this.valueSum; + data['MedCategoryID'] = this.medCategoryID; + data['Month'] = this.month; + data['MonthName'] = this.monthName; + data['PatientID'] = this.patientID; + data['Year'] = this.year; + return data; + } +} diff --git a/lib/models/anicllary-orders/ancillary_order_list_model.dart b/lib/models/anicllary-orders/ancillary_order_list_model.dart new file mode 100644 index 00000000..76ef3a7d --- /dev/null +++ b/lib/models/anicllary-orders/ancillary_order_list_model.dart @@ -0,0 +1,105 @@ +class AncillaryOrdersListModel { + List ancillaryOrderList; + Null errCode; + String message; + int patientID; + String patientName; + int patientType; + int projectID; + String projectName; + String setupID; + int statusCode; + + AncillaryOrdersListModel( + {this.ancillaryOrderList, + this.errCode, + this.message, + this.patientID, + this.patientName, + this.patientType, + this.projectID, + this.projectName, + this.setupID, + this.statusCode}); + + AncillaryOrdersListModel.fromJson(Map json) { + if (json['AncillaryOrderList'] != null) { + ancillaryOrderList = new List(); + json['AncillaryOrderList'].forEach((v) { + ancillaryOrderList.add(new AncillaryOrderList.fromJson(v)); + }); + } + errCode = json['ErrCode']; + message = json['Message']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientType = json['PatientType']; + projectID = json['ProjectID']; + projectName = json['ProjectName']; + setupID = json['SetupID']; + statusCode = json['StatusCode']; + } + + Map toJson() { + final Map data = new Map(); + if (this.ancillaryOrderList != null) { + data['AncillaryOrderList'] = + this.ancillaryOrderList.map((v) => v.toJson()).toList(); + } + data['ErrCode'] = this.errCode; + data['Message'] = this.message; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientType'] = this.patientType; + data['ProjectID'] = this.projectID; + data['ProjectName'] = this.projectName; + data['SetupID'] = this.setupID; + data['StatusCode'] = this.statusCode; + return data; + } +} + +class AncillaryOrderList { + String appointmentDate; + int appointmentNo; + int clinicID; + String clinicName; + int doctorID; + String doctorName; + String orderDate; + int orderNo; + + AncillaryOrderList( + {this.appointmentDate, + this.appointmentNo, + this.clinicID, + this.clinicName, + this.doctorID, + this.doctorName, + this.orderDate, + this.orderNo}); + + AncillaryOrderList.fromJson(Map json) { + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + doctorID = json['DoctorID']; + doctorName = json['DoctorName']; + orderDate = json['OrderDate']; + orderNo = json['OrderNo']; + } + + Map toJson() { + final Map data = new Map(); + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['DoctorID'] = this.doctorID; + data['DoctorName'] = this.doctorName; + data['OrderDate'] = this.orderDate; + data['OrderNo'] = this.orderNo; + return data; + } +} diff --git a/lib/models/anicllary-orders/ancillary_order_proc_model.dart b/lib/models/anicllary-orders/ancillary_order_proc_model.dart new file mode 100644 index 00000000..7322d11a --- /dev/null +++ b/lib/models/anicllary-orders/ancillary_order_proc_model.dart @@ -0,0 +1,249 @@ +class AncillaryOrdersListProcListModel { + List ancillaryOrderProcList; + String appointmentDate; + dynamic appointmentNo; + dynamic clinicID; + String clinicName; + dynamic companyID; + String companyName; + dynamic doctorID; + String doctorName; + Null errCode; + dynamic groupID; + String insurancePolicyNo; + String message; + String patientCardID; + dynamic patientID; + String patientName; + dynamic patientType; + dynamic policyID; + String policyName; + dynamic projectID; + String setupID; + dynamic statusCode; + dynamic subCategoryID; + String subPolicyNo; + + AncillaryOrdersListProcListModel( + {this.ancillaryOrderProcList, + this.appointmentDate, + this.appointmentNo, + this.clinicID, + this.clinicName, + this.companyID, + this.companyName, + this.doctorID, + this.doctorName, + this.errCode, + this.groupID, + this.insurancePolicyNo, + this.message, + this.patientCardID, + this.patientID, + this.patientName, + this.patientType, + this.policyID, + this.policyName, + this.projectID, + this.setupID, + this.statusCode, + this.subCategoryID, + this.subPolicyNo}); + + AncillaryOrdersListProcListModel.fromJson(Map json) { + if (json['AncillaryOrderProcList'] != null) { + ancillaryOrderProcList = new List(); + json['AncillaryOrderProcList'].forEach((v) { + ancillaryOrderProcList.add(new AncillaryOrderProcList.fromJson(v)); + }); + } + appointmentDate = json['AppointmentDate']; + appointmentNo = json['AppointmentNo']; + clinicID = json['ClinicID']; + clinicName = json['ClinicName']; + companyID = json['CompanyID']; + companyName = json['CompanyName']; + doctorID = json['DoctorID']; + doctorName = json['DoctorName']; + errCode = json['ErrCode']; + groupID = json['GroupID']; + insurancePolicyNo = json['InsurancePolicyNo']; + message = json['Message']; + patientCardID = json['PatientCardID']; + patientID = json['PatientID']; + patientName = json['PatientName']; + patientType = json['PatientType']; + policyID = json['PolicyID']; + policyName = json['PolicyName']; + projectID = json['ProjectID']; + setupID = json['SetupID']; + statusCode = json['StatusCode']; + subCategoryID = json['SubCategoryID']; + subPolicyNo = json['SubPolicyNo']; + } + + Map toJson() { + final Map data = new Map(); + if (this.ancillaryOrderProcList != null) { + data['AncillaryOrderProcList'] = + this.ancillaryOrderProcList.map((v) => v.toJson()).toList(); + } + data['AppointmentDate'] = this.appointmentDate; + data['AppointmentNo'] = this.appointmentNo; + data['ClinicID'] = this.clinicID; + data['ClinicName'] = this.clinicName; + data['CompanyID'] = this.companyID; + data['CompanyName'] = this.companyName; + data['DoctorID'] = this.doctorID; + data['DoctorName'] = this.doctorName; + data['ErrCode'] = this.errCode; + data['GroupID'] = this.groupID; + data['InsurancePolicyNo'] = this.insurancePolicyNo; + data['Message'] = this.message; + data['PatientCardID'] = this.patientCardID; + data['PatientID'] = this.patientID; + data['PatientName'] = this.patientName; + data['PatientType'] = this.patientType; + data['PolicyID'] = this.policyID; + data['PolicyName'] = this.policyName; + data['ProjectID'] = this.projectID; + data['SetupID'] = this.setupID; + data['StatusCode'] = this.statusCode; + data['SubCategoryID'] = this.subCategoryID; + data['SubPolicyNo'] = this.subPolicyNo; + return data; + } +} + +class AncillaryOrderProcList { + dynamic approvalLineItemNo; + dynamic approvalNo; + String approvalStatus; + dynamic approvalStatusID; + dynamic companyShare; + dynamic companyShareWithTax; + dynamic companyTaxAmount; + dynamic discountAmount; + dynamic discountCategory; + String discountType; + dynamic discountTypeValue; + bool isApprovalCreated; + bool isApprovalRequired; + bool isCovered; + String orderDate; + dynamic orderLineItemNo; + dynamic orderNo; + dynamic partnerID; + dynamic partnerShare; + String partnerShareType; + dynamic patientShare; + dynamic patientShareWithTax; + dynamic patientTaxAmount; + dynamic procPrice; + dynamic procedureCategoryID; + String procedureCategoryName; + String procedureID; + String procedureName; + dynamic taxAmount; + dynamic taxPct; + + AncillaryOrderProcList( + {this.approvalLineItemNo, + this.approvalNo, + this.approvalStatus, + this.approvalStatusID, + this.companyShare, + this.companyShareWithTax, + this.companyTaxAmount, + this.discountAmount, + this.discountCategory, + this.discountType, + this.discountTypeValue, + this.isApprovalCreated, + this.isApprovalRequired, + this.isCovered, + this.orderDate, + this.orderLineItemNo, + this.orderNo, + this.partnerID, + this.partnerShare, + this.partnerShareType, + this.patientShare, + this.patientShareWithTax, + this.patientTaxAmount, + this.procPrice, + this.procedureCategoryID, + this.procedureCategoryName, + this.procedureID, + this.procedureName, + this.taxAmount, + this.taxPct}); + + AncillaryOrderProcList.fromJson(Map json) { + approvalLineItemNo = json['ApprovalLineItemNo']; + approvalNo = json['ApprovalNo']; + approvalStatus = json['ApprovalStatus']; + approvalStatusID = json['ApprovalStatusID']; + companyShare = json['CompanyShare']; + companyShareWithTax = json['CompanyShareWithTax']; + companyTaxAmount = json['CompanyTaxAmount']; + discountAmount = json['DiscountAmount']; + discountCategory = json['DiscountCategory']; + discountType = json['DiscountType']; + discountTypeValue = json['DiscountTypeValue']; + isApprovalCreated = json['IsApprovalCreated']; + isApprovalRequired = json['IsApprovalRequired']; + isCovered = json['IsCovered']; + orderDate = json['OrderDate']; + orderLineItemNo = json['OrderLineItemNo']; + orderNo = json['OrderNo']; + partnerID = json['PartnerID']; + partnerShare = json['PartnerShare']; + partnerShareType = json['PartnerShareType']; + patientShare = json['PatientShare']; + patientShareWithTax = json['PatientShareWithTax']; + patientTaxAmount = json['PatientTaxAmount']; + procPrice = json['ProcPrice']; + procedureCategoryID = json['ProcedureCategoryID']; + procedureCategoryName = json['ProcedureCategoryName']; + procedureID = json['ProcedureID']; + procedureName = json['ProcedureName']; + taxAmount = json['TaxAmount']; + taxPct = json['TaxPct']; + } + + Map toJson() { + final Map data = new Map(); + data['ApprovalLineItemNo'] = this.approvalLineItemNo; + data['ApprovalNo'] = this.approvalNo; + data['ApprovalStatus'] = this.approvalStatus; + data['ApprovalStatusID'] = this.approvalStatusID; + data['CompanyShare'] = this.companyShare; + data['CompanyShareWithTax'] = this.companyShareWithTax; + data['CompanyTaxAmount'] = this.companyTaxAmount; + data['DiscountAmount'] = this.discountAmount; + data['DiscountCategory'] = this.discountCategory; + data['DiscountType'] = this.discountType; + data['DiscountTypeValue'] = this.discountTypeValue; + data['IsApprovalCreated'] = this.isApprovalCreated; + data['IsApprovalRequired'] = this.isApprovalRequired; + data['IsCovered'] = this.isCovered; + data['OrderDate'] = this.orderDate; + data['OrderLineItemNo'] = this.orderLineItemNo; + data['OrderNo'] = this.orderNo; + data['PartnerID'] = this.partnerID; + data['PartnerShare'] = this.partnerShare; + data['PartnerShareType'] = this.partnerShareType; + data['PatientShare'] = this.patientShare; + data['PatientShareWithTax'] = this.patientShareWithTax; + data['PatientTaxAmount'] = this.patientTaxAmount; + data['ProcPrice'] = this.procPrice; + data['ProcedureCategoryID'] = this.procedureCategoryID; + data['ProcedureCategoryName'] = this.procedureCategoryName; + data['ProcedureID'] = this.procedureID; + data['ProcedureName'] = this.procedureName; + data['TaxAmount'] = this.taxAmount; + data['TaxPct'] = this.taxPct; + return data; + } +} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart index 45bf01b7..549f90b8 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart @@ -30,7 +30,7 @@ class _ConfirmCancelOrderDialogState extends State { contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), title: Center( child: Texts( - "Confirm", + TranslationBase.of(context).confirm, color: Colors.black, ), ), @@ -40,7 +40,7 @@ class _ConfirmCancelOrderDialogState extends State { Divider(), Center( child: Texts( - "Are you sure!! want to cancel this order", + TranslationBase.of(context).cancelOrderMsg , color: Colors.grey, ), ), diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart new file mode 100644 index 00000000..72aa40dc --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart @@ -0,0 +1,156 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:provider/provider.dart'; + +class CMCLocationPage extends StatefulWidget { + final Function(PickResult) onPick; + final double latitude; + final double longitude; + final dynamic model; + + const CMCLocationPage( + {Key key, this.onPick, this.latitude, this.longitude, this.model}) + : super(key: key); + + @override + _CMCLocationPageState createState() => _CMCLocationPageState(); +} + +class _CMCLocationPageState extends State { + double latitude = 0; + double longitude = 0; + + @override + void initState() { + latitude = widget.latitude; + longitude = widget.longitude; + super.initState(); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) {}, + builder: (_, model, widget) => AppScaffold( + isShowDecPage: false, + isShowAppBar: true, + baseViewModel: model, + body: PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + }, + selectedPlaceWidgetBuilder: + (_, selectedPlace, state, isSearchBarFocused) { + print( + "state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: Column( + children: [ + SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () async { + print(selectedPlace); + AddNewAddressRequestModel + addNewAddressRequestModel = + new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: selectedPlace + .formattedAddress, + address2: selectedPlace + .formattedAddress, + customerAttributes: "", + city: "", + createdOnUtc: "", + id: 0, + latLong: + "$latitude,$longitude", + email: "") + ]), + ); + + selectedPlace.addressComponents + .forEach((e) { + if (e.types.contains("country")) { + addNewAddressRequestModel + .customer + .addresses[0] + .country = e.longName; + } + if (e.types + .contains("postal_code")) { + addNewAddressRequestModel + .customer + .addresses[0] + .zipPostalCode = e.longName; + } + if (e.types.contains("locality")) { + addNewAddressRequestModel + .customer + .addresses[0] + .city = e.longName; + } + }); + + await model.addAddressInfo( + addNewAddressRequestModel: + addNewAddressRequestModel); + if (model.state == + ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast( + message: + "Address Added Successfully"); + } + Navigator.of(context).pop(); + }, + label: TranslationBase.of(context) + .addNewAddress, + ), + ], + ), + ), + ); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: false, + ), + )); + } +} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart index 532396cc..f314a9bf 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart @@ -3,15 +3,18 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/Comprehens import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_order_detail_by_order_iD_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/Dialog/confirm_cancel_order_dialog.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/StepsWidget.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:provider/provider.dart'; import 'new_cmc_step_one_page.dart'; import 'new_cmc_step_three_page.dart'; @@ -23,12 +26,10 @@ class NewCMCPage extends StatefulWidget { final CMCViewModel model; @override - _NewCMCPageState createState() => - _NewCMCPageState(); + _NewCMCPageState createState() => _NewCMCPageState(); } -class _NewCMCPageState extends State - with TickerProviderStateMixin { +class _NewCMCPageState extends State with TickerProviderStateMixin { PageController _controller; int _currentIndex = 1; @@ -46,7 +47,8 @@ class _NewCMCPageState extends State price: widget.model.cmcAllServicesList[0].price, serviceID: widget.model.cmcAllServicesList[0].serviceID.toString(), selectedServiceName: widget.model.cmcAllServicesList[0].description, - selectedServiceNameAR: widget.model.cmcAllServicesList[0].description, + selectedServiceNameAR: + widget.model.cmcAllServicesList[0].descriptionN, recordID: 1, totalPrice: widget.model.cmcAllServicesList[0].totalPrice, vAT: widget.model.cmcAllServicesList[0].vAT); @@ -85,6 +87,8 @@ class _NewCMCPageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + void showConfirmMessage( CMCViewModel model, GetOrderDetailByOrderIDResponseModel order) { showDialog( @@ -93,20 +97,24 @@ class _NewCMCPageState extends State model: model, onTap: () async { UpdatePresOrderRequestModel updatePresOrderRequestModel = - UpdatePresOrderRequestModel( - presOrderID: order.presOrderID, - rejectionReason: "", - presOrderStatus: 4, editedBy: 3); + UpdatePresOrderRequestModel( + presOrderID: order.presOrderID, + rejectionReason: "", + presOrderStatus: 4, + editedBy: 3); await model.updateCmcPresOrder(updatePresOrderRequestModel); if (model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast(message: "Done Successfully"); + AppToast.showSuccessToast( + message: + TranslationBase.of(context).processDoneSuccessfully); await model.getCmcAllPresOrders(); } }, )); } + return Scaffold( body: SafeArea( child: SingleChildScrollView( @@ -114,13 +122,16 @@ class _NewCMCPageState extends State height: MediaQuery.of(context).size.height * 0.8, child: Column( children: [ - Container( - margin: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.05, right: MediaQuery.of(context).size.width*0.05), - child: StepsWidget( - index: _currentIndex, - changeCurrentTab: changePageViewIndex, + if (widget.model.cmcAllOrderDetail.length == 0) + Container( + margin: EdgeInsets.only( + left: MediaQuery.of(context).size.width * 0.05, + right: MediaQuery.of(context).size.width * 0.05), + child: StepsWidget( + index: _currentIndex, + changeCurrentTab: changePageViewIndex, + ), ), - ), Expanded( child: PageView( physics: NeverScrollableScrollPhysics(), @@ -134,203 +145,255 @@ class _NewCMCPageState extends State children: [ widget.model.cmcAllOrderDetail.length != 0 ? FractionallySizedBox( - heightFactor: 0.8, - widthFactor: 0.9, - child: Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), + widthFactor: 0.9, + child: SingleChildScrollView( child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, children: [ - Texts( - "Request ID", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - widget.model.cmcAllOrderDetail[0].iD.toString(), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, + Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey, width: 1), + borderRadius: + BorderRadius.circular(12), + color: + Theme.of(context).primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, + bottom: 15, + top: 15, + right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, + ), + ), + // borderRadius: BorderRadius.circular(12), + color: Theme.of(context) + .primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .requestID, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + widget.model + .cmcAllOrderDetail[0].iD + .toString(), + fontSize: 22, + ), + ], + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, + bottom: 15, + top: 15, + right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, + ), + ), + // borderRadius: BorderRadius.circular(12), + color: Theme.of(context) + .primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .OrderStatus, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + projectViewModel.isArabic + ? widget + .model + .cmcAllOrderDetail[0] + .descriptionN + : widget + .model + .cmcAllOrderDetail[0] + .description, + fontSize: 22, + ), + ], + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, + bottom: 15, + top: 15, + right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, + ), + ), + // borderRadius: BorderRadius.circular(12), + color: Theme.of(context) + .primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .pickupDate, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate( + widget + .model + .cmcAllOrderDetail[ + 0] + .createdOn)), + fontSize: 22, + ), + ], + ), + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 15, top: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, + ), + ), + // borderRadius: BorderRadius.circular(12), + color: Theme.of(context) + .primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .serviceName, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + !projectViewModel.isArabic + ? widget + .model + .cmcAllOrderDetail[0] + .description + .toString() + : widget + .model + .cmcAllOrderDetail[0] + .descriptionN + .toString(), + fontSize: 22, + ), + ], + ), + ), + SizedBox( + height: 12, + ), + Center( + child: Container( + width: MediaQuery.of(context) + .size + .width * + 0.85, + child: SecondaryButton( + label: TranslationBase.of( + context) + .cancel + .toUpperCase(), + onTap: () { + showConfirmMessage( + widget.model, + widget.model + .cmcAllOrderDetail[0]); + }, + color: Colors.red[800], + disabled: false, + textColor: Theme.of(context) + .backgroundColor), + ), + ), + SizedBox( + height: 22, + ), + ], ), ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Status", - bold: false, - fontSize: 13, - ), SizedBox( - height: 4, - ), - Texts( - "Pending", - fontSize: 22, + height: 22, ), ], ), ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Pickup Date", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - widget.model.cmcAllOrderDetail[0] - .createdOn)), - fontSize: 22, - ), - ], - ), - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Service Name", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - widget.model.cmcAllOrderDetail[0].description - .toString() ?? - widget.model.cmcAllOrderDetail[0] - .descriptionN - .toString(), - fontSize: 22, - ), - ], - ), - ), - SizedBox( - height: 12, - ), - Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: "Cancel".toUpperCase(), - onTap: () { - showConfirmMessage(widget.model, - widget.model.cmcAllOrderDetail[0]); - } - , - color: Colors.red[800], - disabled: false, - textColor: Theme - .of(context) - .backgroundColor), - ), - ), - SizedBox( - height: 12, - ), - ], - ), - ), - ) + ) : NewCMCStepOnePage( - changePageViewIndex: changePageViewIndex, - cMCInsertPresOrderRequestModel: - cMCInsertPresOrderRequestModel, - model: widget.model, - ), + changePageViewIndex: changePageViewIndex, + cMCInsertPresOrderRequestModel: + cMCInsertPresOrderRequestModel, + model: widget.model, + ), NewCMCStepTowPage( longitude: _longitude, latitude: _latitude, changePageViewIndex: changePageViewIndex, - cmcInsertPresOrderRequestModel: cMCInsertPresOrderRequestModel, + cmcInsertPresOrderRequestModel: + cMCInsertPresOrderRequestModel, model: widget.model, - ), NewCMCStepThreePage( + ), + NewCMCStepThreePage( changePageViewIndex: changePageViewIndex, - cmcInsertPresOrderRequestModel: cMCInsertPresOrderRequestModel, + cmcInsertPresOrderRequestModel: + cMCInsertPresOrderRequestModel, model: widget.model, ), ], diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart index 02d099b4..c07b8345 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_one_page.dart @@ -1,11 +1,16 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_get_items_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.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 NewCMCStepOnePage extends StatefulWidget { final CMCInsertPresOrderRequestModel cMCInsertPresOrderRequestModel; @@ -31,6 +36,8 @@ class _NewCMCStepOnePageState extends State { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( isShowAppBar: false, baseViewModel: widget.model, @@ -50,7 +57,7 @@ class _NewCMCStepOnePageState extends State { height: 20, ), Texts( - "Select Home Health Care Services", + TranslationBase.of(context).selectService, textAlign: TextAlign.center, ), Column( @@ -62,7 +69,7 @@ class _NewCMCStepOnePageState extends State { border: Border.all(color: Colors.grey, width: 1), borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Column( children: [ Row( @@ -80,7 +87,7 @@ class _NewCMCStepOnePageState extends State { selectedServiceName: service.description, selectedServiceNameAR: - service.description, + service.descriptionN, recordID: 1, totalPrice: service.totalPrice, @@ -115,7 +122,9 @@ class _NewCMCStepOnePageState extends State { child: Padding( padding: const EdgeInsets.all(20.0), child: Texts( - service.description, + projectViewModel.isArabic + ? service.descriptionN + : service.description, fontSize: 15, ), ), @@ -134,55 +143,75 @@ class _NewCMCStepOnePageState extends State { height: 30, ), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, width: double.infinity, child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: widget.model.checkupItems.map((item) { - return Center( - child: FractionallySizedBox( - widthFactor: 1, - child: Container( - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration(color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 5, top: 5), - decoration: BoxDecoration( - border: BorderDirectional( - bottom: BorderSide( - style: BorderStyle.solid, - width: 0.5, - color: Colors.grey)), - //borderRadius: , - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - item.itemName, - fontSize: 15, + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 10, left: 10), + child: Texts( + TranslationBase.of(context).coveredService, + fontWeight: FontWeight.bold, + )) + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: widget.model.checkupItems.map((item) { + return Center( + child: FractionallySizedBox( + widthFactor: 1, + child: Container( + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 5, top: 5), + decoration: BoxDecoration( + border: BorderDirectional( + bottom: BorderSide( + style: BorderStyle.solid, + width: 0.5, + color: Colors.grey)), + //borderRadius: , + color: + Theme.of(context).primaryColor), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only( + right: 10, left: 10), + child: Texts(item.itemName, + fontSize: 15, + fontWeight: FontWeight.bold), + ), + ], ), - ], - ), - ), - SizedBox( - height: 12, + ), + SizedBox( + height: 12, + ), + ], ), - ], + ), ), - ), - ), - ); - }).toList()), + ); + }).toList()), + ], + ), ) ], ), @@ -197,28 +226,45 @@ class _NewCMCStepOnePageState extends State { Container( width: MediaQuery.of(context).size.width * 0.9, child: SecondaryButton( - label: "Next", + label: TranslationBase.of(context).next, textColor: Theme.of(context).backgroundColor, - onTap: () { - if (widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList.length = null) { + color: Colors.grey[800], + onTap: () async { + if (widget.cMCInsertPresOrderRequestModel + .patientERCMCInsertServicesList.length != + 0 || + widget.cMCInsertPresOrderRequestModel + .patientERCMCInsertServicesList == + null) { int index = widget.model.cmcAllServicesList.length; PatientERCMCInsertServicesList patientERCMCInsertServicesList = new PatientERCMCInsertServicesList( - price: widget.model.cmcAllServicesList[index-1].price, - serviceID: widget.model.cmcAllServicesList[index-1].serviceID.toString(), - selectedServiceName: widget.model.cmcAllServicesList[index-1].description, - selectedServiceNameAR: widget.model.cmcAllServicesList[index-1].description, + price: widget + .model.cmcAllServicesList[index - 1].price, + serviceID: widget + .model.cmcAllServicesList[index - 1].serviceID + .toString(), + selectedServiceName: widget.model + .cmcAllServicesList[index - 1].description, + selectedServiceNameAR: widget.model + .cmcAllServicesList[index - 1].descriptionN, recordID: 1, - totalPrice: widget.model.cmcAllServicesList[index-1].totalPrice, - vAT: widget.model.cmcAllServicesList[index-1].vAT); + totalPrice: widget + .model.cmcAllServicesList[index - 1].totalPrice, + vAT: + widget.model.cmcAllServicesList[index - 1].vAT); widget.cMCInsertPresOrderRequestModel .patientERCMCInsertServicesList = [ patientERCMCInsertServicesList ]; - - widget.changePageViewIndex(1); + await widget.model.getCustomerInfo(); + if (widget.model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(); + } else { + widget.changePageViewIndex(1); + } } }, ), diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart index e48bb5d5..75699a5c 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_three_page.dart @@ -2,15 +2,16 @@ import 'dart:async'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:provider/provider.dart'; class NewCMCStepThreePage extends StatefulWidget { final CMCInsertPresOrderRequestModel cmcInsertPresOrderRequestModel; @@ -21,15 +22,13 @@ class NewCMCStepThreePage extends StatefulWidget { {Key key, this.changePageViewIndex, this.model, - this.cmcInsertPresOrderRequestModel}); + this.cmcInsertPresOrderRequestModel}); @override - _NewCMCStepThreePageState createState() => - _NewCMCStepThreePageState(); + _NewCMCStepThreePageState createState() => _NewCMCStepThreePageState(); } -class _NewCMCStepThreePageState - extends State { +class _NewCMCStepThreePageState extends State { Completer _controller = Completer(); static CameraPosition _kGooglePlex = CameraPosition( @@ -48,8 +47,7 @@ class _NewCMCStepThreePageState widget.cmcInsertPresOrderRequestModel.latitude.hashCode .toString(), ), - position: LatLng( - widget.cmcInsertPresOrderRequestModel.latitude, + position: LatLng(widget.cmcInsertPresOrderRequestModel.latitude, widget.cmcInsertPresOrderRequestModel.longitude)), ); _kGooglePlex = CameraPosition( @@ -63,31 +61,38 @@ class _NewCMCStepThreePageState @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: false, baseViewModel: widget.model, body: SingleChildScrollView( physics: BouncingScrollPhysics(), child: Container( - height: 400, + height: 500, width: double.maxFinite, margin: EdgeInsets.only(left: 12, right: 12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Order Details'), + Texts( + TranslationBase.of(context).orderDetails, + fontWeight: FontWeight.bold, + ), SizedBox( height: 12, ), Container( decoration: BoxDecoration( - color: Colors.white, + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(12)), padding: EdgeInsets.all(8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Location :'), + Texts( + TranslationBase.of(context).orderLocation + " : ", + fontWeight: FontWeight.bold, + ), SizedBox( height: 12, ), @@ -108,24 +113,32 @@ class _NewCMCStepThreePageState SizedBox( height: 12, ), - Texts('Selected Service :'), + Texts(TranslationBase.of(context).selectedService), ...List.generate( - widget.cmcInsertPresOrderRequestModel.patientERCMCInsertServicesList.length, + widget.cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList.length, (index) => Container( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - 'Service Name :', + TranslationBase.of(context).serviceName, fontSize: 12, + fontWeight: FontWeight.bold, ), SizedBox( height: 5, ), Texts( - widget - .cmcInsertPresOrderRequestModel.patientERCMCInsertServicesList[index] - .selectedServiceName, + projectViewModel.isArabic + ? widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList[index] + .selectedServiceNameAR + : widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList[index] + .selectedServiceName, fontSize: 15, bold: true, ), @@ -148,9 +161,11 @@ class _NewCMCStepThreePageState Container( width: MediaQuery.of(context).size.width * 0.9, child: SecondaryButton( - label: "Confirm", + label: TranslationBase.of(context).confirm, + color: Colors.grey[800], onTap: () async { - await widget.model.insertPresPresOrder(order: widget.cmcInsertPresOrderRequestModel); + await widget.model.insertPresPresOrder( + order: widget.cmcInsertPresOrderRequestModel); if (widget.model.state != ViewState.ErrorLocal) { widget.changePageViewIndex(0); } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart index 27cddfe3..3d969d9e 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_step_tow_page.dart @@ -1,19 +1,23 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_insert_pres_order_request_model.dart'; -import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/close_back.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:google_maps_place_picker/google_maps_place_picker.dart'; import 'package:provider/provider.dart'; +import 'cmc_location_page.dart'; + class NewCMCStepTowPage extends StatefulWidget { final Function(PickResult) onPick; final double latitude; @@ -33,20 +37,18 @@ class NewCMCStepTowPage extends StatefulWidget { : super(key: key); @override - _NewCMCStepTowPageState createState() => - _NewCMCStepTowPageState(); + _NewCMCStepTowPageState createState() => _NewCMCStepTowPageState(); } -class _NewCMCStepTowPageState - extends State { +class _NewCMCStepTowPageState extends State { double latitude = 0; double longitude = 0; + AddressInfo _selectedAddress; @override void initState() { if (widget.cmcInsertPresOrderRequestModel.latitude == null) { - latitude = widget.latitude; - longitude = widget.longitude; + setLatitudeAndLongitude(); } else { latitude = widget.cmcInsertPresOrderRequestModel.latitude; longitude = widget.cmcInsertPresOrderRequestModel.longitude; @@ -54,60 +56,150 @@ class _NewCMCStepTowPageState super.initState(); } + setLatitudeAndLongitude({bool isSetState = false, String latLong}) { + if (latLong == null) + latLong = widget + .model.addressesList[widget.model.addressesList.length - 1].latLong; + List latLongArr = latLong.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: false, - body: PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - widget.changePageViewIndex(3); - }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.cmcInsertPresOrderRequestModel - .latitude = - selectedPlace.geometry.location.lat; - widget.cmcInsertPresOrderRequestModel - .longitude = - selectedPlace.geometry.location.lng; - }); - widget.changePageViewIndex(3); - }, - label: TranslationBase.of(context).next, - ), - ), - ); + body: Stack( + children: [ + PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + widget.changePageViewIndex(3); + }, + selectedPlaceWidgetBuilder: + (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: Column( + children: [ + SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + Navigator.push( + context, + FadePage( + page: CMCLocationPage( + latitude: latitude, + longitude: longitude, + ), + ), + ); + }, + label: TranslationBase.of(context) + .addNewAddress, + ), + SizedBox( + height: 10, + ), + SecondaryButton( + color: Colors.red[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.cmcInsertPresOrderRequestModel + .latitude = + selectedPlace.geometry.location.lat; + widget.cmcInsertPresOrderRequestModel + .longitude = + selectedPlace.geometry.location.lng; + }); + widget.changePageViewIndex(3); + }, + label: TranslationBase.of(context).confirm, + ), + ], + )), + ); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: false, + ), + Container( + child: InkWell( + onTap: () => + confirmSelectLocationDialog(widget.model.addressesList), + child: Container( + padding: EdgeInsets.all(10), + width: double.infinity, + // height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Theme.of(context).primaryColor), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Texts( + getAddressName(), + fontSize: 14, + ), + ), + Icon(Icons.arrow_drop_down) + ], + ), + ), + ), + height: 56, + width: double.infinity, + color: Theme.of(context).scaffoldBackgroundColor, + ) + ], + ), + ); + } + + void confirmSelectLocationDialog(List addresses) { + showDialog( + context: context, + child: SelectLocationDialog( + addresses: addresses, + selectedAddress: _selectedAddress, + onValueSelected: (value) { + setLatitudeAndLongitude(latLong: value.latLong); + setState(() { + _selectedAddress = value; + }); }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: true, ), ); } + + String getAddressName() { + if (_selectedAddress != null) + return _selectedAddress.address1; + else + return TranslationBase.of(context).selectAddress; + } } diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart deleted file mode 100644 index e8e9eccc..00000000 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; -import 'cmc_page.dart'; - -class CMCIndexPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).serviceInformation, - body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "CMC", - fontWeight: FontWeight.normal, - fontSize: 25, - color: Color(0xff60686b), - ), - SizedBox( - height: 12, - ), - Texts( - "This service is designed to help you to set drinking water goals and track the volume of water you are drinking on a daily basis. This service allows for schedule reminders and offers a basic statistical analysis of the amount of what you have consumed over the course of a day, week or month.", - fontWeight: FontWeight.normal, - fontSize: 17, - ), - SizedBox( - height: 22, - ), - Center( - child: Image.asset( - 'assets/images/AlHabibMedicalService/Wifi-AR.png')), - SizedBox( - height: 77, - ), - ], - )), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () => Navigator.push( - context, - FadePage( - page: CMCPage(), - ), - ), - label: "CMC", - textColor: Theme.of(context).backgroundColor), - ), - ], - ), - )); - } -} diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart index 385d0da3..f1d3e72f 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -16,8 +17,7 @@ class CMCPage extends StatefulWidget { _CMCPageState createState() => _CMCPageState(); } -class _CMCPageState extends State - with SingleTickerProviderStateMixin { +class _CMCPageState extends State with SingleTickerProviderStateMixin { TabController _tabController; @override @@ -35,12 +35,19 @@ class _CMCPageState extends State @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model){ - model.getCmcAllPresOrders(); + onModelReady: (model) async { + await model.getCmcAllPresOrders(); }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).homeHealthCare, + description: TranslationBase.of(context).infoCMC, + imagesInfo: [ + ImagesInfo( + imageAr: 'assets/images/Wifi-AR.png', + imageEn: 'assets/images/wifi-EN.png', + isAsset: true) + ], + appBarTitle: TranslationBase.of(context).comprehensiveMedicalCheckup, body: Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( @@ -54,9 +61,7 @@ class _CMCPageState extends State child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), + color: Theme.of(context).primaryColor.withOpacity(0.8), height: 70.0, ), ), @@ -72,29 +77,31 @@ class _CMCPageState extends State color: Theme.of(context).dividerColor, width: 0.7), ), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Center( child: TabBar( isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, indicatorColor: Colors.red[800], labelColor: Theme.of(context).primaryColor, labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), + EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), unselectedLabelColor: Colors.grey[800], tabs: [ Container( width: MediaQuery.of(context).size.width * 0.37, child: Center( - child: Texts("CMC Service"), + child: Texts(TranslationBase.of(context) + .comprehensiveMedicalCheckup), ), ), Container( width: MediaQuery.of(context).size.width * 0.37, child: Center( - child: Texts(TranslationBase.of(context).orderLog), + child: + Texts(TranslationBase.of(context).orderLog), ), ), ], diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart index 6c915a4c..ec686e70 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/orders_log_details_page.dart @@ -2,13 +2,16 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/cmc_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'Dialog/confirm_cancel_order_dialog.dart'; @@ -19,6 +22,9 @@ class OrdersLogDetailsPage extends StatelessWidget { @override Widget build(BuildContext context) { + + ProjectViewModel projectViewModel = Provider.of(context); + void showConfirmMessage( CMCViewModel model, GetHHCAllPresOrdersResponseModel order) { showDialog( @@ -35,7 +41,7 @@ class OrdersLogDetailsPage extends StatelessWidget { if(model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast(message: "Done Successfully"); + AppToast.showSuccessToast(message:TranslationBase.of(context).processDoneSuccessfully ); await model.getCmcAllPresOrders(); } }, @@ -78,7 +84,7 @@ class OrdersLogDetailsPage extends StatelessWidget { Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, bottom: 15, top: 15,right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -89,11 +95,12 @@ class OrdersLogDetailsPage extends StatelessWidget { // borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Request ID", + TranslationBase + .of(context) + .requestID, bold: false, fontSize: 13, ), @@ -110,7 +117,7 @@ class OrdersLogDetailsPage extends StatelessWidget { Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, bottom: 15, top: 15,right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -121,11 +128,12 @@ class OrdersLogDetailsPage extends StatelessWidget { // borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Status", + TranslationBase + .of(context) + .OrderStatus, bold: false, fontSize: 13, ), @@ -133,7 +141,9 @@ class OrdersLogDetailsPage extends StatelessWidget { height: 4, ), Texts( - order.description, + + projectViewModel.isArabic ? order + .descriptionN : order.description, fontSize: 22, ), ], @@ -142,7 +152,7 @@ class OrdersLogDetailsPage extends StatelessWidget { Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, bottom: 15, top: 15,right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -153,11 +163,10 @@ class OrdersLogDetailsPage extends StatelessWidget { // borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Pickup Date", + TranslationBase.of(context).pickupDate, bold: false, fontSize: 13, ), @@ -166,8 +175,7 @@ class OrdersLogDetailsPage extends StatelessWidget { ), Texts( DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - order.createdOn)), + DateUtil.convertStringToDate(order.createdOn)), fontSize: 22, ), ], @@ -176,7 +184,7 @@ class OrdersLogDetailsPage extends StatelessWidget { Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, bottom: 15, top: 15,right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -191,7 +199,7 @@ class OrdersLogDetailsPage extends StatelessWidget { CrossAxisAlignment.start, children: [ Texts( - "Location", + TranslationBase.of(context).orderLocation, bold: false, fontSize: 13, ), @@ -199,10 +207,11 @@ class OrdersLogDetailsPage extends StatelessWidget { height: 4, ), Texts( - order.nearestProjectDescription - .toString() ?? - order.nearestProjectDescriptionN - .toString(), + !projectViewModel.isArabic?order. + projectDescription.toString() : + order + .projectDescriptionN + .toString(), fontSize: 22, ), ], @@ -212,32 +221,33 @@ class OrdersLogDetailsPage extends StatelessWidget { height: 12, ), if (order.status == 1 ||order.status == 2 ) - Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: "Cancel".toUpperCase(), - onTap: () { - showConfirmMessage(model, order); - } - , - color: Colors.red[800], - disabled: false, - textColor: Theme - .of(context) - .backgroundColor), - ), + Center( + child: Container( + width: MediaQuery + .of(context) + .size + .width * + 0.85, + child: SecondaryButton( + label: TranslationBase.of(context).cancel.toUpperCase(), + onTap: () { + showConfirmMessage(model, + order); + } + , + color: Colors.red[800], + disabled: false, + textColor: Theme + .of(context) + .backgroundColor), ), + ), SizedBox( - height: 12, - ), - ], - ), - ); + height: 22, + ), + ], + ), + ); }).toList()) ], ), diff --git a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart index f714bfb9..d58fd29f 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/dialogs/select_country_ingo_Dialog.dart @@ -1481,52 +1481,62 @@ class _SelectCountryDialogState extends State { @override Widget build(BuildContext context) { - return SimpleDialog( + return SimpleDialog( children: [ Column( children: [ Divider(), - ...List.generate( - countryList.length, - (index) => Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 2, - ), - Row( - children: [ - Expanded( - flex: 1, - child: InkWell( - onTap: () { - setState(() { - widget.selectedCountry = countryList[index]; - }); - }, - child: ListTile( - title: Text(countryList[index]["name"]), - leading: Radio( - value: countryList[index], - groupValue: widget.selectedCountry, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - widget.selectedCountry = value; - }); - }, - ), + Container( + height: MediaQuery.of(context).size.height * 0.60, + child: SingleChildScrollView( + child: Column( + children: [ + ...List.generate( + countryList.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 2, ), - ), - ) - ], - ), - SizedBox( - height: 5.0, - ), - ], - ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + widget.selectedCountry = countryList[index]; + }); + }, + child: ListTile( + title: Text(countryList[index]["name"]), + leading: Radio( + value: countryList[index], + groupValue: widget.selectedCountry, + activeColor: Colors.red[800], + onChanged: (value) { + setState(() { + widget.selectedCountry = value; + }); + }, + ), + ), + ), + ) + ], + ), + SizedBox( + height: 5.0, + ), + ], + ), + ), + ], + ), + ) ), + SizedBox( height: 5.0, ), diff --git a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_index_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_index_page.dart deleted file mode 100644 index c837bd2a..00000000 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_index_page.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/viewModels/qr_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/CarouselSlider.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -import '../../../d_q_icons_icons.dart'; -import 'e_referral_page.dart'; - -class EReferralIndexPage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).serviceInformation, - body: SingleChildScrollView( - padding: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - "E-Referral: ", - fontWeight: FontWeight.normal, - fontSize: 25, - color: HexColor("#60686b"), - ), - SizedBox( - height: 12, - ), - Texts( - "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, By filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", - fontWeight: FontWeight.normal, - fontSize: 17, - ), - SizedBox( - height: 22, - ), - Center( - child: SizedBox( - height: MediaQuery.of(context).size.height * 0.55, - width: MediaQuery.of(context).size.width * 0.50, - child: CarouselSlider( - imagesUrlList: [ - "https://hmgwebservices.com/Images/MobileApp/images-info-home/referal/en/0.png", - "https://hmgwebservices.com/Images/MobileApp/images-info-home/referal/en/1.png" - ], - ), - ), - ), - SizedBox( - height: 77, - ), - ], - )), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.10, - width: double.infinity, - child: Column( - children: [ - Container( - width: MediaQuery.of(context).size.width * 0.9, - child: SecondaryButton( - onTap: () => Navigator.push( - context, FadePage(page: EReferralPage())), - label: "E-Referral", - textColor: Theme.of(context).backgroundColor), - ), - ], - ), - )); - } -} diff --git a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart index 9f836860..590d1cf1 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/prescriptions_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/New_E_Referral/new_e_referral_index_page.dart'; @@ -38,19 +39,27 @@ class _EReferralPageState extends State @override Widget build(BuildContext context) { return BaseView( - builder: (_, model, widget) => AppScaffold( - isShowAppBar: true, - appBarTitle: "E-Referral", - body: Scaffold( - extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(65.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, + builder: (_, model, widget) => + AppScaffold( + isShowAppBar: true, + appBarTitle: "E-Referral", + description: "This service allows you to submit a Referral request from any health care providers either inside or outside the kingdom of Saudi Arabia to any of HMG Hospitals, By filling some of the patient's data and attaching the medical reports, moreover you can track the request status (Under process, Accepted or Rejected)", + imagesInfo: [ + ImagesInfo( + imageAr: 'assets/images/Wifi-AR.png', + imageEn: 'assets/images/wifi-EN.png', + isAsset: true) + ], + body: Scaffold( + extendBodyBehindAppBar: true, + appBar: PreferredSize( + preferredSize: Size.fromHeight(65.0), + child: Stack( + children: [ + Positioned( + bottom: 1, + left: 0, + right: 0, child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Container( @@ -78,7 +87,7 @@ class _EReferralPageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, indicatorColor: Colors.red[800], labelColor: Theme.of(context).primaryColor, labelPadding: diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart index 17be8edd..bfab0324 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart @@ -29,7 +29,7 @@ class _ConfirmCancelOrderDialogState extends State { contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), title: Center( child: Texts( - "Confirm", + TranslationBase.of(context).confirm, color: Colors.black, ), ), @@ -39,7 +39,7 @@ class _ConfirmCancelOrderDialogState extends State { Divider(), Center( child: Texts( - "Are you sure!! want to cancel this order", + TranslationBase.of(context).cancelOrderMsg , color: Colors.grey, ), ), diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart new file mode 100644 index 00000000..c87a3eb5 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart @@ -0,0 +1,148 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:provider/provider.dart'; + +class LocationPage extends StatefulWidget { + final Function(PickResult) onPick; + final double latitude; + final double longitude; + final dynamic model; + + const LocationPage({Key key, this.onPick, this.latitude, this.longitude, this.model}) + : super(key: key); + + @override + _LocationPageState createState() => + _LocationPageState(); +} + +class _LocationPageState + extends State { + double latitude = 0; + double longitude = 0; + + @override + void initState() { + + latitude = widget.latitude; + longitude = widget.longitude; + super.initState(); + } + + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) {}, + builder: (_, model, widget) => AppScaffold( + appBarTitle: TranslationBase.of(context).addAddress, + isShowDecPage: false, + isShowAppBar: true, + baseViewModel: model, + body: PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + onPlacePicked: (PickResult result) { + print(result.adrAddress); + + }, + selectedPlaceWidgetBuilder: + (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: Column( + children: [ + SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () async { + AddNewAddressRequestModel + addNewAddressRequestModel = + new AddNewAddressRequestModel( + customer: Customer(addresses: [ + Addresses( + address1: + selectedPlace.formattedAddress, + address2: selectedPlace + .formattedAddress, + customerAttributes: "", + city: "", + createdOnUtc: "", + id: 0, + latLong: "$latitude,$longitude", + email: "") + ]), + ); + + selectedPlace.addressComponents.forEach((e) { + if (e.types.contains("country")) { + addNewAddressRequestModel.customer + .addresses[0].country = e.longName; + } + if (e.types.contains("postal_code")) { + addNewAddressRequestModel.customer + .addresses[0].zipPostalCode = + e.longName; + } + if (e.types.contains("locality")) { + addNewAddressRequestModel.customer + .addresses[0].city = + e.longName; + } + }); + + + await model.addAddressInfo( + addNewAddressRequestModel: addNewAddressRequestModel); + if (model.state == ViewState.ErrorLocal) { + Utils.showErrorToast(model.error); + } else { + AppToast.showSuccessToast( + message: "Address Added Successfully"); + } + Navigator.of(context).pop(addNewAddressRequestModel); + }, + label: TranslationBase.of(context).addNewAddress, + ), + ], + ), + ), + ); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: false, + ), + )); + } +} diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart index 1dbee1b5..86ee791b 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_one_page.dart @@ -2,15 +2,16 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/PatientERHHCInsertServicesList.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:geolocator/geolocator.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; +import 'package:provider/provider.dart'; class NewHomeHealthCareStepOnePage extends StatefulWidget { final PatientERInsertPresOrderRequestModel @@ -30,21 +31,24 @@ class NewHomeHealthCareStepOnePage extends StatefulWidget { _NewHomeHealthCareStepOnePageState(); } -class _NewHomeHealthCareStepOnePageState extends State { - +class _NewHomeHealthCareStepOnePageState + extends State { PickResult _result; - @override void initState() { - if (widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList == null) - widget.patientERInsertPresOrderRequestModel.patientERHHCInsertServicesList = []; + if (widget.patientERInsertPresOrderRequestModel + .patientERHHCInsertServicesList == + null) + widget.patientERInsertPresOrderRequestModel + .patientERHHCInsertServicesList = []; super.initState(); } - @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( isShowAppBar: false, baseViewModel: widget.model, @@ -64,7 +68,7 @@ class _NewHomeHealthCareStepOnePageState extends State { double latitude = 0; double longitude = 0; + AddressInfo _selectedAddress; @override void initState() { if (widget.patientERInsertPresOrderRequestModel.latitude == null) { - latitude = widget.latitude; - longitude = widget.longitude; + setLatitudeAndLongitude(); } else { latitude = widget.patientERInsertPresOrderRequestModel.latitude; longitude = widget.patientERInsertPresOrderRequestModel.longitude; } + super.initState(); } + setLatitudeAndLongitude({bool isSetState = false, String latLong}) { + if (latLong == null) + latLong = widget.model.addressesList[widget.model.addressesList + .length - 1].latLong; + List latLongArr = latLong.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + } + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( isShowDecPage: false, - body: PlacePicker( - apiKey: GOOGLE_API_KEY, - enableMyLocationButton: true, - automaticallyImplyAppBarLeading: false, - autocompleteOnTrailingWhitespace: true, - selectInitialPosition: true, - autocompleteLanguage: projectViewModel.currentLanguage, - enableMapTypeButton: true, - onPlacePicked: (PickResult result) { - print(result.adrAddress); - widget.changePageViewIndex(3); - }, - selectedPlaceWidgetBuilder: - (_, selectedPlace, state, isSearchBarFocused) { - print("state: $state, isSearchBarFocused: $isSearchBarFocused"); - return isSearchBarFocused - ? Container() - : FloatingCard( - bottomPosition: 0.0, - leftPosition: 0.0, - rightPosition: 0.0, - width: 500, - borderRadius: BorderRadius.circular(12.0), - child: state == SearchingState.Searching - ? Center(child: CircularProgressIndicator()) - : Container( - margin: EdgeInsets.all(12), - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.patientERInsertPresOrderRequestModel - .latitude = - selectedPlace.geometry.location.lat; - widget.patientERInsertPresOrderRequestModel - .longitude = - selectedPlace.geometry.location.lng; - }); - widget.changePageViewIndex(3); - }, - label: TranslationBase.of(context).next, - ), - ), - ); + body: Stack( + children: [ + PlacePicker( + apiKey: GOOGLE_API_KEY, + enableMyLocationButton: true, + automaticallyImplyAppBarLeading: false, + autocompleteOnTrailingWhitespace: true, + selectInitialPosition: true, + autocompleteLanguage: projectViewModel.currentLanguage, + enableMapTypeButton: true, + searchForInitialValue: false, + + onPlacePicked: (PickResult result) { + print(result.adrAddress); + widget.changePageViewIndex(3); + }, + selectedPlaceWidgetBuilder: + (_, selectedPlace, state, isSearchBarFocused) { + print("state: $state, isSearchBarFocused: $isSearchBarFocused"); + return isSearchBarFocused + ? Container() + : FloatingCard( + bottomPosition: 0.0, + leftPosition: 0.0, + rightPosition: 0.0, + width: 500, + borderRadius: BorderRadius.circular(12.0), + child: state == SearchingState.Searching + ? Center(child: CircularProgressIndicator()) + : Container( + margin: EdgeInsets.all(12), + child: Column( + children: [ + SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + Navigator.push( + context, + FadePage( + page: + LocationPage( + latitude: latitude, + longitude: longitude, + ), + ), + ); + }, + label: TranslationBase.of(context).addNewAddress, + ), + SizedBox(height: 10,), + SecondaryButton( + color: Colors.red[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.patientERInsertPresOrderRequestModel + .latitude = + selectedPlace.geometry.location.lat; + widget.patientERInsertPresOrderRequestModel + .longitude = + selectedPlace.geometry.location.lng; + }); + widget.changePageViewIndex(3); + }, + label: TranslationBase.of(context).confirm, + ), + ], + ), + ), + ); + }, + initialPosition: LatLng(latitude, longitude), + useCurrentLocation: false, + ), + Container( + child: InkWell( + onTap: () => + confirmSelectLocationDialog(widget.model.addressesList), + child: Container( + padding: EdgeInsets.all(10), + width: double.infinity, + // height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Colors.white), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Texts(getAddressName(), fontSize: 14,),), + Icon(Icons.arrow_drop_down) + ], + ), + ), + ), + height: 56, width: double.infinity, color: Theme + .of(context) + .scaffoldBackgroundColor, + + ) + ], + ), + ); + } + + + void confirmSelectLocationDialog(List addresses) { + showDialog( + context: context, + child: SelectLocationDialog( + addresses: addresses, + selectedAddress: _selectedAddress + , + onValueSelected: (value) { + setLatitudeAndLongitude(latLong: value.latLong); + setState(() { + _selectedAddress = value; + }); }, - initialPosition: LatLng(latitude, longitude), - useCurrentLocation: true, ), ); } + + String getAddressName() { + if (_selectedAddress != null) + return _selectedAddress.address1; + else + return TranslationBase.of(context).selectAddress; + } } diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart index 87a33c6d..ab564cb7 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_home_health_care_page.dart @@ -3,16 +3,19 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealth import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/patient_er_insert_pres_order_request_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/Dialog/confirm_cancel_order_dialog.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_three_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/new_Home_health_care_step_tow_page.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:provider/provider.dart'; import '../StepsWidget.dart'; import 'new_Home_health_care_step_one_page.dart'; @@ -42,15 +45,15 @@ class _NewHomeHealthCarePageState extends State _getCurrentLocation(); } - _getCurrentLocation() async { - await getLastKnownPosition().then((value) { - _latitude = value.latitude; - _longitude = value.longitude; - }).catchError((e) { - _longitude = 0; - _latitude = 0; - }); - } + _getCurrentLocation() async { + await getLastKnownPosition().then((value) { + _latitude = value.latitude; + _longitude = value.longitude; + }).catchError((e) { + _longitude = 0; + _latitude = 0; + }); + } @override void dispose() { @@ -84,7 +87,9 @@ class _NewHomeHealthCarePageState extends State if (model.state == ViewState.ErrorLocal) { Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast(message: "Done Successfully"); + AppToast.showSuccessToast( + message: + TranslationBase.of(context).processDoneSuccessfully); await model.getHHCAllPresOrders(); // await model.getHHCAllServices(); } @@ -92,6 +97,8 @@ class _NewHomeHealthCarePageState extends State )); } + ProjectViewModel projectViewModel = Provider.of(context); + return Scaffold( body: SafeArea( child: SingleChildScrollView( @@ -99,9 +106,10 @@ class _NewHomeHealthCarePageState extends State height: MediaQuery.of(context).size.height * 0.8, child: Column( children: [ - Container( - margin: EdgeInsets.only(left: MediaQuery.of(context).size.width*0.05, right: MediaQuery.of(context).size.width*0.05), + margin: EdgeInsets.only( + left: MediaQuery.of(context).size.width * 0.05, + right: MediaQuery.of(context).size.width * 0.05), child: StepsWidget( index: _currentIndex, changeCurrentTab: _changeCurrentTab, @@ -126,11 +134,13 @@ class _NewHomeHealthCarePageState extends State width: double.infinity, margin: EdgeInsets.only(top: 15), decoration: BoxDecoration( - border: Border.all(color: Colors.grey, width: 1), + border: Border.all( + color: Colors.grey, width: 1), borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ SizedBox( height: 12, @@ -138,7 +148,10 @@ class _NewHomeHealthCarePageState extends State Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, + bottom: 15, + top: 15, + right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -147,12 +160,15 @@ class _NewHomeHealthCarePageState extends State ), ), // borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: + Theme.of(context).primaryColor), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Texts( - "Request ID", + TranslationBase.of(context) + .requestID, bold: false, fontSize: 13, ), @@ -160,7 +176,8 @@ class _NewHomeHealthCarePageState extends State height: 4, ), Texts( - widget.model.pendingOrder.iD.toString(), + widget.model.pendingOrder.iD + .toString(), fontSize: 22, ), ], @@ -169,7 +186,10 @@ class _NewHomeHealthCarePageState extends State Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, + bottom: 15, + top: 15, + right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -178,12 +198,15 @@ class _NewHomeHealthCarePageState extends State ), ), // borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: + Theme.of(context).primaryColor), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Texts( - "Status", + TranslationBase.of(context) + .OrderStatus, bold: false, fontSize: 13, ), @@ -191,7 +214,11 @@ class _NewHomeHealthCarePageState extends State height: 4, ), Texts( - widget.model.pendingOrder.description, + projectViewModel.isArabic + ? widget.model.pendingOrder + .descriptionN + : widget.model.pendingOrder + .description, fontSize: 22, ), ], @@ -200,7 +227,10 @@ class _NewHomeHealthCarePageState extends State Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, + bottom: 15, + top: 15, + right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -209,12 +239,15 @@ class _NewHomeHealthCarePageState extends State ), ), // borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: + Theme.of(context).primaryColor), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ Texts( - "Pickup Date", + TranslationBase.of(context) + .pickupDate, bold: false, fontSize: 13, ), @@ -222,9 +255,14 @@ class _NewHomeHealthCarePageState extends State height: 4, ), Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate(widget - .model.pendingOrder.createdOn)), + DateUtil + .getDayMonthYearDateFormatted( + DateUtil + .convertStringToDate( + widget + .model + .pendingOrder + .createdOn)), fontSize: 22, ), ], @@ -235,7 +273,10 @@ class _NewHomeHealthCarePageState extends State (index) => Container( width: double.infinity, padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + left: 15, + bottom: 15, + top: 15, + right: 15), decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -244,13 +285,15 @@ class _NewHomeHealthCarePageState extends State ), ), // borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context) + .primaryColor), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Service Name", + TranslationBase.of(context) + .serviceName, bold: false, fontSize: 13, ), @@ -258,8 +301,17 @@ class _NewHomeHealthCarePageState extends State height: 4, ), Texts( - widget.model.hhcAllOrderDetail[index] - .description, + projectViewModel.isArabic + ? widget + .model + .hhcAllOrderDetail[ + index] + .descriptionN + : widget + .model + .hhcAllOrderDetail[ + index] + .description, fontSize: 22, bold: true, ), @@ -272,18 +324,24 @@ class _NewHomeHealthCarePageState extends State ), Center( child: Container( - width: - MediaQuery.of(context).size.width * 0.85, + width: MediaQuery.of(context) + .size + .width * + 0.85, child: SecondaryButton( - label: "Cancel".toUpperCase(), + label: TranslationBase.of(context) + .cancel + .toUpperCase(), onTap: () { - showConfirmMessage(widget.model, - widget.model.hhcAllOrderDetail[0]); + showConfirmMessage( + widget.model, + widget.model + .hhcAllOrderDetail[0]); }, color: Colors.red[800], disabled: false, - textColor: - Theme.of(context).backgroundColor), + textColor: Theme.of(context) + .backgroundColor), ), ), SizedBox( @@ -296,22 +354,24 @@ class _NewHomeHealthCarePageState extends State ) : NewHomeHealthCareStepOnePage( changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: patientERInsertPresOrderRequestModel, + patientERInsertPresOrderRequestModel: + patientERInsertPresOrderRequestModel, model: widget.model, ), NewHomeHealthCareStepTowPage( latitude: _latitude, longitude: _longitude, changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: patientERInsertPresOrderRequestModel, + patientERInsertPresOrderRequestModel: + patientERInsertPresOrderRequestModel, model: widget.model, ), NewHomeHealthCareStepThreePage( changePageViewIndex: _changeCurrentTab, - patientERInsertPresOrderRequestModel: patientERInsertPresOrderRequestModel, + patientERInsertPresOrderRequestModel: + patientERInsertPresOrderRequestModel, model: widget.model, ) - ], ), ), diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart index 8f4821f6..b39c918f 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/all_habib_medical_services/e_referral_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; @@ -36,13 +37,19 @@ class _HomeHealthCarePageState extends State @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model){ - // model.getHHCAllServices(); + onModelReady: (model) { model.getHHCAllPresOrders(); }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + description: TranslationBase.of(context).HHCNotAuthMsg, appBarTitle: TranslationBase.of(context).homeHealthCare, + imagesInfo: [ + ImagesInfo( + imageAr: 'assets/images/Wifi-AR.png', + imageEn: 'assets/images/wifi-EN.png', + isAsset: true) + ], body: Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( @@ -74,29 +81,35 @@ class _HomeHealthCarePageState extends State color: Theme.of(context).dividerColor, width: 0.7), ), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Center( child: TabBar( isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, indicatorColor: Colors.red[800], labelColor: Theme.of(context).primaryColor, labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), + EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), unselectedLabelColor: Colors.grey[800], tabs: [ Container( width: MediaQuery.of(context).size.width * 0.37, child: Center( - child: Texts(TranslationBase.of(context).homeHealthCare), + child: Texts( + TranslationBase.of(context).homeHealthCare, + color: Colors.black, + ), ), ), Container( width: MediaQuery.of(context).size.width * 0.37, child: Center( - child: Texts(TranslationBase.of(context).orderLog), + child: Texts( + TranslationBase.of(context).orderLog, + color: Colors.black, + ), ), ), ], diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart index 0cfedb41..f0ca5fe4 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/orders_log_details_page.dart @@ -2,13 +2,16 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/get_hhc_all_pres_orders_response_model.dart'; import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HomeHealthCare/update_pres_oreder_request_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/home_health_care_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; import 'Dialog/confirm_cancel_order_dialog.dart'; @@ -19,6 +22,8 @@ class OrdersLogDetailsPage extends StatelessWidget { @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + void showConfirmMessage( HomeHealthCareViewModel model, GetHHCAllPresOrdersResponseModel order) { showDialog( @@ -29,212 +34,219 @@ class OrdersLogDetailsPage extends StatelessWidget { UpdatePresOrderRequestModel updatePresOrderRequestModel = UpdatePresOrderRequestModel( presOrderID: order.iD, - rejectionReason: "", - presOrderStatus: 4, editedBy: 3); + rejectionReason: "", + presOrderStatus: 4, editedBy: 3); await model.updateHHCPresOrder(updatePresOrderRequestModel); if(model.state == ViewState.ErrorLocal) { - Utils.showErrorToast(model.error); + Utils.showErrorToast(model.error); } else { - AppToast.showSuccessToast(message: "Done Successfully"); + AppToast.showSuccessToast(message:TranslationBase.of(context).processDoneSuccessfully ); await model.getHHCAllPresOrders(); - // await model.getHHCAllServices(); + // await model.getHHCAllServices(); } }, )); } return AppScaffold( - isShowAppBar: false, - baseViewModel: model, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Container( - margin: EdgeInsets.all(12), - child: Center( - child: FractionallySizedBox( - widthFactor: 0.94, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 50, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: model.hhcAllPresOrders.map((order) { - return Container( - width: double.infinity, - margin: EdgeInsets.only(top: 15), - decoration: BoxDecoration( - border: - Border.all(color: Colors.grey, width: 1), - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Request ID", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - order.iD.toString(), - fontSize: 22, + isShowAppBar: false, + baseViewModel: model, + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Container( + margin: EdgeInsets.all(12), + child: Center( + child: FractionallySizedBox( + widthFactor: 0.94, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 50, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: model.hhcAllPresOrders.map((order) { + return Container( + width: double.infinity, + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + border: + Border.all(color: Colors.grey, width: 1), + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 15, top: 15, right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, ), - ], - ), + ), + // borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .requestID, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + order.iD.toString(), + fontSize: 22, + ), + ], ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Status", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - order.description, - fontSize: 22, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 15, top: 15, right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, ), - ], - ), + ), + // borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .OrderStatus, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + + projectViewModel.isArabic ? order.descriptionN : order.description, + fontSize: 22, + ), + ], ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Pickup Date", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - order.createdOn)), - fontSize: 22, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 15, top: 15, right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, ), - ], - ), + ), + // borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .pickupDate, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + DateUtil.getDayMonthYearDateFormatted( + DateUtil.convertStringToDate(order.createdOn)), + fontSize: 22, + ), + ], ), - Container( - width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Location", - bold: false, - fontSize: 13, - ), - SizedBox( - height: 4, - ), - Texts( - order.nearestProjectDescription - .toString() ?? - order.nearestProjectDescriptionN - .toString(), - fontSize: 22, + ), + + SizedBox( + height: 12, + ), + Container( + width: double.infinity, + padding: EdgeInsets.only( + left: 15, bottom: 15, top: 15, right: 15), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey, + width: 1.0, ), - ], - ), - ), - SizedBox( - height: 12, - ), - if (order.status == 1 ||order.status == 2 ) - Center( - child: Container( - width: MediaQuery - .of(context) - .size - .width * - 0.85, - child: SecondaryButton( - label: "Cancel".toUpperCase(), - onTap: () { - showConfirmMessage(model, order); - } - , - color: Colors.red[800], - disabled: false, - textColor: Theme - .of(context) - .backgroundColor), ), + // borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context).orderLocation, + bold: false, + fontSize: 13, + ), + SizedBox( + height: 4, + ), + Texts( + !projectViewModel.isArabic ?order.nearestProjectDescription + .toString() : + order.nearestProjectDescriptionN + .toString(), + fontSize: 22, + ), + ], + ), + ), + SizedBox( + height: 12, + ), + if (order.status == 1 ||order.status == 2 ) + Center( + child: Container( + width: MediaQuery + .of(context) + .size + .width * + 0.85, + child: SecondaryButton( + label: "Cancel".toUpperCase(), + onTap: () { + showConfirmMessage(model, order); + } + , + color: Colors.red[800], + disabled: false, + textColor: Theme + .of(context) + .backgroundColor), ), - SizedBox( - height: 12, + ), + SizedBox( + height: 12, ), ], ), diff --git a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index 1359ab8d..21f277d9 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -3,9 +3,8 @@ import 'package:diplomaticquarterapp/core/service/weather_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/%E2%80%8B%20health_calculators.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_index_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h2o_index_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_converter.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/my_web_view.dart'; @@ -19,10 +18,8 @@ import 'package:diplomaticquarterapp/pages/ErService/ErOptions.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; -import 'package:diplomaticquarterapp/pages/medical/medical_profile_page.dart'; import 'package:diplomaticquarterapp/pages/paymentService/payment_service.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/info.dart'; -import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; @@ -37,6 +34,8 @@ import 'package:geolocator/geolocator.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'h2o/h2o_page.dart'; + class AllHabibMedicalService extends StatefulWidget { //TODO final Function goToMyProfile; @@ -106,7 +105,8 @@ class _AllHabibMedicalServiceState extends State { fontWeight: FontWeight.w600, ), Texts( - TranslationBase.of(context).healthTipsBasedOnCurrentWeather, + TranslationBase.of(context) + .healthTipsBasedOnCurrentWeather, color: Colors.white, fontSize: 14, ), @@ -196,6 +196,17 @@ class _AllHabibMedicalServiceState extends State { 'assets/images/al-habib_online_payment_service_icon.png', title: TranslationBase.of(context).onlinePaymentService, ), + ServicesContainer( + onTap: () => Navigator.push( + context, + FadePage( + page: AnicllaryOrders(), + ), + ), + imageLocation: + 'assets/images/comprehensive_medical_checkup_logo.png', + title: TranslationBase.of(context).anicllaryOrders, + ), ServicesContainer( onTap: () => Navigator.push( context, @@ -203,7 +214,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/al-habib_online_payment_service_icon.png', - title: 'Covid-19- Drive-Thru Test', + title: TranslationBase.of(context).covid19_driveThrueTest, ), ServicesContainer( onTap: () { @@ -227,7 +238,7 @@ class _AllHabibMedicalServiceState extends State { ), ), imageLocation: 'assets/images/pharmacy_logo.png', - title: 'Pharmacy'), + title: TranslationBase.of(context).pharmacy), ServicesContainer( onTap: () => Navigator.push( context, @@ -243,12 +254,10 @@ class _AllHabibMedicalServiceState extends State { onTap: () => Navigator.push( context, FadePage( - page: authUser.patientID == null - ? EReferralIndexPage() - : EReferralPage()), + page: EReferralPage()), ), imageLocation: 'assets/images/ereferral_service_icon.png', - title: 'E-Referral', + title: TranslationBase.of(context).ereferral, ), ServicesContainer( onTap: () => Navigator.push( @@ -259,18 +268,18 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/family_menu_icon_red.png', - title: 'My Family', + title: TranslationBase.of(context).myFamily, ), - if(projectViewModel.havePrivilege(35)) - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage(page: ChildVaccinesPage()), + if (projectViewModel.havePrivilege(35)) + ServicesContainer( + onTap: () => Navigator.push( + context, + FadePage(page: ChildVaccinesPage()), + ), + imageLocation: + 'assets/images/new-design/children_vaccines_icon.png', + title: TranslationBase.of(context).childVaccine, ), - imageLocation: - 'assets/images/new-design/children_vaccines_icon.png', - title: 'Child Vaccines', - ), ServicesContainer( onTap: () => Navigator.push( context, @@ -282,23 +291,23 @@ class _AllHabibMedicalServiceState extends State { 'assets/images/new-design/upcoming_icon_bottom_bar.png', title: TranslationBase.of(context).todoList, ), - if(projectViewModel.havePrivilege(42)) - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage(page: SymptomInfo()), - ), - imageLocation: 'assets/images/new-design/body_icon.png', - title: 'Symptom Checker'), - if(projectViewModel.havePrivilege(36)) + if (projectViewModel.havePrivilege(42)) ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage(page: BloodDonationPage()), + onTap: () => Navigator.push( + context, + FadePage(page: SymptomInfo()), + ), + imageLocation: 'assets/images/new-design/body_icon.png', + title: TranslationBase.of(context).symptomCheckerTitle), + if (projectViewModel.havePrivilege(36)) + ServicesContainer( + onTap: () => Navigator.push( + context, + FadePage(page: BloodDonationPage()), + ), + imageLocation: 'assets/images/new-design/blood_icon.png', + title: TranslationBase.of(context).bloodD, ), - imageLocation: 'assets/images/new-design/blood_icon.png', - title: 'Blood Donation', - ), ServicesContainer( onTap: () => Navigator.push( context, @@ -308,7 +317,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/health_calculator_icon.png', - title: 'Health Calculators', + title: TranslationBase.of(context).calculators, ), ServicesContainer( onTap: () => Navigator.push( @@ -319,28 +328,31 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/health_convertor_icon.png', - title: 'Health Converter', + title: TranslationBase.of(context).converters, ), - if(projectViewModel.havePrivilege(38)) - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage( - page: H2OPageIndexPage(), - ), + if (projectViewModel.havePrivilege(38)) + ServicesContainer( + onTap: () => + Navigator.push(context, FadePage(page: H2OPage())), + // Navigator.push( + // context, + // FadePage( + // page: H2OPageIndexPage(), + // ), + // ), + imageLocation: 'assets/images/new-design/water_icon.png', + title: TranslationBase.of(context).h2o, ), - imageLocation: 'assets/images/new-design/water_icon.png', - title: 'H2O', - ), - if(projectViewModel.havePrivilege(41)) - ServicesContainer( - onTap: () => Navigator.push( - context, - FadePage(), + if (projectViewModel.havePrivilege(41)) + ServicesContainer( + onTap: () => Navigator.push( + context, + FadePage(), + ), + imageLocation: + 'assets/images/new-design/smartwatch_icon.png', + title: TranslationBase.of(context).smartWatches, ), - imageLocation: 'assets/images/new-design/smartwatch_icon.png', - title: TranslationBase.of(context).smartWatches, - ), ServicesContainer( onTap: () => Navigator.push( context, @@ -370,7 +382,7 @@ class _AllHabibMedicalServiceState extends State { }, imageLocation: 'assets/images/new-design/twitter_dashboard_icon.png', - title: 'Latest News', + title: TranslationBase.of(context).latestNews, ), ServicesContainer( onTap: () => Navigator.push( diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart new file mode 100644 index 00000000..eccc1309 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrders.dart @@ -0,0 +1,177 @@ +import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; + +class AnicllaryOrders extends StatefulWidget { + @override + _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); +} + +class _AnicllaryOrdersState extends State + with SingleTickerProviderStateMixin { + TabController _tabController; + void initState() { + super.initState(); + _tabController = TabController(length: 2, vsync: this); + } + + void dispose() { + super.dispose(); + _tabController.dispose(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getOrders(), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).anicllaryOrders, + body: SingleChildScrollView( + padding: EdgeInsets.all(12), + child: model.ancillaryLists.length > 0 + ? Column(children: [ + getPatientInfo(model), + getAncillaryOrdersList(model) + ]) + : SizedBox()))); + } + + Widget getPatientInfo(AnciallryOrdersViewModel model) { + print(model.ancillaryLists); + return Padding( + child: Column( + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).mrn, + fontWeight: FontWeight.bold, + fontSize: 22, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientID.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).patientName, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientName, + ) + ], + ), + Divider() + ], + ), + padding: EdgeInsets.only(top: 5.0, bottom: 10.0), + ); + } + + Widget getAncillaryOrdersList(AnciallryOrdersViewModel model) { + return Column( + children: model.ancillaryLists[0].ancillaryOrderList + .map( + (item) => InkWell( + onTap: () { + ancillaryOrdersDetails(item); + }, + child: Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + width: 0.5, + ))), + padding: EdgeInsets.all(15), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.all(3), + child: Row( + mainAxisAlignment: + MainAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context) + .appointmentNo + + ' : ', + fontWeight: FontWeight.bold, + ), + Texts(item.appointmentNo.toString()) + ], + )), + Padding( + padding: EdgeInsets.all(3), + child: Row( + children: [ + Texts( + TranslationBase.of(context) + .appointmentDate + + ' : ', + fontWeight: FontWeight.bold), + Texts(DateUtil.getFormattedDate( + DateUtil.convertStringToDate( + item.appointmentDate), + "MMM dd,yyyy")) + ], + )), + Padding( + padding: EdgeInsets.all(3), + child: Row( + children: [ + Texts( + TranslationBase.of(context) + .doctorName + + ' : ', + fontWeight: FontWeight.bold), + Texts(item.doctorName.toString()) + ], + )), + Divider( + color: Colors.black12, + height: 1, + ) + ]), + Icon( + Icons.arrow_right, + size: 25, + ) + ]))), + ) + .toList()); + } + + ancillaryOrdersDetails(item) { + Navigator.push( + context, + FadePage( + page: AnicllaryOrdersDetails(item.appointmentNo, item.orderNo), + ), + ); + } +} diff --git a/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart new file mode 100644 index 00000000..20d2966b --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ancillary-orders/ancillaryOrdersDetails.dart @@ -0,0 +1,280 @@ +import 'package:diplomaticquarterapp/core/viewModels/ancillary_orders_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import "package:collection/collection.dart"; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; + +class AnicllaryOrdersDetails extends StatefulWidget { + final dynamic appoNo; + final dynamic orderNo; + AnicllaryOrdersDetails(this.appoNo, this.orderNo); + @override + _AnicllaryOrdersState createState() => _AnicllaryOrdersState(); +} + +class _AnicllaryOrdersState extends State + with SingleTickerProviderStateMixin { + void initState() { + super.initState(); + } + + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => + model.getOrdersDetails(widget.appoNo, widget.orderNo), + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).anicllaryOrders, + body: SingleChildScrollView( + padding: EdgeInsets.all(12), + child: model.ancillaryListsDetails.length > 0 + ? Column(children: [ + getPatientInfo(model), + getInvoiceDetails(model), + getInsuranceDetails(model), + getAncillaryDetails(model), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + TranslationBase.of(context).total, + fontSize: 20, + fontWeight: FontWeight.bold, + ), + Texts( + getTotalValue(model), + fontSize: 20, + fontWeight: FontWeight.bold, + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Button( + label: TranslationBase.of(context).payNow, + onTap: () {}, + ) + ], + ) + ]) + : SizedBox()))); + } + + Widget getPatientInfo(AnciallryOrdersViewModel model) { + print(model.ancillaryListsDetails); + return Padding( + child: Column( + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).mrn, + fontWeight: FontWeight.bold, + fontSize: 22, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryListsDetails[0].patientID.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).patientName, + fontWeight: FontWeight.bold, + fontSize: 20, + ), + Texts( + " : ", + fontSize: 20, + ), + Texts( + model.ancillaryLists[0].patientName, + ) + ], + ), + Divider( + color: Colors.black26, + ) + ], + ), + padding: EdgeInsets.only(top: 5.0, bottom: 5.0), + ); + } + + Widget getInvoiceDetails(model) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Texts( + TranslationBase.of(context).invoiceNo, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + model.ancillaryListsDetails[0].appointmentNo.toString(), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).date, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + DateUtil.getFormattedDate( + DateUtil.convertStringToDate( + model.ancillaryListsDetails[0].appointmentDate), + "MMM dd,yyyy"), + ) + ], + ), + Row( + children: [ + Texts( + TranslationBase.of(context).date, + fontWeight: FontWeight.bold, + ), + Texts(" : "), + Texts( + model.ancillaryListsDetails[0].doctorName, + ), + ], + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.black26, + ) + ], + ); + } + + Widget getInsuranceDetails(model) { + return Padding( + padding: EdgeInsets.only(top: 10, bottom: 10), + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + TranslationBase.of(context).insurance, + fontWeight: FontWeight.bold, + ), + Texts( + TranslationBase.of(context).insuranceID, + fontWeight: FontWeight.bold, + ) + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Texts( + model.ancillaryListsDetails[0].policyName, + ), + Texts( + model.ancillaryListsDetails[0].insurancePolicyNo, + ) + ], + ), + SizedBox( + height: 15, + ), + Divider( + color: Colors.red[800], + thickness: 3, + ) + ], + )); + } + + Widget getAncillaryDetails(model) { + Map newMap = groupBy(model.ancillaryListsDetails[0].ancillaryOrderProcList, + (obj) => obj.procedureCategoryName); + print(newMap); + + return Padding( + padding: EdgeInsets.only(top: 10, bottom: 10), + child: getHeaderDetails(newMap)); + } + + Widget getHeaderDetails(newMap) { + List list = new List(); + + newMap.forEach((key, value) { + list.add( + Texts( + key, + fontWeight: FontWeight.bold, + ), + ); + list.add(Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + getLabDetails(value), + ], + )); + }); + + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: list, + ); + } + + String getTotalValue(value) { + double total = 0.0; + value.ancillaryListsDetails[0].ancillaryOrderProcList + .forEach((result) => {total += result.companyShareWithTax}); + return total.toStringAsFixed(2); + } + + getLabDetails(value) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: value.map((result) { + return Container( + width: MediaQuery.of(context).size.width * .9, + padding: EdgeInsets.all(10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + Expanded( + flex: 3, + child: Text(result.procedureName.toString(), + overflow: TextOverflow.ellipsis)), + Expanded(child: AppText(result.companyShare.toString())), + Expanded(child: AppText(result.companyTaxAmount.toString())), + Expanded( + child: AppText( + result.companyShareWithTax.toString(), + )) + ], + )); + }).toList(), + ); + } +} diff --git a/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart index 90386827..1558b8c7 100644 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart +++ b/lib/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart @@ -12,9 +12,7 @@ class ConfirmAddAmountDialog extends StatefulWidget { final String unit; final H2OViewModel model; - - ConfirmAddAmountDialog( - {Key key, this.model,this.amount,this.unit ="ml"}); + ConfirmAddAmountDialog({Key key, this.model, this.amount, this.unit = "ml"}); @override _ConfirmAddAmountDialogState createState() => _ConfirmAddAmountDialogState(); @@ -29,10 +27,12 @@ class _ConfirmAddAmountDialogState extends State { @override Widget build(BuildContext context) { return SimpleDialog( - contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), + contentPadding: EdgeInsets.fromLTRB(24.0, 0.0, 24.0, 8.0), + titlePadding: EdgeInsets.fromLTRB(24.0, 16.0, 24.0, 8.0), title: Center( child: Texts( - "Confirm", + TranslationBase.of(context).confirm, + textAlign: TextAlign.center, color: Colors.black, ), ), @@ -42,12 +42,13 @@ class _ConfirmAddAmountDialogState extends State { Divider(), Center( child: Texts( - "Are you sure you want to Add ${widget.amount} ${widget.unit} ?", + "${TranslationBase.of(context).areyousure} ${widget.amount} ${widget.unit} ?", + textAlign: TextAlign.center, color: Colors.grey, ), ), SizedBox( - height: 5.0, + height: 16.0, ), Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -79,8 +80,8 @@ class _ConfirmAddAmountDialogState extends State { Expanded( flex: 1, child: InkWell( - onTap: () async{ - InsertUserActivityRequestModel insertUserActivityRequestModel= InsertUserActivityRequestModel(quantityIntake:widget.amount ); + onTap: () async { + InsertUserActivityRequestModel insertUserActivityRequestModel = InsertUserActivityRequestModel(quantityIntake: widget.amount); await widget.model.insertUserActivity(insertUserActivityRequestModel); Navigator.pop(context); }, @@ -88,20 +89,17 @@ class _ConfirmAddAmountDialogState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + TranslationBase.of(context).ok.toUpperCase(), + fontWeight: FontWeight.w400, + )), ), ), ), ], - ) + ), ], ) ], ); } } - - - diff --git a/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart index d70aec4e..2df90419 100644 --- a/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart +++ b/lib/pages/AlHabibMedicalService/h2o/Dialog/select_amount_dialog.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; @@ -5,25 +7,32 @@ import 'package:flutter/material.dart'; // ignore: must_be_immutable class SelectAmountDialog extends StatefulWidget { - List searchAmount = [ - AmountModel(name: "l",nameAr:"لتر",value: 1), - AmountModel(name: "ml",nameAr:"مم لتر",value: 2), - ]; final Function(AmountModel) onValueSelected; AmountModel selectedAmount; - SelectAmountDialog( - {Key key, this.onValueSelected, this.selectedAmount}); + SelectAmountDialog({Key key, this.onValueSelected, this.selectedAmount}); @override _SelectAmountDialogState createState() => _SelectAmountDialogState(); } class _SelectAmountDialogState extends State { + List searchAmount = [ + AmountModel(name: "l", nameAr: "لتر", value: 1), + AmountModel(name: "ml", nameAr: "مم لتر", value: 2), + ]; @override void initState() { super.initState(); - widget.selectedAmount = widget.selectedAmount ?? widget.searchAmount[0]; + widget.selectedAmount = widget.selectedAmount ?? searchAmount[0]; + getLanguage(); + } + + String languageID = "en"; + + void getLanguage() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + setState(() {}); } @override @@ -32,11 +41,14 @@ class _SelectAmountDialogState extends State { children: [ Column( children: [ - Texts("Select the preferred unit", fontSize: 20,), + Texts( + TranslationBase.of(context).preferredunit, + fontSize: 20, + ), Divider(), ...List.generate( - widget.searchAmount.length, - (index) => Column( + searchAmount.length, + (index) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( @@ -49,13 +61,13 @@ class _SelectAmountDialogState extends State { child: InkWell( onTap: () { setState(() { - widget.selectedAmount = widget.searchAmount[index]; + widget.selectedAmount = searchAmount[index]; }); }, child: ListTile( - title: Text(widget.searchAmount[index].name), + title: Text(languageID == "ar" ? searchAmount[index].nameAr : searchAmount[index].name), leading: Radio( - value: widget.searchAmount[index], + value: searchAmount[index], groupValue: widget.selectedAmount, activeColor: Colors.red[800], onChanged: (value) { @@ -116,9 +128,9 @@ class _SelectAmountDialogState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + TranslationBase.of(context).ok, + fontWeight: FontWeight.w400, + )), ), ), ), @@ -130,6 +142,7 @@ class _SelectAmountDialogState extends State { ); } } + class AmountModel { String name; String nameAr; @@ -151,7 +164,3 @@ class AmountModel { return data; } } - - - - diff --git a/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart b/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart new file mode 100644 index 00000000..580207d8 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/h2o/Dialog/setting_page_radio_button_list_dialog.dart @@ -0,0 +1,101 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/material.dart'; + +class CommonRadioButtonDialog extends StatefulWidget { + final List list; + final String title; + final int selectedIndex; + final Function(int) onSelect; + CommonRadioButtonDialog({Key key, this.title = "", this.selectedIndex = 0, this.list, this.onSelect}) : super(key: key); + + @override + _CommonRadioButtonDialogState createState() { + return _CommonRadioButtonDialogState(); + } +} + +class _CommonRadioButtonDialogState extends State { + int _selectedIndex = 0; + + @override + void initState() { + super.initState(); + _selectedIndex = widget.selectedIndex; + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Dialog( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(4), + ), + elevation: 0, + backgroundColor: Colors.white, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + height: widget.title == "" ? 24 : 50, + alignment: Alignment.center, + child: Text( + widget.title, + style: TextStyle(color: Colors.black87, fontSize: 18, fontWeight: FontWeight.w500), + ), + ), + Divider(height: 1, color: Colors.black38), + ListView.builder( + shrinkWrap: true, + padding: EdgeInsets.only(top: 4, bottom: 4), + physics: NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return RadioListTile( + value: index, + dense: true, + activeColor: Colors.black54, + groupValue: _selectedIndex, + onChanged: (_index) => setState(() => _selectedIndex = _index), + title: Text( + widget.list[index], + style: TextStyle(fontWeight: FontWeight.w500), + ), + ); + }, + itemCount: widget.list?.length ?? 0, + ), + Divider(height: 1, color: Colors.black38), + Container( + height: 50, + alignment: Alignment.center, + child: Row( + children: [ + Expanded( + child: FlatButton( + child: Text( + TranslationBase.of(context).cancel, + style: TextStyle(color: Colors.redAccent, fontSize: 16, fontWeight: FontWeight.w500), + ), + onPressed: () => Navigator.pop(context), + ), + ), + Expanded( + child: FlatButton( + child: Text( + TranslationBase.of(context).ok, + style: TextStyle(color: Colors.black87, fontSize: 16, fontWeight: FontWeight.w500), + ), + onPressed: () => widget.onSelect(_selectedIndex), + ), + ) + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart b/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart index 036ed186..2b22a100 100644 --- a/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart +++ b/lib/pages/AlHabibMedicalService/h2o/add_custom_amount.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -36,7 +37,7 @@ class _AddCustomAmountState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: "Enter amount", + appBarTitle:TranslationBase.of(context).customLabel, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -51,7 +52,7 @@ class _AddCustomAmountState extends State { height: 12, ), NewTextFields( - hintText: "Enter the amount of water:", + hintText: TranslationBase.of(context).h2oAmountOfWater, // type: "Number", controller: _nameTextController, ), @@ -81,7 +82,7 @@ class _AddCustomAmountState extends State { ), SecondaryButton( textColor: Colors.white, - label: "OK", + label: TranslationBase.of(context).ok, onTap: () async { Navigator.of(context).pop(); showConfirmMessage (int.parse(_nameTextController.text), widget.model); @@ -120,7 +121,7 @@ void confirmAmountTypeDialog() { if (selectedAmount != null) return selectedAmount.name; else - return "Select unit"; + return TranslationBase.of(context).selectUnit; } diff --git a/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart b/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart new file mode 100644 index 00000000..4295558a --- /dev/null +++ b/lib/pages/AlHabibMedicalService/h2o/h20_setting.dart @@ -0,0 +1,463 @@ +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/user_detail_model.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/H2O_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/BranchView.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.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:flutter/painting.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +import 'Dialog/setting_page_radio_button_list_dialog.dart'; + +class H2oSetting extends StatefulWidget { + final UserDetailModel userDetailModel; + final H2OViewModel viewModel; + H2oSetting({Key key, this.userDetailModel, this.viewModel}) : super(key: key); + + @override + _H2oSettingState createState() { + return _H2oSettingState(); + } +} + +class _H2oSettingState extends State { + TextEditingController _nameController = TextEditingController(); + TextEditingController _heightController = TextEditingController(); + TextEditingController _weightController = TextEditingController(); + bool _isUnitML = false; + bool _isGenderMale = false; + bool _isHeightCM = false; + bool _isWeightKG = false; + double _heightValue = 1; + double _weightValue = 1; + + List _activityLevelListEng = []; + List _remindedTimeListEng = []; + int _selectedActiveLevel = 1; + int _selectedRemindedTime = 0; + DateTime _dobDate = DateTime.now(); + DateTime _tempDate = DateTime.now(); + + UserDetailModel _userDetailModel; + + @override + void initState() { + super.initState(); + _userDetailModel = widget.userDetailModel; + _heightValue = _userDetailModel.height; + _weightValue = _userDetailModel.weight; + _heightController.text = _heightValue.toStringAsFixed(0); + _weightController.text = _weightValue.toStringAsFixed(0); + _nameController.text = _userDetailModel.firstName; + _isWeightKG = _userDetailModel.isWeightInKG; + _isHeightCM = _userDetailModel.isHeightInCM; + _isGenderMale = _userDetailModel.gender == "M" ? true : false; + _dobDate = DateUtil.convertStringToDate(_userDetailModel.dOB); + _selectedActiveLevel = _userDetailModel.activityID ?? 1; + } + + @override + void didChangeDependencies() { + // TODO: implement didChangeDependencies + super.didChangeDependencies(); + + _activityLevelListEng = [ + TranslationBase.of(context).notActive, + TranslationBase.of(context).lightActive, + TranslationBase.of(context).modActive, + TranslationBase.of(context).active + ]; + + _remindedTimeListEng = [ + "1 ${TranslationBase.of(context).time}", + "2 ${TranslationBase.of(context).times}", + "3 ${TranslationBase.of(context).times}", + "4 ${TranslationBase.of(context).times}" + ]; + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).h2o, + showHomeAppBarIcon: false, + body: SingleChildScrollView( + padding: EdgeInsets.fromLTRB(8, 8, 8, 80), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + controller: _nameController, + decoration: InputDecoration( + labelText: TranslationBase.of(context).enterNameHere, + labelStyle: TextStyle(color: Colors.black87), + fillColor: Colors.white, + filled: true, + border: UnderlineInputBorder( + borderSide: BorderSide( + width: 0, + style: BorderStyle.none, + ), + borderRadius: BorderRadius.circular(6.0), + ), + ), + ), + SizedBox(height: 8), + Text(TranslationBase.of(context).preferredunit), + SizedBox(height: 8), + _commonButtonsRow(TranslationBase.of(context).ml, TranslationBase.of(context).l, _isUnitML, (value) { + if (_isUnitML != value) { + setState(() { + _isUnitML = value; + }); + } + }), + Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Divider(height: 1.5, color: Colors.black54), + ), + Text(TranslationBase.of(context).gender), + SizedBox(height: 8), + _commonButtonsRow(TranslationBase.of(context).male, TranslationBase.of(context).female, _isGenderMale, (value) { + if (_isGenderMale != value) { + setState(() { + _isGenderMale = value; + }); + } + }), + Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Divider(height: 1.5, color: Colors.black54), + ), + Text(TranslationBase.of(context).height), + _commonSlidersRow(_heightController, 1, 270, _heightValue, (text) { + _heightController.text = text; + }, (value) { + setState(() { + _heightValue = value; + }); + }), + SizedBox(height: 8), + Text(TranslationBase.of(context).heightUnit), + SizedBox(height: 8), + _commonButtonsRow(TranslationBase.of(context).cm, TranslationBase.of(context).ft, _isHeightCM, (value) { + if (_isHeightCM != value) { + setState(() { + _isHeightCM = value; + }); + } + }), + SizedBox(height: 8), + _commonSlidersRow(_weightController, 1, 250, _weightValue, (text) { + _weightController.text = text; + }, (value) { + setState(() { + _weightValue = value; + }); + }), + SizedBox(height: 8), + Text(TranslationBase.of(context).weightUnit), + SizedBox(height: 8), + _commonButtonsRow(TranslationBase.of(context).kg, TranslationBase.of(context).lb, _isWeightKG, (value) { + if (_isWeightKG != value) { + setState(() { + _isWeightKG = value; + }); + } + }), + Padding( + padding: EdgeInsets.only(top: 8.0, bottom: 8.0), + child: Divider(height: 1.5, color: Colors.black54), + ), + Container( + padding: EdgeInsets.all(8), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("${TranslationBase.of(context).birth_date}:"), + SizedBox(height: 8), + InkWell( + onTap: () { + showModalBottomSheet( + context: context, + builder: (context) { + return Container( + height: 250, + padding: EdgeInsets.all(8), + child: Column(children: [ + Container( + height: 40, + alignment: Alignment.centerRight, + child: Row(mainAxisSize: MainAxisSize.min, children: [ + InkWell( + onTap: () => Navigator.pop(context), + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.fromLTRB(8, 4, 8, 4), + child: Text(TranslationBase.of(context).cancel), + ), + ), + SizedBox(width: 8), + InkWell( + onTap: () { + Navigator.pop(context); + setState(() { + _dobDate = _tempDate; + }); + }, + child: Container( + alignment: Alignment.center, + padding: EdgeInsets.fromLTRB(8, 4, 8, 4), + child: Text(TranslationBase.of(context).ok), + ), + ) + ]), + ), + Expanded( + child: Container( + width: MediaQuery.of(context).size.width, + child: CupertinoDatePicker( + initialDateTime: _dobDate, + mode: CupertinoDatePickerMode.date, + onDateTimeChanged: (_date) { + _tempDate = _date; + }, + ), + ), + ) + ]), + ); + }); + }, // implement cupertino dialog to select date + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [Text(DateUtil.getFormattedDate(_dobDate, "yyyy-MM-dd")), Icon(Icons.arrow_drop_down_outlined)]), + ) + ], + ), + ), + SizedBox(height: 8), + _commonDialogSelectorRow(TranslationBase.of(context).activityLevel, _activityLevelListEng[_selectedActiveLevel - 1], () { + showDialog( + context: context, + child: CommonRadioButtonDialog( + list: _activityLevelListEng, + title: TranslationBase.of(context).activityLevel, + onSelect: (index) { + Navigator.pop(context); + setState(() { + _selectedActiveLevel = index + 1; + }); + }, + selectedIndex: _selectedActiveLevel - 1, + ), + ); + }), + SizedBox(height: 8), + _commonDialogSelectorRow(TranslationBase.of(context).reminderLabel, _remindedTimeListEng[_selectedRemindedTime], () { + showDialog( + context: context, + child: CommonRadioButtonDialog( + list: _remindedTimeListEng, + onSelect: (index) { + Navigator.pop(context); + setState(() { + _selectedRemindedTime = index; + }); + }, + selectedIndex: _selectedRemindedTime, + ), + ); + }), + SizedBox(height: 16), + SizedBox( + height: 50, + width: MediaQuery.of(context).size.width, + child: FlatButton( + color: Theme.of(context).appBarTheme.color, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + onPressed: _updateUserDetails, + child: Text( + TranslationBase.of(context).save, + style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600), + ), + ), + ) + ], + ), + ), + ); + } + + Widget _commonButtonsRow(String rightText, String leftText, bool checkParam, Function(bool) callBack) { + return Row(children: [ + Expanded( + child: SizedBox( + height: 40, + child: RaisedButton( + color: checkParam ? Theme.of(context).appBarTheme.color : Colors.white, + child: Text( + rightText, + style: TextStyle(color: checkParam ? Colors.white : Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w600), + ), + onPressed: () => callBack(true), + ), + ), + ), + SizedBox(width: 12), + Expanded( + child: SizedBox( + height: 40, + child: RaisedButton( + color: !checkParam ? Theme.of(context).appBarTheme.color : Colors.white, + child: Text( + leftText, + style: TextStyle(color: !checkParam ? Colors.white : Theme.of(context).appBarTheme.color, fontWeight: FontWeight.w600), + ), + onPressed: () => callBack(false), + ), + ), + ), + ]); + } + + Widget _commonSlidersRow( + _controller, double _minValue, double _maxValue, double _valueOrg, Function(String) onTextValueChange, Function(double) onValueChange) { + return Container( + margin: EdgeInsets.only(top: 6), + padding: EdgeInsets.all(6), + color: Colors.white, + height: 50, + child: Row( + children: [ + SizedBox( + width: 75, + child: TextField( + controller: _controller, + textAlign: TextAlign.center, + keyboardType: TextInputType.number, + onChanged: (value) { + double _value = double.parse(value); + if (_value > _maxValue) { + onTextValueChange(_maxValue.toStringAsFixed(0)); + onValueChange(_maxValue); + return; + } else if (_value < _minValue) { + onTextValueChange(_minValue.toStringAsFixed(0)); + onValueChange(_minValue); + return; + } else if (_value >= _minValue && _value <= _maxValue) { + onValueChange(_value); + return; + } + }, + inputFormatters: [ + FilteringTextInputFormatter.allow(RegExp(r'[0-9]')), + ], + decoration: InputDecoration( + contentPadding: EdgeInsets.only(left: 4, right: 4), + fillColor: Colors.white, + filled: true, + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Colors.grey, + style: BorderStyle.solid, + ), + borderRadius: BorderRadius.circular(6.0), + ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + width: 1, + color: Colors.grey, + style: BorderStyle.solid, + ), + borderRadius: BorderRadius.circular(6.0), + ), + ), + ), + ), + Expanded( + flex: 6, + child: Slider( + min: _minValue, + max: _maxValue, + activeColor: Colors.redAccent, + inactiveColor: Colors.redAccent.withOpacity(.3), + value: _valueOrg, + onChanged: (value) { + onTextValueChange(value.toStringAsFixed(0)); + onValueChange(value); + }, + ), + ) + ], + ), + ); + } + + Widget _commonDialogSelectorRow(String title, String selectedText, VoidCallback onPressed) { + return Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + Text(title), + SizedBox(height: 8), + InkWell( + onTap: onPressed, + child: Container( + height: 50, + padding: EdgeInsets.all(8), + width: MediaQuery.of(context).size.width, + decoration: BoxDecoration(borderRadius: BorderRadius.circular(8), color: Colors.white), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [Text(selectedText), Icon(Icons.arrow_drop_down_outlined)], + ), + ), + ) + ]); + } + + void _updateUserDetails() async { + _userDetailModel.height = _heightValue; + _userDetailModel.weight = _weightValue; + _userDetailModel.firstName = _nameController.text; + _userDetailModel.isWeightInKG = _isWeightKG; + _userDetailModel.isHeightInCM = _isHeightCM; + _userDetailModel.gender = _isGenderMale ? "M" : "F"; + + var tempDate = DateUtil.convertDateToString(_dobDate); + if (!tempDate.endsWith("/")) { + tempDate = tempDate + "/"; + } + + _userDetailModel.dOB = tempDate; + _userDetailModel.activityID = _selectedActiveLevel; + GifLoaderDialogUtils.showMyDialog(context); + await widget.viewModel.updateUserDetail(_userDetailModel, (tag) { + if (tag) { + AppToast.showSuccessToast(message: TranslationBase.of(context).success); + } + GifLoaderDialogUtils.hideDialog(context); + }); + + Navigator.pop(context); + } +} diff --git a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart index ad2c6ece..b4d39682 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart @@ -1,12 +1,15 @@ import 'dart:ui'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/h20_setting.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/month_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/today_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/week_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -34,9 +37,26 @@ class _H2OPageState extends State @override Widget build(BuildContext context) { return BaseView( + onModelReady: (model) => model.getUserDetail(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: "Water Tracker", + appBarTitle: TranslationBase.of(context).waterTracker, + showHomeAppBarIcon: false, + baseViewModel: model, + appBarIcons: [ + IconButton( + icon: Image.asset("assets/images/new-design/setting_gear_icon.png"), + color: Colors.white, + onPressed: () { + Navigator.push( + context, + FadePage( + page: H2oSetting(userDetailModel: model.userDetail, viewModel: model), + ), + ); + }, + ), + ], body: Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( @@ -50,9 +70,7 @@ class _H2OPageState extends State child: BackdropFilter( filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), + color: Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8), height: 70.0, ), ), @@ -60,48 +78,46 @@ class _H2OPageState extends State Center( child: Container( height: 60.0, - margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, + alignment: Alignment.center, + // margin: EdgeInsets.only(top: 10.0), + // width: MediaQuery.of(context).size.width * 0.9, - child: Center( - child: TabBar( - isScrollable: false, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 10.0, right: 13.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts( - "Today"), - ), + child: TabBar( + isScrollable: false, + controller: _tabController, + indicatorWeight: 5.0, + indicatorSize: TabBarIndicatorSize.tab, + indicatorColor: Colors.red[800], + labelColor: Theme.of(context).primaryColor, + labelPadding: EdgeInsets.only(top: 4.0, left: 10.0, right: 13.0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + Container( + width: MediaQuery.of(context).size.width * 0.28, + child: Center( + child: Texts(TranslationBase.of(context).today), ), - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts("Week"), - ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.28, + child: Center( + child: Texts(TranslationBase.of(context).week), ), - Container( - width: MediaQuery.of(context).size.width * 0.28, - child: Center( - child: Texts("Month"), - ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.28, + child: Center( + child: Texts(TranslationBase.of(context).month), ), - ], - ), + ), + ], ), ), ), ], ), ), + backgroundColor: Colors.white, body: Column( children: [ Expanded( diff --git a/lib/pages/AlHabibMedicalService/h2o/month_page.dart b/lib/pages/AlHabibMedicalService/h2o/month_page.dart index f0baf34d..e0118495 100644 --- a/lib/pages/AlHabibMedicalService/h2o/month_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/month_page.dart @@ -1,11 +1,13 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; class MonthPage extends StatelessWidget { @override @@ -14,12 +16,39 @@ class MonthPage extends StatelessWidget { onModelReady: (model) => model.getUserProgressForMonthData(), builder: (_, model, widget) => AppScaffold( isShowAppBar: false, - appBarTitle: "Water Tracker", - baseViewModel:model , - body: SingleChildScrollView( - padding: EdgeInsets.symmetric(vertical: 12), - child: AppBarChart( - seriesList: model.userProgressForMonthDataSeries), + appBarTitle: TranslationBase.of(context).h2o, + baseViewModel: model, + body: Padding( + padding: EdgeInsets.all(8.0), + child: ListView( + children: [ + Center( + child: Text( + TranslationBase.of(context).waterConsumedInMonth, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 20.0, color: Colors.black87), + ), + ), + SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 10, + width: 40, + color: Colors.blue, + ), + SizedBox(width: 8), + Text( + TranslationBase.of(context).waterConsumedInMonth, + style: TextStyle(fontSize: 12.0), + ), + ], + ), + // SizedBox(height: 8), + AppBarChart(seriesList: model.userProgressForMonthDataSeries), + ], + ), ), ), ); diff --git a/lib/pages/AlHabibMedicalService/h2o/today_page.dart b/lib/pages/AlHabibMedicalService/h2o/today_page.dart index b92efc9e..33383287 100644 --- a/lib/pages/AlHabibMedicalService/h2o/today_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/today_page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.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'; @@ -14,7 +15,7 @@ class TodayPage extends StatelessWidget { onModelReady: (model) => model.getUserProgressForTodayData(), builder: (_, model, widget) => AppScaffold( isShowAppBar: false, - appBarTitle: "Water Tracker", + appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, body: SingleChildScrollView( padding: EdgeInsets.symmetric(vertical: 12), @@ -36,13 +37,14 @@ class TodayPage extends StatelessWidget { //, center: Center( child: Column( + mainAxisSize: MainAxisSize.min, children: [ - SizedBox( - height: 40, - ), + // SizedBox( + // height: 40, + // ), Text( - "Consumed", - style: TextStyle(fontSize: 20.0), + TranslationBase.of(context).consumed, + style: TextStyle(fontSize: 16.0), ), SizedBox( height: 4, @@ -50,13 +52,8 @@ class TodayPage extends StatelessWidget { Text( model.userProgressData == null ? "0.0" - : model.userProgressData.quantityConsumed - .toString() + - 'ml', - style: TextStyle( - fontWeight: FontWeight.bold, - fontSize: 20.0, - color: HexColor("#60BCF9")), + : model.userProgressData.quantityConsumed.toString() + TranslationBase.of(context).ml, + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0, color: HexColor("#60BCF9")), ), SizedBox( height: 4, @@ -70,8 +67,8 @@ class TodayPage extends StatelessWidget { height: 4, ), Text( - "Remaining", - style: TextStyle(fontSize: 20.0), + TranslationBase.of(context).remaining, + style: TextStyle(fontSize: 16.0), ), SizedBox( height: 4, @@ -79,18 +76,11 @@ class TodayPage extends StatelessWidget { Text( model.userProgressData == null ? "0.0" - : (model.userProgressData.quantityLimit - - model.userProgressData - .quantityConsumed) < - 0 - ? "0 ml" - : (model.userProgressData.quantityLimit - - model.userProgressData - .quantityConsumed) - .toString() + - ' ml', - style: TextStyle( - fontWeight: FontWeight.bold, fontSize: 18.0), + : (model.userProgressData.quantityLimit - model.userProgressData.quantityConsumed) < 0 + ? "0 ${TranslationBase.of(context).ml}" + : (model.userProgressData.quantityLimit - model.userProgressData.quantityConsumed).toString() + + ' ${TranslationBase.of(context).ml}', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14.0), ), ], ), @@ -104,42 +94,32 @@ class TodayPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Center( - child: Container( - margin: EdgeInsets.only(left: 20), - height: 30, - width: 70, - decoration: BoxDecoration( - color: HexColor("#D1E3F6"), - borderRadius: - BorderRadius.all(Radius.circular(30))), - ), + Container( + margin: EdgeInsets.only(bottom: 16), + height: 30, + width: 70, + decoration: BoxDecoration(color: HexColor("#D1E3F6"), borderRadius: BorderRadius.all(Radius.circular(30))), ), Text( - "Remaining % ", - style: TextStyle(fontSize: 20.0), + "${TranslationBase.of(context).remaining} %", + style: TextStyle(fontSize: 16.0), ) ], ), Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Center( - child: Container( - margin: EdgeInsets.only(left: 20), - height: 30, - width: 70, - decoration: BoxDecoration( - color: HexColor("#60BCF9"), - borderRadius: - BorderRadius.all(Radius.circular(30))), - ), + Container( + margin: EdgeInsets.only(bottom: 16), + height: 30, + width: 70, + decoration: BoxDecoration(color: HexColor("#60BCF9"), borderRadius: BorderRadius.all(Radius.circular(30))), ), Text( - "Consumed % ", - style: TextStyle(fontSize: 20.0), + "${TranslationBase.of(context).consumed} %", + style: TextStyle(fontSize: 16.0), ) ], ) diff --git a/lib/pages/AlHabibMedicalService/h2o/week_page.dart b/lib/pages/AlHabibMedicalService/h2o/week_page.dart index e42eb19b..34e365e6 100644 --- a/lib/pages/AlHabibMedicalService/h2o/week_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/week_page.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_bar_chart.dart'; import 'package:diplomaticquarterapp/widgets/errors/app_embedded_error.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -15,16 +16,41 @@ class WeekPage extends StatelessWidget { onModelReady: (model) => model.getUserProgressForWeekData(), builder: (_, model, widget) => AppScaffold( isShowAppBar: false, - appBarTitle: "Water Tracker", + appBarTitle: TranslationBase.of(context).h2o, baseViewModel: model, - body: SingleChildScrollView( - padding: EdgeInsets.symmetric(vertical: 12), - child: AppBarChart(seriesList: model.userProgressForWeekDataSeries), + body: Padding( + padding: EdgeInsets.all(8.0), + child: ListView( + children: [ + Center( + child: Text( + TranslationBase.of(context).waterConsumedInWeek, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 20.0, color: Colors.black87), + ), + ), + SizedBox(height: 16), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + height: 10, + width: 40, + color: Colors.blue, + ), + SizedBox(width: 8), + Text( + TranslationBase.of(context).waterConsumedInWeek, + style: TextStyle(fontSize: 12.0), + ), + ], + ), + // SizedBox(height: 8), + AppBarChart(seriesList: model.userProgressForWeekDataSeries), + ], + ), ), ), ); } } - - - diff --git a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart b/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart index 7eaed1a8..b692e6ba 100644 --- a/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart +++ b/lib/pages/AlHabibMedicalService/h2o/widgets/h20_floating_action_button.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/H2O/insert import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/H2O_view_model.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/h2o/Dialog/confirm_add_amount_dialog.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -12,13 +13,7 @@ import 'package:flutter/material.dart'; import '../add_custom_amount.dart'; class H20FloatingActionButton extends StatefulWidget { - const H20FloatingActionButton({ - Key key, - @required AnimationController controller, - @required this.model - - }) : - super(key: key); + const H20FloatingActionButton({Key key, @required AnimationController controller, @required this.model}) : super(key: key); final H2OViewModel model; @@ -26,7 +21,7 @@ class H20FloatingActionButton extends StatefulWidget { _H20FloatingActionButtonState createState() => _H20FloatingActionButtonState(); } -class _H20FloatingActionButtonState extends State with TickerProviderStateMixin { +class _H20FloatingActionButtonState extends State with TickerProviderStateMixin { AnimationController _controller; @override void initState() { @@ -37,15 +32,20 @@ class _H20FloatingActionButtonState extends State with super.initState(); } + void showConfirmMessage(int amount, H2OViewModel model) { + showDialog( + context: context, + child: ConfirmAddAmountDialog( + model: model, + amount: amount, + ), + ); + } + @override Widget build(BuildContext context) { - - void showConfirmMessage(int amount, H2OViewModel model) { - showDialog(context: context, child: ConfirmAddAmountDialog(model: model,amount:amount,)); - } - return Container( - margin: EdgeInsets.only(left: 20), + margin: EdgeInsets.only(left: 20, right: 20), child: new Column(mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, @@ -55,21 +55,21 @@ class _H20FloatingActionButtonState extends State with children: [ ActionButton( controller: _controller, - text: "600ml", + text: "600${TranslationBase.of(context).ml}", onTap: () { showConfirmMessage(600, widget.model); }, ), ActionButton( controller: _controller, - text: "330ml", + text: "330${TranslationBase.of(context).ml}", onTap: () { showConfirmMessage(330, widget.model); }, ), ActionButton( controller: _controller, - text: "200ml", + text: "200${TranslationBase.of(context).ml}", onTap: () { showConfirmMessage(200, widget.model); }, @@ -87,11 +87,9 @@ class _H20FloatingActionButtonState extends State with animation: _controller, builder: (BuildContext context, Widget child) { return new Transform( - transform: new Matrix4.rotationZ( - _controller.value * 0.5 * math.pi), + transform: new Matrix4.rotationZ(_controller.value * 0.5 * math.pi), alignment: FractionalOffset.center, - child: new Icon( - _controller.isDismissed ? Icons.add : Icons.close), + child: new Icon(_controller.isDismissed ? Icons.add : Icons.close), ); }, ), @@ -104,21 +102,21 @@ class _H20FloatingActionButtonState extends State with }, ), new Container( + margin: EdgeInsets.only(left: 8, bottom: 4), alignment: FractionalOffset.topCenter, child: new ScaleTransition( scale: new CurvedAnimation( parent: _controller, - curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, - curve: Curves.easeOut), + curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), ), child: new FloatingActionButton( backgroundColor: Colors.white, heroTag: null, - mini: true, + // mini: true, child: Text( - "Custom", + TranslationBase.of(context).custom, textAlign: TextAlign.center, - style: TextStyle(fontSize: 14.0, color: Colors.grey), + style: TextStyle(fontSize: 12, color: Colors.grey), ), onPressed: () { Navigator.push( @@ -134,23 +132,23 @@ class _H20FloatingActionButtonState extends State with ), ), new Container( + margin: EdgeInsets.only(left: 8, bottom: 4), alignment: FractionalOffset.topCenter, child: new ScaleTransition( scale: new CurvedAnimation( parent: _controller, - curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, - curve: Curves.easeOut), + curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), ), child: new FloatingActionButton( backgroundColor: Colors.white, heroTag: null, - mini: true, + //mini: true, child: Text( - "Undo", + TranslationBase.of(context).undo, textAlign: TextAlign.center, - style: TextStyle(fontSize: 14.0, color: Colors.grey), + style: TextStyle(fontSize: 12.0, color: Colors.grey), ), - onPressed: () {}, + onPressed: undoVolume, ), ), ), @@ -159,14 +157,16 @@ class _H20FloatingActionButtonState extends State with ]), ); } + + void undoVolume() async { + GifLoaderDialogUtils.showMyDialog(context); + await widget.model.undoUserActivity(); + GifLoaderDialogUtils.hideDialog(context); + } } class ActionButton extends StatelessWidget { - const ActionButton( - {Key key, - @required AnimationController controller, - @required this.text, - this.onTap}) + const ActionButton({Key key, @required AnimationController controller, @required this.text, this.onTap}) : _controller = controller, super(key: key); @@ -177,6 +177,7 @@ class ActionButton extends StatelessWidget { @override Widget build(BuildContext context) { return Container( + margin: EdgeInsets.only(left: 4, bottom: 8), alignment: FractionalOffset.topCenter, child: new ScaleTransition( scale: new CurvedAnimation( @@ -184,16 +185,15 @@ class ActionButton extends StatelessWidget { curve: new Interval(0.0, 1.0 - 0 / 6 / 2.0, curve: Curves.easeOut), ), child: new FloatingActionButton( - heroTag: null, - backgroundColor: Colors.white, - mini: true, - child: Text( - text, - textAlign: TextAlign.center, - style: TextStyle(fontSize: 14.0, color: Colors.grey), - ), - onPressed: onTap - ), + heroTag: null, + backgroundColor: Colors.white, + //mini: true, + child: Text( + text, + textAlign: TextAlign.center, + style: TextStyle(fontSize: 12.0, color: Colors.grey), + ), + onPressed: onTap), ), ); } diff --git a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart index dbb46eee..bc1de1f6 100644 --- a/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart +++ b/lib/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/weather_slider/weather_slider.dart'; @@ -20,8 +21,8 @@ class HealthWeatherIndicator extends StatefulWidget { class _HospitalsPageState extends State { var data; - LocationUtils locationUtils; AppSharedPreferences sharedPref = AppSharedPreferences(); + LocationUtils locationUtils; var weather = '--'; @override void initState() { diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart new file mode 100644 index 00000000..d9665aa4 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart @@ -0,0 +1,190 @@ +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/AlHabibMedicalService/HealthCalculator/DiseasesByClinic.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/health-calculator/Bariatrics-viewmodel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +// TODO mosa_remark +class BariatricsPage extends StatefulWidget { + final age; + final gender; + final double obeseResult; + + BariatricsPage(this.age, this.gender, this.obeseResult); + + @override + _BariatricsPageState createState() => _BariatricsPageState(); +} + +class _BariatricsPageState extends State { + DiseasesByClinic _selectedDisease; + + @override + Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + + return BaseView( + onModelReady: (model) => model.getClinicCategory(), + builder: (_, model, w) => + AppScaffold( + isShowAppBar: true, + appBarTitle: "${TranslationBase + .of(context) + .bariatrics}", + baseViewModel: model, + body: Column( + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Center( + child: Texts(TranslationBase + .of(context) + .bariatricsHeaderMsg), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.symmetric( + horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + Expanded( + child: SingleChildScrollView( + child: Column( + children: [ + ...model.diseasesList + .map((item) => + RadioListTile( + title: Texts("${item.diseases}"), + activeColor: Colors.blue.shade700, + value: item.diseasesID, + groupValue: _selectedDisease != null + ? _selectedDisease.diseasesID + : -1, + selected: _selectedDisease != null ? item + .diseasesID == + _selectedDisease.diseasesID : false, + onChanged: (val) { + setState(() { + _selectedDisease = item; + }); + }, + )) + .toList() + ], + ), + ), + ), + Image.asset( + _getImageName(widget.gender, widget.obeseResult, + projectProvider.isArabic), + fit: BoxFit.cover, + ), + ], + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: BorderedButton( + TranslationBase + .of(context) + .continues, + fontSize: SizeConfig.textMultiplier * 2.1, + textColor: Colors.white, + vPadding: 8, + hPadding: 8, + backgroundColor: Theme + .of(context) + .primaryColor, + radius: 8, + fontWeight: FontWeight.bold, + handler: () async { + await model.searchDoctorsByTime(_selectedDisease); + if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + } + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => BariatricsPage()), + // ); + }, + ), + ), + Container( + margin: EdgeInsets.only(bottom: 16.0, left: 16, right: 16), + child: BorderedButton( + TranslationBase + .of(context) + .skip, + fontSize: SizeConfig.textMultiplier * 2.1, + textColor: Colors.blue, + vPadding: 8, + hPadding: 8, + backgroundColor: Color(0x00000000), + radius: 8, + hasBorder: true, + borderColor: Color(0x00000000), + fontWeight: FontWeight.bold, + handler: () async { + await model.searchDoctorsByTime(_selectedDisease); + if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + } + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => BariatricsPage()), + // ); + }, + ), + ), + ], + ), + ), + ); + } + + _getImageName(int gender, double obeseResult, bool isArabic) { + String path = "assets/images/BMI/"; + double result = obeseResult; + + if (result < 18.5 && gender == 1) { + path += "bmi_blue_male"; + } else if (result >= 18.5 && result <= 24.9 && gender == 1) { + path += "bmi_green_male"; + } else if (result >= 25 && result <= 29.9 && gender == 1) { + path += "bmi_yellow_male"; + } else if (result >= 30 && result <= 34.9 && gender == 1) { + path += "bmi_orange_male"; + } else if (result >= 35 && gender == 1) { + path += "bmi_red_male"; + } else if (result < 18.5 && gender == 2) { + path += "bmi_blue_female"; + } else if (result >= 18.5 && result <= 24.9 && gender == 2) { + path += "bmi_green_female"; + } else if (result >= 25 && result <= 29.9 && gender == 2) { + path += "bmi_yellow_female"; + } else if (result >= 30 && result <= 34.9 && gender == 2) { + path += "bmi_orange_female"; + } else if (result >= 35 && gender == 2) { + path += "bmi_red_female"; + } else { + path += "default.png"; + } + + if (isArabic) { + path += "_ar.png"; + } else { + path += "_en.png"; + } + return path; + } +} diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart index c84053c5..8b9a5409 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bmi_calculator.dart @@ -1,6 +1,9 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:math'; @@ -26,6 +29,7 @@ class _BMICalculatorState extends State { Color ftCard = inactiveCardColor; Color lbCard = inactiveCardColor; Color kgCard = activeCardColor; + void updateColor(int type) { //MG/DLT card if (type == 1) { @@ -83,31 +87,27 @@ class _BMICalculatorState extends State { return bmiResult; } - void showTextResult() { + void showTextResult(BuildContext context) { if (bmiResult >= 30) { - textResult = 'Obese'; + textResult = TranslationBase.of(context).obese; } else if (bmiResult < 30 && bmiResult >= 25) { - textResult = 'OverWeight'; + textResult = TranslationBase.of(context).overWeight; } else if (bmiResult < 25 && bmiResult >= 18.5) { - textResult = 'Healthy'; + textResult = TranslationBase.of(context).healthy; } else if (bmiResult < 18.5) { - textResult = 'UnderWeight'; + textResult = TranslationBase.of(context).underWeight; } } - void showMsg() { + void showMsg(BuildContext context) { if (bmiResult >= 30) { - msg = - 'A BMI of over 30 indicates that are heavily overweight. Health may be at risk if not lose weight. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get started.'; + msg = TranslationBase.of(context).bmiCalcMsgObese; } else if (bmiResult < 30 && bmiResult >= 25) { - msg = - 'A BMI of 25 - 30 indicates that are slightly overweight. May be advised to lose some weight for health reasons. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get '; + msg = TranslationBase.of(context).bmiCalcMsgOverweight; } else if (bmiResult < 25 && bmiResult >= 18.5) { - msg = - 'A BMI of 18.5 - 25 indicates that are at a healthy weight for the height. By maintaining a healthy weight, lower the risk of developing severe health problems. To book an appointment, click below to get started.'; + msg = TranslationBase.of(context).bmiCalcMsgHealthy; } else if (bmiResult < 18.5) { - msg = - 'A BMI of less than 18.5 indicates that are underweight, so may need to put on some weight. Recommended talking to a doctor or a dietician for advice. To book an appointment, click below to get started.'; + msg = TranslationBase.of(context).bmiCalcMsgUnderWeight; } } @@ -120,26 +120,28 @@ class _BMICalculatorState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'BMI Calculator', + isShowDecPage: false, + appBarTitle: + "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", body: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ Center( child: Container( - width: 350.0, + margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), child: Padding( padding: EdgeInsets.symmetric(vertical: 15.0), child: Text( - 'Calculate the BMI value and weight\n status to identify the healthy weight .\n Not appropriate for children and women\n who are pregnant or breastfeeding', + TranslationBase.of(context).bmiCalcDesc, style: TextStyle(fontSize: 18.0), ), ), ), ), Container( - height: 200.0, - width: 350.0, + margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), + padding: EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.0), @@ -150,7 +152,7 @@ class _BMICalculatorState extends State { children: [ Padding( padding: EdgeInsets.all(8.0), - child: Texts('Height'), + child: Texts(TranslationBase.of(context).height), ), ], ), @@ -240,7 +242,7 @@ class _BMICalculatorState extends State { children: [ Padding( padding: EdgeInsets.all(8.0), - child: Texts('Select Unit'), + child: Texts(TranslationBase.of(context).selectUnit), ), ], ), @@ -272,7 +274,8 @@ class _BMICalculatorState extends State { child: Padding( padding: const EdgeInsets.symmetric( vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), + child: Center( + child: Texts(TranslationBase.of(context).cm)), ), ), ), @@ -301,7 +304,8 @@ class _BMICalculatorState extends State { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Center(child: Texts('FT')), + child: Center( + child: Texts(TranslationBase.of(context).feet)), ), ), ), @@ -314,8 +318,8 @@ class _BMICalculatorState extends State { height: 25.0, ), Container( - height: 200.0, - width: 350.0, + margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), + padding: EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12.0), @@ -326,7 +330,7 @@ class _BMICalculatorState extends State { children: [ Padding( padding: EdgeInsets.all(8.0), - child: Texts('Weight'), + child: Texts(TranslationBase.of(context).weight), ), ], ), @@ -416,7 +420,7 @@ class _BMICalculatorState extends State { children: [ Padding( padding: EdgeInsets.all(8.0), - child: Texts('Select Unit'), + child: Texts(TranslationBase.of(context).selectUnit), ), ], ), @@ -448,7 +452,8 @@ class _BMICalculatorState extends State { child: Padding( padding: const EdgeInsets.symmetric( vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('KG')), + child: Center( + child: Texts(TranslationBase.of(context).kg)), ), ), ), @@ -477,7 +482,9 @@ class _BMICalculatorState extends State { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Center(child: Texts('LB')), + child: Center( + child: + Texts(TranslationBase.of(context).pound)), ), ), ), @@ -490,27 +497,27 @@ class _BMICalculatorState extends State { height: 25.0, ), Container( - height: 100.0, - width: 350.0, - child: Button( - label: 'CALCULATE', - onTap: () { + margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16), + padding: EdgeInsets.symmetric(vertical: 8), + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + onTap: () => { setState(() { calculateBMI(); - showTextResult(); - showMsg(); + showTextResult(context); + showMsg(context); { Navigator.push( context, - MaterialPageRoute( - builder: (context) => ResultPage( + FadePage( + page: ResultPage( finalResult: bmiResult, textResult: textResult, msg: msg, )), ); } - }); + }) }, ), ), diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart index bfbd10b7..a541b3ce 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmi_calculator/result_page.dart @@ -1,8 +1,13 @@ import 'dart:ffi'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/bmi_calculator/bariatrics-screen.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:percent_indicator/percent_indicator.dart'; @@ -12,6 +17,7 @@ class ResultPage extends StatelessWidget { final String msg; ResultPage({this.finalResult, this.textResult, this.msg}); + Color inductorColor; double percent; @@ -45,53 +51,74 @@ class ResultPage extends StatelessWidget { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: "BMI Calculator", + appBarTitle: + "${TranslationBase.of(context).bmi} ${TranslationBase.of(context).calcHealth}", body: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - SizedBox( - // height: 40.0, - ), - Center( - child: CircularPercentIndicator( - radius: 220.0, - lineWidth: 20.0, - percent: percentInductor(), - center: Column( - mainAxisAlignment: MainAxisAlignment.center, + Expanded( + child: SingleChildScrollView( + child: Column( children: [ - Text( - finalResult.toStringAsFixed(1), - style: TextStyle( - fontSize: 18.0, - fontWeight: FontWeight.bold, + Container( + margin: EdgeInsets.only(top: 50), + child: Center( + child: CircularPercentIndicator( + radius: 220.0, + lineWidth: 20.0, + percent: percentInductor(), + center: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + finalResult.toStringAsFixed(1), + style: TextStyle( + fontSize: 18.0, + fontWeight: FontWeight.bold, + ), + ), + SizedBox( + height: 5.0, + ), + Text( + textResult, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + progressColor: colorInductor(), + backgroundColor: Colors.white, + ), ), ), - SizedBox( - height: 5.0, - ), - Text( - textResult, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.w600, - ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: Texts(msg), ), ], ), - progressColor: colorInductor(), - backgroundColor: Colors.white, ), ), Container( - height: 120, - width: 280.0, - child: Texts(msg), - ), - Container( - width: 350, - child: Button( - label: 'See List Of Doctors', + margin: EdgeInsets.symmetric(horizontal: 16, vertical: 16), + child: BorderedButton( + TranslationBase.of(context).seeListOfDoctor, + fontSize: SizeConfig.textMultiplier * 2.1, + textColor: Colors.white, + vPadding: 8, + hPadding: 8, + backgroundColor: Theme.of(context).primaryColor, + radius: 8, + fontWeight: FontWeight.bold, + handler: (){ + Navigator.push( + context, + FadePage( + page: BariatricsPage(1, 1, finalResult)), + ); + }, ), ), ], diff --git a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart index 1af0f949..9e3d049f 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/bmr_calculator/bmr_calculator.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'dart:math'; @@ -121,6 +123,7 @@ class _BmrCalculatorState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, + isShowDecPage: false, appBarTitle: 'Bmr Calculator', body: Padding( padding: EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), @@ -687,9 +690,9 @@ class _BmrCalculatorState extends State { height: 30.0, ), Container( - height: 100.0, + height: 50.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', onTap: () { setState(() { @@ -699,8 +702,8 @@ class _BmrCalculatorState extends State { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => BmrResultPage( + FadePage( + page: BmrResultPage( bmrResult: bmrResult, calories: calories, )), diff --git a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart index 91847e37..3bda439f 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/body_fat/body_fat.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'dart:math'; @@ -985,8 +987,13 @@ class _BodyFatState extends State { Container( height: 100.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', + // onTap: () => { + // setState(() { + // print('hiii'); + // }) + // } onTap: () { setState(() { calculateBodyFat(); @@ -995,8 +1002,8 @@ class _BodyFatState extends State { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => FatResult( + FadePage( + page: FatResult( bodyFat: bodyFat, fat: fat, textResult: textResult, diff --git a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart index 4361425a..a7f60f68 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart @@ -1,6 +1,9 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'calorie_result_page.dart'; @@ -28,6 +31,7 @@ class _CalorieCalculatorState extends State { int weight = 0; double calories; String dropdownValue; + void updateColor(int type) { //MG/DLT card if (type == 1) { @@ -101,89 +105,91 @@ class _CalorieCalculatorState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Calorie Calculator', - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 15.0), - child: SingleChildScrollView( - child: Container( - height: 890.0, - child: Column( - //mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(10.0), - child: Texts( - 'Calculates daily calorie intake based on several factors, like height, weight, age, gender and daily physical activity rate', - ), - ), - Padding( - padding: - EdgeInsets.symmetric(horizontal: 10.0, vertical: 15.0), - child: Texts('Gender'), - ), - Container( - width: 350, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(35.0), - color: Colors.white, - border: Border.all( - color: Colors.black45, - )), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColor(1); - isMale = false; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: maleCard, - borderRadius: BorderRadius.circular(35.0), + isShowDecPage: false, + appBarTitle: + "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calcHealth}", + body: Column( + children: [ + Expanded( + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + child: Column( + //mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context).calorieCalcDesc, + ), + SizedBox( + height: 8.0, + ), + Texts(TranslationBase.of(context).gender), + SizedBox( + height: 8.0, + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(30.0), + color: Colors.white, + border: Border.all( + color: Colors.black45, + )), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(1); + isMale = false; + }); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration( + color: maleCard, + borderRadius: BorderRadius.circular(30.0), + ), + child: Center( + child: Texts( + TranslationBase.of(context).female)), + ), + ), ), - child: Center(child: Texts('FEMALE')), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColor(2); - isMale = true; - }); - }, - child: Container( - height: 55.0, - width: 170.0, - decoration: BoxDecoration( - color: femaleCard, - borderRadius: BorderRadius.circular(35.0), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColor(2); + isMale = true; + }); + }, + child: Container( + padding: EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration( + color: femaleCard, + borderRadius: BorderRadius.circular(30.0), + ), + child: Center( + child: Texts( + TranslationBase.of(context).male)), + ), + ), ), - child: Center(child: Texts('MALE')), - ), + ], ), - ], - ), - ), - SizedBox( - height: 15.0, - ), - Texts( - 'The Age ( 11 - 120 ) yrs', - ), - SizedBox( - height: 10.0, - ), - Row( - children: [ + ), + SizedBox( + height: 12.0, + ), + Texts( + TranslationBase.of(context).age11_120Years, + ), Container( - width: 340.0, - height: 60.0, + margin: + EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), decoration: BoxDecoration( color: Colors.white, ), @@ -194,7 +200,7 @@ class _CalorieCalculatorState extends State { vertical: 10.0, horizontal: 8.0), child: Center( child: Container( - width: 60.0, + width: 60, foregroundDecoration: BoxDecoration( borderRadius: BorderRadius.circular(5.0), border: Border.all( @@ -205,12 +211,16 @@ class _CalorieCalculatorState extends State { child: Row( children: [ Expanded( - child: Center( - child: Text(age.toString()), + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Center( + child: Text(age.toString()), + ), ), ), Container( - height: 38.0, + padding: + EdgeInsets.symmetric(horizontal: 4), child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -273,16 +283,12 @@ class _CalorieCalculatorState extends State { ], ), ), - ], - ), - Texts( - 'Height', - ), - Row( - children: [ + Texts( + TranslationBase.of(context).height, + ), Container( - width: 340.0, - height: 60.0, + margin: + EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), decoration: BoxDecoration( color: Colors.white, ), @@ -304,12 +310,16 @@ class _CalorieCalculatorState extends State { child: Row( children: [ Expanded( - child: Center( - child: Text(height.toString()), + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Center( + child: Text(height.toString()), + ), ), ), Container( - height: 38.0, + padding: + EdgeInsets.symmetric(horizontal: 4.0), child: Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -372,85 +382,90 @@ class _CalorieCalculatorState extends State { ], ), ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(1); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: - Offset(0, 3), // changes position of shadow - ), - ], - color: cmCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('CM')), - ), - ), + Texts( + TranslationBase.of(context).selectUnit, + ), + SizedBox( + height: 8.0, ), - GestureDetector( - onTap: () { - setState(() { - updateColorHeight(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: ftCard, - borderRadius: BorderRadius.circular(3.0), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: - Offset(0, 3), // changes position of shadow + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColorHeight(1); + }); + }, + child: Container( + padding: EdgeInsets.all(12), + margin: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 7, + offset: Offset( + 0, 3), // changes position of shadow + ), + ], + color: cmCard, + borderRadius: BorderRadius.circular(3.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 0.0, horizontal: 18.0), + child: Center(child: Texts(TranslationBase.of(context).cm)), + ), ), - ], + ), ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Center(child: Texts('Ft')), + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColorHeight(2); + }); + }, + child: Container( + padding: EdgeInsets.all(12), + margin: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: ftCard, + borderRadius: BorderRadius.circular(3.0), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 7, + offset: Offset( + 0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0), + child: Center(child: Texts(TranslationBase.of(context).feet))), + ), + ), ), - ), + ], + ), + SizedBox( + height: 8.0, + ), + Texts( + TranslationBase.of(context).weight, + ), + SizedBox( + height: 5.0, ), - ], - ), - SizedBox( - height: 5.0, - ), - Texts( - 'Weight', - ), - Row( - children: [ Container( - width: 340.0, - height: 60.0, + margin: + EdgeInsets.symmetric(horizontal: 4.0, vertical: 12.0), decoration: BoxDecoration( color: Colors.white, ), @@ -499,7 +514,8 @@ class _CalorieCalculatorState extends State { ), onTap: () { setState(() { - if (weight < 250) weight++; + if (weight < 250) + weight++; }); }, ), @@ -540,137 +556,140 @@ class _CalorieCalculatorState extends State { ], ), ), - ], - ), - Texts('Select Unit'), - SizedBox( - height: 5.0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(1); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: - Offset(0, 3), // changes position of shadow + Texts(TranslationBase.of(context).selectUnit), + SizedBox( + height: 5.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColorWeight(1); + }); + }, + child: Container( + padding: EdgeInsets.all(12), + margin: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 7, + offset: Offset( + 0, 3), // changes position of shadow + ), + ], + color: kgCard, + borderRadius: BorderRadius.circular(3.0), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + vertical: 0.0, horizontal: 18.0), + child: Center(child: Texts(TranslationBase.of(context).kg)), + ), ), - ], - color: kgCard, - borderRadius: BorderRadius.circular(3.0), - ), - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 0.0, horizontal: 18.0), - child: Center(child: Texts('KG')), + ), ), - ), - ), - GestureDetector( - onTap: () { - setState(() { - updateColorWeight(2); - }); - }, - child: Container( - height: 55.0, - width: 150.0, - decoration: BoxDecoration( - color: lbCard, - borderRadius: BorderRadius.circular(3.0), - boxShadow: [ - BoxShadow( - color: Colors.grey.withOpacity(0.5), - spreadRadius: 3, - blurRadius: 7, - offset: - Offset(0, 3), // changes position of shadow + Expanded( + child: GestureDetector( + onTap: () { + setState(() { + updateColorWeight(2); + }); + }, + child: Container( + padding: EdgeInsets.all(12), + margin: EdgeInsets.symmetric(horizontal: 8), + decoration: BoxDecoration( + color: lbCard, + borderRadius: BorderRadius.circular(3.0), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 3, + blurRadius: 7, + offset: Offset( + 0, 3), // changes position of shadow + ), + ], + ), + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0), + child: Center(child: Texts(TranslationBase.of(context).pound)), + ), ), - ], + ), ), - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Center(child: Texts('LB')), + ], + ), + SizedBox( + height: 8.0, + ), + Texts(TranslationBase.of(context).activityLevel), + Container( + child: DropdownButton( + value: dropdownValue, + icon: Icon(Icons.arrow_downward), + iconSize: 24, + elevation: 16, + style: TextStyle(color: Colors.black87), + underline: Container( + height: 2, + color: Colors.black54, ), + onChanged: (String newValue) { + setState(() { + dropdownValue = newValue; + }); + }, + items: [ + 'Almost Inactive(Little or no exercises)', + 'Lighty Active (1-3) days per week', + 'very Active(6-7) days per week', + 'Super Active(very hard exercises)' + ].map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), ), ), - ], - ), - SizedBox( - height: 5.0, - ), - Texts('Activity level'), - Container( - width: 300, - child: DropdownButton( - value: dropdownValue, - icon: Icon(Icons.arrow_downward), - iconSize: 24, - elevation: 16, - style: TextStyle(color: Colors.black87), - underline: Container( - height: 2, - color: Colors.black54, + SizedBox( + height: 25.0, ), - onChanged: (String newValue) { - setState(() { - dropdownValue = newValue; - }); - }, - items: [ - 'Almost Inactive(Little or no exercises)', - 'Lighty Active (1-3) days per week', - 'very Active(6-7) days per week', - 'Super Active(very hard exercises)' - ].map>((String value) { - return DropdownMenuItem( - value: value, - child: Text(value), - ); - }).toList(), - ), - ), - SizedBox( - height: 25.0, - ), - Container( - height: 100.0, - width: 350.0, - child: Button( - label: 'CALCULATE', - onTap: () { - setState(() { - calculateCalories(); - print(calories); - { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => CalorieResultPage( - calorie: calories, - )), - ); - } - }); - }, - ), + ], ), - ], + ), + ), + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.0, vertical: 16.0), + child: SecondaryButton( + label: TranslationBase.of(context).calculate, + onTap: () { + setState(() { + calculateCalories(); + print(calories); + { + Navigator.push( + context, + FadePage( + page: CalorieResultPage( + calorie: calories, + )), + ); + } + }); + }, ), ), - ), + ], ), ); } diff --git a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart index 5c52ecb0..110b2afc 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_result_page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -12,7 +13,8 @@ class CalorieResultPage extends StatelessWidget { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: 'Calorie Calculator', + isShowDecPage: false, + appBarTitle: "${TranslationBase.of(context).calories} ${TranslationBase.of(context).calculators}", isShowAppBar: true, body: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, diff --git a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart index e273b075..78a737bb 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart @@ -1,9 +1,10 @@ +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'dart:math'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:flutter/services.dart'; import 'carbs_result_page.dart'; @@ -206,8 +207,7 @@ class _CarbsState extends State { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => CalorieCalculator()), + FadePage(page: CalorieCalculator()), ); } }); @@ -329,9 +329,9 @@ class _CarbsState extends State { height: 55.0, ), Container( - height: 100.0, + height: 50.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', onTap: () { setState(() { @@ -339,8 +339,8 @@ class _CarbsState extends State { calculate(); Navigator.push( context, - MaterialPageRoute( - builder: (context) => CarbsResult( + FadePage( + page: CarbsResult( cCal: cCal, pCal: pCal, fCal: fCal, diff --git a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart index c9993b95..d19c6017 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/delivery_due/delivery_due.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:intl/intl.dart'; @@ -111,17 +113,17 @@ class _DeliveryDueState extends State { height: 280.0, ), Container( - height: 100.0, + height: 50.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', onTap: () { setState(() { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => DeliveryDueResult( + FadePage( + page: DeliveryDueResult( conceivedDate: conceivedDate, dateFrom: dateFrom, dateTo: dateTo, diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart index 9bdbfb36..4e0b1391 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ideal_body/ideal_body.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'dart:math'; @@ -518,7 +520,7 @@ class _IdealBodyState extends State { Container( height: 100.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', onTap: () { setState(() { @@ -531,8 +533,8 @@ class _IdealBodyState extends State { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => IdealBodyResult( + FadePage( + page: IdealBodyResult( idealBodyWeight: idealWeight, minRange: minRange, mixRange: maxRange, diff --git a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart index 1a272c11..508e8590 100644 --- a/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart +++ b/lib/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:intl/intl.dart'; @@ -319,17 +321,17 @@ class _OvulationPeriodState extends State { height: 220.0, ), Container( - height: 100.0, + height: 50.0, width: 350.0, - child: Button( + child: SecondaryButton( label: 'CALCULATE', onTap: () { setState(() { { Navigator.push( context, - MaterialPageRoute( - builder: (context) => OvulationResult( + FadePage( + page: OvulationResult( conceivedDate: conceivedDate, dateFrom: dateFrom, dateTo: dateTo, diff --git a/lib/pages/AlHabibMedicalService/health_converter.dart b/lib/pages/AlHabibMedicalService/health_converter.dart index 61ea406f..5ae80183 100644 --- a/lib/pages/AlHabibMedicalService/health_converter.dart +++ b/lib/pages/AlHabibMedicalService/health_converter.dart @@ -18,7 +18,8 @@ class _HealthConverterState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Health Converter', + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).converters, body: Column( children: [ Container( @@ -37,9 +38,9 @@ class _HealthConverterState extends State { ); }, child: MedicalProfileItem( - title: 'Blood', + title: TranslationBase.of(context).bloodSugar, imagePath: 'blood_sugar_icon.png', - subTitle: 'Sugar', + subTitle: TranslationBase.of(context).sugar, ), ), ), @@ -55,9 +56,9 @@ class _HealthConverterState extends State { ); }, child: MedicalProfileItem( - title: 'Blood', + title: TranslationBase.of(context).bloodCholesterol, imagePath: 'blood_cholesterol_icon.png', - subTitle: 'Cholesterol', + subTitle: TranslationBase.of(context).cholesterol, ), ), ), @@ -77,9 +78,9 @@ class _HealthConverterState extends State { ); }, child: MedicalProfileItem( - title: 'Triglycerides', + title: TranslationBase.of(context).triglycerides, imagePath: 'triglycerides_blood_icon.png', - subTitle: 'Fat in blood', + subTitle: TranslationBase.of(context).fatInBlood, ), ), ), diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart index 58caee36..513b50ab 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_cholesterol.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; @@ -62,7 +63,7 @@ class _BloodCholesterolState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Blood Cholesterol ', + appBarTitle: TranslationBase.of(context).bloodCholesterol, body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( @@ -74,7 +75,7 @@ class _BloodCholesterolState extends State { Container( width: 350.0, child: Text( - 'Convert blood cholesterol from\n mmol/l to mg/dlt and vice versa.', + TranslationBase.of(context).convertCholesterolStatement, //textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0), ), @@ -95,7 +96,7 @@ class _BloodCholesterolState extends State { child: Row( children: [ Texts( - 'Convert from', + TranslationBase.of(context).convertFrom, ), ], ), @@ -117,7 +118,7 @@ class _BloodCholesterolState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( boxShadow: [ @@ -150,7 +151,7 @@ class _BloodCholesterolState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( color: cardMMOLColor, @@ -196,7 +197,7 @@ class _BloodCholesterolState extends State { decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide(color: Colors.black45)), - labelText: " Enter the reading value", + labelText: TranslationBase.of(context).enterReadingValue, labelStyle: TextStyle( color: Colors.black87, ), @@ -209,7 +210,7 @@ class _BloodCholesterolState extends State { Visibility( visible: _visible, child: Container( - height: 95.0, + height: 115.0, width: 350.0, decoration: BoxDecoration( color: Colors.white, @@ -222,7 +223,7 @@ class _BloodCholesterolState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Texts('Result:'), + Texts(TranslationBase.of(context).result + ":"), Row( children: [ Text( @@ -252,10 +253,10 @@ class _BloodCholesterolState extends State { ), Flexible( child: Container( - height: 100.0, + height: 60.0, width: 150.0, - child: Button( - label: 'CALCULATE', + child: SecondaryButton( + label: TranslationBase.of(context).calculate, onTap: () { setState(() { _visible == false diff --git a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart index f5d66ccf..8a7e9792 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/blood_sugar.dart @@ -64,7 +64,7 @@ class _BloodSugarState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Blood Sugar Conversion', + appBarTitle: TranslationBase.of(context).bloodSugarConversion, body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( @@ -76,7 +76,7 @@ class _BloodSugarState extends State { Container( width: 350.0, child: Text( - 'Convert blood sugar/glucose from mmol/l (UK standard) to mg/dlt (US standard) and vice versa.', + TranslationBase.of(context).convertBloodSugarStatement, //textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0), ), @@ -97,7 +97,7 @@ class _BloodSugarState extends State { child: Row( children: [ Texts( - 'Convert from', + TranslationBase.of(context).convertFrom, ) ], ), @@ -119,7 +119,7 @@ class _BloodSugarState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( boxShadow: [ @@ -152,7 +152,7 @@ class _BloodSugarState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( color: cardMMOLColor, @@ -196,7 +196,7 @@ class _BloodSugarState extends State { ], keyboardType: TextInputType.number, decoration: InputDecoration( - labelText: " Enter the reading value", + labelText: TranslationBase.of(context).enterReadingValue, border: OutlineInputBorder( borderSide: BorderSide(color: Colors.black45)), labelStyle: TextStyle( @@ -211,7 +211,7 @@ class _BloodSugarState extends State { Visibility( visible: _visible, child: Container( - height: 95.0, + height: 115.0, width: 350.0, decoration: BoxDecoration( color: Colors.white, @@ -224,7 +224,7 @@ class _BloodSugarState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Texts('Result:'), + Texts(TranslationBase.of(context).result + ": "), Row( children: [ Text( @@ -254,10 +254,10 @@ class _BloodSugarState extends State { ), Flexible( child: Container( - height: 100.0, + height: 60.0, width: 150.0, - child: Button( - label: 'CALCULATE', + child: SecondaryButton( + label: TranslationBase.of(context).calculate, onTap: () { setState(() { _visible == false diff --git a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart index a86fdb88..4c5f9a83 100644 --- a/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart +++ b/lib/pages/AlHabibMedicalService/health_converter/triglycerides.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -64,7 +65,7 @@ class _TriglyceridesState extends State { Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Triglycerides', + appBarTitle: TranslationBase.of(context).triglycerides, body: Padding( padding: const EdgeInsets.all(16.0), child: SingleChildScrollView( @@ -76,7 +77,7 @@ class _TriglyceridesState extends State { Container( width: 350.0, child: Text( - 'Convert Triglycerides from mmol/l to\n mg/dlt and vice versa.', + TranslationBase.of(context).triglyceridesConvertStatement, //textAlign: TextAlign.center, style: TextStyle(fontSize: 20.0), ), @@ -95,7 +96,9 @@ class _TriglyceridesState extends State { Padding( padding: const EdgeInsets.symmetric(horizontal: 15.0), child: Row( - children: [Texts('Convert from')], + children: [ + Texts(TranslationBase.of(context).convertFrom) + ], ), ), SizedBox( @@ -115,7 +118,7 @@ class _TriglyceridesState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( boxShadow: [ @@ -148,7 +151,7 @@ class _TriglyceridesState extends State { }); }, child: Container( - height: 55.0, + height: 65.0, width: 150.0, decoration: BoxDecoration( color: cardMMOLColor, @@ -194,7 +197,7 @@ class _TriglyceridesState extends State { decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide(color: Colors.black45)), - labelText: " Enter the reading value", + labelText: TranslationBase.of(context).enterReadingValue, labelStyle: TextStyle( color: Colors.black87, ), @@ -207,7 +210,7 @@ class _TriglyceridesState extends State { Visibility( visible: _visible, child: Container( - height: 95.0, + height: 115.0, width: 350.0, decoration: BoxDecoration( color: Colors.white, @@ -220,7 +223,7 @@ class _TriglyceridesState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.center, children: [ - Texts('Result:'), + Texts(TranslationBase.of(context).result + ":"), Row( children: [ Text( @@ -250,10 +253,11 @@ class _TriglyceridesState extends State { ), Flexible( child: Container( - height: 100.0, + height: 60.0, width: 250.0, - child: Button( - label: 'CALCULATE', + child: SecondaryButton( + label: + TranslationBase.of(context).calculate.toUpperCase(), onTap: () { setState(() { _visible == false diff --git a/lib/pages/AlHabibMedicalService/​ health_calculators.dart b/lib/pages/AlHabibMedicalService/​ health_calculators.dart index d3bd4bed..dbd8939c 100644 --- a/lib/pages/AlHabibMedicalService/​ health_calculators.dart +++ b/lib/pages/AlHabibMedicalService/​ health_calculators.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculat import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/calorie_calculator/calorie_calculator.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/carbs/carbs.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health_calculator/ovulation_period/ovulation_period.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -37,7 +38,8 @@ class _HealthCalculatorsState extends State Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, - appBarTitle: 'Health Calculators', + isShowDecPage: false, + appBarTitle: TranslationBase.of(context).calculators, body: Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( @@ -64,7 +66,7 @@ class _HealthCalculatorsState extends State isScrollable: true, indicatorWeight: 4.0, indicatorColor: Colors.red, - labelColor: Theme.of(context).primaryColor, + labelColor: Theme.of(context).buttonColor, labelPadding: EdgeInsets.symmetric(horizontal: 13.0, vertical: 2.0), unselectedLabelColor: Colors.grey, @@ -72,13 +74,15 @@ class _HealthCalculatorsState extends State Container( width: MediaQuery.of(context).size.width * 0.35, child: Center( - child: Texts('General Health'), + child: Texts( + TranslationBase.of(context).generalHealth), ), ), Container( width: MediaQuery.of(context).size.width * 0.35, child: Center( - child: Texts("Women's Health"), + child: + Texts(TranslationBase.of(context).womanHealth), ), ), ], @@ -115,9 +119,10 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'BMI', + title: TranslationBase.of(context).bmi, imagePath: 'bmi_health_calculator.png', - subTitle: 'Calculators', + subTitle: + TranslationBase.of(context).calcHealth, ), ), ), @@ -133,9 +138,10 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Calories', + title: TranslationBase.of(context).calories, imagePath: 'calories-calculator.png', - subTitle: 'Calculators', + subTitle: + TranslationBase.of(context).calcHealth, ), ), ), @@ -155,9 +161,10 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'BMR', + title: TranslationBase.of(context).bmr, imagePath: 'BMR_calculator.png', - subTitle: 'Calculators', + subTitle: + TranslationBase.of(context).calcHealth, ), ), ), @@ -173,9 +180,9 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Ideal Body', + title: TranslationBase.of(context).idealBody, imagePath: 'body_weight.png', - subTitle: 'Weight', + subTitle: TranslationBase.of(context).weight, ), ), ), @@ -195,9 +202,9 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Body', + title: TranslationBase.of(context).bodyWord, imagePath: 'body_fat.png', - subTitle: 'Fat', + subTitle: TranslationBase.of(context).fat, ), ), ), @@ -213,9 +220,11 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Carbohydrate', + title: + TranslationBase.of(context).carbohydrate, imagePath: 'carb_protein.png', - subTitle: 'Protein Fat', + subTitle: + TranslationBase.of(context).proteinFat, ), ), ), @@ -243,9 +252,9 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Ovulation', + title: TranslationBase.of(context).ovulation, imagePath: 'ovulation_period_icon.png', - subTitle: 'Period', + subTitle: TranslationBase.of(context).period, ), ), ), @@ -261,9 +270,9 @@ class _HealthCalculatorsState extends State ); }, child: MedicalProfileItem( - title: 'Delivery', + title: TranslationBase.of(context).delivery, imagePath: 'delivery_date_icon.png', - subTitle: 'Due Date', + subTitle: TranslationBase.of(context).dueDate, ), ), ), diff --git a/lib/pages/Blood/blood_donation.dart b/lib/pages/Blood/blood_donation.dart index 99e5242e..adff790c 100644 --- a/lib/pages/Blood/blood_donation.dart +++ b/lib/pages/Blood/blood_donation.dart @@ -1,25 +1,21 @@ - import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/blood_groub_details.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; + //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info.dart'; -import 'package:diplomaticquarterapp/core/service/blood/blood_details_servies.dart'; -import 'package:diplomaticquarterapp/core/viewModels/blooddonation/blood_details_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/models/FamilyFiles/GetAllSharedRecordByStatusResponse.dart'; import 'package:diplomaticquarterapp/pages/Blood/user_agreement_page.dart'; -import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectCiteisDialog.dart'; -import 'package:diplomaticquarterapp/pages/medical/balance/dialogs/SelectHospitalDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -27,20 +23,17 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:giffy_dialog/giffy_dialog.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:provider/provider.dart'; -//import '../../../core/model/my_balance/AdvanceModel.dart'; -import 'confirm_payment_page.dart'; import 'dialogs/SelectBeneficiaryDialog.dart'; import 'dialogs/SelectBloodDialog.dart'; import 'dialogs/SelectGenderDialog.dart'; import 'dialogs/SelectPatientFamilyDialog.dart'; import 'dialogs/SelectPatientInfoDialog.dart'; -import 'new_text_Field.dart'; enum BeneficiaryType { MyAccount, MyFamilyFiles, OtherAccount, NON } -enum Gender{Male,Female,NON} -enum Blood{Oplus,Ominus,Aplus,Aminus,Bplus,Bminus,ABplus,ABminus,NON} +enum Gender { Male, Female, NON } +enum Blood { Oplus, Ominus, Aplus, Aminus, Bplus, Bminus, ABplus, ABminus, NON } class BloodDonationPage extends StatefulWidget { @override @@ -51,8 +44,8 @@ class _BloodDonationPageState extends State { TextEditingController _fileTextController = TextEditingController(); TextEditingController _notesTextController = TextEditingController(); BeneficiaryType beneficiaryType = BeneficiaryType.NON; - Gender gender = Gender.Male;//Gender.NON; - Blood blood = Blood.Aminus;//Blood.NON; + Gender gender = Gender.Male; //Gender.NON; + Blood blood = Blood.Aminus; //Blood.NON; //HospitalsModel _selectedHospital; CitiesModel _selectedHospital; @@ -62,22 +55,28 @@ class _BloodDonationPageState extends State { AuthenticatedUser authenticatedUser; GetAllSharedRecordsByStatusList selectedPatientFamily; AdvanceModel advanceModel = AdvanceModel(); - List_BloodGroupDetailsModel bloodDetails=List_BloodGroupDetailsModel(); + List_BloodGroupDetailsModel bloodDetails = + List_BloodGroupDetailsModel(bloodGroup: "A-"); AppSharedPreferences sharedPref = AppSharedPreferences(); AuthenticatedUser authUser; - var checkedValue = false; + var checkedValue = false; + @override void initState() { super.initState(); getAuthUser(); } + @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return BaseView( - onModelReady: (model) => model.getCities(),//model.getHospitals(), + onModelReady: (model) => model.getCities(), //model.getHospitals(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: "Blood Donation",//TranslationBase.of(context).advancePayment, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).bloodD, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -86,26 +85,27 @@ class _BloodDonationPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - // TranslationBase.of(context).advancePaymentLabel, - "Enter the required information, In order to register for Blood Donation Service",//+model.user.firstName, + TranslationBase.of(context).bloodDEnterDesc, textAlign: TextAlign.center, ), SizedBox( height: 12, ), InkWell( - onTap: () => confirmSelectHospitalDialog(model.CitiesModelList),//model.hospitals + onTap: () => + confirmSelectHospitalDialog(model.CitiesModelList), + //model.hospitals child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getHospitalName()), + Texts(getHospitalName(projectProvider, context)), Icon(Icons.arrow_drop_down) ], ), @@ -116,68 +116,39 @@ class _BloodDonationPageState extends State { ), InkWell( //======Gender======== - onTap: () => confirmSelectGenderDialog(),//confirmSelectBeneficiaryDialog(model), + onTap: () => confirmSelectGenderDialog(), + //confirmSelectBeneficiaryDialog(model), child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ //Texts(getBeneficiaryType()), - Texts(getGender()), + Texts(getGender(context)), Icon(Icons.arrow_drop_down) ], ), ), ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // SizedBox( - // height: 12, - // ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // InkWell( - // onTap: () { - // model.getFamilyFiles().then((value) { - // confirmSelectFamilyDialog(model - // .getAllSharedRecordsByStatusResponse - // .getAllSharedRecordsByStatusList); - // }).showProgressBar( - // text: "Loading", - // backgroundColor: Colors.blue.withOpacity(0.6)); - // }, - // child: Container( - // padding: EdgeInsets.all(12), - // width: double.infinity, - // height: 65, - // decoration: BoxDecoration( - // borderRadius: BorderRadius.circular(12), - // color: Colors.white), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Texts(getFamilyMembersName()), - // Icon(Icons.arrow_drop_down) - // ], - // ), - // ), - // ), SizedBox( height: 12, ), InkWell( //======Gender======== - onTap: () => confirmSelectBloodDialog(),//confirmSelectBeneficiaryDialog(model), + onTap: () => confirmSelectBloodDialog(), + //confirmSelectBeneficiaryDialog(model), child: Container( padding: EdgeInsets.all(12), width: double.infinity, height: 65, decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), - color: Colors.white), + color: Theme.of(context).primaryColor), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -188,55 +159,28 @@ class _BloodDonationPageState extends State { ), ), ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // SizedBox( - // height: 12, - // ), - // if (beneficiaryType == BeneficiaryType.MyFamilyFiles) - // InkWell( - // onTap: () { - // model.getFamilyFiles().then((value) { - // confirmSelectFamilyDialog(model - // .getAllSharedRecordsByStatusResponse - // .getAllSharedRecordsByStatusList); - // }).showProgressBar( - // text: "Loading", - // backgroundColor: Colors.blue.withOpacity(0.6)); - // }, - // child: Container( - // padding: EdgeInsets.all(12), - // width: double.infinity, - // height: 65, - // decoration: BoxDecoration( - // borderRadius: BorderRadius.circular(12), - // color: Colors.white), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Texts(getFamilyMembersName()), - // Icon(Icons.arrow_drop_down) - // ], - // ), - // ), - // ), SizedBox( height: 12, ), Row( children: [ Container( - child: Text(" To view the terms and conditions "), + child: Text( + TranslationBase.of(context).viewTermsConditions), ), SizedBox( width: MediaQuery.of(context).size.height * 0.10, ), InkWell( onTap: () { - Navigator.of(context).push(MaterialPageRoute( - builder: (BuildContext context) => UserAgreementPage())); + Navigator.of(context) + .push(FadePage(page: UserAgreementPage())); }, child: Container( - child: Texts(" Click here ",color: Colors.blue,), + child: Texts( + TranslationBase.of(context).clickHere, + color: Colors.blue, + ), ), ) ], @@ -247,99 +191,34 @@ class _BloodDonationPageState extends State { Row( children: [ Checkbox( - onChanged: (bool value) { + onChanged: (bool value) { setState(() { checkedValue = value; }); }, - // tristate: checkedValue==true,//i == 1, + // tristate: checkedValue==true,//i == 1, value: checkedValue, - activeColor: Colors.red,//Color(0xFF6200EE), + activeColor: Color(0xFFc5272d), //Color(0xFF6200EE), + ), + SizedBox( + height: 10, + ), + Row( + children: [], ), - SizedBox(height: 10,), - Row(children: [ - - ],), SizedBox( width: 10, ), Text( - 'I agree to the terms and conditions ', - style: Theme.of(context).textTheme.subtitle1.copyWith(color: checkedValue? Colors.red : Colors.black), + TranslationBase.of(context) + .iAgreeToTheTermsAndConditions, + style: Theme.of(context).textTheme.subtitle1.copyWith( + color: checkedValue + ? Color(0xFFc5272d) + : Colors.black), ), ], ), - // NewTextFields( - // hintText: TranslationBase.of(context).fileNumber, - // controller: _fileTextController, - // ), - // if (beneficiaryType == BeneficiaryType.OtherAccount) - // SizedBox( - // height: 12, - // ), - // if (beneficiaryType == BeneficiaryType.OtherAccount) - // InkWell( - // onTap: () { - // if (_fileTextController.text.isNotEmpty) - // model - // .getPatientInfoByPatientID( - // id: _fileTextController.text) - // .then((value) { - // confirmSelectPatientDialog(model.patientInfoList); - // }).showProgressBar( - // text: "Loading", - // backgroundColor: - // Colors.blue.withOpacity(0.6)); - // else - // AppToast.showErrorToast( - // message: 'Please Enter The File Number'); - // }, - // child: Container( - // padding: EdgeInsets.all(12), - // width: double.infinity, - // height: 65, - // decoration: BoxDecoration( - // borderRadius: BorderRadius.circular(12), - // color: Colors.white), - // child: Row( - // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // Texts(getPatientName()), - // Icon(Icons.arrow_drop_down) - // ], - // ), - // ), - // ), - // SizedBox( - // height: 12, - // ), - - // NewTextFields( - // hintText: TranslationBase.of(context).amount, - // keyboardType: TextInputType.number, - // onChanged: (value) { - // setState(() { - // amount = value; - // }); - // }, - // ), - // SizedBox( - // height: 12, - // ), - // NewTextFields( - // hintText: TranslationBase.of(context).depositorEmail, - // initialValue: model.user.emailAddress, - // onChanged: (value) { - // email = value; - // }, - // ), - // SizedBox( - // height: 12, - // ), - // NewTextFields( - // hintText: TranslationBase.of(context).notes, - // controller: _notesTextController, - // ), SizedBox( height: 10, ), @@ -349,42 +228,37 @@ class _BloodDonationPageState extends State { children: [ Center( child: Container( - color: Colors.white, + color: Theme.of(context).primaryColor, width: 350, child: InkWell( onTap: () { showDialog( context: context, - builder: (_) => - AssetGiffyDialog( + builder: (_) => AssetGiffyDialog( title: Text( "", style: TextStyle( fontSize: 22.0, - fontWeight: - FontWeight - .w600), + fontWeight: FontWeight.w600), ), image: Image.asset( 'assets/images/BloodChrt_EN.png'), - buttonCancelText: - Text('cancel'), - buttonCancelColor: - Colors.grey, + buttonCancelText: Text( + TranslationBase.of(context).cancel), + buttonCancelColor: Colors.grey, onlyCancelButton: true, )); }, child: Container( width: 250, height: 200, - child:Image.asset( + child: Image.asset( 'assets/images/BloodChrt_EN.png')), ), ), ), ], ), - SizedBox( height: MediaQuery.of(context).size.height * 0.15, ) @@ -395,25 +269,42 @@ class _BloodDonationPageState extends State { bottomSheet: Container( height: MediaQuery.of(context).size.height * 0.12, width: double.infinity, - padding: EdgeInsets.all(12), child: SecondaryButton( textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "Save", - // - onTap: (){ - - bloodDetails.city=_selectedHospital.toString(); - - // bloodDetails. + color: checkedValue == false + ? Color(0xFFa0a4a6) + : Color.fromRGBO( + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).save, + onTap: () async { + if (_selectedHospital == null) { + AppToast.showErrorToast( + message: TranslationBase.of(context).selectCity); + return; + } + bloodDetails.city = projectProvider.isArabic + ? _selectedHospital.descriptionN + : _selectedHospital.description; + bloodDetails.cityCode = _selectedHospital.iD.toString(); + bloodDetails.gender = gender == Gender.Male ? 1 : 2; + await model.updateBloodGroup(bloodDetails); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: model.updatedRegisterBloodMessage); + } else { + AppToast.showErrorToast(message: model.error); + } }, - - ), )), ); } + //============== void confirmSelectBeneficiaryDialog(MyBalanceViewModel model) { showDialog( @@ -435,94 +326,85 @@ class _BloodDonationPageState extends State { ), ); } - void confirmSelectBloodDialog(){ + + void confirmSelectBloodDialog() { showDialog( context: context, - child: SelectBloodDialog(bloodType: blood, + child: SelectBloodDialog( + bloodType: blood, onValueSelected: (value) { setState(() { if (value == Blood.Oplus) { - bloodDetails.bloodGroup="O+"; + bloodDetails.bloodGroup = "O+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Ominus) { + } else if (value == Blood.Ominus) { // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.bloodGroup="O-"; + bloodDetails.bloodGroup = "O-"; // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.ABplus) { - bloodDetails.bloodGroup="AB+"; + } else if (value == Blood.ABplus) { + bloodDetails.bloodGroup = "AB+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.ABminus) { - bloodDetails.bloodGroup="AB-"; + } else if (value == Blood.ABminus) { + bloodDetails.bloodGroup = "AB-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Aplus) { - bloodDetails.bloodGroup="A+"; + } else if (value == Blood.Aplus) { + bloodDetails.bloodGroup = "A+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Aminus) { - bloodDetails.bloodGroup="A-"; + } else if (value == Blood.Aminus) { + bloodDetails.bloodGroup = "A-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Bplus) { - bloodDetails.bloodGroup="B+"; + } else if (value == Blood.Bplus) { + bloodDetails.bloodGroup = "B+"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - }else - if (value == Blood.Bminus) { - bloodDetails.bloodGroup="B-"; + } else if (value == Blood.Bminus) { + bloodDetails.bloodGroup = "B-"; // _fileTextController.text = model.user.patientID.toString(); // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; - } - - - else + } else _fileTextController.text = ""; // beneficiaryType = value; - blood=value; - } - - - - - ); + blood = value; + }); }, ), ); } - void confirmSelectGenderDialog(){ + + void confirmSelectGenderDialog() { showDialog( context: context, - child: SelectGenderDialog(beneficiaryType: gender, + child: SelectGenderDialog( + beneficiaryType: gender, onValueSelected: (value) { setState(() { if (value == Gender.Male) { // _fileTextController.text = model.user.patientID.toString(); - bloodDetails.patientType=1; + bloodDetails.patientType = 1; // advanceModel.depositorName = // model.user.firstName + " " + model.user.lastName; } else - // _fileTextController.text = ""; - {bloodDetails.gender=2;} + // _fileTextController.text = ""; + { + bloodDetails.gender = 2; + } - // beneficiaryType = value; - gender=value; + // beneficiaryType = value; + gender = value; }); }, ), @@ -591,23 +473,25 @@ class _BloodDonationPageState extends State { return TranslationBase.of(context).otherAccount; break; case BeneficiaryType.NON: - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectBeneficiary; } - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectBeneficiary; } - String getGender() { + + String getGender(BuildContext context) { switch (gender) { case Gender.Male: - return "Male"; + return TranslationBase.of(context).male; case Gender.Female: - return "Female"; + return TranslationBase.of(context).female; break; case Gender.NON: - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectGender; } - return "Select Gender";//TranslationBase.of(context).selectBeneficiary; + return TranslationBase.of(context).selectGender; } + String getBlood() { switch (blood) { case Blood.Oplus: @@ -639,18 +523,20 @@ class _BloodDonationPageState extends State { break; case Blood.NON: - return "Select Blood Type";//TranslationBase.of(context).selectBeneficiary; + return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; } - return "Select Blood Type";//TranslationBase.of(context).selectBeneficiary; + return "Select Blood Type"; //TranslationBase.of(context).selectBeneficiary; } - String getHospitalName() { + String getHospitalName( + ProjectViewModel projectProvider, BuildContext context) { if (_selectedHospital != null) - return _selectedHospital.description; + return projectProvider.isArabic + ? _selectedHospital.descriptionN + : _selectedHospital.description; else - return - "Riyadh"; - // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; + return TranslationBase.of(context).selectCity; + // return List_BloodGroupDetailsModel.fromJson(0).city.toString();//"Select City";//TranslationBase.of(context).selectHospital; } String getPatientName() { @@ -677,8 +563,6 @@ class _BloodDonationPageState extends State { return TranslationBase.of(context).selectFamilyPatientName; } - - //================ - +//================ } diff --git a/lib/pages/Blood/confirm_payment_page.dart b/lib/pages/Blood/confirm_payment_page.dart index 75282190..c384b7b5 100644 --- a/lib/pages/Blood/confirm_payment_page.dart +++ b/lib/pages/Blood/confirm_payment_page.dart @@ -2,7 +2,6 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/AdvanceModel.dart'; import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobile_number.dart'; -import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -166,7 +165,7 @@ class ConfirmPaymentPage extends StatelessWidget { patientID: int.parse(advanceModel.fileNumber), projectID: advanceModel.hospitalsModel.iD) .then((value) { - GifLoaderDialogUtils.hideDialog(context); + GifLoaderDialogUtils.hideDialog(context); if (model.state != ViewState.ErrorLocal && model.state != ViewState.Error) showSMSDialog(); }); @@ -218,7 +217,8 @@ class ConfirmPaymentPage extends StatelessWidget { authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, - browser); + browser, + false); } onBrowserLoadStart(String url) { @@ -277,8 +277,8 @@ class ConfirmPaymentPage extends StatelessWidget { String paymentReference = res['Fort_id'].toString(); GifLoaderDialogUtils.showMyDialog(AppGlobal.context); service - .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], res['Fort_id'], - res['PaymentMethod'], AppGlobal.context) + .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], + res['Fort_id'], res['PaymentMethod'], AppGlobal.context) .then((res) { GifLoaderDialogUtils.hideDialog(AppGlobal.context); print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); @@ -315,5 +315,4 @@ class ConfirmPaymentPage extends StatelessWidget { Future navigateToHome(context) async { Navigator.of(context).pushNamed(HOME); } - } diff --git a/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart b/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart index d165a895..5cfb2372 100644 --- a/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart +++ b/lib/pages/Blood/dialogs/ConfirmSMSDialog.dart @@ -8,13 +8,13 @@ import 'package:diplomaticquarterapp/core/model/my_balance/patient_info_and_mobi import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class ConfirmSMSDialog extends StatefulWidget { final String phoneNumber; @@ -112,32 +112,31 @@ class _ConfirmSMSDialogState extends State { height: 40, color: Theme.of(context).primaryColor, child: Stack( - children: [ Center( - child: Texts( - 'SMS', - color: Colors.white, - textAlign: TextAlign.center, - ), - ), - Positioned(child: Container( - child: InkWell( - onTap: () => Navigator.pop(context), - child: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, color: Colors.white), - child: Icon( - Icons.clear, - color: Colors.grey[900], - )), + child: Texts( + 'SMS', + color: Colors.white, + textAlign: TextAlign.center, ), ), - left: projectViewModel.isArabic? 2:0, - right: projectViewModel.isArabic? 0:2, + Positioned( + child: Container( + child: InkWell( + onTap: () => Navigator.pop(context), + child: Container( + decoration: BoxDecoration( + shape: BoxShape.circle, color: Colors.white), + child: Icon( + Icons.clear, + color: Colors.grey[900], + )), + ), + ), + left: projectViewModel.isArabic ? 2 : 0, + right: projectViewModel.isArabic ? 0 : 2, ) ], - ), ), Image.asset( @@ -335,14 +334,13 @@ class _ConfirmSMSDialogState extends State { void submit(MyBalanceViewModel model) { if (verifyAccountForm.currentState.validate()) { + GifLoaderDialogUtils.showMyDialog(context); final activationCode = digit1.text + digit2.text + digit3.text + digit4.text; model .checkActivationCodeForAdvancePayment(activationCode: activationCode) - .then((value) {}) - .showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) .then((value) { + GifLoaderDialogUtils.hideDialog(context); Navigator.pop(context, true); }); } diff --git a/lib/pages/Blood/dialogs/SelectGenderDialog.dart b/lib/pages/Blood/dialogs/SelectGenderDialog.dart index 295c6dcd..a097ae8e 100644 --- a/lib/pages/Blood/dialogs/SelectGenderDialog.dart +++ b/lib/pages/Blood/dialogs/SelectGenderDialog.dart @@ -38,7 +38,7 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Male"), + title: Text(TranslationBase.of(context).male), leading: Radio( value: Gender.Male, groupValue: beneficiaryType, @@ -68,7 +68,7 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Female"), + title: Text(TranslationBase.of(context).female), leading: Radio( value: Gender.Female, groupValue: beneficiaryType, diff --git a/lib/pages/Blood/dialogs/SelectHospitalDialog.dart b/lib/pages/Blood/dialogs/SelectHospitalDialog.dart index 9a4a359d..c7554c20 100644 --- a/lib/pages/Blood/dialogs/SelectHospitalDialog.dart +++ b/lib/pages/Blood/dialogs/SelectHospitalDialog.dart @@ -49,8 +49,7 @@ class _SelectHospitalDialogState extends State { }); }, child: ListTile( - title: Text(widget.hospitals[index].name + - ' ${widget.hospitals[index].distanceInKilometers} KM'), + title: Text(widget.hospitals[index].name), leading: Radio( value: widget.hospitals[index], groupValue: widget.selectedHospital, diff --git a/lib/pages/Blood/my_balance_page.dart b/lib/pages/Blood/my_balance_page.dart deleted file mode 100644 index 26665c2b..00000000 --- a/lib/pages/Blood/my_balance_page.dart +++ /dev/null @@ -1,110 +0,0 @@ -import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - -import 'advance_payment_page.dart'; -import 'blood_donation.dart'; - -class MyBalancePage extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getPatientAdvanceBalanceAmount(), - builder: (_, model, w) => AppScaffold( - baseViewModel: model, - isShowAppBar: true, - appBarTitle: TranslationBase.of(context).myBalances, - body: Container( - margin: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context).balanceAmount, - color: Colors.black, - bold: true, - ), - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(8), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - color: HexColor('#B61422'), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(7), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).totalBalance, - color: Colors.white, - ), - Texts( - '${model.totalAdvanceBalanceAmount ?? 0} SAR', - color: Colors.white, - bold: true, - ), - ], - ), - ), - SizedBox( - height: 9, - ), - ...List.generate( - model.patientAdvanceBalanceAmountList.length, - (index) => Container( - padding: EdgeInsets.all(8), - height: 65, - margin: EdgeInsets.only(top: 8), - decoration: BoxDecoration( - color: Colors.white, - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(7), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(model.patientAdvanceBalanceAmountList[index] - .projectDescription), - Texts( - '${model.patientAdvanceBalanceAmountList[index].patientAdvanceBalanceAmount} SAR', - bold: true, - ), - ], - ), - ), - ), - ], - ), - ), - bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.1, - width: double.infinity, - padding: EdgeInsets.all(12), - child: SecondaryButton( - // color: Colors.grey[900], - textColor: Colors.white, - label: TranslationBase.of(context).createAdvancedPayment, - onTap: () { - Navigator.push( - context, - //FadePage(page: AdvancePaymentPage())); - FadePage(page: BloodDonationPage())); - }, - ), - ), - ), - ); - } -} diff --git a/lib/pages/Blood/user_agreement_page.dart b/lib/pages/Blood/user_agreement_page.dart index d05725b4..36989ea5 100644 --- a/lib/pages/Blood/user_agreement_page.dart +++ b/lib/pages/Blood/user_agreement_page.dart @@ -1,55 +1,23 @@ +import 'package:diplomaticquarterapp/core/viewModels/TermsConditionsViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.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_html/flutter_html.dart'; class UserAgreementPage extends StatelessWidget { @override Widget build(BuildContext context) { - return AppScaffold( - isShowAppBar: true, - appBarTitle: "User Agreement", - - body: - Container( - child:ListView( - scrollDirection: Axis.vertical, - children: [ - /////////// - Column( - children: [ - SizedBox( - height: 20, - ), - Container( - child:Text("Communication via email, text messages and phone calls",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("I understand that the contact number or Email that \n I have provided on registration will be used for communication by HMG.\n I hereby agree to be notified by HMG through SMS, Email or any other method for appointments notifications, current HMG’s medical services, and any services introduced by the HMG in the future or any modifications made to the services offered by the HMG. And these messages may be submitted as evidence where the HMG has the right to use at any time whatsoever and as it sees fit.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("I understand the risks of communicating by email and text messages, in particular the privacy risks. \nI understand that HMG cannot guarantee the security and confidentiality of email or text communication. HMG will not be responsible for messages that are not received or delivered due to technical failure, or for disclosure of confidential information unless caused by intentional misconduct.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - SizedBox( - height: 20, - ), - Container( - child: - Text("\b I hereby agree to receive emails, text messages, phone calls for appointments notifications, special promotions and new features or products introduced by HMG or any third party.",textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold,fontSize: 16)), - ), - ], - ) - /////////// - ]) - - - - )); + return BaseView( + onModelReady: (model) => model.getUserTermsAndConditions(), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).userAgreement, + body: SingleChildScrollView( + child: Html( + data: model.userAgreementContent, + ), + )), + ); } } diff --git a/lib/pages/BookAppointment/BookConfirm.dart b/lib/pages/BookAppointment/BookConfirm.dart index d7e08a66..966dc4d4 100644 --- a/lib/pages/BookAppointment/BookConfirm.dart +++ b/lib/pages/BookAppointment/BookConfirm.dart @@ -14,6 +14,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -61,6 +62,7 @@ class _BookConfirmState extends State { toDoProvider = Provider.of(context); return AppScaffold( appBarTitle: TranslationBase.of(context).bookAppo, + isShowDecPage: false, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -187,27 +189,29 @@ class _BookConfirmState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), - child: Image.asset( - "assets/images/new-design/icon_hospital.png"), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), - child: Text( - TranslationBase.of(context).hospital + - ": " + - widget.doctor.projectName, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - ), - ], - ), + !widget.isLiveCareAppointment ? Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + margin: + EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), + child: Image.asset( + "assets/images/new-design/icon_hospital.png"), + ), + Container( + margin: + EdgeInsets.fromLTRB(20.0, 5.0, 10.0, 5.0), + child: Text( + TranslationBase.of(context).hospital + + ": " + + widget.doctor.projectName, + style: TextStyle( + fontSize: 14.0, + color: Colors.grey[700], + letterSpacing: 1.0)), + ), + ], + ) : Container(), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ @@ -325,7 +329,8 @@ class _BookConfirmState extends State { Container( margin: EdgeInsets.only(top: 5.0), child: Text( - TranslationBase.of(context).gender + ": " + + TranslationBase.of(context).gender + + ": " + widget.authUser.genderDescription, style: TextStyle( fontSize: 12.0, @@ -335,7 +340,9 @@ class _BookConfirmState extends State { Container( margin: EdgeInsets.only(top: 5.0, bottom: 3.0), child: Text( - TranslationBase.of(context).age + ": " + widget.authUser.age.toString(), + TranslationBase.of(context).age + + ": " + + widget.authUser.age.toString(), style: TextStyle( fontSize: 12.0, color: Colors.grey[600], @@ -423,7 +430,8 @@ class _BookConfirmState extends State { context) .then((res) { if (res['MessageStatus'] == 1) { - AppToast.showSuccessToast(message: TranslationBase.of(context).bookedSuccess); + AppToast.showSuccessToast( + message: TranslationBase.of(context).bookedSuccess); print(res['AppointmentNo']); Future.delayed(new Duration(milliseconds: 500), () { @@ -455,6 +463,7 @@ class _BookConfirmState extends State { dialog.showAlertDialog(context); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); print(err); }); @@ -543,13 +552,13 @@ class _BookConfirmState extends State { getLiveCareAppointmentPatientShare(context, String appointmentNo, int clinicID, int projectID, DoctorList docObject) { - GifLoaderDialogUtils.hideDialog(context); widget.service .getLiveCareAppointmentPatientShare( appointmentNo, clinicID, projectID, context) .then((res) { print(res); widget.patientShareResponse = new PatientShareResponse.fromJson(res); + GifLoaderDialogUtils.hideDialog(context); navigateToBookSuccess(context, docObject, widget.patientShareResponse); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); @@ -620,8 +629,8 @@ class _BookConfirmState extends State { GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, - MaterialPageRoute( - builder: (context) => BookSuccess( + FadePage( + page: BookSuccess( docObject: docObject, patientShareResponse: patientShareResponse, appoDateFormatted: widget.appoDateFormatted, diff --git a/lib/pages/BookAppointment/BookSuccess.dart b/lib/pages/BookAppointment/BookSuccess.dart index f513c434..26a5b0fe 100644 --- a/lib/pages/BookAppointment/BookSuccess.dart +++ b/lib/pages/BookAppointment/BookSuccess.dart @@ -12,6 +12,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; @@ -255,7 +256,7 @@ class _BookSuccessState extends State { minWidth: MediaQuery.of(context).size.width * 0.7, height: 45.0, child: RaisedButton( - color: new Color(0xFF40ACC9), + color: new Color(0xffc5272d), textColor: Colors.white, disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), @@ -318,7 +319,7 @@ class _BookSuccessState extends State { minWidth: MediaQuery.of(context).size.width * 0.7, height: 45.0, child: RaisedButton( - color: new Color(0xFF40ACC9), + color: new Color(0xFFc5272d), textColor: Colors.white, disabledTextColor: Colors.white, disabledColor: new Color(0xFFbcc2c4), @@ -592,7 +593,7 @@ class _BookSuccessState extends State { appo.appointmentNo = widget.patientShareResponse.appointmentNo; Navigator.push( - context, MaterialPageRoute(builder: (context) => PaymentMethod())) + context, FadePage(page: PaymentMethod())) .then((value) { print(value); if (value != null) { @@ -637,7 +638,12 @@ class _BookSuccessState extends State { authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, - widget.browser); + widget.browser, + widget.patientShareResponse.isLiveCareAppointment, + widget.patientShareResponse.appointmentDate, + widget.patientShareResponse.appointmentNo, + widget.patientShareResponse.clinicID, + widget.patientShareResponse.doctorID); } } @@ -915,11 +921,11 @@ class _BookSuccessState extends State { Future navigateToQR(context, String appoQR) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => QRCode( - patientShareResponse: widget.patientShareResponse, - appoQR: appoQR, - ))); + FadePage( + page: QRCode( + patientShareResponse: widget.patientShareResponse, + appoQR: appoQR, + ))); } _getNormalText(text) { diff --git a/lib/pages/BookAppointment/DentalComplaints.dart b/lib/pages/BookAppointment/DentalComplaints.dart index 34a7e1e1..614189e0 100644 --- a/lib/pages/BookAppointment/DentalComplaints.dart +++ b/lib/pages/BookAppointment/DentalComplaints.dart @@ -5,9 +5,9 @@ import 'package:diplomaticquarterapp/pages/BookAppointment/widgets/DentalComplai import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_card.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class DentalComplaints extends StatefulWidget { SearchInfo searchInfo; @@ -59,12 +59,14 @@ class _DentalComplaintsState extends State { } getChiefComplaintsList() { + GifLoaderDialogUtils.showMyDialog(context); getLanguageID(); ClinicListService service = new ClinicListService(); service .getChiefComplaintsList( widget.searchInfo.ClinicID, widget.searchInfo.ProjectID, context) .then((res) { + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { print(res['List_DentalChiefComplain']); setState(() { @@ -75,8 +77,8 @@ class _DentalComplaintsState extends State { }); } else {} }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } } diff --git a/lib/pages/BookAppointment/DoctorProfile.dart b/lib/pages/BookAppointment/DoctorProfile.dart index 392eb24c..2a349cf2 100644 --- a/lib/pages/BookAppointment/DoctorProfile.dart +++ b/lib/pages/BookAppointment/DoctorProfile.dart @@ -12,6 +12,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:rating_bar/rating_bar.dart'; @@ -153,7 +154,8 @@ class _DoctorProfileState extends State alignment: Alignment.center, child: Text( "(" + - widget.docProfileList.noOfPatientsRate.toString() + + widget.docProfileList.noOfPatientsRate + .toString() + " " + TranslationBase.of(context).reviews + ")", @@ -279,7 +281,8 @@ class _DoctorProfileState extends State color: Theme.of(context).primaryColor, margin: EdgeInsets.only(bottom: 5.0), padding: EdgeInsets.all(10.0), - child: Text(TranslationBase.of(context).doctorRating, + child: Text( + TranslationBase.of(context).doctorRating, style: TextStyle( fontSize: 22.0, color: Colors.white))), Container( @@ -297,8 +300,11 @@ class _DoctorProfileState extends State margin: EdgeInsets.only(top: 5.0), alignment: Alignment.center, child: RatingBar.readOnly( - initialRating: - this.widget.doctor.actualDoctorRate.toDouble(), + initialRating: this + .widget + .doctor + .actualDoctorRate + .toDouble(), size: 35.0, filledColor: Colors.yellow[700], emptyColor: Colors.grey[500], @@ -311,7 +317,11 @@ class _DoctorProfileState extends State Container( margin: EdgeInsets.only(top: 10.0), child: Text( - this.widget.doctor.noOfPatientsRate.toString() + + this + .widget + .doctor + .noOfPatientsRate + .toString() + " " + TranslationBase.of(context).reviews, style: TextStyle( @@ -327,7 +337,8 @@ class _DoctorProfileState extends State child: Text( TranslationBase.of(context).excellent, style: TextStyle( - fontSize: 13.0, color: Colors.black))), + fontSize: 13.0, + color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( @@ -349,9 +360,11 @@ class _DoctorProfileState extends State width: 100.0, margin: EdgeInsets.only( top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).v_good, + child: Text( + TranslationBase.of(context).v_good, style: TextStyle( - fontSize: 13.0, color: Colors.black))), + fontSize: 13.0, + color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( @@ -373,9 +386,11 @@ class _DoctorProfileState extends State width: 100.0, margin: EdgeInsets.only( top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).good, + child: Text( + TranslationBase.of(context).good, style: TextStyle( - fontSize: 13.0, color: Colors.black))), + fontSize: 13.0, + color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( @@ -397,9 +412,11 @@ class _DoctorProfileState extends State width: 100.0, margin: EdgeInsets.only( top: 10.0, left: 15.0, right: 15.0), - child: Text(TranslationBase.of(context).average, + child: Text( + TranslationBase.of(context).average, style: TextStyle( - fontSize: 13.0, color: Colors.black))), + fontSize: 13.0, + color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( @@ -422,9 +439,11 @@ class _DoctorProfileState extends State margin: EdgeInsets.only( top: 10.0, left: 15.0, right: 15.0), child: Text( - TranslationBase.of(context).below_average, + TranslationBase.of(context) + .below_average, style: TextStyle( - fontSize: 13.0, color: Colors.black))), + fontSize: 13.0, + color: Colors.black))), Container( margin: EdgeInsets.only(top: 10.0), child: SizedBox( @@ -440,7 +459,8 @@ class _DoctorProfileState extends State ), ), Container( - margin: EdgeInsets.only(top: 40.0), child: Divider()), + margin: EdgeInsets.only(top: 40.0), + child: Divider()), Container( margin: EdgeInsets.only(top: 0.0), child: Align( @@ -462,7 +482,8 @@ class _DoctorProfileState extends State onPressed: () { Navigator.of(context).pop(); }, - child: Text(TranslationBase.of(context).cancel, + child: Text( + TranslationBase.of(context).cancel, style: TextStyle(fontSize: 18.0)), ), ), @@ -485,7 +506,8 @@ class _DoctorProfileState extends State } double getRatingWidth(int patientNumber) { - var width = (patientNumber / this.widget.docProfileList.noOfPatientsRate) * 100; + var width = + (patientNumber / this.widget.docProfileList.noOfPatientsRate) * 100; return width; } @@ -528,8 +550,8 @@ class _DoctorProfileState extends State Future navigateToBookConfirm(context) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => BookConfirm( + FadePage( + page: BookConfirm( doctor: widget.doctor, isLiveCareAppointment: widget.isLiveCareAppointment, selectedDate: DocAvailableAppointments.selectedDate, diff --git a/lib/pages/BookAppointment/QRCode.dart b/lib/pages/BookAppointment/QRCode.dart index e92c2348..00fb2fc8 100644 --- a/lib/pages/BookAppointment/QRCode.dart +++ b/lib/pages/BookAppointment/QRCode.dart @@ -10,11 +10,11 @@ import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsLis import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class QRCode extends StatefulWidget { PatientShareResponse patientShareResponse; @@ -235,6 +235,7 @@ class _QRCodeState extends State { okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () { + GifLoaderDialogUtils.showMyDialog(context); service .sendAppointmentQREmail( widget.authUser.emailAddress, @@ -247,15 +248,14 @@ class _QRCodeState extends State { widget.patientShareResponse.doctorSpeciality), context) .then((res) { - print(res); + GifLoaderDialogUtils.hideDialog(context); ConfirmDialog.closeAlertDialog(context); }).catchError((err) { ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: err); print(err); - }).showProgressBar( - text: "Loading", - backgroundColor: Colors.blue.withOpacity(0.6)); + }); }, cancelFunction: () => {}); dialog.showAlertDialog(context); diff --git a/lib/pages/BookAppointment/Search.dart b/lib/pages/BookAppointment/Search.dart index 94308c1c..6dee1076 100644 --- a/lib/pages/BookAppointment/Search.dart +++ b/lib/pages/BookAppointment/Search.dart @@ -1,21 +1,18 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByClinic.dart'; import 'package:diplomaticquarterapp/pages/BookAppointment/components/SearchByDoctor.dart'; -import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/widgets/others/arrow_back.dart'; -import 'package:diplomaticquarterapp/widgets/others/bottom_bar.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:geolocator/geolocator.dart'; import 'components/SearchByClinic.dart'; class Search extends StatefulWidget { final int type; final List clnicIds; + Search({this.type = 0, this.clnicIds}); + @override _SearchState createState() => _SearchState(); } @@ -43,9 +40,12 @@ class _SearchState extends State with TickerProviderStateMixin { children: [ TabBar( tabs: [ - Tab(text: TranslationBase.of(context).clinicName), Tab( - text: TranslationBase.of(context).doctorName, + child: Text(TranslationBase.of(context).clinicName, + style: TextStyle(color: Colors.black))), + Tab( + child: Text(TranslationBase.of(context).doctorName, + style: TextStyle(color: Colors.black)), ) ], controller: _tabController, diff --git a/lib/pages/BookAppointment/SearchResults.dart b/lib/pages/BookAppointment/SearchResults.dart index 0c65a789..e5f219f0 100644 --- a/lib/pages/BookAppointment/SearchResults.dart +++ b/lib/pages/BookAppointment/SearchResults.dart @@ -26,6 +26,7 @@ class _SearchResultsState extends State { Widget build(BuildContext context) { return AppScaffold( appBarTitle: TranslationBase.of(context).bookAppo, + isShowDecPage: false, isShowAppBar: true, body: Container( margin: EdgeInsets.all(10.0), diff --git a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart index 7caf1977..cd8bb789 100644 --- a/lib/pages/BookAppointment/components/DocAvailableAppointments.dart +++ b/lib/pages/BookAppointment/components/DocAvailableAppointments.dart @@ -16,6 +16,7 @@ import '../../../uitl/date_uitl.dart'; class DocAvailableAppointments extends StatefulWidget { DoctorList doctor; static bool areSlotsAvailable = false; + static bool areAppointmentsAvailable = false; static DateTime selectedAppoDateTime; static String selectedDate; static String selectedTime; @@ -137,7 +138,7 @@ class _DocAvailableAppointmentsState extends State shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), side: BorderSide( - color: Colors.blue[400], //Color of the border + color: Color(0xff76cfb7), //Color of the border style: BorderStyle.solid, //Style of the border width: 1.5, //width of the border ), @@ -209,8 +210,8 @@ class _DocAvailableAppointmentsState extends State color: _calendarController.isSelected(date) ? Colors.green[400] : _calendarController.isToday(date) - ? Colors.brown[300] - : Colors.blue[400], + ? Colors.transparent + : Color(0xff76cfb7), ), width: 40.0, height: 40.0, @@ -321,7 +322,7 @@ class _DocAvailableAppointmentsState extends State Widget getSelectedButton(int index) { return RaisedButton( - color: Colors.blue[400], + color: Color(0xff76cfb7), //Color of the border textColor: Colors.white, onPressed: () { setState(() { @@ -345,17 +346,22 @@ class _DocAvailableAppointmentsState extends State GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['FreeTimeSlots'].length != 0) { + DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['FreeTimeSlots']; print("res['FreeTimeSlots']"); print(res['FreeTimeSlots'].length); _getJSONSlots().then((value) => { setState(() => {_events.clear(), _events = value}) }); - } else {} + } else { + DocAvailableAppointments.areAppointmentsAvailable = false; + } } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); print(err); }); } @@ -370,18 +376,22 @@ class _DocAvailableAppointmentsState extends State GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['PatientER_DoctorFreeSlots'].length != 0) { + DocAvailableAppointments.areAppointmentsAvailable = true; freeSlotsResponse = res['PatientER_DoctorFreeSlots']; print("res['PatientER_DoctorFreeSlots']"); print(res['PatientER_DoctorFreeSlots'].length); _getJSONSlots().then((value) => { setState(() => {_events.clear(), _events = value}) }); - } else {} + } else { + DocAvailableAppointments.areAppointmentsAvailable = false; + } } else { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); print(err); }); } @@ -399,10 +409,10 @@ class _DocAvailableAppointmentsState extends State decoration: BoxDecoration( shape: BoxShape.circle, color: _calendarController.isSelected(date) - ? Colors.green[400] + ? Color(0xffB8382C) : _calendarController.isToday(date) ? Colors.brown[300] - : Colors.blue[400], + : Color(0xff76cfb7), ), width: 40.0, height: 40.0, diff --git a/lib/pages/BookAppointment/components/SearchByClinic.dart b/lib/pages/BookAppointment/components/SearchByClinic.dart index 01c9ee92..63c5e8e1 100644 --- a/lib/pages/BookAppointment/components/SearchByClinic.dart +++ b/lib/pages/BookAppointment/components/SearchByClinic.dart @@ -12,8 +12,8 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class SearchByClinic extends StatefulWidget { final List clnicIds; @@ -213,6 +213,7 @@ class _SearchByClinicState extends State { }); } + // TODO Mosa_REMARk to come back later getDoctorsList(BuildContext context) { GifLoaderDialogUtils.showMyDialog(context); SearchInfo searchInfo = new SearchInfo(); @@ -295,8 +296,8 @@ class _SearchByClinicState extends State { BuildContext context, SearchInfo searchInfo) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => DentalComplaints(searchInfo: searchInfo), + FadePage( + page: DentalComplaints(searchInfo: searchInfo), ), ); } @@ -308,13 +309,14 @@ class _SearchByClinicState extends State { patientDoctorAppointmentListHospital) async { isProjectLoaded = false; Navigator.push( - context, - MaterialPageRoute( - builder: (context) => SearchResults( - isLiveCareAppointment: false, - doctorsList: docList, - patientDoctorAppointmentListHospital: - patientDoctorAppointmentListHospital))).then((value) { + context, + FadePage( + page: SearchResults( + isLiveCareAppointment: false, + doctorsList: docList, + patientDoctorAppointmentListHospital: + patientDoctorAppointmentListHospital))) + .then((value) { getProjectsList(); }); } diff --git a/lib/pages/BookAppointment/components/SearchByDoctor.dart b/lib/pages/BookAppointment/components/SearchByDoctor.dart index 1e1945b5..a1ecb7a0 100644 --- a/lib/pages/BookAppointment/components/SearchByDoctor.dart +++ b/lib/pages/BookAppointment/components/SearchByDoctor.dart @@ -3,8 +3,8 @@ import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsLis import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import '../SearchResults.dart'; @@ -161,8 +161,8 @@ class _SearchByDoctorState extends State { patientDoctorAppointmentListHospital) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchResults( + FadePage( + page: SearchResults( isLiveCareAppointment: false, doctorsList: docList, patientDoctorAppointmentListHospital: diff --git a/lib/pages/BookAppointment/widgets/CardCommon.dart b/lib/pages/BookAppointment/widgets/CardCommon.dart index b03e9b24..ce26200d 100644 --- a/lib/pages/BookAppointment/widgets/CardCommon.dart +++ b/lib/pages/BookAppointment/widgets/CardCommon.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/pages/BookAppointment/Search.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import '../../../Constants.dart'; @@ -8,6 +9,7 @@ class CardCommon extends StatelessWidget { final text; final subText; final type; + const CardCommon( {@required this.image, @required this.text, @@ -58,9 +60,9 @@ class CardCommon extends StatelessWidget { Future navigateToSearch(context, type) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => Search( - type: type, - ))); + FadePage( + page: Search( + type: type, + ))); } } diff --git a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart index 27f37d0a..02d40b3f 100644 --- a/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart +++ b/lib/pages/BookAppointment/widgets/DentalComplaintCard.dart @@ -3,8 +3,9 @@ import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart import 'package:diplomaticquarterapp/pages/BookAppointment/SearchResults.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; // ignore: must_be_immutable class DentalComplaintCard extends StatefulWidget { @@ -70,11 +71,13 @@ class _DentalComplaintCardState extends State { List _patientDoctorAppointmentListHospital = List(); + GifLoaderDialogUtils.showMyDialog(context); ClinicListService service = new ClinicListService(); service .getChiefComplaintDoctorList(widget.listDentalChiefComplain.iD, widget.listDentalChiefComplain.projectID, context) .then((res) { + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { print(res['List_DentalDoctorChiefComplaintMapping']); setState(() { @@ -114,9 +117,9 @@ class _DentalComplaintCardState extends State { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } Future navigateToSearchResults( @@ -126,8 +129,8 @@ class _DentalComplaintCardState extends State { patientDoctorAppointmentListHospital) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchResults( + FadePage( + page: SearchResults( doctorsList: docList, patientDoctorAppointmentListHospital: patientDoctorAppointmentListHospital))); diff --git a/lib/pages/BookAppointment/widgets/DoctorView.dart b/lib/pages/BookAppointment/widgets/DoctorView.dart index d419e4af..bb6fccab 100644 --- a/lib/pages/BookAppointment/widgets/DoctorView.dart +++ b/lib/pages/BookAppointment/widgets/DoctorView.dart @@ -4,17 +4,15 @@ import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsLis import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:rating_bar/rating_bar.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import '../DoctorProfile.dart'; class DoctorView extends StatelessWidget { - final DoctorList doctor; - bool isLiveCareAppointment; - - + final DoctorList doctor; + bool isLiveCareAppointment; DoctorView({@required this.doctor, @required this.isLiveCareAppointment}); @@ -53,48 +51,53 @@ class DoctorView extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - if(doctor.doctorTitle!=null) - Text(this.doctor.doctorTitle + " " + this.doctor.name, - style: TextStyle( - fontSize: 14.0, - color: Colors.grey[700], - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only(top: 3.0), - child: Text(this.doctor.clinicName, + if (doctor.doctorTitle != null) + Text(this.doctor.doctorTitle + " " + this.doctor.name, style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], + fontSize: 14.0, + color: Colors.grey[700], letterSpacing: 1.0)), - ), Container( margin: EdgeInsets.only(top: 3.0), - child: Text(this.doctor.projectName, + child: Text( + this.doctor.clinicName != null + ? this.doctor.clinicName + : "", style: TextStyle( fontSize: 12.0, color: Colors.grey[600], letterSpacing: 1.0)), ), - if(doctor.speciality!=null) Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality(this.doctor.speciality).trim(), + margin: EdgeInsets.only(top: 3.0), + child: Text(this.doctor.projectName, style: TextStyle( fontSize: 12.0, color: Colors.grey[600], letterSpacing: 1.0)), ), - this.doctor.nearestFreeSlot != null ? Container( - margin: EdgeInsets.only(top: 3.0, bottom: 3.0), - child: Text( - getDate(this.doctor.nearestFreeSlot), - style: TextStyle( - fontSize: 14.0, - fontWeight: FontWeight.bold, - color: Colors.green[600], - letterSpacing: 1.0)), - ) : Container(), + if (doctor.speciality != null) + Container( + margin: EdgeInsets.only(top: 3.0, bottom: 3.0), + child: Text( + getDoctorSpeciality(this.doctor.speciality) + .trim(), + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + this.doctor.nearestFreeSlot != null + ? Container( + margin: EdgeInsets.only(top: 3.0, bottom: 3.0), + child: Text(getDate(this.doctor.nearestFreeSlot), + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.bold, + color: Colors.green[600], + letterSpacing: 1.0)), + ) + : Container(), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.max, @@ -176,7 +179,7 @@ class DoctorView extends StatelessWidget { } String getMinute(DateTime dateObj) { - if(dateObj.minute == 0) { + if (dateObj.minute == 0) { return dateObj.minute.toString() + "0"; } else { return dateObj.minute.toString(); @@ -187,12 +190,12 @@ class DoctorView extends StatelessWidget { {isAppo}) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => DoctorProfile( - doctor: docObject, - isLiveCareAppointment: isLiveCareAppointment, - docProfileList: docProfile, - isOpenAppt: isAppo, - ))); + FadePage( + page: DoctorProfile( + doctor: docObject, + isLiveCareAppointment: isLiveCareAppointment, + docProfileList: docProfile, + isOpenAppt: isAppo, + ))); } } diff --git a/lib/pages/ChildVaccines/add_newchild_page.dart b/lib/pages/ChildVaccines/add_newchild_page.dart index 51b89f98..3c0d072b 100644 --- a/lib/pages/ChildVaccines/add_newchild_page.dart +++ b/lib/pages/ChildVaccines/add_newchild_page.dart @@ -11,6 +11,7 @@ import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/active_medications/DayCheckBoxDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -84,10 +85,12 @@ class _AddNewChildPageState extends State { @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + return BaseView( builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: "Vaccintion", + appBarTitle: TranslationBase.of(context).vaccination, body: SingleChildScrollView( physics: ScrollPhysics(), child: Container( @@ -96,10 +99,10 @@ class _AddNewChildPageState extends State { // crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( - height: 50, + height: 20, ), Texts( - "Add the child's information below to recieve the schedule of vaccinations.", + TranslationBase.of(context).vaccinationAddChildMsg, //+model.user.firstName, textAlign: TextAlign.center, ), @@ -107,14 +110,14 @@ class _AddNewChildPageState extends State { height: 12, ), NewTextFields( - hintText: "First Name", + hintText: TranslationBase.of(context).firstName, controller: _firstTextController, ), SizedBox( height: 12, ), NewTextFields( - hintText: "Second Name", + hintText: TranslationBase.of(context).middleName, controller: _secondTextController, ), SizedBox( @@ -124,62 +127,57 @@ class _AddNewChildPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Gender:", + TranslationBase.of(context).gender, textAlign: TextAlign.end, ), ], ), Container( - height: MediaQuery.of(context).size.height * 0.12, width: double.infinity, + height: size.height * 0.12, padding: EdgeInsets.all(12), - - child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: 175, - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 1 ? Colors.white : Colors.black, - color: checkedValue == 1 ? Colors.red : Colors.white, - - label: "Male", - // - onTap: () { + Expanded( + child: Container( + color: Colors.white, + child: SecondaryButton( + textColor: + checkedValue == 1 ? Colors.white : Colors.black, + color: checkedValue == 1 ? Colors.red : Colors.white, + label: TranslationBase.of(context).male, + onTap: () { + setState(() { + checkedValue = 1; + print("checkedValue=" + checkedValue.toString()); + }); - setState(() { - checkedValue = 1; - print("checkedValue=" + checkedValue.toString()); - }); - - // bloodDetails. - }, + // bloodDetails. + }, + ), ), ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: 175, - color: Colors.white, - child: SecondaryButton( - textColor: - checkedValue == 2 ? Colors.white : Colors.black, - color: checkedValue == 2 ? Colors.red : Colors.white, - label: "Female", - // - onTap: () { - setState(() { - checkedValue = 2; - print("checkedValue=" + checkedValue.toString()); - }); - // bloodDetails.city=_selectedHospital.toString(); + Expanded( + child: Container( + color: Colors.white, + child: SecondaryButton( + textColor: + checkedValue == 2 ? Colors.white : Colors.black, + color: checkedValue == 2 ? Colors.red : Colors.white, + label: TranslationBase.of(context).female, + // + onTap: () { + setState(() { + checkedValue = 2; + print("checkedValue=" + checkedValue.toString()); + }); + // bloodDetails.city=_selectedHospital.toString(); - // bloodDetails. - }, + // bloodDetails. + }, + ), ), ) ], @@ -193,7 +191,7 @@ class _AddNewChildPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - "Date Of Birth::", + TranslationBase.of(context).dob, textAlign: TextAlign.end, ), ], @@ -249,29 +247,29 @@ class _AddNewChildPageState extends State { color: checkedValue == false ? Colors.white24 : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: "Add", + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).add, // - onTap: () async{ - newChild.babyName = _firstTextController.text + " " + _secondTextController.text; + onTap: () async { + newChild.babyName = _firstTextController.text + + " " + + _secondTextController.text; newChild.gender = checkedValue.toString(); newChild.strDOB = getStartDay(); newChild.tempValue = true; newChild.isLogin = true; await model.createNewBabyOrders(newChild: newChild); - if(model.isAdded){ - AppToast.showSuccessToast(message: "Record Added"); - Navigator.pop(context,model.isAdded); - }else{ - + if (model.isAdded) { + AppToast.showSuccessToast(message: TranslationBase.of(context).childAddedSuccessfully); + Navigator.pop(context, model.isAdded); + } else { //TODO handling error } - }, ), ), @@ -280,7 +278,7 @@ class _AddNewChildPageState extends State { ), ), ), - // bottomSheet: + // bottomSheet: ), ); } diff --git a/lib/pages/ChildVaccines/child_page.dart b/lib/pages/ChildVaccines/child_page.dart index 806a5b71..fad0b0c2 100644 --- a/lib/pages/ChildVaccines/child_page.dart +++ b/lib/pages/ChildVaccines/child_page.dart @@ -1,19 +1,17 @@ -import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/model/childvaccines/delete_baby_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/add_newchild_page.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/vaccinationtable_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; - -import 'dialogs/delete_child.dart'; class ChildPage extends StatefulWidget { @override @@ -22,30 +20,52 @@ class ChildPage extends StatefulWidget { class _ChildPageState extends State with SingleTickerProviderStateMixin { - DeleteBaby deleteBaby = DeleteBaby(); @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double height = (size.height - kToolbarHeight - 60); + final double itemWidth = size.width / 2; + final double itemHeight = height / 2 + 40; + var checkedValue = true; return BaseView( onModelReady: (model) => model.getNewUserOrders(), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: " Vaccination", + appBarTitle: TranslationBase.of(context).vaccination, baseViewModel: model, - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 15, right: 15, top: 70), - child: Column( - children: [ - ...List.generate( + body: Container( + height: height * 0.85, + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 8, right: 8, top: 16), + child: GridView.count( + crossAxisCount: 2, + childAspectRatio: (itemWidth / (itemHeight + 0)), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + controller: ScrollController(keepScrollOffset: true), + shrinkWrap: true, + padding: const EdgeInsets.all(4.0), + children: [ + ...List.generate( model.babyInformationModelList.length, - (index) => Container( - margin: EdgeInsets.only( - left: 0, right: 0, bottom: 20), - - decoration: BoxDecoration( + (index) => InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: VaccinationTablePage(model + .babyInformationModelList[index]), + ), + ); + }, + child: Container( + margin: EdgeInsets.only( + left: 0, right: 0, bottom: 20), + decoration: BoxDecoration( shape: BoxShape.rectangle, border: Border.all( color: Colors.white, width: 0.5), @@ -54,11 +74,12 @@ class _ChildPageState extends State color: Colors.white, ), padding: EdgeInsets.all(12), - width: 200,//double.infinity, + //double.infinity, child: Column( children: [ Row(children: [ - Texts("CHILD NAME"), + Texts(TranslationBase.of(context) + .childName), ]), Row(children: [ Texts(model @@ -96,19 +117,16 @@ class _ChildPageState extends State Navigator.push( context, FadePage( - - - page: VaccinationTablePage(), - - + page: VaccinationTablePage(model + .babyInformationModelList[ + index]), ), ); - }, ) ]), Row(children: [ - Texts("Birthday"), + Texts(TranslationBase.of(context).dob), ]), Row(children: [ IconButton( @@ -116,9 +134,7 @@ class _ChildPageState extends State 'assets/images/new-design/calender-secondary.png'), tooltip: '', onPressed: () { - setState(() { - - }); + setState(() {}); }, ), Texts(DateUtil.yearMonthDay(model @@ -130,49 +146,47 @@ class _ChildPageState extends State icon: new Image.asset( 'assets/images/new-design/garbage.png'), tooltip: '', - onPressed: ()async { - + onPressed: () async { //===================== - await model.deleteBabyOrders(newChild:deleteBaby ); - + await model.deleteBabyOrders( + newChild: deleteBaby); - deleteBaby.babyID=model.babyInformationModelList[index] + deleteBaby.babyID = model + .babyInformationModelList[index] .babyID; - await model.deleteBabyOrders(newChild:deleteBaby ); - if(model.isDeleted){ - AppToast.showSuccessToast(message: "Record Deleted"); - Navigator.pop(context,model.isDeleted); - }else{ - - //TODO handling error - } - - - - - + await model.deleteBabyOrders( + newChild: deleteBaby); + if (model.isDeleted) { + AppToast.showSuccessToast( + message: TranslationBase.of( + context) + .recordDeleted); + Navigator.pop( + context, model.isDeleted); + } else { + //TODO handling error + } }, ), - Texts("Delete"), + Texts(TranslationBase.of(context) + .deleteView), ]), SizedBox( height: 12, ), ], ), - + ), ), - - - ) - ], - )) + ) + ], + ))), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, + height: height * 0.15, width: double.infinity, - padding: EdgeInsets.all(15), + padding: EdgeInsets.all(16), child: SecondaryButton( textColor: Colors.white, color: checkedValue == false @@ -183,13 +197,13 @@ class _ChildPageState extends State 74, 1, ), - label: "ADD NEW CHILD ", + label: TranslationBase.of(context).addNewChild, // onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => AddNewChildPage(), + FadePage( + page: AddNewChildPage(), ), ).then((value) { if (value) model.getNewUserOrders(); diff --git a/lib/pages/ChildVaccines/child_vaccines_page.dart b/lib/pages/ChildVaccines/child_vaccines_page.dart index 92f3a0be..38c6b5af 100644 --- a/lib/pages/ChildVaccines/child_vaccines_page.dart +++ b/lib/pages/ChildVaccines/child_vaccines_page.dart @@ -1,10 +1,10 @@ - import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/child_vaccines_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/user_information_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/my_balance_view_model.dart'; import 'package:diplomaticquarterapp/pages/ChildVaccines/child_page.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; @@ -13,214 +13,218 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - - class ChildVaccinesPage extends StatefulWidget { @override _ChildVaccinesPageState createState() => _ChildVaccinesPageState(); } class _ChildVaccinesPageState extends State - with SingleTickerProviderStateMixin{ + with SingleTickerProviderStateMixin { TextEditingController titleController = TextEditingController(); - var checkedValue=false; - String addEmail=""; + var checkedValue = false; + String addEmail = ""; + @override Widget build(BuildContext context) { - return BaseView( onModelReady: (model) => model.getUserInformationRequestOrders(), builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - baseViewModel: model, - appBarTitle: " Vaccination",//TranslationBase.of(context).advancePayment, - body: SingleChildScrollView( - physics: ScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - SizedBox( - height: 20, - ), - - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - child: Texts("Welcome back",fontSize: 20,), - ) , - ), - Divider(color:Colors.black , indent: 10, - endIndent: 10,), - SizedBox( - height: 20, - ), - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - child: Texts("Please ensure that the email address is up-to-date and process to view the schedule",fontSize: 20,), - ) , + isShowAppBar: true, + baseViewModel: model, + appBarTitle: TranslationBase.of(context).vaccination, + //TranslationBase.of(context).advancePayment, + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + child: Texts( + TranslationBase.of(context).welcomeBack, + fontSize: 20, ), - - Divider(color:Colors.black , indent: 10, - endIndent: 10,), - Padding( - padding: const EdgeInsets.all(10.0), - child:Container( - - margin: EdgeInsets.only(left: 10, right: 10, top: 15), - child: TextFields( - fillColor: Colors.red, - - hintText: model.user.emailAddress, - controller: titleController, - fontSize: 20, - hintColor: Colors.black, - fontWeight: FontWeight.w600, - onChanged: (text) { - addEmail=text; - model.user.emailAddress==addEmail?checkedValue=false:checkedValue=true; - - - }, - validator: (value) { - - if (value == null) - { - return model.user.emailAddress; - - } - else - - { - return model.user.emailAddress;} - }, - ), - ), + ), + ), + Divider( + color: Colors.black, + indent: 10, + endIndent: 10, + ), + SizedBox( + height: 20, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + child: Texts( + TranslationBase.of(context).msg_email_address_up_to_date, + fontSize: 20, ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "UPDATE EMAIL", - // - onTap: (){ - model.user.emailAddress=addEmail.toString(); - AppToast.showSuccessToast( - message: "Email updated"); - // bloodDetails.city=_selectedHospital.toString(); - - // bloodDetails. - }, - + ), + ), - ), + Divider( + color: Colors.black, + indent: 10, + endIndent: 10, + ), + Padding( + padding: const EdgeInsets.all(10.0), + child: Container( + margin: EdgeInsets.only(left: 10, right: 10, top: 15), + child: TextFields( + fillColor: Colors.red, + hintText: model.user.emailAddress, + controller: titleController, + fontSize: 20, + hintColor: Colors.black, + fontWeight: FontWeight.w600, + onChanged: (text) { + addEmail = text; + model.user.emailAddress == addEmail + ? checkedValue = false + : checkedValue = true; + }, + validator: (value) { + if (value == null) { + return model.user.emailAddress; + } else { + return model.user.emailAddress; + } + }, ), - Container( - height: MediaQuery.of(context).size.height * 0.12, - width: double.infinity, - - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: Color.fromRGBO(63, 72, 74, 1,), - label: " VIEW LIST OF CHILDREN", - // - onTap: () => Navigator.push( - context, - FadePage( - page: ChildPage(), - - - - ), + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.12, + width: double.infinity, + padding: EdgeInsets.all(15), + child: SecondaryButton( + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, ), - - - ), - ), - - // Texts( - // // TranslationBase.of(context).advancePaymentLabel, - // model.user.emailAddress, - // textAlign: TextAlign.center, - // ), - SizedBox( - height: 12, - ), - SizedBox( - height: 12, - ), - SizedBox( - height: 12, + label: TranslationBase.of(context).updateEmail, + // + onTap: () { + model.user.emailAddress = addEmail.toString(); + AppToast.showSuccessToast( + message: TranslationBase.of(context).updateEmailMsg); + // bloodDetails.city=_selectedHospital.toString(); + + // bloodDetails. + }, + ), + ), + Container( + height: MediaQuery.of(context).size.height * 0.12, + width: double.infinity, + padding: EdgeInsets.all(15), + child: SecondaryButton( + textColor: Colors.white, + color: Color.fromRGBO( + 63, + 72, + 74, + 1, ), - - SizedBox( - height: 12, + label: TranslationBase.of(context).viewListChildren, + // + onTap: () => Navigator.push( + context, + FadePage( + page: ChildPage(), + ), ), + ), + ), - SizedBox( - height: 12, - ), + // Texts( + // // TranslationBase.of(context).advancePaymentLabel, + // model.user.emailAddress, + // textAlign: TextAlign.center, + // ), + SizedBox( + height: 12, + ), + SizedBox( + height: 12, + ), + SizedBox( + height: 12, + ), - SizedBox( - height: 10, - ), - // Row( - // mainAxisAlignment: MainAxisAlignment.center, - // crossAxisAlignment: CrossAxisAlignment.center, - // children: [ - // Center( - // child: Container( - // color: Colors.white, - // width: 350, - // child: InkWell( - // onTap: () { - // showDialog( - // context: context, - // builder: (_) => - // AssetGiffyDialog( - // title: Text( - // "", - // style: TextStyle( - // fontSize: 22.0, - // fontWeight: - // FontWeight - // .w600), - // ), - // image: Image.asset( - // 'assets/images/BloodChrt_EN.png'), - // buttonCancelText: - // Text('cancel'), - // buttonCancelColor: - // Colors.grey, - // onlyCancelButton: true, - // )); - // }, - // child: Container( - // width: 250, - // height: 200, - // child:Image.asset( - // 'assets/images/BloodChrt_EN.png')), - // ), - // ), - // ), - // ], - // ), + SizedBox( + height: 12, + ), - SizedBox( - height: MediaQuery.of(context).size.height * 0.15, - ) - ], + SizedBox( + height: 12, ), + SizedBox( + height: 10, + ), + // Row( + // mainAxisAlignment: MainAxisAlignment.center, + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Center( + // child: Container( + // color: Colors.white, + // width: 350, + // child: InkWell( + // onTap: () { + // showDialog( + // context: context, + // builder: (_) => + // AssetGiffyDialog( + // title: Text( + // "", + // style: TextStyle( + // fontSize: 22.0, + // fontWeight: + // FontWeight + // .w600), + // ), + // image: Image.asset( + // 'assets/images/BloodChrt_EN.png'), + // buttonCancelText: + // Text('cancel'), + // buttonCancelColor: + // Colors.grey, + // onlyCancelButton: true, + // )); + // }, + // child: Container( + // width: 250, + // height: 200, + // child:Image.asset( + // 'assets/images/BloodChrt_EN.png')), + // ), + // ), + // ), + // ], + // ), + + SizedBox( + height: MediaQuery.of(context).size.height * 0.15, + ) + ], ), - ), + ), + ), ); } } - diff --git a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart index 259bbdb7..c08749b8 100644 --- a/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart +++ b/lib/pages/ChildVaccines/dialogs/SelectGenderDialog.dart @@ -7,8 +7,11 @@ import 'package:flutter/material.dart'; class SelectGenderDialog extends StatefulWidget { final Email; + final Function okFunction; + + const SelectGenderDialog({Key key, this.Email, this.okFunction}) + : super(key: key); - const SelectGenderDialog({Key key, this.Email}) : super(key: key); @override _SelectGenderDialogState createState() => _SelectGenderDialogState(); } @@ -33,9 +36,8 @@ class _SelectGenderDialogState extends State { }); }, child: ListTile( - title: Text("Send the child's schedule to the email\n Tamer.dasdasdas@gmail.com "), - - + title: Text( + "${TranslationBase.of(context).sendChildEmailMsg}\n Tamer.dasdasdas@gmail.com "), ), ), ) @@ -44,7 +46,6 @@ class _SelectGenderDialogState extends State { SizedBox( height: 5.0, ), - SizedBox( height: 5.0, ), @@ -82,7 +83,7 @@ class _SelectGenderDialogState extends State { flex: 1, child: InkWell( onTap: () { - AppToast.showSuccessToast(message: "Email Sended"); + widget.okFunction(); // widget.onValueSelected(beneficiaryType); Navigator.pop(context); }, @@ -105,7 +106,4 @@ class _SelectGenderDialogState extends State { ], ); } - - - } diff --git a/lib/pages/ChildVaccines/vaccinationtable_page.dart b/lib/pages/ChildVaccines/vaccinationtable_page.dart index c160acfb..7b8499e0 100644 --- a/lib/pages/ChildVaccines/vaccinationtable_page.dart +++ b/lib/pages/ChildVaccines/vaccinationtable_page.dart @@ -1,8 +1,13 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/childvaccines/List_BabyInformationModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/child_vaccines/vaccination_table_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/reports_monthly_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -12,91 +17,161 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'dialogs/SelectGenderDialog.dart'; class VaccinationTablePage extends StatelessWidget { + final List_BabyInformationModel babyInfo; + + VaccinationTablePage(this.babyInfo); + @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double height = (size.height - kToolbarHeight - 60); + var checkedValue; return BaseView( - onModelReady: (model) => model.getCreateVaccinationTable(),//getUserTermsAndConditions(), + onModelReady: (model) => model.getCreateVaccinationTable(babyInfo, false), builder: (_, model, w) => AppScaffold( isShowAppBar: true, baseViewModel: model, - appBarTitle: "Vaccination", - body: SingleChildScrollView( - child:Container( - margin: EdgeInsets.only(left: 15,right: 15,top: 70), - child: Column( - children: [//babyInformationModelList.length - ...List.generate(model.creteVaccinationTableModelList.length, (index) => - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - border: Border.all(color: Colors.white, width: 0.5), - borderRadius: BorderRadius.all(Radius.circular(5)), - color: Colors.white, - - ), - padding: EdgeInsets.all(12), - width: double.infinity, - child: Column( - - children: [ - Row(children: [ - Text(model.creteVaccinationTableModelList[index].visit), - SizedBox(width: 10,), - - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Html( - // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription - data:model.creteVaccinationTableModelList[index].vaccinesDescription, - - ), - ],), - ), - Text(model.creteVaccinationTableModelList[index].givenAt), - - - ],), - Divider(color:Colors.black ,), - - ], - ) - - - ) - - ) - ], + appBarTitle: TranslationBase.of(context).vaccination, + body: Container( + height: height * 0.85, + child: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 16, right: 16, top: 16), + child: Column( + children: [ + Row( + children: [ + Expanded( + child: Texts(TranslationBase.of(context).childName), + ), + Expanded( + child: Texts(TranslationBase.of(context).dob), + ), + ], + ), + SizedBox( + height: 10, + ), + Row( + children: [ + Expanded( + child: Texts(babyInfo.babyName), + ), + Expanded( + child: Texts(DateUtil.getFormattedDate( + babyInfo.dOB, "MMM dd,yyyy")), + ), + ], + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.black, + ), + Row( + children: [ + Text(TranslationBase.of(context).visit), + SizedBox( + width: 25, + ), + Expanded( + child: Text(TranslationBase.of(context).description)), + Text(TranslationBase.of(context).dueDate), + ], + ), + ...List.generate( + model.creteVaccinationTableModelList.length, + (index) => Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + // border: Border.all(color: Colors.white, width: 0.5), + borderRadius: BorderRadius.all(Radius.circular(5)), + // color: Colors.white, + ), + padding: EdgeInsets.all(12), + width: double.infinity, + child: Column( + children: [ + Row( + children: [ + Text(model + .creteVaccinationTableModelList[index] + .visit), + SizedBox( + width: 10, + ), + Expanded( + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Html( + // data:"
BCG
HEPATITIS B
"//model.creteVaccinationTableModelList[index].vaccinesDescription + data: model + .creteVaccinationTableModelList[ + index] + .vaccinesDescription, + ), + ], + ), + ), + Text(model + .creteVaccinationTableModelList[index] + .givenAt), + ], + ), + Divider( + color: Colors.black, + ), + ], + ))) + ], + ), ), - + ), ), - ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.12, + height: height * 0.15, width: double.infinity, - padding: EdgeInsets.all(12), child: SecondaryButton( - textColor: Colors.white, - color: checkedValue== false ?Colors.white24:Color.fromRGBO(63, 72, 74, 1,), - label: "Send Email ", - // - onTap: () { - //SelectGenderDialog(); + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, + ), + label: TranslationBase.of(context).sendEmail, + // + onTap: () { + //SelectGenderDialog(); //=============== - showDialog( - context: context, - child: SelectGenderDialog( - ), - ); - //========= - } - - - ), + showDialog( + context: context, + child: SelectGenderDialog( + okFunction: () async { + await model.getCreateVaccinationTable(babyInfo, true); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: TranslationBase.of(context) + .emailSentSuccessfully); + } else { + AppToast.showErrorToast( + message: TranslationBase.of(context) + .EmailSentError); + } + }, + ), + ); + //========= + }), ), ), ); diff --git a/lib/pages/ContactUs/findus/findus_page.dart b/lib/pages/ContactUs/findus/findus_page.dart index 5cf59e21..80648292 100644 --- a/lib/pages/ContactUs/findus/findus_page.dart +++ b/lib/pages/ContactUs/findus/findus_page.dart @@ -78,10 +78,7 @@ class _FindUsPageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - //indicatorSize: TabBarIndicatorSize.label, indicatorSize: TabBarIndicatorSize.tab, - - indicatorColor: Theme.of(context).primaryColor, labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), diff --git a/lib/pages/ContactUs/findus/hospitrals_page.dart b/lib/pages/ContactUs/findus/hospitrals_page.dart index 308dbeca..2d257488 100644 --- a/lib/pages/ContactUs/findus/hospitrals_page.dart +++ b/lib/pages/ContactUs/findus/hospitrals_page.dart @@ -107,7 +107,7 @@ class _HospitalsPageState extends State { bottom: 1), child: Texts( '${widget.findusHospitalModelList[index].locationName}', - textAlign: TextAlign.center, + textAlign: TextAlign.start, ))), //model.cOCItemList[index].cOCTitl Expanded( flex: 2, @@ -116,7 +116,12 @@ class _HospitalsPageState extends State { CrossAxisAlignment.center, children: [ IconButton( - icon: Icon(Icons.location_on,color: Theme.of(context).primaryColor,size: 35,), + icon: Icon( + Icons.location_on, + color: Theme.of(context) + .primaryColor, + size: 35, + ), // icon: new Image.asset( // 'assets/images/new-design/navigate.png'), tooltip: '', @@ -139,7 +144,12 @@ class _HospitalsPageState extends State { }, ), IconButton( - icon: Icon(Icons.phone,color: Theme.of(context).primaryColor,size: 35,), + icon: Icon( + Icons.phone, + color: Theme.of(context) + .primaryColor, + size: 35, + ), // icon: new Image.asset( // 'assets/images/new-design/call.png'), tooltip: '', diff --git a/lib/pages/ContactUs/widgets/card_common_contat.dart b/lib/pages/ContactUs/widgets/card_common_contat.dart index cfb9108b..8848e2ff 100644 --- a/lib/pages/ContactUs/widgets/card_common_contat.dart +++ b/lib/pages/ContactUs/widgets/card_common_contat.dart @@ -7,6 +7,8 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../../Constants.dart'; + class CardCommonContact extends StatelessWidget { final image; final text; @@ -37,7 +39,7 @@ class CardCommonContact extends StatelessWidget { margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), child: Texts(this.text, // overflow: TextOverflow.clip, - color:Theme.of(context).primaryColor, + color:secondaryColor, fontWeight: FontWeight.w700, fontSize: 20.0), ), diff --git a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart index 3e58b657..04a7178f 100644 --- a/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart +++ b/lib/pages/Covid-DriveThru/Covid-TimeSlots.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/models/Appointments/DoctorListResponse.dart'; import 'package:diplomaticquarterapp/models/Appointments/FreeSlot.dart'; @@ -9,13 +10,15 @@ import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.da import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:intl/intl.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:provider/provider.dart'; import 'package:table_calendar/table_calendar.dart'; class CovidTimeSlots extends StatefulWidget { @@ -28,6 +31,8 @@ class CovidTimeSlots extends StatefulWidget { int selectedClinicID; int selectedDoctorID; + var language; + PatientShareResponse patientShareResponse; CovidTimeSlots({@required this.projectID}); @@ -89,10 +94,10 @@ class _CovidTimeSlotsState extends State super.dispose(); } - void _onDaySelected(DateTime day, List events) { + void _onDaySelected(DateTime day, List events, ProjectViewModel projectViewModel) { final DateFormat formatter = DateFormat('yyyy-MM-dd'); setState(() { - this.selectedDate = DateUtil.getMonthDayYearDateFormatted(day); + this.selectedDate = DateUtil.getWeekDayMonthDayYearDateFormatted(day, projectViewModel.isArabic ? "ar" : "en"); openTimeSlotsPickerForDate(day, docFreeSlots); CovidTimeSlots.selectedDate = formatter.format(day); print(CovidTimeSlots.selectedDate); @@ -111,8 +116,9 @@ class _CovidTimeSlotsState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: "COVID-19 TEST", + appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -146,8 +152,8 @@ class _CovidTimeSlotsState extends State children: [ Container( margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 40.0), - child: Text("COVID-19 TEST", + left: 20.0, right: 20.0, top: 20.0), + child: Text(TranslationBase.of(context).covidTest, style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, @@ -156,7 +162,7 @@ class _CovidTimeSlotsState extends State Container( margin: EdgeInsets.only( left: 20.0, right: 20.0, top: 10.0), - child: Text("Drive-Thru", + child: Text(TranslationBase.of(context).driveThru, style: TextStyle( color: Colors.white, fontSize: 24.0)), ), @@ -170,16 +176,16 @@ class _CovidTimeSlotsState extends State borderRadius: BorderRadius.circular(10.0), color: Colors.white), margin: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 5.0), - padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), + padding: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 20.0), width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height * 0.65, + // height: MediaQuery.of(context).size.height * 0.65, child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, children: [ Container( margin: EdgeInsets.all(10.0), - child: Text( - "Kindly select one of the available appointments from below: ", + child: Text(TranslationBase.of(context).selectAppo, style: TextStyle(color: Colors.black, fontSize: 16.0)), ), @@ -220,7 +226,7 @@ class _CovidTimeSlotsState extends State }, ), ), - _buildTableCalendarWithBuilders(), + _buildTableCalendarWithBuilders(projectViewModel), ], ), ), @@ -254,7 +260,7 @@ class _CovidTimeSlotsState extends State onPressed: () { bookCovidTestAppointment(); }, - child: Text("BOOK", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).bookNow, style: TextStyle(fontSize: 18.0)), ), ), ), @@ -265,9 +271,9 @@ class _CovidTimeSlotsState extends State ); } - Widget _buildTableCalendarWithBuilders() { + Widget _buildTableCalendarWithBuilders(ProjectViewModel projectViewModel) { return TableCalendar( - locale: 'en_US', + locale: projectViewModel.isArabic ? 'ar_SA' : 'en_US', calendarController: _calendarController, events: _events, initialCalendarFormat: CalendarFormat.month, @@ -352,6 +358,7 @@ class _CovidTimeSlotsState extends State _onDaySelected( date, event, + projectViewModel ); _animationController.forward(from: 0.0); }, @@ -469,9 +476,7 @@ class _CovidTimeSlotsState extends State } bookCovidTestAppointment() { -// Navigator.push(context, -// MaterialPageRoute(builder: (context) => CovidPaymentAlert())); - + GifLoaderDialogUtils.showMyDialog(context); DoctorList docObject = new DoctorList(); docObject.doctorID = widget.selectedDoctorID; docObject.clinicID = widget.selectedClinicID; @@ -491,14 +496,12 @@ class _CovidTimeSlotsState extends State CovidTimeSlots.selectedDate, context) .then((res) { - print(res); if (res['MessageStatus'] == 1) { AppToast.showSuccessToast(message: "Appointment Booked Successfully"); - Future.delayed(new Duration(milliseconds: 1800), () { - getPatientShare(context, res['AppointmentNo'], docObject.clinicID, - docObject.projectID, docObject); - }); + getPatientShare(context, res['AppointmentNo'], docObject.clinicID, + docObject.projectID, docObject); } else { + GifLoaderDialogUtils.hideDialog(context); appo = new AppoitmentAllHistoryResultList(); appo.appointmentNo = res['SameClinicApptList'][0]['AppointmentNo']; appo.clinicID = res['SameClinicApptList'][0]['DoctorID']; @@ -522,27 +525,28 @@ class _CovidTimeSlotsState extends State } }).catchError((err) { AppToast.showErrorToast(message: err); + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } cancelAppointment(DoctorList docObject, AppoitmentAllHistoryResultList appo, BuildContext context) { ConfirmDialog.closeAlertDialog(context); + GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service.cancelAppointment(appo, context).then((res) { if (res['MessageStatus'] == 1) { - Future.delayed(new Duration(milliseconds: 1500), () { - insertAppointmentCovidTest(context, docObject); - }); + // Future.delayed(new Duration(milliseconds: 1500), () { + insertAppointmentCovidTest(context, docObject); + // }); } else { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } getPatientShare(context, String appointmentNo, int clinicID, int projectID, @@ -551,35 +555,34 @@ class _CovidTimeSlotsState extends State service .getPatientShare(appointmentNo, clinicID, projectID, context) .then((res) { - print(res); - widget.patientShareResponse = new PatientShareResponse.fromJson(res); - }) - .catchError((err) { - print(err); - }) - .showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) - .then((value) { - navigateToPaymentAlert(); - }); + GifLoaderDialogUtils.hideDialog(context); + print(res); + widget.patientShareResponse = new PatientShareResponse.fromJson(res); + navigateToPaymentAlert(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } navigateToPaymentAlert() { Navigator.push( - context, - MaterialPageRoute( - builder: (context) => CovidPaymentAlert( - patientShareResponse: widget.patientShareResponse))); + context, + FadePage( + page: CovidPaymentAlert( + patientShareResponse: widget.patientShareResponse), + ), + ); } getCovidFreeSlots(BuildContext context, int projectID) { CovidDriveThruService service = new CovidDriveThruService(); + GifLoaderDialogUtils.showMyDialog(context); service.getCovidFreeSlots(context, projectID).then((res) { - print(res['COVID19_FreeTimeSlots']); + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { if (res['COVID19_FreeTimeSlots'].length != 0) { freeSlotsResponse = res['COVID19_FreeTimeSlots']; - print(res['COVID19_FreeTimeSlots'].length); _getJSONSlots().then((value) => { setState(() => { widget.selectedClinicID = @@ -592,11 +595,11 @@ class _CovidTimeSlotsState extends State }); } else {} } else { + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } } diff --git a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart index 0563c4bd..a8cb5048 100644 --- a/lib/pages/Covid-DriveThru/covid-drivethru-location.dart +++ b/lib/pages/Covid-DriveThru/covid-drivethru-location.dart @@ -1,13 +1,17 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/CovidPaymentInfoResponse.dart'; import 'package:diplomaticquarterapp/models/CovidDriveThru/DriveThroughTestingCenterModel.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-details.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/covid-drivethru/covid-drivethru.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:maps_launcher/maps_launcher.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; +import 'package:provider/provider.dart'; class CovidDrivethruLocation extends StatefulWidget { @override @@ -23,6 +27,8 @@ class _CovidDrivethruLocationState extends State { String projectName = ""; String projectID = ""; + ProjectViewModel projectViewModel; + @override void initState() { WidgetsBinding.instance @@ -32,8 +38,9 @@ class _CovidDrivethruLocationState extends State { @override Widget build(BuildContext context) { + projectViewModel = Provider.of(context); return AppScaffold( - appBarTitle: "COVID-19 TEST", + appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -41,8 +48,10 @@ class _CovidDrivethruLocationState extends State { child: Column( children: [ Container( - alignment: Alignment.centerLeft, - child: Text("Get The Result During 8 Hours", + alignment: projectViewModel.isArabic + ? Alignment.centerRight + : Alignment.centerLeft, + child: Text(TranslationBase.of(context).resultHeader, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 22.0, @@ -50,14 +59,15 @@ class _CovidDrivethruLocationState extends State { ), Container( margin: EdgeInsets.only(top: 10.0), - child: Text( - "We are using the advance technology to test COVID-19, The sample for examination is taking between the nose and mouth (nasopharyngeal swab), the examination is done by ELITE In Genius of the company ELITECH GROUP MOLECULAR DIAGNOSTICS, Note that the device belongs to an Italian company and is manufactured in Japan with RC- PCR​", + child: Text(TranslationBase.of(context).covidInfo, style: TextStyle(fontSize: 16.0, color: Colors.black)), ), Container( margin: EdgeInsets.only(top: 20.0), - alignment: Alignment.centerLeft, - child: Text("Select Location", + alignment: projectViewModel.isArabic + ? Alignment.centerRight + : Alignment.centerLeft, + child: Text(TranslationBase.of(context).selectLocation, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 18.0, @@ -79,7 +89,7 @@ class _CovidDrivethruLocationState extends State { margin: EdgeInsets.only(top: 15.0), child: DropdownButtonHideUnderline( child: DropdownButton( - hint: new Text("Select Address"), + hint: new Text(TranslationBase.of(context).selectAddress), value: projectDropdownValue, items: projectsList.map((item) { return new DropdownMenuItem( @@ -98,8 +108,10 @@ class _CovidDrivethruLocationState extends State { isLocationSelected ? Container( margin: EdgeInsets.only(top: 15.0), - alignment: Alignment.centerLeft, - child: Text("Selected Location", + alignment: projectViewModel.isArabic + ? Alignment.centerRight + : Alignment.centerLeft, + child: Text(TranslationBase.of(context).selectLocation, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 18.0, @@ -150,8 +162,8 @@ class _CovidDrivethruLocationState extends State { onPressed: () { getDirections(); }, - child: - Text("GET DIRECTIONS", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).getDirections, + style: TextStyle(fontSize: 18.0)), ), ), ), @@ -178,7 +190,8 @@ class _CovidDrivethruLocationState extends State { onPressed: () { back(); }, - child: Text("BACK", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).back, + style: TextStyle(fontSize: 18.0)), ), ), ), @@ -201,7 +214,8 @@ class _CovidDrivethruLocationState extends State { onPressed: () { next(); }, - child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).next, + style: TextStyle(fontSize: 18.0)), ), ), ), @@ -258,35 +272,35 @@ class _CovidDrivethruLocationState extends State { CovidPaymentInfoResponse covidPaymentInfoResponse = new CovidPaymentInfoResponse(); + GifLoaderDialogUtils.showMyDialog(context); + service .getCovidPaymentInformation(context, int.parse(projectID)) .then((res) { + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { covidPaymentInfoResponse = CovidPaymentInfoResponse.fromJson( res['COVID19_PatientShare']); print(covidPaymentInfoResponse.procedureNameField); }); + Navigator.push( + context, + FadePage( + page: CovidPaymentDetails( + covidPaymentInfoResponse: covidPaymentInfoResponse, + projectID: int.parse(projectID), + ))); } else {} }) .catchError((err) { print(err); - }) - .showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) - .then((value) { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => CovidPaymentDetails( - covidPaymentInfoResponse: covidPaymentInfoResponse, - projectID: int.parse(projectID), - ))); }); } getProjectsList(BuildContext context) { CovidDriveThruService service = new CovidDriveThruService(); + GifLoaderDialogUtils.showMyDialog(context); service.getCovidProjectsList(context).then((res) { print(res); if (res['MessageStatus'] == 1) { @@ -296,10 +310,11 @@ class _CovidDrivethruLocationState extends State { projectsList.add(new DriveThroughTestingCenterModel.fromJson(v)); }); }); + GifLoaderDialogUtils.hideDialog(context); } else {} }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } } diff --git a/lib/pages/Covid-DriveThru/covid-payment-alert.dart b/lib/pages/Covid-DriveThru/covid-payment-alert.dart index ac5f45fc..ca6640c0 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-alert.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-alert.dart @@ -1,7 +1,13 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-payment-summary.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -15,10 +21,13 @@ class CovidPaymentAlert extends StatefulWidget { } class _CovidPaymentAlertState extends State { + AppSharedPreferences sharedPref = AppSharedPreferences(); + AuthenticatedUser authUser; + @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: "COVID-19 TEST", + appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, body: SingleChildScrollView( child: Column( @@ -43,7 +52,7 @@ class _CovidPaymentAlertState extends State { children: [ Container( margin: EdgeInsets.only(left: 30.0, right: 20.0), - child: Text("Alert", + child: Text(TranslationBase.of(context).covidAlert, style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, @@ -54,7 +63,8 @@ class _CovidPaymentAlertState extends State { margin: EdgeInsets.only( left: 30.0, right: 20.0, top: 5.0), child: Text( - "Pay With-in 15 mins to confirm the appointment", + TranslationBase.of(context).covidAlertHeader, + // "Pay With-in 15 mins to confirm the appointment", overflow: TextOverflow.clip, style: TextStyle( color: Colors.white, fontSize: 20.0)), @@ -72,7 +82,7 @@ class _CovidPaymentAlertState extends State { children: [ Container( alignment: Alignment.center, - child: Text("Pay With-in 15 mins", + child: Text(TranslationBase.of(context).covidAlertMins, overflow: TextOverflow.clip, style: TextStyle( color: new Color(0xFFc5272d), @@ -83,7 +93,7 @@ class _CovidPaymentAlertState extends State { alignment: Alignment.center, margin: EdgeInsets.only(top: 15.0), child: Text( - "Payment for Covid-19 Test should Be made with-in 15 mins otherwise The system will Cancel the Scheduled appointment automatically​.", + TranslationBase.of(context).covidAlertInfo, textAlign: TextAlign.center, style: TextStyle( color: Colors.grey[700], @@ -115,7 +125,7 @@ class _CovidPaymentAlertState extends State { Container( margin: EdgeInsets.only( top: 15.0, bottom: 10.0, left: 20.0, right: 20.0), - child: Text("COVID-19 TEST", + child: Text(TranslationBase.of(context).covidTest, style: TextStyle( fontSize: 18.0, color: Colors.black, @@ -137,10 +147,12 @@ class _CovidPaymentAlertState extends State { child: Text( widget.patientShareResponse.projectName != null - ? widget.patientShareResponse.projectName + ? widget + .patientShareResponse.projectName : "NULL", style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), + fontSize: 18.0, + color: Colors.grey[700])), ), ], ), @@ -159,14 +171,16 @@ class _CovidPaymentAlertState extends State { )), Container( child: Text( - widget.patientShareResponse.appointmentDate != + widget.patientShareResponse + .appointmentDate != null ? getDate(widget.patientShareResponse .appointmentDate) .split(" ")[0] : "NULL", style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), + fontSize: 18.0, + color: Colors.grey[700])), ), ], ), @@ -185,14 +199,16 @@ class _CovidPaymentAlertState extends State { )), Container( child: Text( - widget.patientShareResponse.appointmentDate != + widget.patientShareResponse + .appointmentDate != null ? getDate(widget.patientShareResponse .appointmentDate) .split(" ")[1] : "NULL", style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), + fontSize: 18.0, + color: Colors.grey[700])), ), ], ), @@ -216,7 +232,8 @@ class _CovidPaymentAlertState extends State { .patientShareResponse.doctorNameObj : "NULL", style: TextStyle( - fontSize: 18.0, color: Colors.grey[700])), + fontSize: 18.0, + color: Colors.grey[700])), ), ], ), @@ -251,9 +268,9 @@ class _CovidPaymentAlertState extends State { disabledTextColor: Colors.white, disabledColor: Colors.grey[500], onPressed: () { -// bookCovidTestAppointment(); + startPaymentProcess(); }, - child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).next, style: TextStyle(fontSize: 18.0)), ), ), ), @@ -264,6 +281,37 @@ class _CovidPaymentAlertState extends State { ); } + startPaymentProcess() { + navigateToPaymentMethod(context, widget.patientShareResponse); + } + + Future navigateToPaymentMethod( + context, PatientShareResponse patientShareResponse) async { + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + setState(() { + authUser = data; + }); + } + + Navigator.push( + context, FadePage(page: PaymentMethod())) + .then((value) { + print(value); + if (value != null) { + Navigator.push( + context, + FadePage( + page: CovidPaymentSummary( + patientShareResponse: widget.patientShareResponse, + selectedPaymentMethod: value.toString()), + ), + ); + } + }); + } + String getDate(String appoDate) { var appoDateFormatted = ""; diff --git a/lib/pages/Covid-DriveThru/covid-payment-details.dart b/lib/pages/Covid-DriveThru/covid-payment-details.dart index 1254997d..e6c87d0a 100644 --- a/lib/pages/Covid-DriveThru/covid-payment-details.dart +++ b/lib/pages/Covid-DriveThru/covid-payment-details.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/pages/Covid-DriveThru/Covid-TimeSlots.dart' import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -17,13 +18,13 @@ class CovidPaymentDetails extends StatefulWidget { _CovidPaymentDetailsState createState() => _CovidPaymentDetailsState(); } -class _CovidPaymentDetailsState extends State { +class _CovidPaymentDetailsState extends State { bool isAgree = false; @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: "COVID-19 TEST", + appBarTitle: TranslationBase.of(context).covidTest, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -57,8 +58,8 @@ class _CovidPaymentDetailsState extends State { children: [ Container( margin: EdgeInsets.only( - left: 20.0, right: 20.0, top: 40.0), - child: Text("COVID-19 TEST", + left: 20.0, right: 20.0, top: 20.0), + child: Text(TranslationBase.of(context).covidTest, style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold, @@ -67,7 +68,7 @@ class _CovidPaymentDetailsState extends State { Container( margin: EdgeInsets.only( left: 20.0, right: 20.0, top: 10.0), - child: Text("Drive-Thru", + child: Text(TranslationBase.of(context).driveThru, style: TextStyle( color: Colors.white, fontSize: 24.0)), ), @@ -88,7 +89,7 @@ class _CovidPaymentDetailsState extends State { alignment: Alignment.center, margin: EdgeInsets.only(left: 0.0, right: 20.0, top: 30.0), - child: Text("Test Fees", + child: Text(TranslationBase.of(context).testFee, style: TextStyle( color: Colors.black, fontSize: 22.0, @@ -156,7 +157,7 @@ class _CovidPaymentDetailsState extends State { Container( alignment: Alignment.center, margin: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 5.0), - child: Text("You can pay by following options: ", + child: Text(TranslationBase.of(context).payOptions, textAlign: TextAlign.center, style: TextStyle( fontSize: 16.0, @@ -197,7 +198,8 @@ class _CovidPaymentDetailsState extends State { onPressed: () { cancel(); }, - child: Text("CANCEL", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).cancel, + style: TextStyle(fontSize: 18.0)), ), ), ), @@ -218,7 +220,8 @@ class _CovidPaymentDetailsState extends State { disabledTextColor: Colors.white, disabledColor: Colors.grey[500], onPressed: isAgree ? next : null, - child: Text("NEXT", style: TextStyle(fontSize: 18.0)), + child: Text(TranslationBase.of(context).next, + style: TextStyle(fontSize: 18.0)), ), ), ), @@ -232,10 +235,10 @@ class _CovidPaymentDetailsState extends State { void next() { Navigator.push( context, - MaterialPageRoute( - builder: (context) => CovidTimeSlots( - projectID: widget.projectID, - ))); + FadePage( + page: CovidTimeSlots( + projectID: widget.projectID, + ))); } cancel() { diff --git a/lib/pages/Covid-DriveThru/covid-payment-summary.dart b/lib/pages/Covid-DriveThru/covid-payment-summary.dart new file mode 100644 index 00000000..e71285b5 --- /dev/null +++ b/lib/pages/Covid-DriveThru/covid-payment-summary.dart @@ -0,0 +1,333 @@ +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Appointments/PatientShareResposne.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; +import 'package:diplomaticquarterapp/pages/BookAppointment/QRCode.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class CovidPaymentSummary extends StatefulWidget { + PatientShareResponse patientShareResponse; + + final String selectedPaymentMethod; + MyInAppBrowser browser; + AuthenticatedUser authenticatedUser; + AppSharedPreferences sharedPref = AppSharedPreferences(); + String transID = ""; + + CovidPaymentSummary( + {@required this.patientShareResponse, this.selectedPaymentMethod}); + + @override + _CovidPaymentSummaryState createState() => _CovidPaymentSummaryState(); +} + +class _CovidPaymentSummaryState extends State { + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + appBarTitle: TranslationBase.of(context).covidTest, + isShowAppBar: true, + body: SingleChildScrollView( + physics: ScrollPhysics(), + child: Container( + margin: EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase.of(context).confirmThePayment, + textAlign: TextAlign.center, + fontWeight: FontWeight.w500, + fontSize: 24, + ), + SizedBox( + height: 12, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + height: 100.0, + padding: EdgeInsets.all(7.0), + width: MediaQuery.of(context).size.width * 0.45, + child: + Image.asset(getImagePath(widget.selectedPaymentMethod)), + ), + Texts( + '${widget.patientShareResponse.patientShareWithTax} ' + + TranslationBase.of(context).sar, + fontSize: 26, + bold: true, + ) + ], + ), + SizedBox( + height: 12, + ), + Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.all(3), + child: NewTextFields( + hintText: TranslationBase.of(context).fileNumber, + initialValue: + projectViewModel.user.patientID.toString(), + isEnabled: false, + ), + ), + ), + Expanded( + child: Container( + margin: EdgeInsets.all(3), + child: NewTextFields( + hintText: TranslationBase.of(context).name, + initialValue: projectViewModel.user.firstName, + isEnabled: false, + ), + ), + ), + ], + ), + SizedBox( + height: 12, + ), + NewTextFields( + hintText: TranslationBase.of(context).mobileNumber, + initialValue: projectViewModel.user.mobileNumber, + isEnabled: false, + ), + SizedBox( + height: 12, + ), + NewTextFields( + hintText: TranslationBase.of(context).depositorName, + initialValue: projectViewModel.user.firstName + + " " + + projectViewModel.user.middleName + + " " + + projectViewModel.user.lastName, + isEnabled: false, + ), + ], + ), + ), + ), + bottomSheet: Container( + height: MediaQuery.of(context).size.height * 0.1, + width: double.infinity, + padding: EdgeInsets.all(12), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).confirm.toUpperCase(), + onTap: () { + startPaymentProcess(projectViewModel.user); + }, + ), + ), + ); + } + + startPaymentProcess(AuthenticatedUser authenticatedUser) { + AppoitmentAllHistoryResultList appo = new AppoitmentAllHistoryResultList(); + appo.projectID = widget.patientShareResponse.projectID; + appo.clinicID = widget.patientShareResponse.clinicID; + appo.appointmentNo = widget.patientShareResponse.appointmentNo; + + openPayment( + widget.selectedPaymentMethod, + authenticatedUser, + double.parse( + widget.patientShareResponse.patientShareWithTax.toString()), + widget.patientShareResponse, + appo); + } + + openPayment( + String paymentMethod, + AuthenticatedUser authenticatedUser, + double amount, + PatientShareResponse patientShareResponse, + AppoitmentAllHistoryResultList appo) async { + if (paymentMethod == "ApplePay") { + // await widget.chromeBrowser.open( + // url: "https://applepay-datatrans-sample.herokuapp.com/", + // options: ChromeSafariBrowserClassOptions( + // android: AndroidChromeCustomTabsOptions( + // addDefaultShareMenuItem: false), + // ios: IOSSafariOptions(barCollapsingEnabled: true))); + } else { + widget.browser = new MyInAppBrowser( + onExitCallback: onBrowserExit, + appo: appo, + onLoadStartCallback: onBrowserLoadStart); + + widget.browser.openPaymentBrowser( + amount, + "Appointment check in", + Utils.getAppointmentTransID( + appo.projectID, appo.clinicID, appo.appointmentNo), + appo.projectID.toString(), + authenticatedUser.emailAddress, + paymentMethod, + authenticatedUser.patientType, + authenticatedUser.firstName, + authenticatedUser.patientID, + authenticatedUser, + widget.browser, + widget.patientShareResponse.isLiveCareAppointment, + widget.patientShareResponse.appointmentDate, + widget.patientShareResponse.appointmentNo, + widget.patientShareResponse.clinicID, + widget.patientShareResponse.doctorID); + } + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (widget.browser.isOpened()) widget.browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (widget.browser.isOpened()) widget.browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + if (isPaymentMade) checkPaymentStatus(appo); + } + + checkPaymentStatus(AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service + .checkPaymentStatus( + Utils.getAppointmentTransID( + appo.projectID, appo.clinicID, appo.appointmentNo), + context) + .then((res) { + print("Printing Payment Status Reponse!!!!"); + print(res); + String paymentInfo = res['Response_Message']; + if (paymentInfo == 'Success') { + createAdvancePayment(res, appo); + } else { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: res['Response_Message']); + } + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + createAdvancePayment(res, AppoitmentAllHistoryResultList appo) { + DoctorsListService service = new DoctorsListService(); + String paymentReference = res['Fort_id'].toString(); + service + .createAdvancePayment(appo, appo.projectID.toString(), res['Amount'], + res['Fort_id'], res['PaymentMethod'], context) + .then((res) { + print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); + addAdvancedNumberRequest( + res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), + paymentReference, + appo.appointmentNo.toString()); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + addAdvancedNumberRequest( + String advanceNumber, String paymentReference, String appointmentID) { + DoctorsListService service = new DoctorsListService(); + service + .addAdvancedNumberRequest( + advanceNumber, paymentReference, appointmentID, context) + .then((res) { + print(res); + getAppoQR(context); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + getAppoQR(context) { + DoctorsListService service = new DoctorsListService(); + service + .generateAppointmentQR(widget.patientShareResponse, context) + .then((res) { + print(res); + GifLoaderDialogUtils.hideDialog(context); + navigateToQR(context, res['AppointmentQR']); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + + Future navigateToQR(context, String appoQR) async { + Navigator.push( + context, + FadePage( + page: QRCode( + patientShareResponse: widget.patientShareResponse, + appoQR: appoQR, + ))); + } + + String getImagePath(String paymentMethod) { + switch (paymentMethod) { + case "MADA": + return 'assets/images/new-design/mada.png'; + break; + case "SADAD": + return 'assets/images/new-design/sadad.png'; + break; + case "VISA": + return 'assets/images/new-design/visa.png'; + break; + case "MASTERCARD": + return 'assets/images/new-design/mastercard.png'; + break; + case "Installment": + return 'assets/images/new-design/installment.png'; + break; + } + + return 'assets/images/new-design/mada.png'; + } +} diff --git a/lib/pages/DrawerPages/family/add-family_type.dart b/lib/pages/DrawerPages/family/add-family_type.dart index 33e39397..96e055b3 100644 --- a/lib/pages/DrawerPages/family/add-family_type.dart +++ b/lib/pages/DrawerPages/family/add-family_type.dart @@ -27,7 +27,7 @@ class AddFamilyMemberType extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( - 'assets/images/DQ/dq_logo_icon.png', + 'assets/images/habib-logo.png', height: 80, width: 80, ), diff --git a/lib/pages/DrawerPages/family/my-family.dart b/lib/pages/DrawerPages/family/my-family.dart index 2d7e4270..07f99b16 100644 --- a/lib/pages/DrawerPages/family/my-family.dart +++ b/lib/pages/DrawerPages/family/my-family.dart @@ -5,6 +5,7 @@ import 'package:diplomaticquarterapp/core/model/ImagesInfo.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/service/medical/vital_sign_service.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -37,9 +38,7 @@ import 'package:provider/provider.dart'; class MyFamily extends StatefulWidget { final bool isAppbarVisible; - MyFamily({this.isAppbarVisible = true}); - @override _MyFamily createState() => _MyFamily(); } @@ -58,6 +57,9 @@ class _MyFamily extends State with TickerProviderStateMixin { ProjectViewModel projectViewModel; AuthenticatedUser user; VitalSignService _vitalSignService = locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); + var isVaiable = false; @override void initState() { @@ -114,8 +116,7 @@ class _MyFamily extends State with TickerProviderStateMixin { child: Container( height: 60.0, margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.92, - // 0.9, + width: MediaQuery.of(context).size.width * 0.92, // 0.9, decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -130,6 +131,8 @@ class _MyFamily extends State with TickerProviderStateMixin { indicatorWeight: 5.0, //indicatorSize: TabBarIndicatorSize.label, indicatorSize: TabBarIndicatorSize.tab, + + indicatorColor: Theme.of(context).primaryColor, labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), @@ -174,38 +177,38 @@ class _MyFamily extends State with TickerProviderStateMixin { ), ); - return AppScaffold( - appBarTitle: TranslationBase.of(context).myFamilyFiles, - isShowAppBar: widget.isAppbarVisible, - body: SingleChildScrollView( - child: Container( - height: SizeConfig.screenHeight * .9, - width: SizeConfig.realScreenWidth, - padding: EdgeInsets.all(20), - child: Stack( - children: [ - TabBar( - controller: _tabController, - indicatorColor: Colors.red, - tabs: [ - Tab( - // padding: EdgeInsets.all(6), - child: AppText(TranslationBase.of(context).family)), - Tab( - // padding: EdgeInsets.all(6), - child: - AppText(TranslationBase.of(context).request)), - ], - ), - TabBarView( - controller: _tabController, - children: [ - myFamilyDetails(context), - myFamilyRequest(context) - ], - ) - ], - )))); + // return AppScaffold( + // appBarTitle: TranslationBase.of(context).myFamilyFiles, + // isShowAppBar: widget.isAppbarVisible, + // body: SingleChildScrollView( + // child: Container( + // height: SizeConfig.screenHeight * .9, + // width: SizeConfig.realScreenWidth, + // padding: EdgeInsets.all(20), + // child: Stack( + // children: [ + // TabBar( + // controller: _tabController, + // indicatorColor: Colors.red, + // tabs: [ + // Tab( + // // padding: EdgeInsets.all(6), + // child: AppText(TranslationBase.of(context).family)), + // Tab( + // // padding: EdgeInsets.all(6), + // child: + // AppText(TranslationBase.of(context).request)), + // ], + // ), + // TabBarView( + // controller: _tabController, + // children: [ + // myFamilyDetails(context), + // myFamilyRequest(context) + // ], + // ) + // ], + // )))); } Widget myFamilyDetails(context) { @@ -392,20 +395,12 @@ class _MyFamily extends State with TickerProviderStateMixin { left: 10, right: 10), child: Row(children: [ Expanded( - flex: 3, - child: AppText( - TranslationBase.of(context) - .theName)), + flex: 3, child: AppText('Name')), Expanded( - flex: 1, - child: AppText( - TranslationBase.of(context) - .allowView)), + flex: 1, child: AppText('Allow')), Expanded( flex: 1, - child: AppText( - TranslationBase.of(context) - .rejectView)), + child: AppText('Reject')), ])), Column( children: familyFileProvider @@ -516,10 +511,7 @@ class _MyFamily extends State with TickerProviderStateMixin { result.statusDescription, color: result.status == 3 ? Colors.green - : result.status == 2 - ? Colors - .yellow[800] - : Colors.red, + : Colors.red, )), ], )); @@ -556,54 +548,66 @@ class _MyFamily extends State with TickerProviderStateMixin { else return Column( children: [ + // Padding( + // padding:EdgeInsets.only(left:10, right:10), + // child: Row( + // mainAxisAlignment: + // MainAxisAlignment.spaceBetween, + // children: [ + // Expanded( + // flex: 3, + // child: AppText( + // TranslationBase.of(context).request), + // ), + // Expanded( + // flex: 2, + // child: AppText( + // TranslationBase.of(context).switchUser, + // )), + // Expanded( + // flex: 1, + // child: AppText( + // TranslationBase.of(context).deleteView, + // )), + // ], + // )), Column(children: [ Padding( padding: EdgeInsets.only(left: 10, right: 10), child: Row(children: [ Expanded( - flex: 3, - child: AppText( - TranslationBase.of(context) - .theName)), + flex: 3, child: AppText('Name')), Expanded( - flex: 1, - child: AppText( - TranslationBase.of(context) - .deleteView)), + flex: 1, child: AppText('Delete')), ])), Column( children: familyFileProvider .allSharedRecordsByStatusResponse .getAllSharedRecordsByStatusList .map((result) { - return result.status == 3 - ? Padding( - padding: EdgeInsets.all(10), - child: Row( - children: [ - Expanded( - flex: 3, - child: AppText( - result.patientName)), - Expanded( - flex: 1, - child: IconButton( - icon: Icon( - Icons.delete, - color: Colors.black, - ), - onPressed: () { - deactivateRequest( - result.iD, - 5, - context); - }, - )), - ], - )) - : Container( - child: AppText(isAvailable())); + return Padding( + padding: EdgeInsets.all(10), + child: Row( + children: [ + Expanded( + flex: 3, + child: AppText( + result.patientName)), + Expanded( + flex: 1, + child: IconButton( + icon: Icon( + Icons.delete, + color: Colors.black, + ), + onPressed: () { + deactivateRequest( + result.iD, 5, context); + }, + )), + ], + )); }).toList()) ]) ], @@ -656,14 +660,15 @@ class _MyFamily extends State with TickerProviderStateMixin { okText: TranslationBase.of(context).confirm, cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { - removeFamily(family, context), - ConfirmDialog.closeAlertDialog(context) + ConfirmDialog.closeAlertDialog(context), + removeFamily(family, context) }, cancelFunction: () => {}); dialog.showAlertDialog(context); } removeFamily(GetAllSharedRecordsByStatusList family, context) { + GifLoaderDialogUtils.showMyDialog(context); this.userID = family.iD; Map request = {}; request['ID'] = this.userID; @@ -675,7 +680,7 @@ class _MyFamily extends State with TickerProviderStateMixin { } refreshFamily(context) { - //sharedPref.remove(FAMILY_FILE); + GifLoaderDialogUtils.hideDialog(context); setState(() { sharedPref.remove(FAMILY_FILE); }); @@ -693,11 +698,8 @@ class _MyFamily extends State with TickerProviderStateMixin { .familyFileProvider .silentLoggin(user is AuthenticatedUser ? null : user, mainUser: user is AuthenticatedUser) - .then((value) { - _vitalSignService.heightCm = ""; - _vitalSignService.weightKg = ""; - loginAfter(value, context); - }).catchError((err) { + .then((value) => loginAfter(value, context)) + .catchError((err) { print(err); AppToast.showErrorToast(message: err); Navigator.of(context).pop(); @@ -705,11 +707,14 @@ class _MyFamily extends State with TickerProviderStateMixin { } loginAfter(result, context) async { - //GifLoaderDialogUtils.hideDialog(context); - Provider.of(context, listen: false).setPrivilege(privilegeList: result,isLoginChild: true); + GifLoaderDialogUtils.hideDialog(context); var currentLang = await sharedPref.getString(APP_LANGUAGE); + Provider.of(context, listen: false) + .setPrivilege(privilegeList: result, isLoginChild: true); result = list.CheckActivationCode.fromJson(result); var familyFile = await sharedPref.getObject(FAMILY_FILE); + + result = list.CheckActivationCode.fromJson(result); var mainUser = await sharedPref.getObject(MAIN_USER); var bloodType = await sharedPref.getString(BLOOD_TYPE); this.sharedPref.clear(); @@ -718,7 +723,7 @@ class _MyFamily extends State with TickerProviderStateMixin { } this.sharedPref.setString(APP_LANGUAGE, currentLang); this.sharedPref.setObject(MAIN_USER, mainUser); - this.sharedPref.setString(BLOOD_TYPE, bloodType); + this.sharedPref.setString(APP_LANGUAGE, currentLang); this.sharedPref.setObject(USER_PROFILE, result.list); this.sharedPref.setObject(FAMILY_FILE, familyFile); this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); @@ -728,6 +733,12 @@ class _MyFamily extends State with TickerProviderStateMixin { authenticatedUserObject.user; Provider.of(context, listen: false) .setUser(authenticatedUserObject.user); + + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) + await pharmacyModuleViewModel.createUser(); + }); + appointmentRateViewModel .getIsLastAppointmentRatedList() .then((value) => { diff --git a/lib/pages/DrawerPages/notifications/notifications_page.dart b/lib/pages/DrawerPages/notifications/notifications_page.dart index 53aad843..9745609d 100644 --- a/lib/pages/DrawerPages/notifications/notifications_page.dart +++ b/lib/pages/DrawerPages/notifications/notifications_page.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -57,15 +58,14 @@ class NotificationsPage extends StatelessWidget { .map( (notification) => InkWell( onTap: () async { - if(!notification.isRead) + if (!notification.isRead) model.markAsRead(notification.id); Navigator.push( context, - MaterialPageRoute( - builder: (BuildContext context) => - NotificationsDetailsPage( - notification: notification, - ))); + FadePage( + page: NotificationsDetailsPage( + notification: notification, + ))); }, child: Container( width: double.infinity, @@ -122,8 +122,7 @@ class NotificationsPage extends StatelessWidget { ..add( InkWell( onTap: () async { - GifLoaderDialogUtils.showMyDialog( - context); + GifLoaderDialogUtils.showMyDialog(context); currentIndex++; GetNotificationsRequestModel getNotificationsRequestModel = @@ -132,10 +131,9 @@ class NotificationsPage extends StatelessWidget { pagingSize: 14, notificationStatusID: 2); - await model.getNotifications(getNotificationsRequestModel,context); - GifLoaderDialogUtils.hideDialog( - context); - + await model.getNotifications( + getNotificationsRequestModel, context); + GifLoaderDialogUtils.hideDialog(context); }, child: Center( child: Image.asset('assets/images/notf.png'), diff --git a/lib/pages/ErService/AmbulanceReq.dart b/lib/pages/ErService/AmbulanceReq.dart index 1690254a..1d4e78ee 100644 --- a/lib/pages/ErService/AmbulanceReq.dart +++ b/lib/pages/ErService/AmbulanceReq.dart @@ -79,7 +79,7 @@ class _AmbulanceReqState extends State child: Container( height: 60.0, margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.93, + width: MediaQuery.of(context).size.width * 0.90, decoration: BoxDecoration( border: Border( bottom: BorderSide( @@ -93,7 +93,6 @@ class _AmbulanceReqState extends State controller: _tabController, indicatorWeight: 5.0, indicatorSize: TabBarIndicatorSize.label, - indicatorColor: Colors.red[800], labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), @@ -108,7 +107,7 @@ class _AmbulanceReqState extends State Container( width: MediaQuery.of(context).size.width * 0.30, child: Center( - child: Texts("Orders Log"), + child: Texts(TranslationBase.of(context).ordersLog), ), ), ], diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart index 5f303846..f36eadc5 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart @@ -62,18 +62,18 @@ class _AmbulanceRequestIndexPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ OrderLogItem( - title: 'Request ID', + title: TranslationBase.of(context).reqId, value: widget.amRequestViewModel.pickUpRequestPresOrder .presOrderID .toString(), ), OrderLogItem( - title: 'Status', + title: TranslationBase.of(context).status, value: widget.amRequestViewModel.pickUpRequestPresOrder .ambulateDescription, ), OrderLogItem( - title: 'Last edit time', + title: TranslationBase.of(context).pickupDate, value: DateUtil.getDayMonthYearDateFormatted( DateUtil.convertStringToDate(widget .amRequestViewModel @@ -81,17 +81,17 @@ class _AmbulanceRequestIndexPageState extends State { .lastEditDate)), ), OrderLogItem( - title: 'Pickup Location', + title: TranslationBase.of(context).pickupLocation, value: widget.amRequestViewModel.pickUpRequestPresOrder .pickupLocationName, ), OrderLogItem( - title: 'Drop off Location', + title: TranslationBase.of(context).dropoffLocation, value: widget.amRequestViewModel.pickUpRequestPresOrder .dropoffLocationName, ), OrderLogItem( - title: 'Trasfaer way', + title: TranslationBase.of(context).transportMethod, value: widget .amRequestViewModel.pickUpRequestPresOrder.title, ), @@ -124,7 +124,7 @@ class _AmbulanceRequestIndexPageState extends State { : Column( children: [ SizedBox( - height: 80, + height: 20, ), Container( margin: EdgeInsets.only(left: 12, right: 12), diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart index cc6af0f2..59528df6 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart @@ -2,8 +2,10 @@ import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -44,306 +46,309 @@ class _BillAmountState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Bill Amount '), - SizedBox( - height: 10, - ), - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 1.0, color: Colors.grey[300]), - outside: BorderSide(width: 1.0, color: Colors.grey[300])), - children: [ - TableRow( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + return AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).billAmount), + SizedBox( + height: 10, + ), + Table( + border: TableBorder.symmetric( + inside: BorderSide(width: 1.0, color: Colors.grey[300]), + outside: BorderSide(width: 1.0, color: Colors.grey[300])), + children: [ + TableRow( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.0), + ), ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'Amount before tax: ', - textAlign: TextAlign.start, - color: Colors.black, - fontSize: 15, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareB, + textAlign: TextAlign.start, + color: Colors.black, + fontSize: 15, + ), ), ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topRight: Radius.circular(10.0), + ), ), - ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.price}', - color: Colors.black, - textAlign: TextAlign.start, - fontSize: 15, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.price}', + color: Colors.black, + textAlign: TextAlign.start, + fontSize: 15, + ), ), ), - ), - ], - ), - TableRow( - children: [ - Container( - color: Colors.white, - height: MediaQuery.of(context).size.height * 0.09, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'Tax amount :', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - ), - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - color: Colors.white, - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.vAT}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, + ], + ), + TableRow( + children: [ + Container( + color: Colors.white, + height: MediaQuery.of(context).size.height * 0.09, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareTax, + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - ), - ], - ), - TableRow( - children: [ - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( + Container( + height: MediaQuery.of(context).size.height * 0.09, color: Colors.white, - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10.0), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.vAT}', + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'Total amount payable', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, - bold: true, + ], + ), + TableRow( + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.0), + ), ), - ), - ), - Container( - height: MediaQuery.of(context).size.height * 0.09, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - bottomRight: Radius.circular(10.0), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).patientShareTotal, + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + bold: true, + ), ), ), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.totalPrice}', - color: Colors.black, - fontSize: 15, - textAlign: TextAlign.start, + Container( + height: MediaQuery.of(context).size.height * 0.09, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + bottomRight: Radius.circular(10.0), + ), + ), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}', + color: Colors.black, + fontSize: 15, + textAlign: TextAlign.start, + ), ), ), - ), - ], - ), - ], - ), - SizedBox( - height: 10, - ), - Texts('Select Ambulate',bold: true,), - SizedBox(height: 5,), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Wheelchair; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Wheelchair'), - leading: Radio( - value: Ambulate.Wheelchair, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + ], + ), + ], + ), + SizedBox( + height: 10, + ), + Texts(TranslationBase.of(context).selectAmbulate,bold: true,), + SizedBox(height: 5,), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Wheelchair; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).wheelchair), + leading: Radio( + value: Ambulate.Wheelchair, + groupValue: _ambulate, + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Walker; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Walker'), - leading: Radio( - value: Ambulate.Walker, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Walker; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).walker), + leading: Radio( + value: Ambulate.Walker, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - ], - ), - SizedBox(height: 5,), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.Stretcher; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Stretcher'), - leading: Radio( - value: Ambulate.Stretcher, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + ], + ), + SizedBox(height: 5,), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.Stretcher; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).stretcher), + leading: Radio( + value: Ambulate.Stretcher, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _ambulate = Ambulate.None; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('None'), - leading: Radio( - value: Ambulate.None, - groupValue: _ambulate, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _ambulate = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _ambulate = Ambulate.None; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Text(TranslationBase.of(context).none), + leading: Radio( + value: Ambulate.None, + groupValue: _ambulate, + + onChanged: (value) { + setState(() { + _ambulate = value; + }); + }, + ), ), ), ), ), - ), - ], - ), - SizedBox(height: 12,), - NewTextFields( - hintText: 'Note', - initialValue: note, - onChanged: (value){ - setState(() { - note = value; - }); - }, - ), - - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { + ], + ), + SizedBox(height: 12,), + NewTextFields( + hintText: TranslationBase.of(context).notes, + initialValue: note, + onChanged: (value){ setState(() { - widget.patientER.ambulate = _ambulate; - widget.patientER.requesterNote = note; - widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); - widget.changeCurrentTab(3); + note = value; }); }, - label: 'Next', ), - ) - ], + + SizedBox( + height: 100, + ), + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.patientER.ambulate = _ambulate; + widget.patientER.requesterNote = note; + widget.patientER.selectedAmbulate = _ambulate.selectAmbulateNumber(); + widget.changeCurrentTab(3); + }); + }, + label: TranslationBase.of(context).next, ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart index b99596c8..b0c541f9 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart @@ -5,12 +5,14 @@ import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.da import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; import 'package:diplomaticquarterapp/pages/Blood/dialogs/SelectHospitalDialog.dart'; import 'package:diplomaticquarterapp/pages/ErService/widgets/AppointmentCard.dart'; -import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; import 'package:diplomaticquarterapp/uitl/ProgressDialog.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -18,9 +20,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_place_picker/google_maps_place_picker.dart'; -import 'package:google_maps_flutter/google_maps_flutter.dart'; -import '../AmbulanceReq.dart'; import '../AvailableAppointmentsPage.dart'; enum HaveAppointment { YES, NO } @@ -67,27 +67,30 @@ class _PickupLocationState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (widget.patientER.direction == 1) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Pickup Location'), - SizedBox( - height: 15, - ), - InkWell( - onTap: (){ - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PickupLocationFromMap( + return AppScaffold( + isShowAppBar: false, + isShowDecPage: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (widget.patientER.direction == 1) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).pickupLocation), + SizedBox( + height: 15, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PickupLocationFromMap( latitude: _latitude, longitude: _longitude, onPick: (value) { @@ -95,342 +98,369 @@ class _PickupLocationState extends State { _result = value; }); }, - ), + )), + ); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Texts(getSelectFromMapName(context))), + Icon( + FontAwesomeIcons.mapMarkerAlt, + size: 24, + color: Colors.black, + ) + ], ), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getSelectFromMapName()), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) - ], ), ), - ), - SizedBox( - height: 12, - ), - Texts('Pickup Spot'), - SizedBox( - height: 5, - ), - InkWell( - onTap: () { - setState(() { - _isInsideHome = !_isInsideHome; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Texts('Inside Home'), - leading: Checkbox( - activeColor: Colors.red[800], - value: _isInsideHome, - onChanged: (value) { - setState(() { - _isInsideHome = value; - }); - }, + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).pickupSpot), + SizedBox( + height: 5, + ), + InkWell( + onTap: () { + setState(() { + _isInsideHome = !_isInsideHome; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).insideHome), + leading: Checkbox( + value: _isInsideHome, + onChanged: (value) { + setState(() { + _isInsideHome = value; + }); + }, + ), ), ), ), - ), - SizedBox( - height: 12, - ), - Texts('Do you have an appointment ?'), - SizedBox( - height: 5, - ), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - if (myAppointment == null) { - getAppointment(); + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).haveAppo), + SizedBox( + height: 5, + ), + Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + if (myAppointment == null) { + getAppointment(); + setState(() { + _haveAppointment = HaveAppointment.YES; + }); + } + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).yes), + leading: Radio( + value: HaveAppointment.YES, + groupValue: _haveAppointment, + onChanged: (value) { + if (myAppointment == null) { + getAppointment(); + setState(() { + _haveAppointment = value; + }); + } + }, + ), + ), + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { setState(() { - _haveAppointment = HaveAppointment.YES; + _haveAppointment = HaveAppointment.NO; + myAppointment = null; }); - } - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Yes'), - leading: Radio( - value: HaveAppointment.YES, - groupValue: _haveAppointment, - activeColor: Colors.red[800], - onChanged: (value) { - if (myAppointment == null) { - getAppointment(); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).no), + leading: Radio( + value: HaveAppointment.NO, + groupValue: _haveAppointment, + onChanged: (value) { setState(() { _haveAppointment = value; + myAppointment = null; }); - } - }, + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _haveAppointment = HaveAppointment.NO; - myAppointment = null; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('No'), - leading: Radio( - value: HaveAppointment.NO, - groupValue: _haveAppointment, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _haveAppointment = value; - myAppointment = null; - }); - }, - ), - ), - ), - ), - ), - ], - ), - if (myAppointment != null) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - AppointmentCard( - appointment: myAppointment, - ) ], ), - SizedBox( - height: 12, - ), - Texts('Drop off Location'), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if (myAppointment != null) + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts(getHospitalName('Pickup Location')), - Icon( - Icons.arrow_drop_down, - size: 24, - color: Colors.black, + SizedBox( + height: 12, + ), + AppointmentCard( + appointment: myAppointment, ) ], ), + SizedBox( + height: 12, ), - ), - ], - ), - if (widget.patientER.direction == 0) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Pickup Location'), - SizedBox( - height: 15, - ), - InkWell( - onTap: () { - confirmSelectHospitalDialog( - widget.amRequestViewModel.hospitals); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, + Texts(TranslationBase.of(context).dropoffLocation), + SizedBox( + height: 8, + ), + + InkWell( + onTap: () { + confirmSelectHospitalDialog( + widget.amRequestViewModel.hospitals); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(getHospitalName( + TranslationBase.of(context).pickupLocation)), + Icon( + Icons.arrow_drop_down, + size: 24, + color: Colors.black, + ) + ], + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getHospitalName('Pickup Location')), - Icon( - Icons.arrow_drop_down, - size: 24, - color: Colors.black, - ) - ], + ), + ], + ), + if (widget.patientER.direction == 0) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).pickupLocation), + SizedBox( + height: 15, + ), + InkWell( + onTap: () { + confirmSelectHospitalDialog( + widget.amRequestViewModel.hospitals); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(getHospitalName( + TranslationBase.of(context).pickupLocation)), + Icon( + Icons.arrow_drop_down, + size: 24, + color: Colors.black, + ) + ], + ), ), ), - ), - SizedBox( - height: 12, - ), - Texts('Drop off Location'), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PickupLocationFromMap( - latitude: _latitude, - longitude: _longitude, - onPick: (value) { - setState(() { - _result = value; - }); - }, + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).dropoffLocation), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PickupLocationFromMap( + latitude: _latitude, + longitude: _longitude, + onPick: (value) { + setState(() { + _result = value; + }); + }, + ), ), + ); + }, + child: Container( + padding: EdgeInsets.all(12), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Texts(getSelectFromMapName(context))), + Icon( + FontAwesomeIcons.mapMarkerAlt, + size: 24, + color: Colors.black, + ) + ], ), - ); - }, - child: Container( - padding: EdgeInsets.all(12), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(getSelectFromMapName()), - Icon( - FontAwesomeIcons.mapMarkerAlt, - size: 24, - color: Colors.black, - ) - ], ), ), - ), - ], + ], + ), + SizedBox( + height: 45, ), + if (myAppointment != null) + SizedBox( + height: 100, + ), + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + if (_result == null || _selectedHospital == null) + AppToast.showErrorToast( + message: TranslationBase.of(context).selectAll); + else + setState(() { + widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; + if (widget.patientER.direction == 0) { + widget.patientER.pickupLocationLattitude = + _result.geometry.location.lat.toString(); + widget.patientER.pickupLocationLongitude = + _result.geometry.location.lng.toString(); + widget.patientER.dropoffLocationLattitude = + _selectedHospital.latitude; + widget.patientER.dropoffLocationLongitude = + _selectedHospital.longitude; + } else { + widget.patientER.pickupLocationLattitude = + _selectedHospital.latitude; + widget.patientER.pickupLocationLongitude = + _selectedHospital.longitude; + widget.patientER.dropoffLocationLattitude = + _result.geometry.location.lat.toString(); + widget.patientER.dropoffLocationLongitude = + _result.geometry.location.lng.toString(); + } - SizedBox( - height: 45, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - if (_result == null || _selectedHospital == null) - AppToast.showErrorToast( - message: 'please select all fields'); - else - setState(() { - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - if (widget.patientER.direction == 0) { - widget.patientER.pickupLocationLattitude = _result.geometry.location.lat.toString(); - widget.patientER.pickupLocationLongitude = _result.geometry.location.lng.toString(); - widget.patientER.dropoffLocationLattitude = _selectedHospital.latitude; - widget.patientER.dropoffLocationLongitude = _selectedHospital.longitude; - } else { - widget.patientER.pickupLocationLattitude = _selectedHospital.latitude; - widget.patientER.pickupLocationLongitude = _selectedHospital.longitude; - widget.patientER.dropoffLocationLattitude = _result.geometry.location.lat.toString(); - widget.patientER.dropoffLocationLongitude = _result.geometry.location.lng.toString(); - } - - widget.patientER.latitude = widget.patientER.pickupLocationLattitude; - widget.patientER.longitude = widget.patientER.pickupLocationLongitude; - widget.patientER.dropoffLocationName = _selectedHospital.name; - widget.patientER.createdBy = widget.amRequestViewModel.user.patientID; - widget.patientER.isOutPatient = widget.amRequestViewModel.user.outSA; - widget.patientER.patientIdentificationID = widget.amRequestViewModel.user.patientIdentificationNo; - widget.patientER.pickupDateTime = DateUtil.convertDateToStringLocation(DateTime.now()); - widget.patientER.pickupLocationName = _result.formattedAddress; - widget.patientER.projectID = widget.amRequestViewModel.user.projectID; - widget.patientER.requesterFileNo = widget.amRequestViewModel.user.patientID; - widget.patientER.requesterIsOutSA = false; - widget.patientER.lineItemNo =0; - widget.patientER.requesterMobileNo = widget.amRequestViewModel.user.mobileNumber; + widget.patientER.latitude = + widget.patientER.pickupLocationLattitude; + widget.patientER.longitude = + widget.patientER.pickupLocationLongitude; + widget.patientER.dropoffLocationName = _selectedHospital.name; + widget.patientER.createdBy = + widget.amRequestViewModel.user.patientID; + widget.patientER.isOutPatient = + widget.amRequestViewModel.user.outSA; + widget.patientER.patientIdentificationID = + widget.amRequestViewModel.user.patientIdentificationNo; + widget.patientER.pickupDateTime = + DateUtil.convertDateToStringLocation(DateTime.now()); + widget.patientER.pickupLocationName = _result.formattedAddress; + widget.patientER.projectID = + widget.amRequestViewModel.user.projectID; + widget.patientER.requesterFileNo = + widget.amRequestViewModel.user.patientID; + widget.patientER.requesterIsOutSA = false; + widget.patientER.lineItemNo = 0; + widget.patientER.requesterMobileNo = + widget.amRequestViewModel.user.mobileNumber; - if (_haveAppointment == HaveAppointment.YES) { - widget.patientER.appointmentNo = myAppointment.appointmentNo.toString(); - widget.patientER.appointmentClinicName = myAppointment.clinicName; - widget.patientER.appointmentDoctorName = myAppointment.doctorNameObj; - widget.patientER.appointmentBranch = myAppointment.projectName; - widget.patientER.appointmentTime = myAppointment.appointmentDate; - widget.patientER.haveAppointment = true; - } else { - widget.patientER.appointmentNo = "0"; - widget.patientER.appointmentClinicName = null; - widget.patientER.appointmentDoctorName = null; - widget.patientER.appointmentBranch = null; - widget.patientER.appointmentTime = null; - widget.patientER.haveAppointment = false; - } + if (_haveAppointment == HaveAppointment.YES) { + widget.patientER.appointmentNo = + myAppointment.appointmentNo.toString(); + widget.patientER.appointmentClinicName = + myAppointment.clinicName; + widget.patientER.appointmentDoctorName = + myAppointment.doctorNameObj; + widget.patientER.appointmentBranch = + myAppointment.projectName; + widget.patientER.appointmentTime = + myAppointment.appointmentDate; + widget.patientER.haveAppointment = true; + } else { + widget.patientER.appointmentNo = "0"; + widget.patientER.appointmentClinicName = null; + widget.patientER.appointmentDoctorName = null; + widget.patientER.appointmentBranch = null; + widget.patientER.appointmentTime = null; + widget.patientER.haveAppointment = false; + } - widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; - widget.changeCurrentTab(2); - }); - }, - label: 'Next', - ), - ) - ], + widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; + widget.changeCurrentTab(2); + }); + }, + label: TranslationBase.of(context).next, ), ), ); @@ -455,12 +485,14 @@ class _PickupLocationState extends State { return _selectedHospital == null ? title : _selectedHospital.name; } - String getSelectFromMapName() { - return _result != null ? _result.formattedAddress : 'Select From Map'; + String getSelectFromMapName(context) { + return _result != null + ? _result.formattedAddress + : TranslationBase.of(context).selectMap; } getAppointment() { - ProgressDialogUtil.showProgressDialog(context); + GifLoaderDialogUtils.showMyDialog(context); widget.amRequestViewModel.getAppointmentHistory().then((value) { if (widget.amRequestViewModel.state == ViewState.Error || widget.amRequestViewModel.state == ViewState.ErrorLocal) { @@ -468,11 +500,11 @@ class _PickupLocationState extends State { } else if (widget .amRequestViewModel.appoitmentAllHistoryResultList.length > 0) { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); Navigator.push( context, - MaterialPageRoute( - builder: (context) => AvailableAppointmentsPage( + FadePage( + page: AvailableAppointmentsPage( appointmentsAllHistoryList: widget.amRequestViewModel.appoitmentAllHistoryResultList, ), @@ -490,14 +522,15 @@ class _PickupLocationState extends State { } }); } else { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); setState(() { _haveAppointment = HaveAppointment.NO; }); - AppToast.showErrorToast(message: 'You don\'t have any appointment'); + AppToast.showErrorToast( + message: TranslationBase.of(context).noAppointment); } }).catchError((e) { - ProgressDialogUtil.hideProgressDialog(context); + GifLoaderDialogUtils.hideDialog(context); AppToast.showErrorToast(message: e); }); } diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart index 01683b55..63d915d1 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart @@ -1,14 +1,15 @@ import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; -import 'package:diplomaticquarterapp/core/enum/OrderService.dart'; import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; import 'package:diplomaticquarterapp/core/model/er/get_all_transportation_method_list_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.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'; enum Direction { ToHospital, FromHospital } enum Way { OneWay, TwoWays } @@ -57,251 +58,273 @@ class _SelectTransportationMethodState @override Widget build(BuildContext context) { - return SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 12, - ), - Texts('Select Transportation Method'), - ...List.generate( - widget.amRequestViewModel.amRequestModeList.length, - (index) => InkWell( - onTap: () { - setState(() { - _erTransportationMethod = - widget.amRequestViewModel.amRequestModeList[index]; - }); - }, - child: Container( - margin: EdgeInsets.all(5), - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: Row( - children: [ - Expanded( - flex: 3, - child: ListTile( - title: Text(widget.amRequestViewModel - .amRequestModeList[index].title), - leading: Radio( - value: widget - .amRequestViewModel.amRequestModeList[index], - groupValue: _erTransportationMethod, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _erTransportationMethod = value; - }); - }, + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( + isShowAppBar: false, + isShowDecPage: false, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).transportHeading), + ...List.generate( + widget.amRequestViewModel.amRequestModeList.length, + (index) => InkWell( + onTap: () { + setState(() { + _erTransportationMethod = + widget.amRequestViewModel.amRequestModeList[index]; + }); + }, + child: Container( + margin: EdgeInsets.all(5), + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: Row( + children: [ + Expanded( + flex: 3, + child: ListTile( + title: Texts(projectViewModel.isArabic + ? widget.amRequestViewModel + .amRequestModeList[index].titleAR + : widget.amRequestViewModel + .amRequestModeList[index].title), + leading: Radio( + value: widget + .amRequestViewModel.amRequestModeList[index], + groupValue: _erTransportationMethod, + onChanged: (value) { + setState(() { + _erTransportationMethod = value; + }); + }, + ), ), ), - ), - Expanded( - flex: 1, - child: Texts( - 'SR ${widget.amRequestViewModel.amRequestModeList[index].price}'), - ) - ], + Expanded( + flex: 1, + child: Texts(TranslationBase.of(context).sar + + ' ${widget.amRequestViewModel.amRequestModeList[index].price}'), + ) + ], + ), ), ), ), - ), - SizedBox( - height: 12, - ), - Texts('Select Direction'), - SizedBox( - height: 5, - ), - Container( - width: double.maxFinite, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _direction = Direction.ToHospital; - }); - }, - child: Container( - width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('To Hospital'), - leading: Radio( - value: Direction.ToHospital, - groupValue: _direction, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + SizedBox( + height: 12, + ), + Texts(TranslationBase.of(context).directionHeading), + SizedBox( + height: 5, + ), + Container( + width: double.maxFinite, + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _direction = Direction.ToHospital; + }); + }, + child: Container( + width: double.maxFinite, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: Texts(TranslationBase.of(context).toHospital), + leading: Radio( + value: Direction.ToHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value; + }); + }, + ), ), ), ), ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _direction = Direction.FromHospital; - }); - }, - child: Container( - width: double.maxFinite, - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Form Hospital'), - leading: Radio( - value: Direction.FromHospital, - groupValue: _direction, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _direction = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _direction = Direction.FromHospital; + }); + }, + child: Container( + width: double.maxFinite, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).fromHospital), + leading: Radio( + value: Direction.FromHospital, + groupValue: _direction, + onChanged: (value) { + setState(() { + _direction = value; + }); + }, + ), ), ), ), ), - ), - ], + ], + ), ), - ), - if (_direction == Direction.ToHospital) - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - ), - Texts('Select Direction'), - SizedBox( - height: 5, - ), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.OneWay; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('One Way'), - leading: Radio( - value: Way.OneWay, - groupValue: _way, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _way = value; - }); - }, + if (_direction == Direction.ToHospital) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 8, + ), + Texts(TranslationBase.of(context).directionHeading), + SizedBox( + height: 5, + ), + Container( + margin: EdgeInsets.only(bottom:65 ), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.OneWay; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).oneDirec), + leading: Radio( + value: Way.OneWay, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), + ), ), ), ), - ), - ), - Expanded( - child: InkWell( - onTap: () { - setState(() { - _way = Way.TwoWays; - }); - }, - child: Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.circular(8), - border: - Border.all(color: Colors.grey, width: 0.5), - color: Colors.white, - ), - child: ListTile( - title: Text('Two Ways'), - leading: Radio( - value: Way.TwoWays, - groupValue: _way, - activeColor: Colors.red[800], - onChanged: (value) { - setState(() { - _way = value; - }); - }, + Expanded( + child: InkWell( + onTap: () { + setState(() { + _way = Way.TwoWays; + }); + }, + child: Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.circular(8), + border: + Border.all(color: Colors.grey, width: 0.5), + color: Colors.white, + ), + child: ListTile( + title: + Texts(TranslationBase.of(context).twoDirec), + leading: Radio( + value: Way.TwoWays, + groupValue: _way, + onChanged: (value) { + setState(() { + _way = value; + }); + }, + ), + ), ), ), ), - ), + ], ), - ], - ), - ], - ), - SizedBox( - height: 15, - ), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child: SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - onTap: () { - setState(() { - widget.patientER.transportationMethodId =(widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); - widget.patientER.direction = _direction == Direction.ToHospital ? 1 : 0; - widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; - widget.patientER.selectedAmbulate = (widget.amRequestViewModel.amRequestModeList.indexOf(_erTransportationMethod) + 1); - widget.patientER.patientERTransportationMethod = _erTransportationMethod; - widget.patientER.orderServiceID = _orderService.getIdOrderService(); - widget.patientER.pickupUrgency = 1; - widget.patientER.lineItemNo = 1; - widget.patientER.cost = _erTransportationMethod.price; - widget.patientER.vAT = _erTransportationMethod.vAT ?? 0; - widget.patientER.totalPrice = _erTransportationMethod.totalPrice; - widget.changeCurrentTab(1); - }); - }, - label: 'Next', + ), + SizedBox( + height: 30, + ), + ], + ), + SizedBox( + height: 15, ), - ) - ], + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child: SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + onTap: () { + setState(() { + widget.patientER.transportationMethodId = (widget + .amRequestViewModel.amRequestModeList + .indexOf(_erTransportationMethod) + + 1); + widget.patientER.direction = + _direction == Direction.ToHospital ? 1 : 0; + widget.patientER.tripType = _way == Way.TwoWays ? 0 : 1; + widget.patientER.selectedAmbulate = (widget + .amRequestViewModel.amRequestModeList + .indexOf(_erTransportationMethod) + + 1); + widget.patientER.patientERTransportationMethod = + _erTransportationMethod; + widget.patientER.orderServiceID = + _orderService.getIdOrderService(); + widget.patientER.pickupUrgency = 1; + widget.patientER.lineItemNo = 1; + widget.patientER.cost = _erTransportationMethod.price; + widget.patientER.vAT = _erTransportationMethod.vAT ?? 0; + widget.patientER.totalPrice = + _erTransportationMethod.totalPrice; + widget.changeCurrentTab(1); + }); + }, + label: TranslationBase.of(context).next, ), ), ); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 7696dd09..4ddfaaa3 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -1,7 +1,9 @@ import 'package:diplomaticquarterapp/core/model/er/PatientER.dart'; import 'package:diplomaticquarterapp/core/viewModels/er/am_request_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/core/enum/Ambulate.dart'; @@ -17,89 +19,94 @@ class Summary extends StatefulWidget { _SummaryState createState() => _SummaryState(); } -//TODO it should be dynamic class _SummaryState extends State { @override Widget build(BuildContext context) { - return SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(left: 12, right: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Summary'), - SizedBox(height: 5,), - Container( - width: double.infinity, - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts('Transportation Method',color: Colors.grey,), - Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), - SizedBox(height: 8,), + return AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(left: 12, right: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).RRTSummary), + SizedBox(height: 5,), + Container( + width: double.infinity, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(TranslationBase.of(context).transportMethod,color: Colors.grey,), + Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), + SizedBox(height: 8,), - Texts('Direction',color: Colors.grey,), - Texts('From Hospital',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).directions,color: Colors.grey,), + Texts(widget.patientER.direction ==0? TranslationBase.of(context).toHospital:TranslationBase.of(context).fromHospital,bold: true,), + SizedBox(height: 8,), - Texts('Pickup Location',color: Colors.grey,), - Texts('SZR Medical Center',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).pickupLocation,color: Colors.grey,), + Texts('${widget.patientER.pickupLocationName}',bold: true,), + SizedBox(height: 8,), - Texts('Drop off location',color: Colors.grey,), - Texts('6199, Al Ameen wlfn nif',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).dropoffLocation,color: Colors.grey,), + Texts('${widget.patientER.dropoffLocationName}',bold: true,), + SizedBox(height: 8,), - Texts('Select Ambulate',color: Colors.grey,), - Texts('${widget.patientER.ambulate.getAmbulateTitle(context)}',bold: true,), - SizedBox(height: 8,), + Texts(TranslationBase.of(context).selectAmbulate,color: Colors.grey,), + Texts('${widget.patientER.ambulate.getAmbulateTitle(context)}',bold: true,), + SizedBox(height: 8,), - Texts('Note',color: Colors.grey,), - Texts('${widget.patientER.requesterNote?? '---'}',bold: true,), - SizedBox(height: 8,), - ], - ), - ), - SizedBox(height: 20,), - Texts('Bill Amount',textAlign: TextAlign.start,), - SizedBox(height: 5,), - Container( - height: 55, - padding: EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8) + Texts(TranslationBase.of(context).notes,color: Colors.grey,), + Texts('${widget.patientER.requesterNote?? '---'}',bold: true,), + SizedBox(height: 8,), + ], + ), ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Total amount payable:'), - Texts('SR ${widget.patientER.patientERTransportationMethod.totalPrice}') - ], + SizedBox(height: 20,), + Texts(TranslationBase.of(context).billAmount,textAlign: TextAlign.start,), + SizedBox(height: 5,), + Container( + + height: 55, + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8) + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).patientShareTotal+':'), + Texts(TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}') + ], + ), ), - ), + SizedBox(height: 130), - SizedBox(height: 45,), - Container( - padding: EdgeInsets.all(15), - width: double.maxFinite, - height: 76, - child:SecondaryButton( - color: Colors.grey[800], - textColor: Colors.white, - label: 'Send', - onTap: () async { - await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); - } - ), - ) - ], + ], + ), + ), + ), + bottomSheet: Container( + padding: EdgeInsets.all(15), + width: double.maxFinite, + height: 90, + child:SecondaryButton( + color: Colors.grey[800], + textColor: Colors.white, + label: TranslationBase.of(context).send, + onTap: () async { + await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); + + } ), ), ); diff --git a/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart b/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart new file mode 100644 index 00000000..1144e587 --- /dev/null +++ b/lib/pages/ErService/EdOnline/ConfirmExitPageDialog.dart @@ -0,0 +1,76 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class ConfirmExitPageDialog extends StatelessWidget { + final GestureTapCallback onTapYes; + final GestureTapCallback onTapNo; + + const ConfirmExitPageDialog({Key key, this.onTapYes, this.onTapNo}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return SimpleDialog( + contentPadding: EdgeInsets.fromLTRB(28.0, 24.0, 28.0, 0.0), + title: Center( + child: Texts( + TranslationBase.of(context).confirm, + color: Colors.black, + ), + ), + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Texts( + "Are you sure you want to exit this page ?", + color: Colors.grey, + ), + SizedBox( + height: 5, + ), + Divider(), + SizedBox( + height: 5.0, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () { + onTapNo(); + }, + child: Container( + child: Center( + child: Texts( + TranslationBase.of(context).no, + color: Colors.red, + ), + ), + ), + ), + + InkWell( + onTap: () { + Navigator.pop(context); + onTapYes(); + }, + child: Container( + child: Center( + child: Texts(TranslationBase.of(context).yes), + ), + ), + ), + ], + ), + SizedBox( + height: 20.0, + ), + ], + ) + ], + ); + } +} diff --git a/lib/pages/ErService/EdOnline/DdServicesPage.dart b/lib/pages/ErService/EdOnline/DdServicesPage.dart new file mode 100644 index 00000000..7395b901 --- /dev/null +++ b/lib/pages/ErService/EdOnline/DdServicesPage.dart @@ -0,0 +1,120 @@ +import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; +import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +import 'EdOnlineAgreementPage.dart'; +import 'EdOnlineNotesPage.dart'; +import 'EdOnlineQuestionsPage.dart'; +import 'EdOnlineSelectedHospitalPage.dart'; +import 'EdPaymentInformationPage.dart'; +import 'ConfirmExitPageDialog.dart'; + +class DdServicesPage extends StatefulWidget { + @override + _DdServicesPageState createState() => _DdServicesPageState(); +} + +class _DdServicesPageState extends State { + PageController pageController; + + bool isAgree = false; + TriageInformationRequest triageInformationRequest = new TriageInformationRequest(); + + List selectedQuestions = List(); + + @override + void initState() { + super.initState(); + pageController = new PageController(); + + } + + _changePageViewIndex(int tab) { + setState(() { + pageController.jumpToPage(tab); + pageController.animateToPage(tab, + duration: Duration(milliseconds: 800), curve: Curves.easeOutQuart); + }); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return Scaffold( + appBar: AppBar( + elevation: 0, + textTheme: TextTheme( + headline6: TextStyle( + color: Theme.of(context).textTheme.headline1.color, + fontWeight: FontWeight.bold), + ), + title: Text( + 'ED Online', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).textTheme.headline1.color, + fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans'), + // bold: true, + // color: Colors.white, + ), + leading: Builder( + builder: (BuildContext context) { + return IconButton( + icon: Icon(Icons.arrow_back), + color: Theme.of(context).textTheme.headline1.color, + onPressed: () { + showConfirmMessage(context); + }, + ); + }, + ), + centerTitle: true, + ), + body: PageView( + physics: NeverScrollableScrollPhysics(), + controller: pageController, + onPageChanged: _changePageViewIndex, + children: [ + EdOnlineSelectedHospitalPage( + changePageViewIndex: _changePageViewIndex, + triageInformationRequest: triageInformationRequest, + ), + EdOnlineAgreementPage( + changePageViewIndex: _changePageViewIndex, + isAgree: isAgree, + ), + EdOnlineQuestionsPage( + changePageViewIndex: _changePageViewIndex, + selectedQuestions: selectedQuestions, + ), + EdOnlineNotesPage( + changePageViewIndex: _changePageViewIndex, + selectedQuestions: selectedQuestions, + triageInformationRequest: triageInformationRequest, + ), + EdPaymentInformationPage(selectedHospital: triageInformationRequest.selectedHospital,) + ], + ), + ); + } + + void showConfirmMessage( + BuildContext context, + ) { + showDialog( + context: context, + child: ConfirmExitPageDialog( + onTapYes: () { + Navigator.pop(context); + }, + onTapNo: () { + Navigator.pop(context); + }, + ), + ); + } +} diff --git a/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart b/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart new file mode 100644 index 00000000..950dc2e0 --- /dev/null +++ b/lib/pages/ErService/EdOnline/EdOnlineAgreementPage.dart @@ -0,0 +1,99 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class EdOnlineAgreementPage extends StatefulWidget { + final HospitalsModel selectedHospital; + final Function changePageViewIndex; + bool isAgree; + EdOnlineAgreementPage({Key key, this.selectedHospital, this.changePageViewIndex,this.isAgree}) : super(key: key); + + @override + _EdOnlineAgreementPageState createState() => _EdOnlineAgreementPageState(); +} + +class _EdOnlineAgreementPageState extends State { + + + @override + Widget build(BuildContext context) { + return AppScaffold( + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + SizedBox(), + InkWell( + onTap: (){ + setState(() { + widget.isAgree = !widget.isAgree; + }); + }, + child: Row( + children: [ + Checkbox( + value: widget.isAgree, + activeColor: Colors.red[800], + onChanged: (bool newValue) { + setState(() { + widget.isAgree = !widget.isAgree; + }); + }), + Expanded( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Texts( + TranslationBase.of(context).onlineCheckInAgreement, + fontSize: 15, + ), + ), + ), + ], + ), + ), + SizedBox(), + ], + ), + ), + bottomSheet: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 56, + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).back.toUpperCase(), + onTap: () => widget.changePageViewIndex(0), + ), + ), + ), + SizedBox(width: 10,), + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).next.toUpperCase(), + disabled: !widget.isAgree, + onTap: () => widget.changePageViewIndex(2), + ), + ), + ), + + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart b/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart new file mode 100644 index 00000000..45df4041 --- /dev/null +++ b/lib/pages/ErService/EdOnline/EdOnlineNotesPage.dart @@ -0,0 +1,177 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; +import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/Blood/new_text_Field.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; +import 'package:provider/provider.dart'; + +class EdOnlineNotesPage extends StatefulWidget { + final List selectedQuestions; + final Function changePageViewIndex; + TriageInformationRequest triageInformationRequest; + EdOnlineNotesPage( + {Key key, this.selectedQuestions, this.changePageViewIndex,this.triageInformationRequest}) + ; + + @override + _EdOnlineNotesPageState createState() => _EdOnlineNotesPageState(); +} + +class _EdOnlineNotesPageState extends State { + TextEditingController _chiefComplaintsTextController = + TextEditingController(); + TextEditingController _noteTextController = TextEditingController(); + DateTime selectedTime; + final _formKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Form( + key: _formKey, + child: NewTextFields( + controller: _chiefComplaintsTextController, + maxLines: 15, + minLines: 5, + hintText: TranslationBase.of(context).chiefComplaints, + validator: (value) { + if (value.isEmpty) return TranslationBase.of(context).errorChiefComplaints; + return null; + }, + ), + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showDateTimePicker( + context, + showTitleActions: true, + minTime: DateTime.now(), + maxTime: DateTime.now().add(Duration(hours: 24)), + onConfirm: (date) { + setState(() { + selectedTime = date; + }); + }, + currentTime: DateTime.now(), + locale: projectViewModel.localeType, + ); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + // height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(selectedTime == null ?TranslationBase.of(context).errorExpectedArrivalTime:TranslationBase.of(context).expectedArrivalTime), + Texts(getDate(context)), + ], + ), + ), + ), + SizedBox( + height: 8, + ), + NewTextFields( + controller: _noteTextController, + maxLines: 15, + minLines: 5, + hintText: TranslationBase.of(context).notes, + ), + ], + ), + ), + ), + bottomSheet: Container( + height: 56, + margin: EdgeInsets.only(bottom: 5), + width: double.infinity, + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).back.toUpperCase(), + onTap: () => widget.changePageViewIndex(2), + ), + ), + ), + SizedBox(width: 10,), + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).save.toUpperCase(), + disabled: selectedTime == null, + onTap: () async { + if (_formKey.currentState.validate()) { + GifLoaderDialogUtils.showMyDialog(context); + model.saveQuestionsInformation( + chiefComplaint: + _chiefComplaintsTextController.text.toString(), + notes: _noteTextController.text.toString(), + selectedQuestions: widget.selectedQuestions, + projectId: widget.triageInformationRequest.projectID,selectedTime: selectedTime).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(model.state == ViewState.ErrorLocal) + AppToast.showErrorToast(message: model.error); + else + { + widget.changePageViewIndex(4); + } + + }).catchError((onError){ + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: onError.toString()); + }); + } + }), + ), + ), + ], + ), + ), + ), + ); + } + + getDate(BuildContext context) { + String message = ""; + if (selectedTime != null) { + message = "${selectedTime.hour}:${selectedTime.minute}"; + } + return message; + } +} diff --git a/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart b/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart new file mode 100644 index 00000000..e3eb1c4c --- /dev/null +++ b/lib/pages/ErService/EdOnline/EdOnlineQuestionsPage.dart @@ -0,0 +1,127 @@ +import 'package:diplomaticquarterapp/core/model/er/TriageQuestionsModel.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +// ignore: must_be_immutable +class EdOnlineQuestionsPage extends StatefulWidget { + final HospitalsModel selectedHospital; + final Function changePageViewIndex; + List selectedQuestions; + + EdOnlineQuestionsPage({Key key, this.selectedHospital,this.selectedQuestions, this.changePageViewIndex}); + + + @override + _EdOnlineQuestionsPageState createState() => _EdOnlineQuestionsPageState(); +} + +class _EdOnlineQuestionsPageState extends State { + + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getQuestions(), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + ...List.generate( + model.triageQuestionsModelList.length, + (index) => + InkWell( + onTap: (){ + setState(() { + if (widget.selectedQuestions + .contains(model.triageQuestionsModelList[index])) { + widget.selectedQuestions + .remove(model.triageQuestionsModelList[index]); + } else { + widget.selectedQuestions + .add(model.triageQuestionsModelList[index]); + } + }); + }, + child: Row( + children: [ + Checkbox( + value: widget.selectedQuestions.contains(model.triageQuestionsModelList[index]), + activeColor: Colors.red[800], + onChanged: (bool newValue) { + setState(() { + if (widget.selectedQuestions + .contains(model.triageQuestionsModelList[index])) { + widget.selectedQuestions + .remove(model.triageQuestionsModelList[index]); + } else { + widget.selectedQuestions + .add(model.triageQuestionsModelList[index]); + } + }); + }), + Expanded( + child: Padding( + padding: const EdgeInsets.all(20.0), + child: Texts( + model.triageQuestionsModelList[index].question, + fontSize: 15, + ), + ), + ), + ], + ), + ), + + ), + SizedBox(height: 80,) + ], + ), + ), + bottomSheet: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: 56, + child: Row( + children: [ + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).back.toUpperCase(), + onTap: () => widget.changePageViewIndex(1), + ), + ), + ), + SizedBox(width: 10,), + Expanded( + child: Container( + margin: EdgeInsets.only(left: 5,right: 5), + child: SecondaryButton( + textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).next.toUpperCase(), + disabled: widget.selectedQuestions.isEmpty, + onTap: () => widget.changePageViewIndex(3), + ), + ), + ), + + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart b/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart new file mode 100644 index 00000000..34c41040 --- /dev/null +++ b/lib/pages/ErService/EdOnline/EdOnlineSelectedHospitalPage.dart @@ -0,0 +1,102 @@ +import 'package:diplomaticquarterapp/core/model/er/TriageInformationRequest.dart'; +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import '../../../Constants.dart'; + + +class EdOnlineSelectedHospitalPage extends StatefulWidget { + final Function changePageViewIndex; + TriageInformationRequest triageInformationRequest; + + EdOnlineSelectedHospitalPage( + {Key key, this.changePageViewIndex,this.triageInformationRequest}) + : super(key: key); + + @override + _EdOnlineSelectedHospitalPageState createState() => + _EdOnlineSelectedHospitalPageState(); +} + +class _EdOnlineSelectedHospitalPageState + extends State { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getHospitals(), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + ...List.generate( + model.hospitals.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 2, + ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + widget.triageInformationRequest.selectedHospital = model.hospitals[index]; + widget.triageInformationRequest.projectID = model.hospitals[index].iD; + }); + }, + child: ListTile( + title: Text(model.hospitals[index].name + + ' ${model.hospitals[index].distanceInKilometers} ' + + TranslationBase.of(context).km), + leading: Radio( + value: model.hospitals[index], + groupValue: widget.triageInformationRequest.selectedHospital, + activeColor: secondaryColor, + onChanged: (value) { + setState(() { + widget.triageInformationRequest.selectedHospital = model.hospitals[index]; + widget.triageInformationRequest.projectID = model.hospitals[index].iD; + }); + }, + ), + ), + ), + ) + ], + ), + SizedBox( + height: 5.0, + ), + ], + ), + ) + ], + ), + ), + bottomSheet: Container( + height: 76, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SecondaryButton( + // textColor: Colors.white, + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).next.toUpperCase(), + disabled: widget.triageInformationRequest.selectedHospital==null, + onTap: () => widget.changePageViewIndex(1)), + ), + ), + ), + ); + } +} diff --git a/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart b/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart new file mode 100644 index 00000000..c510196b --- /dev/null +++ b/lib/pages/ErService/EdOnline/EdPaymentInformationPage.dart @@ -0,0 +1,112 @@ +import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/er/EdOnlineViewModel.dart'; +import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class EdPaymentInformationPage extends StatefulWidget { + final HospitalsModel selectedHospital; + + const EdPaymentInformationPage({Key key, this.selectedHospital}) : super(key: key); + @override + _EdPaymentInformationPageState createState() => + _EdPaymentInformationPageState(); +} + +class _EdPaymentInformationPageState extends State { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getPatientPaymentInformation(), + builder: (_, model, w) => AppScaffold( + baseViewModel: model, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), + color: Colors.white), + margin: EdgeInsets.fromLTRB(0.0, 30.0, 0.0, 5.0), + padding: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 20.0), + child: Column( + children: [ + Container( + alignment: Alignment.center, + margin: + EdgeInsets.only(left: 0.0, right: 20.0, top: 30.0), + child: Text(TranslationBase.of(context).testFee, + style: TextStyle( + color: Colors.black, + fontSize: 22.0, + fontWeight: FontWeight.bold)), + ), + if(model.erPatientShareModel!=null) + Table( + children: [ + TableRow(children: [ + TableCell( + child: + Texts(TranslationBase.of(context).testFee)), + TableCell( + child: Texts(model + .erPatientShareModel.patientShare + .toStringAsFixed(2))), + ]), + TableRow(children: [ + TableCell( + child: Texts( + TranslationBase.of(context).patientTaxToDo)), + TableCell( + child: Texts(model + .erPatientShareModel.patientTaxAmount + .toStringAsFixed(2))), + ]), + TableRow(children: [ + TableCell( + child: Texts(TranslationBase.of(context) + .patientShareTotalToDo)), + TableCell( + child: Texts(model + .erPatientShareModel.patientShareWithTax + .toStringAsFixed(2))), + ]), + ], + ), + ], + ), + ), + ], + ), + ), + bottomSheet: Container( + height: 76, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SecondaryButton( + color: Theme.of(context).primaryColor, + label: TranslationBase.of(context).next.toUpperCase(), + onTap: () { + Navigator.push(context, FadePage(page: PaymentMethod())).then( + (value) { + //TODO Haroun call API here + }, + ); + }, + ), + ), + ), + ), + ); + } + + + +} diff --git a/lib/pages/ErService/ErOptions.dart b/lib/pages/ErService/ErOptions.dart index 886d47d2..e0ff3ed4 100644 --- a/lib/pages/ErService/ErOptions.dart +++ b/lib/pages/ErService/ErOptions.dart @@ -1,10 +1,16 @@ import 'package:diplomaticquarterapp/uitl/location_util.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import '../../uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/pages/ErService/widgets/card_common.dart'; +import 'AmbulanceReq.dart'; +import 'EdOnline/DdServicesPage.dart'; +import 'EdOnline/EdOnlineSelectedHospitalPage.dart'; +import 'NearestEr.dart'; + class ErOptions extends StatefulWidget { final bool isAppbar; @@ -49,7 +55,12 @@ class _ErOptionsState extends State { image: 'assets/images/new-design/AM.PNG', text: TranslationBase.of(context).ambulancerequest, subText: TranslationBase.of(context).requestA, - type: 0, + onTap: (){ + Navigator.push( + context, + FadePage( + page: AmbulanceReq())); + }, ), ), @@ -58,8 +69,39 @@ class _ErOptionsState extends State { image: 'assets/images/new-design/emergency_icon.png', text: TranslationBase.of(context).nearester, subText: TranslationBase.of(context).locationa, - type: 1), + onTap:(){ + Navigator.push( + context, + FadePage( + page: NearestEr())); + }), + + ) + ], + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Expanded( + child: CardCommonEr( + image: 'assets/images/new-design/AM.PNG', + text:'ED service', + subText: 'ED service', + onTap: (){ + Navigator.push( + context, + FadePage( + page: DdServicesPage())); + }, + ), + ), + Expanded( + child: Container(), ) ], ), diff --git a/lib/pages/ErService/NearestEr.dart b/lib/pages/ErService/NearestEr.dart index 227cfb3b..eaf0d4ef 100644 --- a/lib/pages/ErService/NearestEr.dart +++ b/lib/pages/ErService/NearestEr.dart @@ -20,6 +20,10 @@ class NearestEr extends StatelessWidget { @override Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double itemHeight = (size.height - kToolbarHeight - 24) / 2; + final double itemWidth = size.width / 2; + return BaseView( onModelReady: appointmentNo != null && projectID != null ? (model) => model.getProjectAvgERWaitingTimeOrders( @@ -27,14 +31,14 @@ class NearestEr extends StatelessWidget { : (model) => model.getProjectAvgERWaitingTimeOrders(), builder: (_, mode, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: 'Nearest ER', + appBarTitle: TranslationBase.of(context).NearestEr, baseViewModel: mode, body: mode.ProjectAvgERWaitingTimeModeList.length > 0 ? Container( child: ListView( children: [ Text( - "\nThis service Displays nearest branch\n among all the branches of All Habib \n medical Group based on your current Location", + "${TranslationBase.of(context).NearestErDesc}", textAlign: TextAlign.center, style: TextStyle( fontSize: 18.0, @@ -42,301 +46,55 @@ class NearestEr extends StatelessWidget { fontWeight: FontWeight.w900, color: new Color(0xFF60686b))), Container( - margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Container( - child: CardPosition( - text: mode - .ProjectAvgERWaitingTimeModeList[0] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - subText: mode - .ProjectAvgERWaitingTimeModeList[0] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[0].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[0] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[0] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[0] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[0] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[0] - .projectName, - ), - ), - - ), - Expanded( - child: Container( - child: CardPosition( - text: mode - .ProjectAvgERWaitingTimeModeList[1] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - subText: mode - .ProjectAvgERWaitingTimeModeList[1] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[1].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[1] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[1] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[1] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[1] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[1] - .projectName, - ), - ), - - ) - ], - ), - Row( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Container( - child: CardPosition( - - text: mode - .ProjectAvgERWaitingTimeModeList[2] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - - subText: mode - .ProjectAvgERWaitingTimeModeList[2] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[2].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[2] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[2] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[2] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[2] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[2] - .projectName, - ), - ), - - ), - Expanded( - child: Container( - child: CardPosition( - - text: mode - .ProjectAvgERWaitingTimeModeList[3] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - - subText: mode - .ProjectAvgERWaitingTimeModeList[3] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[3].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[3] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[3] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[3] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[3] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[3] - .projectName, - ), - ), - flex: 0, - ) - ], - ), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Container( - child: CardPosition( - - text: mode - .ProjectAvgERWaitingTimeModeList[4] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - - subText: mode - .ProjectAvgERWaitingTimeModeList[4] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[4].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[4] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[4] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[4] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[4] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[4] - .projectName, - ), - ), - - ), - Expanded( - child: Container( - child: CardPosition( - text: mode - .ProjectAvgERWaitingTimeModeList[5] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - subText: mode - .ProjectAvgERWaitingTimeModeList[5] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[5].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[5] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[5] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[5] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[5] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[5] - .projectName, - ), - ), - - ) - ], + margin: EdgeInsets.fromLTRB(2.0, 10.0, 0.0, 10.0), + child: GridView.count( + crossAxisCount: 2, + childAspectRatio: (itemWidth / itemWidth), + crossAxisSpacing: 10, + mainAxisSpacing: 10, + controller: + new ScrollController(keepScrollOffset: false), + shrinkWrap: true, + padding: const EdgeInsets.all(4.0), + children: List.generate(7, (index) { + return Container( + child: CardPosition( + text: mode + .ProjectAvgERWaitingTimeModeList[index] + .projectName + .toString(), + image: + 'assets/images/new-design/find_us_icon.png', + subText: mode + .ProjectAvgERWaitingTimeModeList[index] + .distanceInKilometers + .toString(), + type: mode + .ProjectAvgERWaitingTimeModeList[index].iD + .toString(), + telephone: mode + .ProjectAvgERWaitingTimeModeList[index] + .phoneNumber + .toString(), + networkImage: mode + .ProjectAvgERWaitingTimeModeList[index] + .projectImageURL + .toString(), + latitude: mode + .ProjectAvgERWaitingTimeModeList[index] + .latitude, + longitude: mode + .ProjectAvgERWaitingTimeModeList[index] + .longitude, + projectname: mode + .ProjectAvgERWaitingTimeModeList[index] + .projectName, + cardSize: itemWidth, ), - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: Container( - child: CardPosition( - text: mode - .ProjectAvgERWaitingTimeModeList[6] - .projectName - .toString(), - image: - 'assets/images/new-design/find_us_icon.png', - subText: mode - .ProjectAvgERWaitingTimeModeList[6] - .distanceInKilometers - .toString(), - type: mode - .ProjectAvgERWaitingTimeModeList[6].iD - .toString(), - telephone: mode - .ProjectAvgERWaitingTimeModeList[6] - .phoneNumber - .toString(), - networkImage: mode - .ProjectAvgERWaitingTimeModeList[6] - .projectImageURL - .toString(), - latitude: mode - .ProjectAvgERWaitingTimeModeList[6] - .latitude, - longitude: mode - .ProjectAvgERWaitingTimeModeList[6] - .longitude, - projectname: mode - .ProjectAvgERWaitingTimeModeList[6] - .projectName, - ), - ), - flex: 0, - ), - ], - ), - ], - )), + ); + }), + ), + ), ], ), ) @@ -347,4 +105,3 @@ class NearestEr extends StatelessWidget { ); } } - diff --git a/lib/pages/ErService/OrderLogPage.dart b/lib/pages/ErService/OrderLogPage.dart index 6929cd0b..7d2a4a5b 100644 --- a/lib/pages/ErService/OrderLogPage.dart +++ b/lib/pages/ErService/OrderLogPage.dart @@ -30,28 +30,28 @@ class OrderLogPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ OrderLogItem( - title: 'Request ID', + title: TranslationBase.of(context).reqId, value: amRequestViewModel.patientAllPresOrdersList[index].iD .toString(), ), OrderLogItem( - title: 'Status', + title: TranslationBase.of(context).orderStatus, value: amRequestViewModel .patientAllPresOrdersList[index].description, ), OrderLogItem( - title: 'Pickup Date', + title: TranslationBase.of(context).pickupDate, value: DateUtil.getDayMonthYearDateFormatted( DateUtil.convertStringToDate(amRequestViewModel .patientAllPresOrdersList[index].createdOn)), ), OrderLogItem( - title: 'Pickup Location', + title: TranslationBase.of(context).pickupLocation, value: amRequestViewModel .patientAllPresOrdersList[index].pickupLocationName, ), OrderLogItem( - title: 'Drop off Location', + title: TranslationBase.of(context).dropoffLocation, value: amRequestViewModel .patientAllPresOrdersList[index].dropoffLocationName, ), diff --git a/lib/pages/ErService/widgets/StepsWidget.dart b/lib/pages/ErService/widgets/StepsWidget.dart index c5864710..56b3de6b 100644 --- a/lib/pages/ErService/widgets/StepsWidget.dart +++ b/lib/pages/ErService/widgets/StepsWidget.dart @@ -13,7 +13,8 @@ class StepsWidget extends StatelessWidget { @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return projectViewModel.isArabic? Stack( + return projectViewModel.isArabic? + Stack( children: [ Container( height: 50, @@ -29,7 +30,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: 0, + right: 0, child: InkWell( onTap: () => changeCurrentTab(0), child: Container( @@ -51,7 +52,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: MediaQuery.of(context).size.width * 0.3, + right: MediaQuery.of(context).size.width * 0.3, child: InkWell( onTap: () => index >= 2 ? changeCurrentTab(1) : null, child: Container( @@ -73,7 +74,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: MediaQuery.of(context).size.width * 0.6, + right: MediaQuery.of(context).size.width * 0.6, child: InkWell( onTap: () => index >= 3 ? changeCurrentTab(2) : null, child: Container( @@ -95,7 +96,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: 0, + left: 0, child: InkWell( onTap: () => index == 2 ?changeCurrentTab(3):null, child: Container( @@ -117,7 +118,8 @@ class StepsWidget extends StatelessWidget { ), ), ], - ):Stack( + ): + Stack( children: [ Container( height: 50, @@ -133,7 +135,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: 0, + left: 0, child: InkWell( onTap: () => changeCurrentTab(0), child: Container( @@ -155,7 +157,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: MediaQuery.of(context).size.width * 0.3, + left: MediaQuery.of(context).size.width * 0.3, child: InkWell( onTap: () => index >= 2 ? changeCurrentTab(1) : null, child: Container( @@ -177,7 +179,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - right: MediaQuery.of(context).size.width * 0.6, + left: MediaQuery.of(context).size.width * 0.6, child: InkWell( onTap: () => index >= 3 ? changeCurrentTab(2) : null, child: Container( @@ -199,7 +201,7 @@ class StepsWidget extends StatelessWidget { ), Positioned( top: 10, - left: 0, + right: 0, child: InkWell( onTap: () => index == 2 ?changeCurrentTab(3):null, child: Container( diff --git a/lib/pages/ErService/widgets/card_common.dart b/lib/pages/ErService/widgets/card_common.dart index 35ece966..6b396dc9 100644 --- a/lib/pages/ErService/widgets/card_common.dart +++ b/lib/pages/ErService/widgets/card_common.dart @@ -10,20 +10,18 @@ class CardCommonEr extends StatelessWidget { final image; final text; final subText; - final type; + + final Function onTap; const CardCommonEr( {@required this.image, @required this.text, @required this.subText, - @required this.type}); + @required this.onTap}); @override Widget build(BuildContext context) { return GestureDetector( - onTap: () { - navigateToSearch(context, this.type); - - }, + onTap: () => onTap(), child: Container( margin: EdgeInsets.fromLTRB(9.0, 9.0, 9.0, 9.0), decoration: BoxDecoration(boxShadow: [ @@ -59,25 +57,4 @@ class CardCommonEr extends StatelessWidget { ); } - Future navigateToSearch(context, type) async { -//===Switch case=== - if(type==0) - { - - Navigator.push( - context, - FadePage( - page: AmbulanceReq())); - } - else{ - - Navigator.push( - context, - FadePage( - page: NearestEr())); - - } - - - } } diff --git a/lib/pages/ErService/widgets/card_position.dart b/lib/pages/ErService/widgets/card_position.dart index 8647ad62..69ccaffe 100644 --- a/lib/pages/ErService/widgets/card_position.dart +++ b/lib/pages/ErService/widgets/card_position.dart @@ -19,6 +19,8 @@ class CardPosition extends StatelessWidget { final latitude; final longitude; final projectname; + final cardSize; + const CardPosition( { @required this.image, @@ -30,6 +32,7 @@ class CardPosition extends StatelessWidget { @required this.latitude, @required this.longitude, @required this.projectname , + @required this.cardSize , }); @override @@ -40,17 +43,17 @@ class CardPosition extends StatelessWidget { }, child: Container( - width:MediaQuery.of(context).size.width * 0.47,//165, - margin: EdgeInsets.fromLTRB(7.0, 7.0, 7.0, 7.0), + // width:MediaQuery.of(context).size.width * 0.47,//165, + margin: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0), decoration: BoxDecoration(boxShadow: [ BoxShadow(color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) ], borderRadius: BorderRadius.circular(10), color: Colors.white), child: Column( - crossAxisAlignment: CrossAxisAlignment.center, children: [ Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 10.0, 0.0), + height: cardSize * 0.2 - 8, + margin: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 0.0), child: Text(this.text, overflow: TextOverflow.clip, style: TextStyle( @@ -59,12 +62,14 @@ class CardPosition extends StatelessWidget { fontSize: 2 * SizeConfig.textMultiplier)), ), Container( + height: cardSize * 0.5 - 8, alignment: Alignment.center, - margin: EdgeInsets.fromLTRB(0.0, 0.0, 10.0, 8.0), - child: Image.asset(this.image, width: 60.0, height: 60.0), + margin: EdgeInsets.fromLTRB(0.0, 0.0, 8.0, 8.0), + child: Image.asset(this.image, width: 60.0, height: cardSize * 0.4), ), Container( - margin: EdgeInsets.fromLTRB(10.0, 0.0, 10.0, 0.0), + margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 0.0), + height: cardSize * 0.2 - 8, child: Text(this.subText, overflow: TextOverflow.clip, style: TextStyle( diff --git a/lib/pages/MyAppointments/AppointmentDetails.dart b/lib/pages/MyAppointments/AppointmentDetails.dart index 17b6d57b..9848b394 100644 --- a/lib/pages/MyAppointments/AppointmentDetails.dart +++ b/lib/pages/MyAppointments/AppointmentDetails.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; @@ -236,9 +237,10 @@ class _AppointmentDetailsState extends State Future navigateToBookConfirm(context) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => BookConfirm( + FadePage( + page: BookConfirm( doctor: getDoctorObject(), + isLiveCareAppointment: widget.appo.isLiveCareAppointment, selectedDate: DocAvailableAppointments.selectedDate, selectedTime: DocAvailableAppointments.selectedTime))); } diff --git a/lib/pages/MyAppointments/MyAppointments.dart b/lib/pages/MyAppointments/MyAppointments.dart index a49149b5..5ed0fef4 100644 --- a/lib/pages/MyAppointments/MyAppointments.dart +++ b/lib/pages/MyAppointments/MyAppointments.dart @@ -82,9 +82,17 @@ class _MyAppointmentsState extends State child: Column(children: [ TabBar( tabs: [ - Tab(text: TranslationBase.of(context).booked), - Tab(text: TranslationBase.of(context).confirmed), - Tab(text: TranslationBase.of(context).arrived), + Tab( + child: Text(TranslationBase.of(context).booked, + style: TextStyle(color: Colors.black))), + Tab( + child: Text(TranslationBase.of(context).confirmed, + style: TextStyle(color: Colors.black)), + ), + Tab( + child: Text(TranslationBase.of(context).arrived, + style: TextStyle(color: Colors.black)), + ) ], controller: _tabController, ), @@ -103,7 +111,7 @@ class _MyAppointmentsState extends State leading: Radio( value: FilterType.Clinic, groupValue: filterType, - activeColor: Theme.of(context).primaryColor, + activeColor: Color(0xffB8382C), onChanged: (FilterType value) { setFilterType(value); }, @@ -120,7 +128,7 @@ class _MyAppointmentsState extends State leading: Radio( value: FilterType.Hospital, groupValue: filterType, - activeColor: Theme.of(context).primaryColor, + activeColor: Color(0xffB8382C), onChanged: (FilterType value) => setFilterType(value), ), ), diff --git a/lib/pages/MyAppointments/widgets/AppointmentActions.dart b/lib/pages/MyAppointments/widgets/AppointmentActions.dart index 60035ee1..b335c740 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentActions.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentActions.dart @@ -110,7 +110,7 @@ class _AppointmentActionsState extends State { child: Text(e.title, overflow: TextOverflow.clip, style: TextStyle( - color: new Color(0xFF40ACC9), + color: new Color(0xffB8382C), letterSpacing: 1.0, fontSize: 18.0)), ), @@ -498,8 +498,8 @@ class _AppointmentActionsState extends State { dynamic listPres) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => PrescriptionReportPage( + FadePage( + page: PrescriptionReportPage( prescriptionReportEnhList: prescriptionReportEnhList, listPres: listPres, appo: widget.appo))); @@ -508,18 +508,16 @@ class _AppointmentActionsState extends State { Future navigateToLabResults(PatientLabOrders patientLabOrders) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => - LaboratoryResultPage(patientLabOrders: patientLabOrders))) + FadePage( + page: LaboratoryResultPage(patientLabOrders: patientLabOrders))) .then((value) {}); } Future navigateToRadiologyDetails(FinalRadiology finalRadiology) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => - RadiologyDetailsPage(finalRadiology: finalRadiology))) + FadePage( + page: RadiologyDetailsPage(finalRadiology: finalRadiology))) .then((value) {}); } @@ -542,7 +540,17 @@ class _AppointmentActionsState extends State { transform: Matrix4.translationValues(0.0, curvedValue * 200, 0.0), child: Opacity( opacity: a1.value, - child: ReminderDialog(appo: appo), + child: ReminderDialog( + eventId: appo.appointmentNo.toString(), + title: "Doctor Appointment", + description: "You have an appointment with " + + appo.doctorTitle + + " " + + appo.doctorNameObj, + startDate: appo.appointmentDate, + endDate: appo.appointmentDate, + location: appo.projectName, + ), ), ); }, @@ -668,7 +676,10 @@ class _AppointmentActionsState extends State { context, FadePage( page: VitalSignDetailsScreen( - appointmentNo: appoNo, projectID: projectID,isNotOneAppointment: false,))); + appointmentNo: appoNo, + projectID: projectID, + isNotOneAppointment: false, + ))); } navigateToInsertComplaint() { diff --git a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart index c4299e33..51e18ff4 100644 --- a/lib/pages/MyAppointments/widgets/AppointmentCardView.dart +++ b/lib/pages/MyAppointments/widgets/AppointmentCardView.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResu import 'package:diplomaticquarterapp/pages/MyAppointments/models/AppointmentType.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/countdown_timer_controller.dart'; import 'package:flutter_countdown_timer/current_remaining_time.dart'; @@ -57,14 +58,14 @@ class _ApointmentCardState extends State { children: [ Container( width: projectViewModel.isArabic ? 27 : 20, - height: projectViewModel.isArabic ? 165 : 140, + height: projectViewModel.isArabic ? 165 : 140, decoration: BoxDecoration( //Colors.red[900] Color(0xff404545) color: widget.appo.isLiveCareAppointment ? Color(0xff404545) : !widget.appo.isInOutPatient - ? Colors.red[900] - : Theme.of(context).primaryColor, + ? Colors.red[900] + : Theme.of(context).primaryColor, borderRadius: BorderRadius.only( topLeft: projectViewModel.isArabic ? Radius.circular(0) @@ -85,21 +86,21 @@ class _ApointmentCardState extends State { child: Center( child: Text( widget.appo.isLiveCareAppointment - ? TranslationBase.of(context) - .liveCare - .toUpperCase() + ? TranslationBase.of(context).liveCare.toUpperCase() : !widget.appo.isInOutPatient - ? TranslationBase.of(context) - .inPatient - .toUpperCase() - : TranslationBase.of(context) - .outpatient - .toUpperCase(), + ? TranslationBase.of(context) + .inPatient + .toUpperCase() + : TranslationBase.of(context) + .outpatient + .toUpperCase(), style: TextStyle(color: Colors.white), ), )), ), - SizedBox(width: 8,), + SizedBox( + width: 8, + ), ClipRRect( borderRadius: BorderRadius.circular(100.0), child: Image.network(widget.appo.doctorImageURL, @@ -179,17 +180,18 @@ class _ApointmentCardState extends State { ), ], ), - (widget.appo.patientStatusType == AppointmentType.BOOKED || + (widget.appo.patientStatusType == + AppointmentType.BOOKED || widget.appo.patientStatusType == AppointmentType.CONFIRMED) ? Container( child: CountdownTimer( controller: new CountdownTimerController( - endTime: - DateTime.now().millisecondsSinceEpoch + - (widget.appo.remaniningHoursTocanPay * - 1000) * - 60), + endTime: DateTime.now() + .millisecondsSinceEpoch + + (widget.appo.remaniningHoursTocanPay * + 1000) * + 60), widgetBuilder: (_, CurrentRemainingTime time) { return time != null ? Text( @@ -235,10 +237,7 @@ class _ApointmentCardState extends State { } Future navigateToAppointmentDetails(context, appo) async { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AppointmentDetails(appo: appo))) + Navigator.push(context, FadePage(page: AppointmentDetails(appo: appo))) .then((value) { widget.onReloadAppointmentHistory(); }); diff --git a/lib/pages/MyAppointments/widgets/reminder_dialog.dart b/lib/pages/MyAppointments/widgets/reminder_dialog.dart index b8803469..0db8cda4 100644 --- a/lib/pages/MyAppointments/widgets/reminder_dialog.dart +++ b/lib/pages/MyAppointments/widgets/reminder_dialog.dart @@ -9,9 +9,14 @@ import 'package:manage_calendar_events/manage_calendar_events.dart'; class ReminderDialog extends StatefulWidget { static var selectedDuration; - AppoitmentAllHistoryResultList appo; + final String eventId; + final String title; + final String description; + final String startDate; + final String endDate; + final String location; - ReminderDialog({@required this.appo}); + ReminderDialog({@required this.eventId, @required this.title, @required this.description, @required this.startDate, @required this.endDate, @required this.location}); @override _ReminderDialogState createState() => _ReminderDialogState(); @@ -98,17 +103,14 @@ class _ReminderDialogState extends State { }); CalendarEvent calendarEvent = new CalendarEvent( - eventId: widget.appo.appointmentNo.toString(), - title: "Doctor Appointment", - description: "You have an appointment with " + - widget.appo.doctorTitle + - " " + - widget.appo.doctorNameObj, - startDate: DateUtil.convertStringToDate(widget.appo.appointmentDate) + eventId: widget.eventId, + title: widget.title, + description: widget.description, + startDate: DateUtil.convertStringToDate(widget.startDate) .subtract( new Duration(microseconds: ReminderDialog.selectedDuration)), - endDate: DateUtil.convertStringToDate(widget.appo.appointmentDate), - location: widget.appo.projectName, + endDate: DateUtil.convertStringToDate(widget.endDate), + location: widget.location, duration: new Duration(minutes: 15).inMinutes, isAllDay: false, hasAlarm: true); @@ -118,7 +120,7 @@ class _ReminderDialogState extends State { .then((value) { print("Cal event"); print(value); - if (int.parse(value) == widget.appo.appointmentNo) { + if (int.parse(value) == int.parse(widget.eventId)) { AppToast.showSuccessToast(message: TranslationBase.of(context).reminderSuccess); } Navigator.of(context).pop(); diff --git a/lib/pages/TestPage.dart b/lib/pages/TestPage.dart new file mode 100644 index 00000000..8ec70237 --- /dev/null +++ b/lib/pages/TestPage.dart @@ -0,0 +1,41 @@ +import 'package:diplomaticquarterapp/uitl/location_util.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; +import 'package:flutter/cupertino.dart'; + +class TestPage extends StatefulWidget{ + @override + State createState() => TestPageState(); + +} + +class TestPageState extends State{ + bool isGMS = false; + bool isHMS = false; + + @override + void initState() { + super.initState(); + // openStore(); + location(); + } + + + + openStore() async{ + openAppStore(androidPackageName: "com.ejada.hmg", iOSAppID: "733503978"); + } + + void location(){ + LocationUtils().getCurrentLocation(callBack: (latLng){ + debugPrint(latLng.toString()); + }); + } + + + @override + Widget build(BuildContext context) { + return Container( + ); + } + +} \ No newline at end of file diff --git a/lib/pages/ToDoList/ToDo.dart b/lib/pages/ToDoList/ToDo.dart index 1066ca15..79bcd94b 100644 --- a/lib/pages/ToDoList/ToDo.dart +++ b/lib/pages/ToDoList/ToDo.dart @@ -13,7 +13,6 @@ import 'package:diplomaticquarterapp/pages/ToDoList/payment_method_select.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/widgets/paymentDialog.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; -import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; @@ -22,11 +21,11 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_countdown_timer/countdown_timer_controller.dart'; import 'package:flutter_countdown_timer/current_remaining_time.dart'; import 'package:flutter_countdown_timer/flutter_countdown_timer.dart'; -import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; @@ -95,249 +94,320 @@ class _ToDoState extends State { itemBuilder: (context, index) { return Container( margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Row( - children: [ - Image.asset( - "assets/images/new-design/time_icon.png", - width: 20.0, - height: 20.0), - Container( - margin: - EdgeInsets.only(left: 10.0, right: 10.0), - child: Text( - DateUtil.getWeekDayMonthDayYearDateFormatted( - DateUtil.convertStringToDate( - widget.appoList[index] - .appointmentDate), - projectViewModel.isArabic - ? "ar" - : "en") + - " " + - widget.appoList[index].startTime - .substring(0, 5), - style: TextStyle(fontSize: 10.0)), - ), - widget.appoList[index].isLiveCareAppointment - ? SvgPicture.asset( - "assets/images/new-design/liveCare_logo_icon.svg", - width: 20.0, - height: 20.0) - : Image.asset( - "assets/images/new-design/hospital_address_icon.png", - width: 20.0, - height: 20.0), - Container( - margin: - EdgeInsets.only(left: 5.0, right: 5.0), - child: widget - .appoList[index].isLiveCareAppointment - ? Text( - TranslationBase.of(context) - .liveCareAppo, - style: TextStyle(fontSize: 12.0)) - : Text( - widget.appoList[index].projectName != - null - ? widget - .appoList[index].projectName - : "-", - overflow: TextOverflow.clip, - maxLines: 2, - style: TextStyle(fontSize: 10.0)), - ), - ], + child: Column( + children: [ + Container( + child: Card( + margin: EdgeInsets.fromLTRB(8.0, 0.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), ), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Divider( - color: Colors.grey[500], - ), - ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 1, - child: Container( - height: MediaQuery.of(context).size.height * - 0.1, + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Row( + children: [ + Image.asset( + "assets/images/new-design/time_icon.png", + width: 20.0, + height: 20.0), + Container( + margin: EdgeInsets.only( + left: 10.0, right: 10.0), + child: Text( + DateUtil.getWeekDayMonthDayYearDateFormatted( + DateUtil.convertStringToDate( + widget.appoList[index] + .appointmentDate), + projectViewModel.isArabic + ? "ar" + : "en") + + " " + + widget.appoList[index].startTime + .substring(0, 5), + style: TextStyle(fontSize: 10.0)), + ), + !widget.appoList[index] + .isLiveCareAppointment + ? Image.asset( + "assets/images/new-design/hospital_address_icon.png", + width: 20.0, + height: 20.0) + : Container(), + Container( + margin: EdgeInsets.only( + left: 5.0, right: 5.0), + child: widget.appoList[index] + .isLiveCareAppointment + ? Container() + : Text( + widget.appoList[index] + .projectName != + null + ? widget.appoList[index] + .projectName + : "-", + overflow: TextOverflow.clip, + maxLines: 2, + style: + TextStyle(fontSize: 10.0)), + ), + ], + ), + Container( margin: EdgeInsets.only(top: 5.0), - child: ClipRRect( - borderRadius: - BorderRadius.circular(100.0), - child: Image.network( - widget.appoList[index].doctorImageURL, - fit: BoxFit.fill), + child: Divider( + color: Colors.grey[500], ), ), - ), - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 10.0, left: 20.0, right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Text( - widget.appoList[index].doctorTitle + - " " + + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 1, + child: Container( + height: MediaQuery.of(context) + .size + .height * + 0.1, + margin: EdgeInsets.only(top: 5.0), + child: ClipRRect( + borderRadius: + BorderRadius.circular(100.0), + child: Image.network( widget.appoList[index] - .doctorNameObj, - style: TextStyle( - fontSize: 14.0, - color: Colors.black, - fontWeight: FontWeight.bold, - letterSpacing: 1.0)), - Container( - margin: EdgeInsets.only( - top: 3.0, bottom: 3.0), - child: Text( - getDoctorSpeciality(widget - .appoList[index] - .doctorSpeciality) - .trim(), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[600], - letterSpacing: 1.0)), + .doctorImageURL, + fit: BoxFit.fill), + ), ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.max, - children: [ - RatingBar.readOnly( - initialRating: widget - .appoList[index] - .actualDoctorRate - .toDouble(), - size: 20.0, - filledColor: Colors.yellow[700], - emptyColor: Colors.grey[500], - isHalfAllowed: true, - halfFilledIcon: Icons.star_half, - filledIcon: Icons.star, - emptyIcon: Icons.star, - ), - ], + ), + Expanded( + flex: 3, + child: Container( + margin: EdgeInsets.only( + top: 10.0, + left: 20.0, + right: 20.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + widget.appoList[index] + .doctorTitle + + " " + + widget.appoList[index] + .doctorNameObj, + style: TextStyle( + fontSize: 14.0, + color: Colors.black, + fontWeight: + FontWeight.bold, + letterSpacing: 1.0)), + Container( + margin: EdgeInsets.only( + top: 3.0, bottom: 3.0), + child: Text( + getDoctorSpeciality(widget + .appoList[index] + .doctorSpeciality) + .trim(), + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[600], + letterSpacing: 1.0)), + ), + Row( + mainAxisAlignment: + MainAxisAlignment + .spaceBetween, + mainAxisSize: MainAxisSize.max, + children: [ + RatingBar.readOnly( + initialRating: widget + .appoList[index] + .actualDoctorRate + .toDouble(), + size: 20.0, + filledColor: + Colors.yellow[700], + emptyColor: + Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: + Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ], + ), + Container( + child: CountdownTimer( + controller: new CountdownTimerController( + endTime: DateTime.now() + .millisecondsSinceEpoch + + (widget + .appoList[ + index] + .remaniningHoursTocanPay * + 1000) * + 60), + widgetBuilder: (_, + CurrentRemainingTime + time) { + return time != null + ? Text( + '${time.days != null ? time.days : "0"}:${time.hours.toString().length == 1 ? "0" + time.hours.toString() : time.hours}:${time.min}:${time.sec} ' + + TranslationBase.of( + context) + .upcomingTimeLeft, + style: TextStyle( + fontSize: 12.0, + color: Color( + 0xff40ACC9))) + : Container(); + }, + ), + ), + ], + ), ), - Container( - child: CountdownTimer( - controller: new CountdownTimerController( - endTime: DateTime.now() - .millisecondsSinceEpoch + - (widget.appoList[index] - .remaniningHoursTocanPay * - 1000) * - 60), - widgetBuilder: - (_, CurrentRemainingTime time) { - return time != null - ? Text( - '${time.days}:${time.hours}:${time.min}:${time.sec} ' + - TranslationBase.of( - context) - .upcomingTimeLeft, + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () => performNextAction( + widget.appoList[index]), + child: Container( + margin: EdgeInsets.only(top: 20.0), + child: Column( + children: [ + Image.asset( + getNextActionImage(widget + .appoList[index] + .nextAction), + width: 50.0, + height: 50.0), + Container( + margin: + EdgeInsets.only(top: 5.0), + child: Text( + getNextActionText(widget + .appoList[index] + .nextAction), + textAlign: + TextAlign.center, style: TextStyle( - fontSize: 12.0, - color: Color( - 0xff40ACC9))) - : Container(); - }, + fontSize: 12.0)), + ) + ], + ), ), ), - ], - ), + ) + ], + ), + Divider( + color: Colors.grey[500], ), - ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => performNextAction( - widget.appoList[index]), - child: Container( - margin: EdgeInsets.only(top: 20.0), - child: Column( - children: [ - Image.asset( - getNextActionImage(widget + Flex( + direction: Axis.horizontal, + children: [ + Expanded( + flex: 2, + child: Container( + child: Text( + getNextActionDescription(widget .appoList[index].nextAction), - width: 50.0, - height: 50.0), - Container( - margin: EdgeInsets.only(top: 5.0), - child: Text( - getNextActionText(widget - .appoList[index] - .nextAction), - textAlign: TextAlign.center, - style: - TextStyle(fontSize: 12.0)), - ) - ], + style: TextStyle( + fontSize: 12.0, + color: Colors.grey[700])), + ), ), - ), + Expanded( + flex: 1, + child: GestureDetector( + onTap: () { + navigateToAppointmentDetails( + context, + widget.appoList[index]); + }, + child: Container( + child: Text( + TranslationBase.of(context) + .upcomingDetails, + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 12.0, + color: + new Color(0xFF40ACC9), + decoration: TextDecoration + .underline)), + ), + ), + ) + ], ), - ) - ], - ), - Divider( - color: Colors.grey[500], + ], + ), ), - Flex( - direction: Axis.horizontal, - children: [ - Expanded( - flex: 2, - child: Container( - child: Text( - getNextActionDescription( - widget.appoList[index].nextAction), - style: TextStyle( - fontSize: 12.0, - color: Colors.grey[700])), - ), - ), - Expanded( - flex: 1, - child: GestureDetector( - onTap: () { - navigateToAppointmentDetails( - context, widget.appoList[index]); - }, - child: Container( + ), + ), + Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(10.0), + bottomRight: Radius.circular(10.0)), + color: Color(0xff20bc44), + ), + height: 30.0, + margin: projectViewModel.isArabic + ? EdgeInsets.fromLTRB(160.0, 0.0, 30.0, 0.0) + : EdgeInsets.fromLTRB(20.0, 0.0, 160.0, 0.0), + transform: Matrix4.translationValues(0.0, -8.0, 0.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + widget.appoList[index].isLiveCareAppointment + ? Container( + margin: EdgeInsets.fromLTRB( + 5.0, 0.0, 5.0, 0.0), + child: Image.asset( + "assets/images/new-design/video.png"), + ) + : Container( + margin: EdgeInsets.fromLTRB( + 5.0, 0.0, 5.0, 0.0), + child: Image.asset( + "assets/images/new-design/walkin.png"), + ), + widget.appoList[index].isLiveCareAppointment + ? Container( + child: Text( + TranslationBase.of(context).videoAppo, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 11.0)), + ) + : Container( child: Text( TranslationBase.of(context) - .upcomingDetails, - textAlign: TextAlign.end, + .walkinAppo, style: TextStyle( - fontSize: 12.0, - color: new Color(0xFF40ACC9), - decoration: - TextDecoration.underline)), - ), - ), - ) - ], - ), - ], + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 11.0)), + ) + ], + ), ), - ), + ], ), ); }, @@ -531,8 +601,8 @@ class _ToDoState extends State { Future navigateToAppointmentDetails(context, appo) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => AppointmentDetails(appo: appo))) + FadePage( + page: AppointmentDetails(appo: appo))) .then((value) { getPatientAppointmentHistory(); }); @@ -567,12 +637,34 @@ class _ToDoState extends State { } getPatientShare(context, AppoitmentAllHistoryResultList appo) { - GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); + if (appo.isLiveCareAppointment) { + getLiveCareAppointmentPatientShare(context, service, appo); + } else { + GifLoaderDialogUtils.showMyDialog(context); + service + .getPatientShare(appo.appointmentNo.toString(), appo.clinicID, + appo.projectID, context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); + widget.patientShareResponse = new PatientShareResponse.fromJson(res); + openPaymentDialog(appo, widget.patientShareResponse); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: err); + print(err); + }); + } + } + + getLiveCareAppointmentPatientShare(context, DoctorsListService service, + AppoitmentAllHistoryResultList appo) { + GifLoaderDialogUtils.showMyDialog(context); service - .getPatientShare(appo.appointmentNo.toString(), appo.clinicID, - appo.projectID, context) + .getLiveCareAppointmentPatientShare(appo.appointmentNo.toString(), + appo.clinicID, appo.projectID, context) .then((res) { + print(res); GifLoaderDialogUtils.hideDialog(context); widget.patientShareResponse = new PatientShareResponse.fromJson(res); openPaymentDialog(appo, widget.patientShareResponse); @@ -611,8 +703,8 @@ class _ToDoState extends State { context, String appoQR, PatientShareResponse patientShareResponse) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => QRCode( + FadePage( + page: QRCode( patientShareResponse: patientShareResponse, appoQR: appoQR, ))).then((value) { @@ -674,7 +766,12 @@ class _ToDoState extends State { authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, - widget.browser); + widget.browser, + appo.isLiveCareAppointment, + appo.appointmentDate, + appo.appointmentNo, + appo.clinicID, + appo.doctorID); } onBrowserLoadStart(String url) { @@ -734,20 +831,25 @@ class _ToDoState extends State { res['Fort_id'], res['PaymentMethod'], context) .then((res) { GifLoaderDialogUtils.hideDialog(context); - print(res['OnlineCheckInAppointments'][0]['AdvanceNumber']); + print(res['OnlineCheckInAppointments'][0]); addAdvancedNumberRequest( res['OnlineCheckInAppointments'][0]['AdvanceNumber'].toString(), paymentReference, appo.appointmentNo.toString(), - appo); + appo, + res['OnlineCheckInAppointments'][0]); }).catchError((err) { print(err); GifLoaderDialogUtils.hideDialog(context); }); } - addAdvancedNumberRequest(String advanceNumber, String paymentReference, - String appointmentID, AppoitmentAllHistoryResultList appo) { + addAdvancedNumberRequest( + String advanceNumber, + String paymentReference, + String appointmentID, + AppoitmentAllHistoryResultList appo, + dynamic apptData) { GifLoaderDialogUtils.showMyDialog(context); DoctorsListService service = new DoctorsListService(); service @@ -755,8 +857,25 @@ class _ToDoState extends State { advanceNumber, paymentReference, appointmentID, context) .then((res) { GifLoaderDialogUtils.hideDialog(context); + if (appo.isLiveCareAppointment) + addVIDARequestInsert(advanceNumber, paymentReference, apptData); + else + getAppoQR(context, appo); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); + } + + addVIDARequestInsert( + String advanceNumber, String paymentReference, dynamic apptData) { + GifLoaderDialogUtils.showMyDialog(context); + DoctorsListService service = new DoctorsListService(); + service + .addVIDARequest(advanceNumber, paymentReference, apptData, context) + .then((res) { + GifLoaderDialogUtils.hideDialog(context); print(res); - getAppoQR(context, appo); }).catchError((err) { GifLoaderDialogUtils.hideDialog(context); print(err); @@ -789,7 +908,7 @@ class _ToDoState extends State { } Navigator.push( - context, MaterialPageRoute(builder: (context) => PaymentMethod())) + context, FadePage(page: PaymentMethod())) .then((value) { print(value); getPatientAppointmentHistory(); diff --git a/lib/pages/ToDoList/payment_method_select.dart b/lib/pages/ToDoList/payment_method_select.dart index 3a0734dc..9a22eada 100644 --- a/lib/pages/ToDoList/payment_method_select.dart +++ b/lib/pages/ToDoList/payment_method_select.dart @@ -27,7 +27,7 @@ class _PaymentMethodState extends State { Container( margin: EdgeInsets.fromLTRB(0.0, 15.0, 0.0, 0.0), alignment: Alignment.center, - child: Text("Select Payment Method", + child: Text(TranslationBase.of(context).selectPaymentOption, style: TextStyle( fontSize: 26.0, fontWeight: FontWeight.bold)), ), diff --git a/lib/pages/ToDoList/widgets/upcomingCard.dart b/lib/pages/ToDoList/widgets/upcomingCard.dart index 04930e59..6610ed33 100644 --- a/lib/pages/ToDoList/widgets/upcomingCard.dart +++ b/lib/pages/ToDoList/widgets/upcomingCard.dart @@ -4,6 +4,7 @@ import 'package:diplomaticquarterapp/pages/MyAppointments/AppointmentDetails.dar import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:rating_bar/rating_bar.dart'; @@ -197,7 +198,7 @@ class _TodoListCardState extends State { ), ) ], - ) + ), ], ), ), @@ -351,6 +352,6 @@ class _TodoListCardState extends State { Future navigateToAppointmentDetails(context) async { Navigator.push( - context, MaterialPageRoute(builder: (context) => AppointmentDetails())); + context, FadePage(page: AppointmentDetails())); } } diff --git a/lib/pages/feedback/feedback_home_page.dart b/lib/pages/feedback/feedback_home_page.dart index 309b5713..f7f998bf 100644 --- a/lib/pages/feedback/feedback_home_page.dart +++ b/lib/pages/feedback/feedback_home_page.dart @@ -73,8 +73,7 @@ class _FeedbackHomePageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - indicatorColor: Colors.red[800], + indicatorSize: TabBarIndicatorSize.tab, labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), diff --git a/lib/pages/feedback/send_feedback_page.dart b/lib/pages/feedback/send_feedback_page.dart index 4d511452..189b4761 100644 --- a/lib/pages/feedback/send_feedback_page.dart +++ b/lib/pages/feedback/send_feedback_page.dart @@ -8,6 +8,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; import 'package:diplomaticquarterapp/widgets/bottom_options/BottomSheet.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; @@ -409,7 +410,7 @@ class _SendFeedbackPageState extends State { ), )), SizedBox( - height: 45, + height: 100, ), ], ), @@ -417,27 +418,27 @@ class _SendFeedbackPageState extends State { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.13, + height: MediaQuery.of(context).size.height * 0.12, width: double.infinity, - padding: EdgeInsets.all(8.0), + padding: EdgeInsets.all(15.0), child: Center( child: Container( height: MediaQuery.of(context).size.height * 0.1, - width: MediaQuery.of(context).size.width * 0.8, - child: Button( + child: SecondaryButton( label: TranslationBase.of(context).send, - loading: model.state == ViewState.BusyLocal, + textColor: Colors.white, + disabled: (titleController.text.toString().isEmpty || messageController.text.toString().isEmpty|| messageType == MessageType.NON), onTap: () { final form = formKey.currentState; - if (form.validate()) if (messageType != MessageType.NON) - model - .sendCOCItem( + if (form.validate()) + if (messageType != MessageType.NON){ + GifLoaderDialogUtils.showMyDialog(context); + model.sendCOCItem( title: titleController.text, attachment: images.length > 0 ? images[0] : "", details: messageController.text, cOCTypeName: getCOCName(), - appointHistory:messageType == - MessageType.ComplaintOnAnAppointment + appointHistory:messageType == MessageType.ComplaintOnAnAppointment ? appointHistory : null) .then((value) { @@ -448,12 +449,14 @@ class _SendFeedbackPageState extends State { images = []; }); setMessageType(MessageType.NON); + GifLoaderDialogUtils.hideDialog(context); AppToast.showSuccessToast( message: TranslationBase.of(context).yourFeedback); } else { AppToast.showErrorToast(message: model.error); + GifLoaderDialogUtils.hideDialog(context); } - }); + });} else { AppToast.showErrorToast(message: TranslationBase.of(context).selectPart); } @@ -554,6 +557,30 @@ class FeedbackTypeDialogState extends State { height: 2.5, color: Colors.grey[500], ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () => setMessageDialogType( + MessageType.NON), + child: ListTile( + title: Texts(TranslationBase.of(context).notClassified), + leading: Radio( + value: MessageType.NON, + groupValue: messageTypeDialog, + activeColor: Theme.of(context).primaryColor, + onChanged: (MessageType value) => + setMessageDialogType(value), + ), + ), + ), + ) + ], + ), + SizedBox( + height: 5.0, + ), Row( children: [ Expanded( diff --git a/lib/pages/final_products_page.dart b/lib/pages/final_products_page.dart index 03adee97..66969331 100644 --- a/lib/pages/final_products_page.dart +++ b/lib/pages/final_products_page.dart @@ -1,15 +1,21 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'base/base_view.dart'; class FinalProductsPage extends StatefulWidget { - String id; - FinalProductsPage({this.id}); + final String id; + final int productType; // 1 : default, 2 : manufacturer , 3 : recently viewed + + FinalProductsPage({this.id, this.productType = 1}); + @override _FinalProductsPageState createState() => _FinalProductsPageState(id: id); } @@ -28,11 +34,26 @@ class _FinalProductsPageState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getFinalProducts(i: id), + onModelReady: (model) { + if (widget.productType == 1) { + model.getFinalProducts(i: id); + } else if (widget.productType == 2) { + model.getManufacturerProducts(id); + } else if (widget.productType == 3) { + model.getLastVisitedProducts(); + } else if (widget.productType == 4){ + model.getMostViewedProducts(); + } else if (widget.productType == 5){ + model.getNewProducts(); + } else { + model.getBestSellerProducts(); + } + }, + allowAny: true, builder: (BuildContext context, PharmacyCategoriseViewModel model, Widget child) => PharmacyAppScaffold( - appBarTitle: 'Products', + appBarTitle: "Products", isBottomBar: false, isShowAppBar: true, backgroundColor: Colors.white, @@ -117,193 +138,220 @@ class _FinalProductsPageState extends State { itemBuilder: (BuildContext context, int index) { return NetworkBaseView( baseViewModel: model, - child: Card( - color: model.finalProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, + child: InkWell( + child: Card( + color: model.finalProducts[index] + .discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, ), - color: Colors.white, - ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( - children: [ - Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.finalProducts[index] - .images.isNotEmpty - ? model - .finalProducts[ - index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), - ), - Container( - width: model + padding: EdgeInsets.symmetric( + horizontal: 0), + width: MediaQuery.of(context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack( + children: [ + Container( + margin: + EdgeInsets.fromLTRB( + 0, 16, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model .finalProducts[ index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 2.8 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), + .images + .isNotEmpty + ? model + .finalProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), ), - child: Texts( - model.finalProducts[index] + Container( + width: model + .finalProducts[ + index] .rxMessage != null - ? model - .finalProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w600, + ? MediaQuery.of( + context) + .size + .width / + 2.8 + : 0, + padding: + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), + child: Texts( + model + .finalProducts[ + index] + .rxMessage != + null + ? model + .finalProducts[ + index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w600, + ), ), - ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, + ], ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (model + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + if (model + .finalProducts[ + index] + .discountName != + null) + Container( + width: + double.infinity, + height: 13.0, + decoration: + BoxDecoration( + color: Color( + 0xff5AB145), + ), + child: Center( + child: Texts( + model + .finalProducts[ + index] + .discountName, + regular: true, + color: + Colors.white, + fontSize: 10.4, + ), + ), + ), + Texts( + model .finalProducts[ index] - .discountName != - null) - Container( - width: double.infinity, - height: 13.0, - decoration: - BoxDecoration( - color: - Color(0xff5AB145), - ), - child: Center( - child: Texts( - model - .finalProducts[ - index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 10.4, - ), + .name, + regular: true, + fontSize: 12, + fontWeight: + FontWeight.w400, + ), + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: 4), + child: Texts( + "SAR ${model.finalProducts[index].price}", + bold: true, + fontSize: 14, ), ), - Texts( - model.finalProducts[index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w400, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.finalProducts[index].price}", - bold: true, - fontSize: 14, + Row( + children: [ + StarRating( + totalAverage: model + .finalProducts[ + index] + .approvedRatingSum > + 0 + ? (model.finalProducts[index].approvedRatingSum + .toDouble() / + model + .finalProducts[index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.finalProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .finalProducts[ - index] - .approvedRatingSum > - 0 - ? (model.finalProducts[index].approvedRatingSum - .toDouble() / - model - .finalProducts[index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.finalProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), - ], + ], + ), ), - ), - ], + ], + ), ), ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.finalProducts[index]), + )), + }, )); }, ), @@ -316,158 +364,186 @@ class _FinalProductsPageState extends State { itemCount: model.finalProducts.length, itemBuilder: (BuildContext context, int index) { - return Card( - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - Container( - decoration: BoxDecoration(), - child: Padding( - padding: EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, + return InkWell( + child: Card( + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, + ), ), ), - ), - Container( - margin: EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.finalProducts[index] - .images.isNotEmpty - ? model - .finalProducts[ - index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.contain, - height: 80, + Container( + margin: + EdgeInsets.fromLTRB( + 0, 0, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model + .finalProducts[ + index] + .images + .isNotEmpty + ? model + .finalProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, + height: 80, + ), ), - ), - ], + ], + ), + Column( + children: [ + Container( + width: model + .finalProducts[ + index] + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 3.5 + : 0, + padding: + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), + child: Texts( + model + .finalProducts[ + index] + .rxMessage != + null + ? model + .finalProducts[ + index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w600, + ), + ), + ], + ), + ], + ), + Container( + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - Column( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ + SizedBox( + height: 4.0, + ), Container( - width: model - .finalProducts[ - index] - .rxMessage != - null - ? MediaQuery.of(context) + width: + MediaQuery.of(context) .size - .width / - 3.5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), - ), + .width * + 0.65, child: Texts( model.finalProducts[index] - .rxMessage != - null - ? model - .finalProducts[ - index] - .rxMessage - : "", - color: Colors.white, + .name, regular: true, - fontSize: 10, + fontSize: 13.2, fontWeight: - FontWeight.w600, + FontWeight.w500, + maxLines: 5, ), ), - ], - ), - ], - ), - Container( - height: 100.0, - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 4.0, - ), - Container( - height: 35.0, - width: 250.0, - child: Texts( - model.finalProducts[index] - .name, - regular: true, - fontSize: 13.2, - fontWeight: FontWeight.w500, - maxLines: 2, + SizedBox( + height: 8.0, ), - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.finalProducts[index].price}", - bold: true, - fontSize: 14, + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.finalProducts[index].price}", + bold: true, + fontSize: 14, + ), ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .finalProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .finalProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .finalProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.finalProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), - ], + Row( + children: [ + StarRating( + totalAverage: model + .finalProducts[ + index] + .approvedRatingSum > + 0 + ? (model + .finalProducts[ + index] + .approvedRatingSum + .toDouble() / + model + .finalProducts[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.finalProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], + ), ), - ), - ], + ], + ), ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.finalProducts[index]), + )), + }, ); }), ), diff --git a/lib/pages/insurance/insurance_card_screen.dart b/lib/pages/insurance/insurance_card_screen.dart index 42efc179..da66c572 100644 --- a/lib/pages/insurance/insurance_card_screen.dart +++ b/lib/pages/insurance/insurance_card_screen.dart @@ -109,58 +109,92 @@ class _InsuranceCardState extends State { ), Column( crossAxisAlignment: - CrossAxisAlignment.stretch, + CrossAxisAlignment.start, children: [ - Texts( - TranslationBase.of(context).category +": "+ - model.insurance[index] - .subCategoryDesc, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .category, + fontSize: 18.5), + Texts( + model.insurance[index] + .subCategoryDesc, + fontSize: 18.5) + ], ), Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ Texts( - TranslationBase.of(context) - .expirationDate +": "+ - convertDateFormat(model - .insurance[index].cardValidTo), - fontSize: 18.5, - ), - Expanded( - child: Column( - children: [ - model.insurance[index].isActive == true - ? Texts( - TranslationBase.of(context) - .activeInsurence, - color: Colors.green, - fontWeight: FontWeight.w900, - fontSize: 17.9) - : Texts( - TranslationBase.of(context) - .notActive, - color: Colors.red, - fontWeight: FontWeight.w900, - fontSize: 17.9) - ], - ), - ), + TranslationBase.of(context) + .expirationDate, + fontSize: 18.5), + Texts( + convertDateFormat( + model.insurance[index] + .cardValidTo, + ), + fontSize: 18.5), ], ), - Texts( - TranslationBase.of(context) - .patientCard +": "+ - model - .insurance[index].patientCardID, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .status + + ": ", + fontSize: 18.5), + model.insurance[index].isActive == + true + ? Texts( + TranslationBase.of(context) + .activeInsurence, + color: Colors.green, + fontWeight: FontWeight.w900, + fontSize: 17.9) + : Texts( + TranslationBase.of(context) + .notActive, + color: Colors.red, + fontWeight: FontWeight.w900, + fontSize: 17.9) + ], ), - Texts( - TranslationBase.of(context) - .policyNumber +" "+ - model.insurance[index] - .insurancePolicyNumber, - fontSize: 18.5, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .patientCard, + fontSize: 18.5), + Texts( + model.insurance[index] + .patientCardID, + fontSize: 18.5) + ], ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context) + .policyNumber, + fontSize: 18.5, + ), + Texts( + model.insurance[index] + .insurancePolicyNumber, + fontSize: 18.5, + ) + ]), ], ), SizedBox( diff --git a/lib/pages/insurance/insurance_page.dart b/lib/pages/insurance/insurance_page.dart index f938d9e5..a391f554 100644 --- a/lib/pages/insurance/insurance_page.dart +++ b/lib/pages/insurance/insurance_page.dart @@ -16,7 +16,7 @@ class InsurancePage extends StatelessWidget { final InsuranceViewModel model; InsuranceCardService _insuranceCardService = locator(); - InsurancePage({Key key, this.model}) : super(key: key); + InsurancePage({Key key, this.model}) : super(key: key); @override Widget build(BuildContext context) { return SingleChildScrollView( @@ -31,24 +31,20 @@ class InsurancePage extends StatelessWidget { width: MediaQuery.of(context).size.width, padding: EdgeInsets.all(10.0), child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.max, children: [ if (model.user != null) Expanded( flex: 3, child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), + margin: + EdgeInsets.only(top: 2.0, left: 10.0, right: 20.0), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - model.user.firstName ?? '' + " " + model.user.lastName ?? '', + model.user.firstName + " " + model.user.lastName, fontSize: 14, color: Colors.black, fontWeight: FontWeight.w500, @@ -57,11 +53,9 @@ class InsurancePage extends StatelessWidget { height: 8, ), Texts( - TranslationBase.of(context) - .fileno + + TranslationBase.of(context).fileno + ": " + - model.user.patientID - .toString(), + model.user.patientID.toString(), fontSize: 14, color: Colors.black, fontWeight: FontWeight.w500, @@ -78,9 +72,7 @@ class InsurancePage extends StatelessWidget { children: [ Container( child: SecondaryButton( - label: TranslationBase.of( - context) - .fetchData, + label: TranslationBase.of(context).fetchData, small: true, textColor: Colors.white, onTap: () { @@ -88,15 +80,12 @@ class InsurancePage extends StatelessWidget { setupID: '010266', projectID: 15, patientIdentificationID: - model.user - .patientIdentificationNo, - patientID: model - .user.patientID, - name: model.user - .firstName + + model.user.patientIdentificationNo, + patientID: model.user.patientID, + name: model.user.firstName + " " + - model - .user.lastName,context: context); + model.user.lastName, + context: context); }, ), ), @@ -107,122 +96,115 @@ class InsurancePage extends StatelessWidget { ], ), ), - if(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList != null ?? false) - ...List.generate(model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList.length, (index) => - model.getAllSharedRecordsByStatusResponse.getAllSharedRecordsByStatusList[index].status == 3 - ? Container( - margin: EdgeInsets.all(10.0), - child: Card( - margin: EdgeInsets.fromLTRB( - 8.0, 16.0, 8.0, 8.0), - color: Colors.white, - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(10), - ), - child: Container( - width: MediaQuery.of(context).size.width, - padding: EdgeInsets.all(10.0), - child: Row( - crossAxisAlignment: - CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - Expanded( - flex: 3, - child: Container( - margin: EdgeInsets.only( - top: 2.0, - left: 10.0, - right: 20.0), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts( - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientName, - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, - ), - SizedBox( - height: 8, - ), - Texts( - TranslationBase.of( - context) - .fileno + - ": " + - model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientID - .toString(), - fontSize: 14, - color: Colors.black, - fontWeight: - FontWeight.w500, - ) - ], - ), - ), - ), - Expanded( - flex: 2, - child: Container( - margin: - EdgeInsets.only(top: 2.0), - child: Column( - children: [ - Container( - child: SecondaryButton( - label: TranslationBase - .of(context) - .fetchData, - small: true, - textColor: - Colors.white, - onTap: () { - getDetails( - projectID: 15, - patientIdentificationID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .patientIdenficationNumber, - setupID: - '010266', - patientID: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index] - .responseID, - name: model - .getAllSharedRecordsByStatusResponse - .getAllSharedRecordsByStatusList[ - index].patientName,context: context); - }, - ), + if (model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList != + null ?? + false) + ...List.generate( + model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList.length, + (index) => model.getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[index].status == + 3 + ? Container( + margin: EdgeInsets.all(10.0), + child: Card( + margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + color: Colors.white, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(10.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + flex: 3, + child: Container( + margin: EdgeInsets.only( + top: 2.0, left: 10.0, right: 20.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientName, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + SizedBox( + height: 8, + ), + Texts( + TranslationBase.of(context).fileno + + ": " + + model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientID + .toString(), + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ) + ], + ), + ), + ), + Expanded( + flex: 2, + child: Container( + margin: EdgeInsets.only(top: 2.0), + child: Column( + children: [ + Container( + child: SecondaryButton( + label: TranslationBase.of(context) + .fetchData, + small: true, + textColor: Colors.white, + onTap: () { + getDetails( + projectID: 15, + patientIdentificationID: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientIdenficationNumber, + setupID: '010266', + patientID: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .responseID, + name: model + .getAllSharedRecordsByStatusResponse + .getAllSharedRecordsByStatusList[ + index] + .patientName, + context: context); + }, + ), + ), + ], + ), + ), + ) + ], ), - ], + ), ), - ), - ) - ], - ), - ), - ), - ) - : Container() - ), - + ) + : Container()), ], ), ); @@ -230,29 +212,32 @@ class InsurancePage extends StatelessWidget { getDetails( {String setupID, - int projectID, - String patientIdentificationID, - int patientID, - String name,BuildContext context}) { + int projectID, + String patientIdentificationID, + int patientID, + String name, + BuildContext context}) { GifLoaderDialogUtils.showMyDialog(context); _insuranceCardService .getPatientInsuranceDetails( - setupID: setupID, - projectID: projectID, - patientID: patientID, - patientIdentificationID: patientIdentificationID) + setupID: setupID, + projectID: projectID, + patientID: patientID, + patientIdentificationID: patientIdentificationID) .then((value) { GifLoaderDialogUtils.hideDialog(context); - if (!_insuranceCardService.hasError && _insuranceCardService.isHaveInsuranceCard) { + if (!_insuranceCardService.hasError && + _insuranceCardService.isHaveInsuranceCard) { Navigator.push( context, FadePage( page: InsuranceCardUpdateDetails( - insuranceCardDetailsModel: _insuranceCardService.insuranceCardDetailsList, - patientID: patientID, - patientIdentificationID: patientIdentificationID, - name: name, - ))); + insuranceCardDetailsModel: + _insuranceCardService.insuranceCardDetailsList, + patientID: patientID, + patientIdentificationID: patientIdentificationID, + name: name, + ))); } else { AppToast.showErrorToast(message: _insuranceCardService.error); } diff --git a/lib/pages/insurance/insurance_update_screen.dart b/lib/pages/insurance/insurance_update_screen.dart index 36b424a8..6c3ee61c 100644 --- a/lib/pages/insurance/insurance_update_screen.dart +++ b/lib/pages/insurance/insurance_update_screen.dart @@ -32,7 +32,11 @@ class _InsuranceUpdateState extends State super.initState(); _tabController = TabController(length: 2, vsync: this); - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: + 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/en/0.png', + imageAr: + 'https://hmgwebservices.com/Images/MobileApp/imges-info/insurance-card/ar/0.png')); } void dispose() { @@ -111,7 +115,7 @@ class _InsuranceUpdateState extends State physics: BouncingScrollPhysics(), controller: _tabController, children: [ - InsurancePage(model:model), + InsurancePage(model: model), Container( child: ListView.builder( itemCount: model.insuranceUpdate == null @@ -227,6 +231,4 @@ class _InsuranceUpdateState extends State ), ); } - - } diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index cd8a8a2d..ef38ae9c 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -1,17 +1,20 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart'; -import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; import 'package:diplomaticquarterapp/pages/Covid-DriveThru/covid-drivethru-location.dart'; 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/paymentService/payment_service.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -34,6 +37,9 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State { + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); + @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -41,6 +47,7 @@ class _HomePageState extends State { onModelReady: (model) => model.getPatientRadOrders(), builder: (_, model, wi) => AppScaffold( isShowDecPage: false, + isHelp: true, body: Container( width: double.infinity, child: SingleChildScrollView( @@ -68,12 +75,12 @@ class _HomePageState extends State { right: 5, child: Container( width: - MediaQuery.of(context).size.width * 0.8, + MediaQuery.of(context).size.width * 0.8, child: Row( children: [ Expanded( child: Container( - height: 120, + height: 125, padding: EdgeInsets.all(5), margin: EdgeInsets.all(5), decoration: BoxDecoration( @@ -83,24 +90,27 @@ class _HomePageState extends State { fit: BoxFit.fill, ), color: - Colors.white.withOpacity(0.3), + Colors.white.withOpacity(0.3), borderRadius: BorderRadius.all( Radius.circular(5))), child: Container( - margin: EdgeInsets.only(top: 10.0), child: Column( children: [ - Text("COVID-19 TEST", - style: TextStyle( - color: Colors.white, - fontWeight: - FontWeight.bold, - fontSize: 18.0)), + Texts( + TranslationBase.of(context) + .covidTest, + color: Colors.white, + fontWeight: FontWeight.w700, + ), Row( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, children: [ Container( margin: EdgeInsets.only( - top: 15.0, left: 3.5, right: 3.5), + top: 15.0, + ), child: SvgPicture.asset( 'assets/images/new-design/covid-19-car.svg', width: 45.0, @@ -108,51 +118,54 @@ class _HomePageState extends State { ), Container( margin: EdgeInsets.only( - left: 10.0, - top: 10.0), + top: 5.0), child: Column( children: [ - Text("Drive-Thru", - style: TextStyle( - color: Colors - .white, - fontWeight: - FontWeight - .bold, - fontSize: - 16.0)), + Texts( + TranslationBase.of( + context) + .driveThru, + fontWeight: + FontWeight.w700, + color: Colors.white, + ), ButtonTheme( shape: - RoundedRectangleBorder( + RoundedRectangleBorder( borderRadius: - BorderRadius - .circular( - 5.0), + BorderRadius + .circular( + 5.0), ), minWidth: MediaQuery.of( - context) - .size - .width * + context) + .size + .width * 0.15, height: 25.0, child: RaisedButton( color: Colors .red[800], textColor: - Colors.white, + Colors.white, disabledTextColor: - Colors.white, + Colors.white, disabledColor: - new Color( - 0xFFbcc2c4), + new Color( + 0xFFbcc2c4), onPressed: () { navigateToCovidDriveThru(); }, - child: Text( - "BOOK NOW", - style: TextStyle( - fontSize: - 12.0)), + child: Texts( + TranslationBase.of( + context) + .bookNow, + fontWeight: + FontWeight + .w700, + color: Colors + .white, + ), ), ), ], @@ -170,7 +183,7 @@ class _HomePageState extends State { onTap: () => Navigator.push(context, FadePage(page: LiveCareHome())), child: Container( - height: 120, + height: 125, padding: EdgeInsets.all(15), margin: EdgeInsets.all(5), decoration: BoxDecoration( @@ -193,263 +206,302 @@ class _HomePageState extends State { ], ), ), - Container(width: double.infinity, height: 80) + Container( + width: double.infinity, + height: projectViewModel.isArabic ? 110 : 80) ], ), Positioned( top: 155, left: MediaQuery.of(context).size.width * (MediaQuery.of(context).orientation == - Orientation.landscape + Orientation.landscape ? 0.02 : 0.03), right: MediaQuery.of(context).size.width * (MediaQuery.of(context).orientation == - Orientation.landscape + Orientation.landscape ? 0.02 : 0.03), - child: (!model.isLogin && projectViewModel.user == null) + child: (!model.isLogin) ? Container( - width: double.infinity, - height: 125, - decoration: BoxDecoration( - color: HexColor('#A59E9E'), - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(9)), - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/bg_graphic.png'), - fit: BoxFit.cover)), - child: Container( - margin: EdgeInsets.all(5), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - ), - Texts( - TranslationBase.of(context).myMedicalFile, - color: Colors.black87, - bold: true, - fontSize: 23, - ), - SizedBox( - height: 5, - ), - Texts( - TranslationBase.of(context) - .myMedicalFileSubTitle, - color: Colors.black, - fontSize: 16, - ), - Align( - alignment: projectViewModel.isArabic - ? Alignment.bottomRight - : Alignment.bottomLeft, - child: InkWell( - onTap: () { - widget.goToMyProfile(); - }, - child: Container( - margin: EdgeInsets.all(2), - width: 90, - height: 30, - decoration: BoxDecoration( - color: HexColor('#D81A2E'), - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, - width: 0.5), - borderRadius: BorderRadius.all( - Radius.circular(9)), + width: double.infinity, + height: 125, + decoration: BoxDecoration( + color: HexColor('#A59E9E'), + shape: BoxShape.rectangle, + border: Border.all( + color: Colors.transparent, width: 0.5), + borderRadius: + BorderRadius.all(Radius.circular(9)), + image: DecorationImage( + image: ExactAssetImage( + 'assets/images/bg_graphic.png'), + fit: BoxFit.cover)), + child: Container( + margin: EdgeInsets.all(5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 2, ), - child: Center( - child: Texts( - TranslationBase.of(context) - .viewMore, - color: Colors.white, - fontSize: 12, - ), + Texts( + TranslationBase.of(context).myMedicalFile, + color: Colors.black87, + fontWeight: FontWeight.w700, + fontSize: 23, ), - ), - ), - ) - ], - ), - ), - ) - : Container( - width: double.infinity, - height: 130, - decoration: BoxDecoration( - color: HexColor('#A59E9E'), - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, width: 0.5), - borderRadius: - BorderRadius.all(Radius.circular(9)), - image: DecorationImage( - image: ExactAssetImage( - 'assets/images/bg_graphic.png'), - fit: BoxFit.cover), - ), - child: Container( - margin: EdgeInsets.all(5), - child: Column( - children: [ - Row( - children: [ - if (model.user != null) - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 8, - ), - Texts( - model.user.firstName + - " " + - model.user.lastName, - color: Colors.grey[100], - bold: true, - fontSize: 15, - ), - Texts( - '${model.user.patientID}', - color: Colors.white, - fontSize: 14, - ), - SizedBox( - height: 5, + Texts( + TranslationBase.of(context) + .myMedicalFileSubTitle, + color: Colors.black, + fontSize: 16, + ), + Align( + alignment: projectViewModel.isArabic + ? Alignment.bottomLeft + : Alignment.bottomRight, + child: InkWell( + onTap: () { + widget.goToMyProfile(); + }, + child: Container( + margin: EdgeInsets.only( + left: 15, right: 15), + width: 90, + height: 30, + decoration: BoxDecoration( + color: HexColor('#D81A2E'), + shape: BoxShape.rectangle, + border: Border.all( + color: Colors.transparent, + width: 0.5), + borderRadius: BorderRadius.all( + Radius.circular(0)), ), - Texts( - '${DateUtil.getMonthDayYearDateFormatted(model.user.dateofBirthDataTime)} ,${model.user.genderDescription} ${model.user.ageDesc}', - color: Colors.grey[100], - fontWeight: FontWeight.normal, - fontSize: 14, + child: Center( + child: Texts( + TranslationBase.of(context) + .viewMore, + color: Colors.white, + fontWeight: FontWeight.w700, + fontSize: 12, + ), ), - ], - ), - ), - InkWell( - onTap: () { - widget.goToMyProfile(); - }, - child: Container( - margin: EdgeInsets.all(2), - width: 90, - height: 30, - decoration: BoxDecoration( - color: HexColor('#D81A2E'), - shape: BoxShape.rectangle, - border: Border.all( - color: Colors.transparent, - width: 0.5), - borderRadius: BorderRadius.all( - Radius.circular(5), - ), - ), - child: Center( - child: Texts( - TranslationBase.of(context) - .viewMore, - color: Colors.white, - fontSize: 12, ), ), - ), - ) - ], + ) + ], + ), ), - Row( - //crossAxisAlignment: CrossAxisAlignment.center, - //mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - Expanded( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + ) + : Container( + width: double.infinity, + height: projectViewModel.isArabic ? 160 : 130, + decoration: BoxDecoration( + color: HexColor('#A59E9E'), + shape: BoxShape.rectangle, + border: Border.all( + color: Colors.transparent, width: 0.5), + borderRadius: + BorderRadius.all(Radius.circular(9)), + image: DecorationImage( + image: ExactAssetImage( + 'assets/images/bg_graphic.png'), + fit: BoxFit.cover), + ), + child: Container( + margin: EdgeInsets.all(5), + child: Column( + children: [ + Row( children: [ - Image.asset( - 'assets/images/height_icon.png', - width: 35, - height: 40, - ), - Texts( - "${model.heightCm}", - color: Colors.white, + if (projectViewModel.user != null && + model.isLogin) + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 8, + ), + Row( + children: [ + Texts( + model.user.firstName + + " " + + model.user.lastName, + color: Colors.grey[100], + bold: true, + fontSize: 15, + ), + Container( + margin: + EdgeInsets.fromLTRB( + 8.0, + 0.0, + 8.0, + 0.0), + child: SvgPicture.asset( + "assets/images/new-design/verification_check.svg"), + ), + ], + ), + Texts( + '${model.user.patientID}', + color: Colors.white, + fontSize: 14, + ), + SizedBox( + height: 5, + ), + Texts( + '${DateUtil.getMonthDayYearDateFormatted(model.user.dateofBirthDataTime)} ,${model.user.genderDescription} ${model.user.ageDesc}', + color: Colors.grey[100], + fontWeight: FontWeight.normal, + fontSize: 14, + ), + ], + ), + ), + InkWell( + onTap: () { + widget.goToMyProfile(); + }, + child: Container( + margin: EdgeInsets.all(2), + width: 90, + height: 30, + decoration: BoxDecoration( + color: HexColor('#D81A2E'), + shape: BoxShape.rectangle, + border: Border.all( + color: Colors.transparent, + width: 0.5), + borderRadius: BorderRadius.all( + Radius.circular(5), + ), + ), + child: Center( + child: Texts( + TranslationBase.of(context) + .viewMore, + color: Colors.white, + fontSize: 12, + ), + ), + ), ) ], ), - ), - SizedBox( - width: 3, - ), - Expanded( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, + Row( children: [ - Image.asset( - 'assets/images/weight_icon.png', - width: 25, - height: 40, + Expanded( + child: Row( + children: [ + Image.asset( + 'assets/images/height_icon.png', + width: 35, + height: 40, + ), + Texts( + "${model.heightCm}", + color: Colors.white, + fontSize: 17, + ) + ], + ), ), - Texts( - '${model.weightKg}', - color: Colors.white, - ) - ], - ), - ), - SizedBox( - width: 3, - ), - Expanded( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Image.asset( - 'assets/images/blood_icon.png', - width: 35, - height: 40, + SizedBox( + width: 3, + ), + Expanded( + child: Row( + children: [ + Image.asset( + 'assets/images/weight_icon.png', + width: 25, + height: 40, + ), + Texts('${model.weightKg}', + color: Colors.white, + fontSize: 17) + ], + ), + ), + SizedBox( + width: 3, + ), + Expanded( + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Image.asset( + 'assets/images/blood_icon.png', + width: 35, + height: 40, + ), + Texts( + '${model.booldType}', + color: Colors.white, + ) + ], + ), ), - Texts( - '${model.booldType}', - color: Colors.white, - ) ], - ), - ), - ], - ) - ], - ), + ) + ], + ), + ), + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.only(bottom: 15, right: 15, left: 15), + child: InkWell( + onTap: (){ + Navigator.of(context).push(MaterialPageRoute(builder: (context) => PackagesHomePage())); + }, + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + color: Color(0xffB8382C), + ), + child: Padding( + padding: const EdgeInsets.all(8), + child: Row( + children: [ + Texts( + TranslationBase.of(context).offerAndPackages, + color: Colors.white, fontSize: 20, fontWeight: FontWeight.normal, + ), + Spacer(), + Image.asset("assets/images/offer_icon.png"), + ], ), ), ), - ], + ), ), - if(projectViewModel.havePrivilege(64)||projectViewModel.havePrivilege(65)||projectViewModel.havePrivilege(67)) + if (projectViewModel.havePrivilege(64) || + projectViewModel.havePrivilege(65) || + projectViewModel.havePrivilege(67)) Container( margin: EdgeInsets.only(left: 15, right: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - if(projectViewModel.havePrivilege(64)) + if (projectViewModel.havePrivilege(64)) DashboardItem( onTap: () { Navigator.push( context, FadePage( - page: HomeHealthCareIndexPage(), + page: HomeHealthCarePage(), ), ); }, @@ -464,15 +516,16 @@ class _HomePageState extends State { height: 50, ), SizedBox( - height: 3, + height: 10, ), Texts( TranslationBase.of(context) - .homeHealthCareService, + .homeHealthCare, textAlign: TextAlign.center, color: Colors.white, - bold: true, - fontSize: SizeConfig.textMultiplier * 1.7, + fontWeight: FontWeight.w700, + fontSize: + SizeConfig.textMultiplier * 1.55, ) ], ), @@ -482,10 +535,9 @@ class _HomePageState extends State { imageName: 'home_healthcare_service_bg.png', opacity: 0.5, ), - if(projectViewModel.havePrivilege(65)) + if (projectViewModel.havePrivilege(65)) DashboardItem( - onTap: () => Navigator.push(context, FadePage(page: LandingPagePharmacy())), - + onTap: () => getPharmacyToken(model), child: Center( child: Padding( padding: const EdgeInsets.all(15.0), @@ -500,11 +552,13 @@ class _HomePageState extends State { height: 20, ), Texts( - TranslationBase.of(context).onlinePharmacy, + TranslationBase.of(context) + .onlinePharmacy, textAlign: TextAlign.center, color: Colors.white, - bold: true, - fontSize: SizeConfig.textMultiplier * 1.7, + fontWeight: FontWeight.w700, + fontSize: + SizeConfig.textMultiplier * 1.55, ) ], ), @@ -513,13 +567,13 @@ class _HomePageState extends State { height: MediaQuery.of(context).size.width * 0.4, imageName: 'al-habib_onlne_pharmacy_bg.png', ), - if(projectViewModel.havePrivilege(67)) + if (projectViewModel.havePrivilege(67)) DashboardItem( - onTap: (){ + onTap: () { Navigator.push( context, FadePage( - page: CMCIndexPage(), + page: CMCPage(), ), ); }, @@ -534,14 +588,15 @@ class _HomePageState extends State { height: 50, ), SizedBox( - height: 3, + height: 10, ), Texts( - TranslationBase.of(context).emergencyService, + TranslationBase.of(context).cmcHeading, textAlign: TextAlign.center, color: Colors.white, - bold: true, - fontSize: SizeConfig.textMultiplier * 1.7, + fontWeight: FontWeight.w700, + fontSize: + SizeConfig.textMultiplier * 1.55, ) ], ), @@ -629,7 +684,7 @@ class _HomePageState extends State { borderRadius: BorderRadius.circular(6.0), color: Colors.white, )), - if(projectViewModel.havePrivilege(60)) + if (projectViewModel.havePrivilege(60)) Container( width: MediaQuery.of(context).size.width * 0.29, child: InkWell( @@ -637,8 +692,8 @@ class _HomePageState extends State { context, FadePage( page: ErOptions( - isAppbar: true, - ))), + isAppbar: true, + ))), child: Center( child: Padding( padding: const EdgeInsets.all(15.0), @@ -658,7 +713,8 @@ class _HomePageState extends State { textAlign: TextAlign.center, color: Colors.black87, bold: false, - fontSize: SizeConfig.textMultiplier * 1.7, + fontSize: + SizeConfig.textMultiplier * 1.7, ) ], ), @@ -776,24 +832,42 @@ class _HomePageState extends State { ); } + getPharmacyToken(DashboardViewModel model) async { + if(!model.isLogin) { + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } else { + GifLoaderDialogUtils.showMyDialog(context); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) { + await pharmacyModuleViewModel.createUser().then((value) { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + }); + } else { + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: LandingPagePharmacy())); + } + }); + } + } + navigateToCovidDriveThru() { - Navigator.push(context, - MaterialPageRoute(builder: (context) => CovidDrivethruLocation())); + Navigator.push(context, FadePage(page: CovidDrivethruLocation())); } } class DashboardItem extends StatelessWidget { const DashboardItem( {this.hasBorder = false, - this.imageName, - @required this.child, - this.onTap, - Key key, - this.width, - this.height, - this.color, - this.opacity = 0.4, - this.hasColorFilter = true}) + this.imageName, + @required this.child, + this.onTap, + Key key, + this.width, + this.height, + this.color, + this.opacity = 0.4, + this.hasColorFilter = true}) : super(key: key); final bool hasBorder; final String imageName; @@ -814,13 +888,13 @@ class DashboardItem extends StatelessWidget { height: height != null ? height : MediaQuery.of(context).orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.19 - : MediaQuery.of(context).size.height * 0.35, + ? MediaQuery.of(context).size.height * 0.17 + : MediaQuery.of(context).size.height * 0.35, decoration: BoxDecoration( color: !hasBorder ? color != null - ? color - : HexColor('#050705').withOpacity(opacity) + ? color + : HexColor('#050705').withOpacity(opacity) : Colors.white, borderRadius: BorderRadius.circular(6.0), border: hasBorder @@ -828,11 +902,13 @@ class DashboardItem extends StatelessWidget { : Border.all(width: 0.0, color: Colors.transparent), image: imageName != null ? DecorationImage( - image: ExactAssetImage('assets/images/$imageName'), - fit: BoxFit.cover, - colorFilter: hasColorFilter ? new ColorFilter.mode( - Colors.black.withOpacity(0.2), BlendMode.dstIn) : null, - ) + image: ExactAssetImage('assets/images/$imageName'), + fit: BoxFit.cover, + colorFilter: hasColorFilter + ? new ColorFilter.mode( + Colors.black.withOpacity(0.2), BlendMode.dstIn) + : null, + ) : null, ), child: Center( diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index e1dd6b63..c99930aa 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -61,8 +61,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { var themeNotifier; ///inject the user data - AuthenticatedUserObject authenticatedUserObject = locator< - AuthenticatedUserObject>(); + AuthenticatedUserObject authenticatedUserObject = + locator(); final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); final authService = new AuthProvider(); @@ -72,12 +72,12 @@ class _LandingPageState extends State with WidgetsBindingObserver { void _requestIOSPermissions() { flutterLocalNotificationsPlugin .resolvePlatformSpecificImplementation< - IOSFlutterLocalNotificationsPlugin>() + IOSFlutterLocalNotificationsPlugin>() ?.requestPermissions( - alert: true, - badge: true, - sound: true, - ); + alert: true, + badge: true, + sound: true, + ); } bool isPageNavigated = false; @@ -86,7 +86,12 @@ class _LandingPageState extends State with WidgetsBindingObserver { _changeCurrentTab(int tab) { setState(() { currentTab = tab; - pageController.jumpToPage(tab); + if (tab != 0) + pageController.jumpToPage(tab); + else { + IS_VOICE_COMMAND_CLOSED = false; + pageController.jumpToPage(tab); + } }); } @@ -110,10 +115,9 @@ class _LandingPageState extends State with WidgetsBindingObserver { if (!isPageNavigated) { isPageNavigated = true; Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - IncomingCall( + context, + MaterialPageRoute( + builder: (context) => IncomingCall( incomingCallData: LandingPage.incomingCallData))) .then((value) { isPageNavigated = false; @@ -149,21 +153,25 @@ class _LandingPageState extends State with WidgetsBindingObserver { pageController = PageController(keepPage: true); _firebaseMessaging.setAutoInitEnabled(true); + locationUtils = + new LocationUtils(isShowConfirmDialog: true, context: context); + WidgetsBinding.instance + .addPostFrameCallback((_) => locationUtils.getCurrentLocation()); // HMG (Guest/Internet) Wifi Access [Zohaib Kambrani] HMGNetworkConnectivity(context, () { GifLoaderDialogUtils.showMyDialog(context); - PlatformBridge().connectHMGGuestWifi().then((value) => - { - GifLoaderDialogUtils.hideDialog(context) - }); + PlatformBridge() + .connectHMGGuestWifi() + .then((value) => {GifLoaderDialogUtils.hideDialog(context)}); }).checkAndConnectIfNoInternet(); if (Platform.isIOS) { _firebaseMessaging.requestNotificationPermissions(); } - // Flip Permission Checks [Zohaib Kambrani] requestPermissions().then((results) { + registerGeofences(); + if (results[Permission.notification].isGranted) _firebaseMessaging.getToken().then((String token) { sharedPref.setString(PUSH_TOKEN, token); @@ -172,13 +180,12 @@ class _LandingPageState extends State with WidgetsBindingObserver { checkUserStatus(token); } }); - - if (results[Permission.location].isGranted); - if (results[Permission.storage].isGranted); - if (results[Permission.camera].isGranted); - if (results[Permission.photos].isGranted); - if (results[Permission.accessMediaLocation].isGranted); - if (results[Permission.calendar].isGranted); + if (results[Permission.location].isGranted) ; + if (results[Permission.storage].isGranted) ; + if (results[Permission.camera].isGranted) ; + if (results[Permission.photos].isGranted) ; + if (results[Permission.accessMediaLocation].isGranted) ; + // if (results[Permission.calendar].isGranted) ; }); requestPermissions(); // }); @@ -304,12 +311,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { ConfirmDialog dialog = new ConfirmDialog( context: context, confirmMessage: message, - okText: TranslationBase - .of(context) - .confirm, - cancelText: TranslationBase - .of(context) - .cancel_nocaps, + okText: TranslationBase.of(context).confirm, + cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => {}, cancelFunction: () => {}); dialog.showAlertDialog(context); @@ -324,69 +327,18 @@ class _LandingPageState extends State with WidgetsBindingObserver { Permission.photos, Permission.notification, Permission.accessMediaLocation, - Permission.calendar, + // Permission.calendar, + Permission.activityRecognition ].request(); - var permissionsGranted = await deviceCalendarPlugin.hasPermissions(); - if (permissionsGranted.isSuccess && !permissionsGranted.data) { - permissionsGranted = await deviceCalendarPlugin.requestPermissions(); - if (!permissionsGranted.isSuccess || !permissionsGranted.data) {} - } + // var permissionsGranted = await deviceCalendarPlugin.hasPermissions(); + // if (permissionsGranted.isSuccess && !permissionsGranted.data) { + // permissionsGranted = await deviceCalendarPlugin.requestPermissions(); + // if (!permissionsGranted.isSuccess || !permissionsGranted.data) {} + // } return permissionResults; } - setTheme() async { - // - // defaultTheme = - // ThemeData( - // fontFamily:projectViewModel.isArabic ? 'Cairo' : 'WorkSans', - // primarySwatch: Colors.blue, - // visualDensity: VisualDensity.adaptivePlatformDensity, - // brightness: Brightness.light, - // pageTransitionsTheme: const PageTransitionsTheme( - // builders: { - // TargetPlatform.android: ZoomPageTransitionsBuilder(), - // TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - // }, - // ), - // hintColor: Colors.grey[400], - // disabledColor: Colors.grey[300], - // errorColor: Color.fromRGBO(235, 80, 60, 1.0), - // scaffoldBackgroundColor: Color(0xffEEEEEE), - // textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - // textSelectionHandleColor: Colors.grey, - // canvasColor: Colors.white, - // backgroundColor: Colors.white, - // highlightColor: Colors.grey[100].withOpacity(0.4), - // splashColor: Colors.transparent, - // primaryColor: Color(0xff40ACC9), - // bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - // cursorColor: Colors.grey, - // cardColor: Colors.white, - // iconTheme: IconThemeData(), - // appBarTheme: AppBarTheme( - // color: Color(0xff40ACC9), - // brightness: Brightness.dark, - // elevation: 10.0, - // actionsIconTheme: IconThemeData( - // color: Color(0xff40ACC9), - // ), - // ), - // ); - // themeNotifier.setTheme(defaultTheme); - } - - void checkUserStatus(token, {isLoader = true}) async { - if (isLoader) - //GifLoaderDialogUtils.showMyDialog(context); - authService - .selectDeviceImei(token) - .then((SelectDeviceIMEIRES value) => setUserValues(value)) - .catchError((err) { - //GifLoaderDialogUtils.hideDialog(context); - }); - } - static Future myBackgroundMessageHandler( Map message) async { Map myMap = new Map.from(message['data']); @@ -423,8 +375,8 @@ class _LandingPageState extends State with WidgetsBindingObserver { void doIt() { getUserInformation().then((value) { - if (value != null) projectViewModel.platformBridge() - .registerHmgGeofences(); + if (value != null) + projectViewModel.platformBridge().registerHmgGeofences(); }); } @@ -437,8 +389,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { } }); } - - requestPermissions().then((results) {}); } login() async { @@ -472,31 +422,29 @@ class _LandingPageState extends State with WidgetsBindingObserver { getNotificationCount(token) async { if (await sharedPref.getObject(USER_PROFILE) != null) { var data = - AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); if (data != null) { authService .registeredAuthenticatedUser(data, token, 0, 0) .then((res) => {print(res)}); - authService.getDashboard().then((value) => - { - setState(() { - notificationCount = value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] > - 99 - ? '99+' - : value['List_PatientDashboard'][0] - ['UnreadPatientNotificationCount'] - .toString(); - - sharedPref.setString(NOTIFICATION_COUNT, notificationCount); - }) - }); + authService.getDashboard().then((value) => { + setState(() { + notificationCount = value['List_PatientDashboard'][0] + ['UnreadPatientNotificationCount'] > + 99 + ? '99+' + : value['List_PatientDashboard'][0] + ['UnreadPatientNotificationCount'] + .toString(); + + sharedPref.setString(NOTIFICATION_COUNT, notificationCount); + }) + }); familyFileProvider.getSharedRecordByStatus(); } } } - @override Widget build(BuildContext context) { projectViewModel = Provider.of(context); @@ -506,13 +454,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { elevation: 0, textTheme: TextTheme( headline6: TextStyle( - color: Colors.white, fontWeight: FontWeight.bold), + color: Theme.of(context).textTheme.headline1.color, + fontWeight: FontWeight.bold), ), title: Text( getText(currentTab).toUpperCase(), style: TextStyle( fontWeight: FontWeight.bold, - color: Colors.white, + color: Theme.of(context).textTheme.headline1.color, fontFamily: projectViewModel.isArabic ? 'Cairo' : 'WorkSans'), // bold: true, // color: Colors.white, @@ -521,35 +470,47 @@ class _LandingPageState extends State with WidgetsBindingObserver { builder: (BuildContext context) { return new Stack( children: [ - IconButton( - icon: Icon(Icons.menu), - color: Colors.white, - onPressed: () => Scaffold.of(context).openDrawer(), - ), + currentTab == 0 + ? IconButton( + icon: Icon(Icons.menu), + color: Theme.of(context).textTheme.headline1.color, + onPressed: () => Scaffold.of(context).openDrawer(), + ) + : IconButton( + icon: Icon(Icons.arrow_back), + color: Theme.of(context).textTheme.headline1.color, + onPressed: () { + setState(() { + currentTab = 0; + }); + + pageController.jumpToPage(0); + }, + ), notificationCount != '' ? new Positioned( - right: projectViewModel.isArabic ? 35 : 0, - top: 5, - child: new Container( - padding: EdgeInsets.all(4), - decoration: new BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(20), - ), - constraints: BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: new Text( - notificationCount, - style: new TextStyle( - color: Colors.white, - fontSize: projectViewModel.isArabic ? 8 : 9, - ), - textAlign: TextAlign.center, - ), - ), - ) + right: projectViewModel.isArabic ? 35 : 0, + top: 5, + child: new Container( + padding: EdgeInsets.all(4), + decoration: new BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(20), + ), + constraints: BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: new Text( + notificationCount, + style: new TextStyle( + color: Colors.white, + fontSize: projectViewModel.isArabic ? 8 : 9, + ), + textAlign: TextAlign.center, + ), + ), + ) : SizedBox() ], ); @@ -560,7 +521,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { //iconSize: 70, icon: Icon( projectViewModel.isLogin ? Icons.settings : Icons.login, - color: Colors.white, + color: Theme.of(context).textTheme.headline1.color, ), onPressed: () { if (projectViewModel.isLogin) @@ -582,7 +543,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { children: [ HomePage( goToMyProfile: () { - _changeCurrentTab(1); + _changeCurrentTab(0); }, ), MedicalProfilePage(), @@ -596,13 +557,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { index: currentTab, ), floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked, - floatingActionButton: currentTab == 0 - ? FloatingButton( - elevation: true, - onTap: () { - _changeCurrentTab(2); - }) - : null); + floatingActionButton: + (projectViewModel.havePrivilege(34) && currentTab == 0) + ? FloatingButton( + elevation: true, + onTap: () { + _changeCurrentTab(2); + }) + : null); } triggerRobot() { @@ -617,14 +579,36 @@ class _LandingPageState extends State with WidgetsBindingObserver { return TranslationBase.of(context).medicalProfile; case 2: return TranslationBase.of(context).bookAppo; + case 5: + return TranslationBase.of(context).bookAppo; case 3: return TranslationBase.of(context).services; case 4: - return TranslationBase - .of(context) - .bookAppo; + return TranslationBase.of(context).bookAppo; } } -} - + void checkUserStatus(token) async { + authService + .selectDeviceImei(token) + .then((SelectDeviceIMEIRES value) => setUserValues(value)); + if (projectViewModel.isLoading == true) { + var data = + AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); + if (data != null) { + authService + .registeredAuthenticatedUser(data, token, 0, 0) + .then((res) => {print(res)}); + authService.getDashboard().then((value) => { + setState(() { + if (value != null) { + notificationCount = value['List_PatientDashboard'][0] + ['UnreadPatientNotificationCount'] + .toString(); + } + }) + }); + } + } + } +} diff --git a/lib/pages/landing/landing_page_pharmcy.dart b/lib/pages/landing/landing_page_pharmcy.dart index 52bbb888..04c9bb54 100644 --- a/lib/pages/landing/landing_page_pharmcy.dart +++ b/lib/pages/landing/landing_page_pharmcy.dart @@ -1,18 +1,22 @@ +import 'package:barcode_scan_fix/barcode_scan.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/parent_categorise_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/wishlist.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/profile/profile.dart'; import 'package:diplomaticquarterapp/pages/pharmacy_categorise.dart'; import 'package:diplomaticquarterapp/pages/search_products_page.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:diplomaticquarterapp/widgets/drawer/app_drawer_widget.dart'; import 'package:diplomaticquarterapp/widgets/pharmacy/bottom_nav_pharmacy_bar.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/wishlist.dart'; - -import '../offers_categorise_page.dart'; class LandingPagePharmacy extends StatefulWidget { @override @@ -39,7 +43,7 @@ class _LandingPagePharmacyState extends State { @override Widget build(BuildContext context) { return Scaffold( - appBar: currentTab == 0 || currentTab == 1 + appBar: currentTab != 4 ? AppBar( backgroundColor: Color(0xff5AB145), elevation: 0, @@ -70,66 +74,71 @@ class _LandingPagePharmacyState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchProductsPage()), + FadePage(page: SearchProductsPage()), ); }, ), ), leading: Builder( builder: (BuildContext context) { - return Container( - height: 2.0, - width: 10.0, - child: Image.asset( - 'assets/images/pharmacy_logo.png', + return InkWell( + onTap: () { + setState(() { + currentTab = 0; + pageController.jumpToPage(0); + }); + }, + child: Container( + height: 2.0, + width: 10.0, + child: Image.asset( + 'assets/images/pharmacy_logo.png', + ), ), ); }, ), actions: [ - // IconButton( - // iconSize: 70, - // icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', - // height: 100, width: 100, fit: BoxFit.cover), - // onPressed: () { - // triggerRobot(); - // } //do something, - // ) + IconButton( + // iconSize: 70, + icon: Image.asset( + 'assets/images/new-design/qr-code.png', + ), + onPressed: _scanQrAndGetProduct //do something, + ) ], centerTitle: true, ) - : currentTab == 4 - ? null - : AppBar( - backgroundColor: Color(0xff5AB145), - elevation: 0, - textTheme: TextTheme( - headline6: TextStyle( - color: Colors.white, fontWeight: FontWeight.bold), - ), - title: Text(getText(currentTab).toUpperCase()), - leading: Builder( - builder: (BuildContext context) { - return IconButton( - icon: Icon(Icons.arrow_back), - color: Colors.white, - onPressed: () => Scaffold.of(context).openDrawer(), - ); - }, - ), - actions: [ - // IconButton( - // iconSize: 70, - // icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', - // height: 100, width: 100, fit: BoxFit.cover), - // onPressed: () { - // triggerRobot(); - // } //do something, - // ) - ], - centerTitle: true, - ), + : null, + // : AppBar( + // backgroundColor: Color(0xff5AB145), + // elevation: 0, + // textTheme: TextTheme( + // headline6: TextStyle( + // color: Colors.white, fontWeight: FontWeight.bold), + // ), + // title: Text(getText(currentTab).toUpperCase()), + // leading: Builder( + // builder: (BuildContext context) { + // return IconButton( + // icon: Icon(Icons.arrow_back), + // color: Colors.white, + // onPressed: () => Scaffold.of(context).openDrawer(), + // ); + // }, + // ), + // actions: [ + // // IconButton( + // // iconSize: 70, + // // icon: SvgPicture.asset('assets/images/svg/robort_svg.svg', + // // height: 100, width: 100, fit: BoxFit.cover), + // // onPressed: () { + // // triggerRobot(); + // // } //do something, + // // ) + // ], + // centerTitle: true, + // ), extendBody: false, body: PageView( physics: NeverScrollableScrollPhysics(), @@ -138,7 +147,7 @@ class _LandingPagePharmacyState extends State { PharmacyPage(), PharmacyCategorisePage(), // OffersCategorisePage(), - WishlistPage(), + WishlistPage(false), PharmacyProfilePage(), // Container( // child: Text('text'), @@ -153,6 +162,30 @@ class _LandingPagePharmacyState extends State { ); } + void _scanQrAndGetProduct() async { + try { + String result = await BarcodeScanner.scan(); + try { + String barcode = result; + GifLoaderDialogUtils.showMyDialog(context); + await BaseAppClient() + .getPharmacy("$GET_PHARMACY_PRODUCTs_BY_SKU$barcode", + onSuccess: (dynamic response, int statusCode) { + print(response); + var product = PharmacyProduct.fromJson(response["products"][0]); + GifLoaderDialogUtils.hideDialog(context); + Navigator.push(context, FadePage(page: ProductDetailPage(product))); + }, onFailure: (String error, int statusCode) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: "Product not found"); + }); + } catch (apiEx) { + AppToast.showErrorToast( + message: "Something went wrong, please try again"); + } + } catch (barcodeEx) {} + } + getText(currentTab) { switch (currentTab) { case 2: diff --git a/lib/pages/livecare/livecare_home.dart b/lib/pages/livecare/livecare_home.dart index fc5c4eab..bbad8d4c 100644 --- a/lib/pages/livecare/livecare_home.dart +++ b/lib/pages/livecare/livecare_home.dart @@ -3,12 +3,10 @@ import 'package:diplomaticquarterapp/pages/livecare/widgets/LiveCarePendingReque import 'package:diplomaticquarterapp/pages/livecare/widgets/clinic_list.dart'; import 'package:diplomaticquarterapp/pages/livecare/widgets/livecare_logs.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; - -import 'livecare_type_select.dart'; class LiveCareHome extends StatefulWidget { static bool showFooterButton = true; @@ -35,7 +33,9 @@ class _LiveCareHomeState extends State pendingERRequestHistoryList = new ErRequestHistoryList(); - WidgetsBinding.instance.addPostFrameCallback((_) => getLiveCareHistory()); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (!isDataLoaded) getLiveCareHistory(); + }); super.initState(); } @@ -49,6 +49,7 @@ class _LiveCareHomeState extends State child: Column(children: [ /// this is will not colored with theme data TabBar( + labelColor: Colors.black, tabs: [ Tab(text: TranslationBase.of(context).consultation), Tab(text: TranslationBase.of(context).logs), @@ -88,6 +89,7 @@ class _LiveCareHomeState extends State } void getLiveCareHistory() { + GifLoaderDialogUtils.showMyDialog(context); setState(() { isDataLoaded = false; hasLiveCareRequest = false; @@ -95,38 +97,31 @@ class _LiveCareHomeState extends State LiveCareService service = new LiveCareService(); PatientERVirtualHistoryResponse patientERVirtualHistoryResponse = new PatientERVirtualHistoryResponse(); - service - .getLivecareHistory(context) - .then((res) { - setState(() { - print(res['ErRequestHistoryList'].length); - if (res['ErRequestHistoryList'].length != 0) { - patientERVirtualHistoryResponse = - PatientERVirtualHistoryResponse.fromJson(res); - erRequestHistoryList = - patientERVirtualHistoryResponse.erRequestHistoryList; + service.getLivecareHistory(context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + setState(() { + print(res['ErRequestHistoryList'].length); + if (res['ErRequestHistoryList'].length != 0) { + patientERVirtualHistoryResponse = + PatientERVirtualHistoryResponse.fromJson(res); + erRequestHistoryList = + patientERVirtualHistoryResponse.erRequestHistoryList; - if (patientERVirtualHistoryResponse - .erRequestHistoryList[0].callStatus < - 4) { - pendingERRequestHistoryList = - patientERVirtualHistoryResponse.erRequestHistoryList[0]; - hasLiveCareRequest = true; - } else { - hasLiveCareRequest = false; - } - } - }); - }) - .catchError((err) { - print(err); - }) - .showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) - .then((value) { - setState(() { - isDataLoaded = true; - }); - }); + if (patientERVirtualHistoryResponse + .erRequestHistoryList[0].callStatus < + 4) { + pendingERRequestHistoryList = + patientERVirtualHistoryResponse.erRequestHistoryList[0]; + hasLiveCareRequest = true; + } else { + hasLiveCareRequest = false; + } + } + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } } diff --git a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart index 4309cc62..72ca4ce9 100644 --- a/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart +++ b/lib/pages/livecare/livecare_scheduling/schedule_clinic_card.dart @@ -21,7 +21,7 @@ class _ScheduleClinicCardState extends State { return Container( child: Card( margin: EdgeInsets.fromLTRB(15.0, 10.0, 15.0, 8.0), - color: widget.isSelected ? Colors.blue : Colors.white, + color: widget.isSelected ? Color(0xff06b806) : Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), @@ -35,8 +35,8 @@ class _ScheduleClinicCardState extends State { Container( child: Text( widget.languageID == 'ar' - ? widget.clinicsHaveScheduleList.clinicDescN - : widget.clinicsHaveScheduleList.clinicDesc, + ? widget.clinicsHaveScheduleList.clinicDescN != null ? widget.clinicsHaveScheduleList.clinicDescN: "" + : widget.clinicsHaveScheduleList.clinicDesc != null ? widget.clinicsHaveScheduleList.clinicDesc: "Test Clinic", style: TextStyle( fontSize: 16.0, color: diff --git a/lib/pages/livecare/livecare_type_select.dart b/lib/pages/livecare/livecare_type_select.dart index 833c9698..00c2b717 100644 --- a/lib/pages/livecare/livecare_type_select.dart +++ b/lib/pages/livecare/livecare_type_select.dart @@ -51,20 +51,19 @@ class _LiveCareTypeSelectState extends State { ), Container( alignment: Alignment.center, - child: Text("LiveCare Service", + child: Text(TranslationBase.of(context).livecareService, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20.0))), Container( margin: EdgeInsets.only(top: 10.0), alignment: Alignment.center, child: Text( - "is to obtain medical advice with a specialist doctor Via a video call", + TranslationBase.of(context).livecareServiceDesc, textAlign: TextAlign.center, style: TextStyle(fontSize: 18.0))), Container( margin: EdgeInsets.only(top: 15.0), - alignment: Alignment.centerLeft, - child: Text("WHY LIVECARE?", + child: Text(TranslationBase.of(context).whyLivecare, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 20.0))), Container( @@ -77,7 +76,7 @@ class _LiveCareTypeSelectState extends State { width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), child: Text( - "No need to wait, you will get Medical consultation immediately via Video call.", + TranslationBase.of(context).livecarePoint1, overflow: TextOverflow.clip, style: TextStyle(fontSize: 14.0)), ) @@ -93,7 +92,7 @@ class _LiveCareTypeSelectState extends State { Container( width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), - child: Text("The doctor will see your medical file.", + child: Text(TranslationBase.of(context).docVirtualAppoIns4, overflow: TextOverflow.clip, style: TextStyle(fontSize: 14.0)), ) @@ -109,7 +108,7 @@ class _LiveCareTypeSelectState extends State { Container( width: MediaQuery.of(context).size.width * 0.72, margin: EdgeInsets.all(10.0), - child: Text("Free Prescription delivery service.", + child: Text(TranslationBase.of(context).docVirtualAppoIns5, overflow: TextOverflow.clip, style: TextStyle(fontSize: 14.0)), ) @@ -119,7 +118,7 @@ class _LiveCareTypeSelectState extends State { Container( margin: EdgeInsets.only(top: 20.0), child: Text( - "** The service is included with some insurance companies according to the terms and conditions With our best wishes for health and wellness", + TranslationBase.of(context).livecareSummary, style: TextStyle(fontSize: 16.0))), InkWell( onTap: (){ @@ -134,7 +133,7 @@ class _LiveCareTypeSelectState extends State { child: Row( children: [ Container( - margin: EdgeInsets.only(left: 20.0), + margin: EdgeInsets.only(left: 10.0, right: 10.0), child: SvgPicture.asset( "assets/images/new-design/liveCare_logo_icon_white.svg", width: 80), @@ -144,7 +143,7 @@ class _LiveCareTypeSelectState extends State { margin: EdgeInsets.fromLTRB(30.0, 20.0, 0.0, 0.0), child: Column( children: [ - Text("Get Medical consultation immediately", + Text(TranslationBase.of(context).livecareOption1, overflow: TextOverflow.clip, style: TextStyle( fontWeight: FontWeight.bold, @@ -152,8 +151,7 @@ class _LiveCareTypeSelectState extends State { color: Colors.white)), Container( margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.centerLeft, - child: Text("Instant video call", + child: Text(TranslationBase.of(context).livecareOption2, style: TextStyle( fontSize: 18.0, color: Colors.white)), ) @@ -176,19 +174,18 @@ class _LiveCareTypeSelectState extends State { child: Row( children: [ Container( - margin: EdgeInsets.only(left: 20.0), + margin: EdgeInsets.only(left: 10.0, right: 10.0), child: Image.asset( "assets/images/new-design/calendar.png", width: 70), ), Container( width: MediaQuery.of(context).size.width * 0.58, - margin: EdgeInsets.fromLTRB(30.0, 30.0, 0.0, 0.0), + margin: EdgeInsets.fromLTRB(30.0, 20.0, 0.0, 0.0), child: Column( children: [ Container( - alignment: Alignment.centerLeft, - child: Text("Book Appointment", + child: Text(TranslationBase.of(context).livecareOption3, overflow: TextOverflow.clip, style: TextStyle( fontWeight: FontWeight.bold, @@ -197,8 +194,7 @@ class _LiveCareTypeSelectState extends State { ), Container( margin: EdgeInsets.only(top: 10.0), - alignment: Alignment.centerLeft, - child: Text("Schedule Video Call", + child: Text(TranslationBase.of(context).livecareOption4, style: TextStyle( fontSize: 18.0, color: Colors.white)), ) diff --git a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart index 25ec8514..36e8274f 100644 --- a/lib/pages/livecare/widgets/LiveCareHistoryCard.dart +++ b/lib/pages/livecare/widgets/LiveCareHistoryCard.dart @@ -5,11 +5,11 @@ import 'package:diplomaticquarterapp/pages/feedback/feedback_home_page.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class LiveCareHistoryCard extends StatefulWidget { ErRequestHistoryList erRequestHistoryList; @@ -42,10 +42,11 @@ class _LiveCareHistoryCardState extends State { ), child: Container( width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height * 0.22, + // height: MediaQuery.of(context).size.height * 0.22, padding: EdgeInsets.all(10.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, children: [ Text("Requested date:", style: @@ -177,6 +178,7 @@ class _LiveCareHistoryCardState extends State { sendInvoiceEmail(context) { ConfirmDialog.closeAlertDialog(context); LiveCareService service = new LiveCareService(); + GifLoaderDialogUtils.showMyDialog(context); service .sendLiveCareInvoiceEmail( widget.erRequestHistoryList.appointmentNo.toString(), @@ -188,8 +190,7 @@ class _LiveCareHistoryCardState extends State { }).catchError((err) { AppToast.showErrorToast(message: err); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } getAuthenticatedUser() async { diff --git a/lib/pages/livecare/widgets/LiveCarePendingRequest.dart b/lib/pages/livecare/widgets/LiveCarePendingRequest.dart index bfd42e62..839fb02c 100644 --- a/lib/pages/livecare/widgets/LiveCarePendingRequest.dart +++ b/lib/pages/livecare/widgets/LiveCarePendingRequest.dart @@ -3,9 +3,9 @@ import 'package:diplomaticquarterapp/models/FamilyFiles/PatientERVirtualHistoryR import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class LiveCarePendingRequest extends StatefulWidget { ErRequestHistoryList pendingERRequestHistoryList; @@ -149,19 +149,17 @@ class _LiveCarePendingRequestState extends State { cancelLiveCareRequest() { LiveCareService service = new LiveCareService(); + GifLoaderDialogUtils.showMyDialog(context); service .cancelLiveCareRequest(widget.pendingERRequestHistoryList.vCID, context) .then((res) { - AppToast.showSuccessToast( - message: "LiveCare request cancelled successfully"); - }) - .catchError((err) { - print(err); - }) - .showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)) - .then((value) { - widget.getLiveCareHistory(); - }); + GifLoaderDialogUtils.hideDialog(context); + AppToast.showSuccessToast( + message: "LiveCare request cancelled successfully"); + widget.getLiveCareHistory(); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + print(err); + }); } } diff --git a/lib/pages/livecare/widgets/clinic_card.dart b/lib/pages/livecare/widgets/clinic_card.dart index 56613034..9ea12f01 100644 --- a/lib/pages/livecare/widgets/clinic_card.dart +++ b/lib/pages/livecare/widgets/clinic_card.dart @@ -2,8 +2,8 @@ import 'package:diplomaticquarterapp/models/LiveCare/ClinicsServiceTimingsRespon import 'package:diplomaticquarterapp/models/LiveCare/LiveCareClinicsListResponse.dart'; import 'package:diplomaticquarterapp/services/livecare_services/livecare_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import 'ClinicTimingsDialog.dart'; @@ -90,9 +90,11 @@ class _State extends State { getClinicTimings(PatientERGetClinicsList patientERGetClinicsList) { LiveCareService service = new LiveCareService(); + GifLoaderDialogUtils.showMyDialog(context); service .getLivecareClinicTiming(patientERGetClinicsList.serviceID, context) .then((res) { + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { setState(() { clinicsServiceTimingsResponse = @@ -129,8 +131,8 @@ class _State extends State { AppToast.showErrorToast(message: res['ErrorEndUserMessage']); } }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } } diff --git a/lib/pages/livecare/widgets/clinic_list.dart b/lib/pages/livecare/widgets/clinic_list.dart index fc27d92b..103066d5 100644 --- a/lib/pages/livecare/widgets/clinic_list.dart +++ b/lib/pages/livecare/widgets/clinic_list.dart @@ -22,6 +22,7 @@ import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -54,6 +55,8 @@ class _clinic_listState extends State { MyInAppBrowser browser; + bool isLiveCareTypeSelected = false; + @override void initState() { liveCareClinicsListResponse = new LiveCareClinicsListResponse(); @@ -61,7 +64,7 @@ class _clinic_listState extends State { new LiveCareScheduleClinicsListResponse(); WidgetsBinding.instance.addPostFrameCallback((_) { - openLiveCareSelectionDialog(); + if (!isLiveCareTypeSelected) openLiveCareSelectionDialog(); }); getLanguageID(); @@ -254,9 +257,7 @@ class _clinic_listState extends State { }); } - Navigator.push( - context, MaterialPageRoute(builder: (context) => PaymentMethod())) - .then((value) { + Navigator.push(context, FadePage(page: PaymentMethod())).then((value) { print(value); if (value != null) { openPayment(value, authUser, @@ -283,7 +284,8 @@ class _clinic_listState extends State { authenticatedUser.firstName, authenticatedUser.patientID, authenticatedUser, - browser); + browser, + false); } onBrowserLoadStart(String url) { @@ -430,6 +432,7 @@ class _clinic_listState extends State { Navigator.pop(context); } else { print(value); + isLiveCareTypeSelected = true; if (value == "immediate") { setState(() { currentSelectedLiveCareType = "immediate"; @@ -665,8 +668,8 @@ class _clinic_listState extends State { patientDoctorAppointmentListHospital) async { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchResults( + FadePage( + page: SearchResults( doctorsList: docList, isLiveCareAppointment: true, patientDoctorAppointmentListHospital: diff --git a/lib/pages/login/confirm-login.dart b/lib/pages/login/confirm-login.dart index 646158db..1952de64 100644 --- a/lib/pages/login/confirm-login.dart +++ b/lib/pages/login/confirm-login.dart @@ -2,6 +2,7 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; @@ -21,6 +22,7 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/otp/sms-popup.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; @@ -44,6 +46,8 @@ class _ConfirmLogin extends State { var sharedPref = new AppSharedPreferences(); bool authenticated; final authService = new AuthProvider(); + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); int mobileNumber; String errorMsg = ''; SelectDeviceIMEIRES user; @@ -109,11 +113,11 @@ class _ConfirmLogin extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( - 'assets/images/DQ/dq_logo_icon.png', + 'assets/images/habib-logo.png', height: 90, width: 90, ), - AppText( + Texts( TranslationBase.of(context).welcomeBack + ' ' + user.name, @@ -122,7 +126,7 @@ class _ConfirmLogin extends State { SizedBox( height: 20, ), - AppText( + Texts( TranslationBase.of(context).accountInfo, fontSize: SizeConfig.textMultiplier * 2.5, ), @@ -173,17 +177,17 @@ class _ConfirmLogin extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( - 'assets/images/DQ/dq_logo_icon.png', + 'assets/images/habib-logo.png', height: 90, width: 90, ), this.onlySMSBox == false - ? AppText( + ? Texts( TranslationBase.of(context).verifyLoginWith, fontSize: SizeConfig.textMultiplier * 3.5, textAlign: TextAlign.left, ) - : AppText( + : Texts( TranslationBase.of(context) .verifyFingerprint2, fontSize: SizeConfig.textMultiplier * 2.5, @@ -349,6 +353,7 @@ class _ConfirmLogin extends State { sendActivationCode(type) async { var request = this.getCommonRequest(type: type); + request.sMSSignature = await SMSOTP.getSignature(); GifLoaderDialogUtils.showMyDialog(context); await this.authService.sendActivationCode(request).then((result) { GifLoaderDialogUtils.hideDialog(context); @@ -510,8 +515,7 @@ class _ConfirmLogin extends State { .then((result) => { if (result is Map) { - projectViewModel.setPrivilege(privilegeList: result), - result = CheckActivationCode.fromJson(result), + result = CheckActivationCode.fromJson(result), if (this.registerd_data != null && this.registerd_data.isRegister == true) { @@ -582,8 +586,7 @@ class _ConfirmLogin extends State { }); } - goToHome() async { - await authenticatedUserObject.getUser(getUser: true); + goToHome() { authenticatedUserObject.isLogin = true; appointmentRateViewModel.isLogin = true; projectViewModel.isLogin = true; @@ -591,6 +594,12 @@ class _ConfirmLogin extends State { Provider.of(context, listen: false) .setUser(authenticatedUserObject.user); getToDoCount(); + + pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) + await pharmacyModuleViewModel.createUser(); + }); + appointmentRateViewModel .getIsLastAppointmentRatedList() .then((value) => { @@ -634,11 +643,11 @@ class _ConfirmLogin extends State { return InkWell( onTap: () => {authenticateUser(4, true)}, child: RoundedContainer( - height: 140, + height: 150, borderColor: Colors.grey, showBorder: true, child: Padding( - padding: EdgeInsets.fromLTRB(5, 15, 5, 15), + padding: EdgeInsets.fromLTRB(30, 15, 30, 15), child: Column( children: [ Image.asset( @@ -649,10 +658,9 @@ class _ConfirmLogin extends State { SizedBox( height: 20, ), - AppText( - TranslationBase.of(context).verifyWhatsApp, - fontSize: SizeConfig.textMultiplier * 2, - ) + Texts(TranslationBase.of(context).verifyWhatsApp, + fontSize: SizeConfig.textMultiplier * 2, + color: Colors.black) ], ), ))); @@ -661,11 +669,11 @@ class _ConfirmLogin extends State { return InkWell( onTap: () => {authenticateUser(1, true)}, child: RoundedContainer( - height: 140, + height: 150, borderColor: Colors.grey, showBorder: true, child: Padding( - padding: EdgeInsets.fromLTRB(5, 15, 5, 15), + padding: EdgeInsets.fromLTRB(30, 15, 30, 15), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -676,18 +684,15 @@ class _ConfirmLogin extends State { ), projectViewModel.isArabic ? SizedBox( - height: 20, + height: 0, ) : SizedBox( height: 20, ), - AppText( - TranslationBase.of(context).verifySMS, - fontSize: projectViewModel.isArabic - ? SizeConfig.textMultiplier * 1.8 - : SizeConfig.textMultiplier * 2, - textAlign: TextAlign.center, - ) + Texts(TranslationBase.of(context).verifySMS, + fontSize: SizeConfig.textMultiplier * 2, + textAlign: TextAlign.center, + color: Colors.black) ], ), ))); @@ -696,14 +701,14 @@ class _ConfirmLogin extends State { return InkWell( onTap: () => {authenticateUser(2, BiometricType.fingerprint.index)}, child: RoundedContainer( - height: 140, + height: 150, backgroundColor: BiometricType.fingerprint.index == 1 ? Colors.white : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( - padding: EdgeInsets.fromLTRB(5, 15, 5, 15), + padding: EdgeInsets.fromLTRB(30, 15, 30, 15), child: Column( children: [ Image.asset( @@ -714,10 +719,9 @@ class _ConfirmLogin extends State { SizedBox( height: 20, ), - AppText( - TranslationBase.of(context).verifyFingerprint, - fontSize: SizeConfig.textMultiplier * 2, - ) + Texts(TranslationBase.of(context).verifyFingerprint, + fontSize: SizeConfig.textMultiplier * 2, + color: Colors.black) ], ), ))); @@ -726,14 +730,14 @@ class _ConfirmLogin extends State { return InkWell( onTap: () => {authenticateUser(3, BiometricType.face.index)}, child: RoundedContainer( - height: 140, + height: 150, backgroundColor: checkIfBiometricAvailable(BiometricType.face) ? Colors.white : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( - padding: EdgeInsets.fromLTRB(5, 15, 5, 15), + padding: EdgeInsets.fromLTRB(30, 15, 30, 15), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -745,10 +749,9 @@ class _ConfirmLogin extends State { SizedBox( height: 20, ), - AppText( - TranslationBase.of(context).verifyFaceID, - fontSize: SizeConfig.textMultiplier * 2, - ) + Texts(TranslationBase.of(context).verifyFaceID, + fontSize: SizeConfig.textMultiplier * 2, + color: Colors.black) ], ), ))); @@ -762,19 +765,19 @@ class _ConfirmLogin extends State { }) }, child: RoundedContainer( - height: 140, + height: 150, backgroundColor: BiometricType.fingerprint.index == 1 ? Colors.white : Colors.white.withOpacity(.7), borderColor: Colors.grey, showBorder: true, child: Padding( - padding: EdgeInsets.fromLTRB(5, 15, 5, 15), + padding: EdgeInsets.fromLTRB(0, 0, 0, 5), child: Column( children: [ Image.asset( 'assets/images/login/more_icon.png', - height: SizeConfig.imageSizeMultiplier * 13, + height: 45, width: SizeConfig.imageSizeMultiplier * 16, ), projectViewModel.isArabic @@ -782,13 +785,12 @@ class _ConfirmLogin extends State { height: 15, ) : SizedBox( - height: 10, + height: 20, ), - AppText( - TranslationBase.of(context).moreVerification, - fontSize: SizeConfig.textMultiplier * 2, - textAlign: TextAlign.center, - ) + Texts(TranslationBase.of(context).moreVerification, + fontSize: SizeConfig.textMultiplier * 1.8, + textAlign: TextAlign.center, + color: Colors.black) ], ), ))); diff --git a/lib/pages/login/login-type.dart b/lib/pages/login/login-type.dart index 6113fb71..f8af8eac 100644 --- a/lib/pages/login/login-type.dart +++ b/lib/pages/login/login-type.dart @@ -1,10 +1,14 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/pages/login/forgot-password.dart'; +import 'package:diplomaticquarterapp/pages/login/login.dart'; +import 'package:diplomaticquarterapp/pages/login/register.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -32,7 +36,7 @@ class LoginType extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset( - 'assets/images/DQ/dq_logo_icon.png', + 'assets/images/DQ/logo.png', height: 90, width: 90, ), @@ -50,8 +54,8 @@ class LoginType extends StatelessWidget { child: InkWell( onTap: () => { LoginType.loginType = 1, - Navigator.of(context) - .pushNamed(LOGIN_PAGE) + Navigator.of(context) + .push(FadePage(page: Login())), }, child: RoundedContainer( borderColor: Colors.grey, @@ -90,8 +94,8 @@ class LoginType extends StatelessWidget { child: InkWell( onTap: () => { LoginType.loginType = 2, - Navigator.of(context) - .pushNamed(LOGIN_PAGE) + Navigator.of(context) + .push(FadePage(page: Login())), }, child: RoundedContainer( borderColor: Colors.grey, @@ -136,8 +140,8 @@ class LoginType extends StatelessWidget { Center( child: InkWell( onTap: () => { - Navigator.of(context) - .pushNamed(FORGOT_PASSWORD) + Navigator.of(context) + .push(FadePage(page: ForgotPassword())), }, child: AppText( TranslationBase.of(context) @@ -166,9 +170,8 @@ class LoginType extends StatelessWidget { child: DefaultButton( TranslationBase.of(context).registerNow, () => { - Navigator.of(context).pushNamed( - REGISTER, - ) + Navigator.of(context) + .push(FadePage(page: Register())), }, )), ], diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index c2a943d2..8d655f76 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -2,15 +2,17 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/service/AuthenticatedUserObject.dart'; import 'package:diplomaticquarterapp/core/viewModels/appointment_rate_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/locator.dart'; import 'package:diplomaticquarterapp/models/Appointments/toDoCountProviderModel.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_activation_code_response.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_paitent_authentication_req.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; +import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/pages/login/register.dart'; import 'package:diplomaticquarterapp/pages/rateAppointment/rate_appointment_doctor.dart'; -import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/services/clinic_services/get_clinic_service.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; @@ -18,17 +20,18 @@ import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; -import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import '../../Constants.dart'; + class Login extends StatefulWidget { @override _Login createState() => _Login(); @@ -46,6 +49,8 @@ class _Login extends State { bool isLoading = false; AppointmentRateViewModel appointmentRateViewModel = locator(); + PharmacyModuleViewModel pharmacyModuleViewModel = + locator(); AuthenticatedUserObject authenticatedUserObject = locator(); @@ -82,8 +87,10 @@ class _Login extends State { children: [ Expanded( flex: 2, - child: AppText( - TranslationBase.of(context).enterNationalId, + child: Texts( + loginType == 1 + ? TranslationBase.of(context).enterNationalId + : TranslationBase.of(context).enterFile, fontSize: SizeConfig.textMultiplier * 3.5, textAlign: TextAlign.start, )), @@ -92,7 +99,12 @@ class _Login extends State { child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - MobileNo(onNumberChange: (value) => {mobileNo = value, validateForm()}, onCountryChange: (value) => countryCode = value), + Directionality( + textDirection: TextDirection.ltr, + child: MobileNo( + onNumberChange: (value) => + {mobileNo = value, validateForm()}, + onCountryChange: (value) => countryCode = value)), Directionality( textDirection: TextDirection.ltr, child: Container( @@ -105,7 +117,7 @@ class _Login extends State { loginType == 1 ? Icons.chrome_reader_mode : Icons.receipt, - color: Color(0xFF40ACC9)), + color: secondaryColor), padding: EdgeInsets.only( top: 20, bottom: 20, left: 10, right: 10), hintText: loginType == 1 @@ -194,7 +206,7 @@ class _Login extends State { sharedPref.setString(LOGIN_TOKEN_ID, value['LogInTokenID']), sharedPref.setObject(REGISTER_DATA_FOR_LOGIIN, request), GifLoaderDialogUtils.hideDialog(context), - Navigator.of(context).pushNamed(CONFIRM_LOGIN) + Navigator.of(context).push(FadePage(page: ConfirmLogin())), } else { @@ -210,9 +222,7 @@ class _Login extends State { cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { ConfirmDialog.closeAlertDialog(context), - Navigator.of(context).pushNamed( - REGISTER, - ), + Navigator.of(context).push(FadePage(page: Register())), }, cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); dialog.showAlertDialog(context); @@ -242,50 +252,55 @@ class _Login extends State { this.authService.checkActivationCode(request, code).then((result) async { sharedPref.remove(FAMILY_FILE); // Register GeoZones after login - registerGeoZones(); - projectViewModel.setPrivilege(privilegeList: result); - result = CheckActivationCode.fromJson(result); - result.list.isFamily = false; - // this.sharedPref.setString(BLOOD_TYPE, result['PatientBloodType']), - this.sharedPref.setObject(USER_PROFILE, result.list); - this.sharedPref.setObject(MAIN_USER, result.list); - this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); - this.sharedPref.setString(TOKEN, result.authenticationTokenID); - await authenticatedUserObject.getUser(getUser: true); - authenticatedUserObject.isLogin = true; - appointmentRateViewModel.isLogin = true; - projectViewModel.isLogin = true; - projectViewModel.user = authenticatedUserObject.user; - appointmentRateViewModel - .getIsLastAppointmentRatedList() - .then((value) => { - getToDoCount(), - GifLoaderDialogUtils.hideDialog(context), - if (appointmentRateViewModel.isHaveAppointmentNotRate) - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: RateAppointmentDoctor(), - ), - (r) => false) - } - else - { - Navigator.pushAndRemoveUntil( - context, - FadePage( - page: LandingPage(), - ), - (r) => false) - } - }) - .catchError((err) { - print(err); - GifLoaderDialogUtils.hideDialog(context); - }); + registerGeoZones(); + projectViewModel.setPrivilege(privilegeList: result); + result = CheckActivationCode.fromJson(result); + result.list.isFamily = false; + // this.sharedPref.setString(BLOOD_TYPE, result['PatientBloodType']), + this.sharedPref.setObject(USER_PROFILE, result.list); + this.sharedPref.setObject(MAIN_USER, result.list); + this.sharedPref.setObject(LOGIN_TOKEN_ID, result.logInTokenID); + this.sharedPref.setString(TOKEN, result.authenticationTokenID); + await authenticatedUserObject.getUser(getUser: true); + authenticatedUserObject.isLogin = true; + appointmentRateViewModel.isLogin = true; + projectViewModel.isLogin = true; + projectViewModel.user = authenticatedUserObject.user; - }); + await pharmacyModuleViewModel.generatePharmacyToken().then((value) async { + if (pharmacyModuleViewModel.error.isNotEmpty) + await pharmacyModuleViewModel.createUser(); + }); + + appointmentRateViewModel + .getIsLastAppointmentRatedList() + .then((value) => { + getToDoCount(), + GifLoaderDialogUtils.hideDialog(context), + if (appointmentRateViewModel.isHaveAppointmentNotRate) + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: RateAppointmentDoctor(), + ), + (r) => false) + } + else + { + Navigator.pushAndRemoveUntil( + context, + FadePage( + page: LandingPage(), + ), + (r) => false) + } + }) + .catchError((err) { + print(err); + GifLoaderDialogUtils.hideDialog(context); + }); + }); } getToDoCount() { diff --git a/lib/pages/login/register.dart b/lib/pages/login/register.dart index 131db748..c6a3b872 100644 --- a/lib/pages/login/register.dart +++ b/lib/pages/login/register.dart @@ -3,24 +3,22 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_reponse.dart'; import 'package:diplomaticquarterapp/models/Authentication/check_user_status_req.dart'; import 'package:diplomaticquarterapp/models/Authentication/checkpatient_for_registration.dart'; +import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; -import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; -import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; -import 'package:diplomaticquarterapp/widgets/card/rounded_container.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/mobile-no/mobile_no.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/widgets/progress_indicator/app_circular_progress_Indeicator.dart'; import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -43,6 +41,7 @@ class _Register extends State { final sharedPref = new AppSharedPreferences(); bool isLoading; + @override Widget build(BuildContext context) { return AppScaffold( @@ -50,39 +49,38 @@ class _Register extends State { isShowAppBar: true, isShowDecPage: false, body: SingleChildScrollView( - child: Container( - padding: - EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), - height: SizeConfig.realScreenHeight * .9, - width: SizeConfig.realScreenWidth, - child: Column(children: [ - Expanded( - flex: 1, - child: AppText( - TranslationBase.of(context).enterNationalId, - fontSize: SizeConfig.textMultiplier * 3, - textAlign: TextAlign.left, - )), - Expanded( - flex: 4, - child: Column( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - MobileNo( - onNumberChange: (value) => - {mobileNo = value, validateForm()}, - onCountryChange: (value) => countryCode = value), - Container( - child: TextFields( - controller: nationalIDorFile, - onChanged: (value) => validateForm(), - keyboardType: TextInputType.number, - prefixIcon: Icon(Icons.chrome_reader_mode, - color: Color(0xFF40ACC9)), - padding: EdgeInsets.only( - top: 20, bottom: 20, left: 10, right: 10), - hintText: TranslationBase.of(context).nationalID, - )), + child: Container( + padding: EdgeInsets.only(top: 10, left: 20, right: 20, bottom: 30), + height: SizeConfig.realScreenHeight * .9, + width: SizeConfig.realScreenWidth, + child: Column(children: [ + Expanded( + flex: 1, + child: AppText( + TranslationBase.of(context).enterNationalId, + fontSize: SizeConfig.textMultiplier * 3, + textAlign: TextAlign.left, + )), + Expanded( + flex: 4, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + MobileNo( + onNumberChange: (value) => + {mobileNo = value, validateForm()}, + onCountryChange: (value) => countryCode = value), + Container( + child: TextFields( + controller: nationalIDorFile, + onChanged: (value) => validateForm(), + keyboardType: TextInputType.number, + prefixIcon: Icon(Icons.chrome_reader_mode, + color: Color(0xFF40ACC9)), + padding: EdgeInsets.only( + top: 20, bottom: 20, left: 10, right: 10), + hintText: TranslationBase.of(context).nationalID, + )), Row( children: [ Expanded( @@ -226,9 +224,7 @@ class _Register extends State { cancelText: TranslationBase.of(context).cancel_nocaps, okFunction: () => { ConfirmDialog.closeAlertDialog(context), - Navigator.of(context).pushNamed( - REGISTER, - ), + Navigator.of(context).push(FadePage(page: Register())), }, cancelFunction: () => {ConfirmDialog.closeAlertDialog(context)}); dialog.showAlertDialog(context); @@ -312,16 +308,10 @@ class _Register extends State { { result = CheckUserStatusResponse.fromJson(result), sharedPref.setObject(NHIC_DATA, result), - Navigator.of(context).pushNamed( - CONFIRM_LOGIN, - ) - // Navigator.of(context).pushNamed( - // REGISTER_INFO, - // ) + Navigator.of(context).push(FadePage(page: ConfirmLogin())), } else {AppToast.showErrorToast(message: result)} - //this.onRegister(); }); } diff --git a/lib/pages/login/welcome.dart b/lib/pages/login/welcome.dart index 419df302..6a007e0a 100644 --- a/lib/pages/login/welcome.dart +++ b/lib/pages/login/welcome.dart @@ -1,8 +1,12 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/pages/login/login-type.dart'; +import 'package:diplomaticquarterapp/pages/login/register.dart'; import 'package:diplomaticquarterapp/routes.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/text/app_texts_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -36,22 +40,21 @@ class _WelcomeLogin extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Image.asset('assets/images/DQ/dq_logo_icon.png', + Image.asset('assets/images/DQ/logo.png', height: 90, width: 90), - Text( + AppText( TranslationBase.of(context).welcome, - style: TextStyle( - fontSize: 30, fontWeight: FontWeight.bold), - textAlign: TextAlign.start, + fontSize: 30, + fontWeight: FontWeight.bold, ), - Text( + AppText( TranslationBase.of(context).welcomeText, - style: TextStyle(fontSize: 24), + fontSize: 24, textAlign: TextAlign.start, ), - Text( + AppText( TranslationBase.of(context).welcomeText2, - style: TextStyle(fontSize: 24), + fontSize: 24, textAlign: TextAlign.start, ), SizedBox( @@ -71,11 +74,10 @@ class _WelcomeLogin extends State { child: DefaultButton( TranslationBase.of(context).yes, () => { - Navigator.of(context).pushNamed( - LOGIN_TYPE, - ), + Navigator.of(context) + .push(FadePage(page: LoginType())), }, - color: Color(0xFF40ACC9), + color: Color(0xFFc5272c), textColor: Colors.white, )) ], @@ -86,9 +88,8 @@ class _WelcomeLogin extends State { child: DefaultButton( TranslationBase.of(context).no, () => { - Navigator.of(context).pushNamed( - REGISTER, - ) + Navigator.of(context) + .push(FadePage(page: Register())), }, )) ], diff --git a/lib/pages/medical/ask_doctor/ask_doctor_page.dart b/lib/pages/medical/ask_doctor/ask_doctor_page.dart index 6beed0dc..795d1869 100644 --- a/lib/pages/medical/ask_doctor/ask_doctor_page.dart +++ b/lib/pages/medical/ask_doctor/ask_doctor_page.dart @@ -12,7 +12,6 @@ import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:rating_bar/rating_bar.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; class AskDoctorPage extends StatelessWidget { @override diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index a3005db5..d3921d4a 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -20,7 +20,6 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import '../../../core/model/my_balance/AdvanceModel.dart'; import 'confirm_payment_page.dart'; @@ -215,14 +214,14 @@ class _AdvancePaymentPageState extends State { SizedBox( height: 12, ), - if(model.user!=null) - NewTextFields( - hintText: TranslationBase.of(context).depositorEmail, - initialValue: model.user.emailAddress, - onChanged: (value) { - email = value; - }, - ), + if (model.user != null) + NewTextFields( + hintText: TranslationBase.of(context).depositorEmail, + initialValue: model.user.emailAddress, + onChanged: (value) { + email = value; + }, + ), SizedBox( height: 12, ), @@ -238,9 +237,9 @@ class _AdvancePaymentPageState extends State { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.13, + height: 90, width: double.infinity, - padding: EdgeInsets.all(12), + padding: EdgeInsets.all(18), child: SecondaryButton( textColor: Colors.white, label: TranslationBase.of(context).submit, @@ -281,10 +280,8 @@ class _AdvancePaymentPageState extends State { if (model.state != ViewState.Error && model.state != ViewState.ErrorLocal) { Utils.hideKeyboard(context); - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PaymentMethod())).then( + Navigator.push(context, FadePage(page: PaymentMethod())) + .then( (value) { Navigator.push( context, diff --git a/lib/pages/medical/balance/confirm_payment_page.dart b/lib/pages/medical/balance/confirm_payment_page.dart index 8a69bf5d..eecb6abd 100644 --- a/lib/pages/medical/balance/confirm_payment_page.dart +++ b/lib/pages/medical/balance/confirm_payment_page.dart @@ -225,7 +225,8 @@ class ConfirmPaymentPage extends StatelessWidget { advanceModel.patientName, advanceModel.fileNumber, authenticatedUser, - browser); + browser, + false); } onBrowserLoadStart(String url) { diff --git a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart b/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart index b004bc38..d7ce3fac 100644 --- a/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectBeneficiaryDialog.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../../../../Constants.dart'; import '../advance_payment_page.dart'; class SelectBeneficiaryDialog extends StatefulWidget { @@ -45,7 +46,7 @@ class _SelectBeneficiaryDialogState extends State { leading: Radio( value: BeneficiaryType.MyAccount, groupValue: beneficiaryType, - activeColor: Color(0xFF40ACC9), + activeColor: secondaryColor, onChanged: (BeneficiaryType value) { setState(() { beneficiaryType = value; diff --git a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart index 3d07c08c..19e4fea4 100644 --- a/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectCiteisDialog.dart @@ -1,9 +1,11 @@ //import 'package:diplomaticquarterapp/core/model/hospitals/hospitals_model.dart'; import 'package:diplomaticquarterapp/core/model/blooddonation/get_all_cities.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class SelectCiteisDialog extends StatefulWidget { final List hospitals; @@ -12,6 +14,7 @@ class SelectCiteisDialog extends StatefulWidget { SelectCiteisDialog( {Key key, this.hospitals, this.onValueSelected, this.selectedHospital}); + @override _SelectCiteisDialogState createState() => _SelectCiteisDialogState(); } @@ -24,9 +27,10 @@ class _SelectCiteisDialogState extends State { widget.selectedHospital = widget.selectedHospital ?? widget.hospitals[0]; } - @override Widget build(BuildContext context) { + ProjectViewModel projectProvider = Provider.of(context); + return SimpleDialog( children: [ Column( @@ -34,7 +38,7 @@ class _SelectCiteisDialogState extends State { Divider(), ...List.generate( widget.hospitals.length, - (index) => Column( + (index) => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( @@ -53,7 +57,9 @@ class _SelectCiteisDialogState extends State { child: ListTile( // title: Text(widget.hospitals[index].description + // ' ${widget.hospitals[index].distanceInKilometers} KM'), - title: Text(widget.hospitals[index].description), + title: Text(projectProvider.isArabic + ? widget.hospitals[index].descriptionN + : widget.hospitals[index].description), leading: Radio( value: widget.hospitals[index], groupValue: widget.selectedHospital, @@ -116,9 +122,9 @@ class _SelectCiteisDialogState extends State { padding: const EdgeInsets.all(8.0), child: Center( child: Texts( - TranslationBase.of(context).ok, - fontWeight: FontWeight.w400, - )), + TranslationBase.of(context).ok, + fontWeight: FontWeight.w400, + )), ), ), ), diff --git a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart b/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart index 42bd66b7..a9a4fea2 100644 --- a/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectHospitalDialog.dart @@ -4,6 +4,8 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../../../../Constants.dart'; + class SelectHospitalDialog extends StatefulWidget { final List hospitals; final Function(HospitalsModel) onValueSelected; @@ -54,7 +56,7 @@ class _SelectHospitalDialogState extends State { leading: Radio( value: widget.hospitals[index], groupValue: widget.selectedHospital, - activeColor: Color(0xFF40ACC9), + activeColor: secondaryColor, onChanged: (value) { setState(() { widget.selectedHospital = value; diff --git a/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart index bb9afd6c..ab2b48d5 100644 --- a/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectPatientFamilyDialog.dart @@ -4,6 +4,8 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../../../../Constants.dart'; + class SelectPatientFamilyDialog extends StatefulWidget { final List getAllSharedRecordsByStatusList; final Function(GetAllSharedRecordsByStatusList) onValueSelected; @@ -53,7 +55,7 @@ class _SelectPatientFamilyDialogState extends State { leading: Radio( value: widget.getAllSharedRecordsByStatusList[index], groupValue: widget.selectedPatientFamily, - activeColor: Colors.red[800], + activeColor: secondaryColor, onChanged: (value) { setState(() { widget.selectedPatientFamily = value; diff --git a/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart b/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart index bea4f694..3cce8e61 100644 --- a/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart +++ b/lib/pages/medical/balance/dialogs/SelectPatientInfoDialog.dart @@ -6,6 +6,8 @@ import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import '../../../../Constants.dart'; + class SelectPatientInfoDialog extends StatefulWidget { final List patientInfoList ; final Function(PatientInfo) onValueSelected; @@ -55,7 +57,7 @@ class _SelectPatientInfoDialogState extends State { leading: Radio( value: widget.patientInfoList[index], groupValue: widget.selectedPatientInfo, - activeColor: Colors.red[800], + activeColor: secondaryColor, onChanged: (value) { setState(() { widget.selectedPatientInfo = value; diff --git a/lib/pages/medical/balance/my_balance_page.dart b/lib/pages/medical/balance/my_balance_page.dart index 1edbcbf6..7639bb2f 100644 --- a/lib/pages/medical/balance/my_balance_page.dart +++ b/lib/pages/medical/balance/my_balance_page.dart @@ -13,12 +13,15 @@ import 'package:hexcolor/hexcolor.dart'; import 'advance_payment_page.dart'; class MyBalancePage extends StatelessWidget { - List imagesInfo = List(); @override Widget build(BuildContext context) { - imagesInfo.add(ImagesInfo(imageEn: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/en/0.png',imageAr: 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/ar/0.png')); + imagesInfo.add(ImagesInfo( + imageEn: + 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/en/0.png', + imageAr: + 'https://hmgwebservices.com/Images/MobileApp/images-info-home/my-balance/ar/0.png')); return BaseView( onModelReady: (model) => model.getPatientAdvanceBalanceAmount(), builder: (_, model, w) => AppScaffold( @@ -46,16 +49,16 @@ class MyBalancePage extends StatelessWidget { width: double.infinity, height: 65, decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Colors.red[700], shape: BoxShape.rectangle, borderRadius: BorderRadius.circular(7), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts( - '${model.totalAdvanceBalanceAmount ?? 0} '+ TranslationBase.of(context).sar, + '${model.totalAdvanceBalanceAmount ?? 0} ' + + TranslationBase.of(context).sar, color: Colors.white, bold: true, ), @@ -83,9 +86,9 @@ class MyBalancePage extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts( - '${model.patientAdvanceBalanceAmountList[index].patientAdvanceBalanceAmount} '+TranslationBase.of(context).sar, + '${model.patientAdvanceBalanceAmountList[index].patientAdvanceBalanceAmount} ' + + TranslationBase.of(context).sar, bold: true, ), Texts(model.patientAdvanceBalanceAmountList[index] @@ -94,7 +97,9 @@ class MyBalancePage extends StatelessWidget { ), ), ), - SizedBox(height: MediaQuery.of(context).size.height * 0.13 ,) + SizedBox( + height: MediaQuery.of(context).size.height * 0.13, + ) ], ), ), diff --git a/lib/pages/medical/balance/new_text_Field.dart b/lib/pages/medical/balance/new_text_Field.dart index ad9eb580..f61c7267 100644 --- a/lib/pages/medical/balance/new_text_Field.dart +++ b/lib/pages/medical/balance/new_text_Field.dart @@ -42,38 +42,39 @@ final _mobileFormatter = NumberTextInputFormatter(); class NewTextFields extends StatefulWidget { NewTextFields( {Key key, - this.type, - this.hintText, - this.suffixIcon, - this.autoFocus, - this.onChanged, - this.initialValue, - this.minLines, - this.maxLines, - this.inputFormatters, - this.padding, - this.focus = false, - this.maxLengthEnforced = true, - this.suffixIconColor, - this.inputAction, - this.onSubmit, - this.keepPadding = true, - this.textCapitalization = TextCapitalization.none, - this.controller, - this.keyboardType, - this.validator, - this.borderOnlyError = false, - this.onSaved, - this.onSuffixTap, - this.readOnly: false, - this.maxLength, - this.prefixIcon, - this.bare = false, - this.onTap, - this.fontSize = 16.0, - this.fontWeight = FontWeight.w700, - this.autoValidate = false, - this.hintColor,this.isEnabled=true}) + this.type, + this.hintText, + this.suffixIcon, + this.autoFocus, + this.onChanged, + this.initialValue, + this.minLines, + this.maxLines, + this.inputFormatters, + this.padding, + this.focus = false, + this.maxLengthEnforced = true, + this.suffixIconColor, + this.inputAction, + this.onSubmit, + this.keepPadding = true, + this.textCapitalization = TextCapitalization.none, + this.controller, + this.keyboardType, + this.validator, + this.borderOnlyError = false, + this.onSaved, + this.onSuffixTap, + this.readOnly: false, + this.maxLength, + this.prefixIcon, + this.bare = false, + this.onTap, + this.fontSize = 16.0, + this.fontWeight = FontWeight.w700, + this.autoValidate = false, + this.hintColor, + this.isEnabled = true}) : super(key: key); final String hintText; @@ -142,7 +143,6 @@ class _NewTextFieldsState extends State { super.dispose(); } - bool _determineReadOnly() { if (widget.readOnly != null && widget.readOnly) { _focusNode.unfocus(); @@ -156,12 +156,11 @@ class _NewTextFieldsState extends State { Widget build(BuildContext context) { return AnimatedContainer( duration: Duration(milliseconds: 300), - decoration:BoxDecoration( + decoration: BoxDecoration( borderRadius: BorderRadius.circular(12), color: Colors.white), child: Container( margin: EdgeInsets.only(top: 8), - child: TextFormField( enabled: widget.isEnabled, initialValue: widget.initialValue, @@ -171,10 +170,10 @@ class _NewTextFieldsState extends State { textCapitalization: widget.textCapitalization, onFieldSubmitted: widget.inputAction == TextInputAction.next ? (widget.onSubmit != null - ? widget.onSubmit - : (val) { - _focusNode.nextFocus(); - }) + ? widget.onSubmit + : (val) { + _focusNode.nextFocus(); + }) : widget.onSubmit, textInputAction: widget.inputAction, minLines: widget.minLines ?? 1, @@ -190,45 +189,36 @@ class _NewTextFieldsState extends State { autofocus: widget.autoFocus ?? false, validator: widget.validator, onSaved: widget.onSaved, - - style: Theme.of(context) - .textTheme - .body2 - .copyWith(fontSize: widget.fontSize, fontWeight: widget.fontWeight), + style: Theme.of(context).textTheme.body2.copyWith( + fontSize: widget.fontSize, fontWeight: widget.fontWeight), inputFormatters: widget.keyboardType == TextInputType.phone ? [ - WhitelistingTextInputFormatter.digitsOnly, - _mobileFormatter, - ] + WhitelistingTextInputFormatter.digitsOnly, + _mobileFormatter, + ] : widget.inputFormatters, decoration: InputDecoration( labelText: widget.hintText, - labelStyle: TextStyle(color: Colors.black), + labelStyle: + TextStyle(color: Theme.of(context).textTheme.bodyText1.color), errorBorder: OutlineInputBorder( borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(0.5), + color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(12.0)), focusedErrorBorder: OutlineInputBorder( borderSide: BorderSide( - color: Theme.of(context) - .errorColor - .withOpacity(0.5), + color: Theme.of(context).errorColor.withOpacity(0.5), width: 1.0), borderRadius: BorderRadius.circular(8.0)), focusedBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), + borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), disabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), + borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12)), enabledBorder: OutlineInputBorder( - borderSide: - BorderSide(color: Colors.white, width: 1.0), + borderSide: BorderSide(color: Colors.white, width: 1.0), borderRadius: BorderRadius.circular(12), ), ), diff --git a/lib/pages/medical/eye/ClassesPage.dart b/lib/pages/medical/eye/ClassesPage.dart index 7904178c..21a07d23 100644 --- a/lib/pages/medical/eye/ClassesPage.dart +++ b/lib/pages/medical/eye/ClassesPage.dart @@ -1,17 +1,28 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class ClassesPage extends StatelessWidget { final ListHISGetGlassPerscription glassPerscription; + final int appointmentNo; + final String projectName; + final int projectID; - const ClassesPage({Key key, this.glassPerscription}) : super(key: key); + const ClassesPage( + {Key key, + this.glassPerscription, + this.appointmentNo, + this.projectName, + this.projectID}) + : super(key: key); @override Widget build(BuildContext context) { @@ -38,11 +49,16 @@ class ClassesPage extends StatelessWidget { bold: true, ), ), - getRow(TranslationBase.of(context).sphere, '${glassPerscription.rightEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, '${glassPerscription.rightEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, '${glassPerscription.rightEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, '${glassPerscription.rightEyePrism}', '-'), - getRow(TranslationBase.of(context).va, '${glassPerscription.rightEyeVA}', '-'), + getRow(TranslationBase.of(context).sphere, + '${glassPerscription.rightEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, + '${glassPerscription.rightEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, + '${glassPerscription.rightEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, + '${glassPerscription.rightEyePrism}', '-'), + getRow(TranslationBase.of(context).va, + '${glassPerscription.rightEyeVA}', '-'), ], ), ), @@ -65,11 +81,16 @@ class ClassesPage extends StatelessWidget { bold: true, ), ), - getRow(TranslationBase.of(context).sphere, '${glassPerscription.leftEyeSpherical}', '-'), - getRow(TranslationBase.of(context).cylinder, '${glassPerscription.leftEyeCylinder}', '-'), - getRow(TranslationBase.of(context).axis, '${glassPerscription.leftEyeAxis}', '-'), - getRow(TranslationBase.of(context).prism, '${glassPerscription.leftEyePrism}', '-'), - getRow(TranslationBase.of(context).va, '${glassPerscription.leftEyeVA}', '-'), + getRow(TranslationBase.of(context).sphere, + '${glassPerscription.leftEyeSpherical}', '-'), + getRow(TranslationBase.of(context).cylinder, + '${glassPerscription.leftEyeCylinder}', '-'), + getRow(TranslationBase.of(context).axis, + '${glassPerscription.leftEyeAxis}', '-'), + getRow(TranslationBase.of(context).prism, + '${glassPerscription.leftEyePrism}', '-'), + getRow(TranslationBase.of(context).va, + '${glassPerscription.leftEyeVA}', '-'), ], ), ), @@ -80,6 +101,16 @@ class ClassesPage extends StatelessWidget { width: double.infinity, child: SecondaryButton( label: TranslationBase.of(context).sendEmail, + onTap: () { + showConfirmMessage(context, () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendGlassesPrescriptionEmail( + appointmentNo: appointmentNo, + projectName: projectName, + projectID: projectID); + GifLoaderDialogUtils.hideDialog(context); + }, model.user.emailAddress); + }, textColor: Colors.white, color: Colors.red[700], icon: Icon( @@ -96,6 +127,19 @@ class ClassesPage extends StatelessWidget { ); } + void showConfirmMessage( + BuildContext context, GestureTapCallback onTap, String email) { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: email, + onTapSendEmail: () { + onTap(); + }, + ), + ); + } + Widget getRow(String title, String val1, String val2) => Padding( padding: const EdgeInsets.all(8.0), child: Column( @@ -113,7 +157,7 @@ class ClassesPage extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Texts(val1 == 'null' ? '-' : val1), - Texts(val2 != 'null' ? '-' :val2), + Texts(val2 != 'null' ? '-' : val2), ], ), ) diff --git a/lib/pages/medical/eye/ContactLensPage.dart b/lib/pages/medical/eye/ContactLensPage.dart index 373c3c79..b70b9c09 100644 --- a/lib/pages/medical/eye/ContactLensPage.dart +++ b/lib/pages/medical/eye/ContactLensPage.dart @@ -1,8 +1,12 @@ import 'package:diplomaticquarterapp/core/model/eye/AppoimentAllHistoryResult.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/EyeViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -10,95 +14,126 @@ import 'package:provider/provider.dart'; class ContactLensPage extends StatelessWidget { final ListHISGetContactLensPerscription listHISGetContactLensPerscription; + final int appointmentNo; + final String projectName; + final int projectID; - const ContactLensPage({Key key, this.listHISGetContactLensPerscription}) + const ContactLensPage( + {Key key, + this.listHISGetContactLensPerscription, + this.appointmentNo, + this.projectName, + this.projectID}) : super(key: key); @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return AppScaffold( - body: SingleChildScrollView( - child: Container( - margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), - child: Column( - children: [ - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).rightEye, - fontSize: 23, - bold: true, + return BaseView( + builder: (_,model,w)=> + AppScaffold( + body: SingleChildScrollView( + child: Container( + margin: EdgeInsets.only(top: 70, left: 15, right: 15, bottom: 15), + child: Column( + children: [ + Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).rightEye, + fontSize: 23, + bold: true, + ), ), - ), - getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow('Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, '${listHISGetContactLensPerscription.remarks}'), - - - ], + getRow(TranslationBase.of(context).brand, + '${listHISGetContactLensPerscription.brand}'), + getRow('B.C', + '${listHISGetContactLensPerscription.baseCurve}'), + getRow(TranslationBase.of(context).power, + '${listHISGetContactLensPerscription.power}'), + getRow(TranslationBase.of(context).diameter, + '${listHISGetContactLensPerscription.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription.cT}'), + getRow( + 'Blend', '${listHISGetContactLensPerscription.blend}'), + getRow(TranslationBase.of(context).reminder, + '${listHISGetContactLensPerscription.remarks}'), + ], + ), ), - ), - SizedBox( - height: 17, - ), - Container( - decoration: BoxDecoration( - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all(Radius.circular(8)), - color: Colors.white), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts( - TranslationBase.of(context).leftEye, - fontSize: 23, - bold: true, - ), - ), - getRow(TranslationBase.of(context).brand, '${listHISGetContactLensPerscription.brand}'), - getRow('B.C', '${listHISGetContactLensPerscription.baseCurve}'), - getRow(TranslationBase.of(context).power, '${listHISGetContactLensPerscription.power}'), - getRow(TranslationBase.of(context).diameter, '${listHISGetContactLensPerscription.diameter}'), - getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), - getRow('CT', '${listHISGetContactLensPerscription.cT}'), - getRow('Blend', '${listHISGetContactLensPerscription.blend}'), - getRow(TranslationBase.of(context).reminder, '${listHISGetContactLensPerscription.remarks}'), - ], + SizedBox( + height: 17, ), - ), - SizedBox( - height: 17, - ), - if(projectViewModel.havePrivilege(15)) - Container( - width: double.infinity, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - textColor: Colors.white, - color: Colors.red[700], - icon: Icon( - Icons.email, - color: Colors.white, + Container( + decoration: BoxDecoration( + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all(Radius.circular(8)), + color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts( + TranslationBase.of(context).leftEye, + fontSize: 23, + bold: true, + ), + ), + getRow(TranslationBase.of(context).brand, + '${listHISGetContactLensPerscription.brand}'), + getRow('B.C', + '${listHISGetContactLensPerscription.baseCurve}'), + getRow(TranslationBase.of(context).power, + '${listHISGetContactLensPerscription.power}'), + getRow(TranslationBase.of(context).diameter, + '${listHISGetContactLensPerscription.diameter}'), + getRow('OZ', '${listHISGetContactLensPerscription.oZ}'), + getRow('CT', '${listHISGetContactLensPerscription.cT}'), + getRow( + 'Blend', '${listHISGetContactLensPerscription.blend}'), + getRow(TranslationBase.of(context).reminder, + '${listHISGetContactLensPerscription.remarks}'), + ], ), ), - ) - ], + SizedBox( + height: 17, + ), + if (projectViewModel.havePrivilege(15)) + Container( + width: double.infinity, + child: SecondaryButton( + label: TranslationBase.of(context).sendEmail, + textColor: Colors.white, + color: Colors.red[700], + onTap: (){ + showConfirmMessage(context, () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.sendContactLensPrescriptionEmail( + appointmentNo: appointmentNo, + projectName: projectName, + projectID: projectID); + GifLoaderDialogUtils.hideDialog(context); + }, model.user.emailAddress); + }, + icon: Icon( + Icons.email, + color: Colors.white, + ), + ), + ) + ], + ), ), ), ), @@ -130,4 +165,18 @@ class ContactLensPage extends StatelessWidget { ], ), ); + + + void showConfirmMessage( + BuildContext context, GestureTapCallback onTap, String email) { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: email, + onTapSendEmail: () { + onTap(); + }, + ), + ); + } } diff --git a/lib/pages/medical/eye/EyeHomePage.dart b/lib/pages/medical/eye/EyeHomePage.dart index 3f4df55f..3af2279e 100644 --- a/lib/pages/medical/eye/EyeHomePage.dart +++ b/lib/pages/medical/eye/EyeHomePage.dart @@ -43,6 +43,7 @@ class _EyeHomePageState extends State Widget build(BuildContext context) { return AppScaffold( isShowAppBar: true, + isShowDecPage: false, appBarTitle: TranslationBase.of(context).measurements, body: Scaffold( extendBodyBehindAppBar: true, @@ -74,20 +75,20 @@ class _EyeHomePageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), unselectedLabelColor: Colors.grey[800], tabs: [ Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.40, child: Center( child: Texts(TranslationBase.of(context).classes), ), ), Container( - width: MediaQuery.of(context).size.width * 0.27, + width: MediaQuery.of(context).size.width * 0.40, child: Center( child: Texts(TranslationBase.of(context).contactLens), ), @@ -110,11 +111,15 @@ class _EyeHomePageState extends State ClassesPage( glassPerscription: widget.appointmentAllHistoryResultList .listHISGetGlassPerscription[0], + appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, + projectName: widget.appointmentAllHistoryResultList.projectName, + projectID: widget.appointmentAllHistoryResultList.projectID, ), ContactLensPage( - listHISGetContactLensPerscription: widget - .appointmentAllHistoryResultList - .listHISGetContactLensPerscription[0], + listHISGetContactLensPerscription: widget.appointmentAllHistoryResultList.listHISGetContactLensPerscription[0], + appointmentNo: widget.appointmentAllHistoryResultList.appointmentNo, + projectName: widget.appointmentAllHistoryResultList.projectName, + projectID: widget.appointmentAllHistoryResultList.projectID, ) ], ), diff --git a/lib/pages/medical/medical_profile_page.dart b/lib/pages/medical/medical_profile_page.dart index ade69f45..8d49a89b 100644 --- a/lib/pages/medical/medical_profile_page.dart +++ b/lib/pages/medical/medical_profile_page.dart @@ -54,19 +54,24 @@ class MedicalProfilePage extends StatefulWidget { class _MedicalProfilePageState extends State { var authProvider = new AuthProvider(); - List medical=List(); + List medical = List(); ProjectViewModel projectViewModel; + @override Widget build(BuildContext context) { - projectViewModel = Provider.of(context); + projectViewModel = Provider.of(context); var appoCountProvider = Provider.of(context); - - List myMedicalList = Utils.myMedicalList(projectViewModel: projectViewModel,context: context,count: appoCountProvider.count,isLogin: projectViewModel.isLogin); - return BaseView( + List myMedicalList = Utils.myMedicalList( + projectViewModel: projectViewModel, + context: context, + count: appoCountProvider.count, + isLogin: projectViewModel.isLogin); + return BaseView( onModelReady: (model) => model.getAppointmentHistory(), builder: (_, model, widget) => AppScaffold( isShowDecPage: false, baseViewModel: model, + isHelp: true, body: Container( child: SingleChildScrollView( child: Column( @@ -97,25 +102,30 @@ class _MedicalProfilePageState extends State { itemCount: model .appoitmentAllHistoryResultList.length, scrollDirection: Axis.horizontal, - reverse: !projectViewModel.isArabic, + reverse: projectViewModel.isArabic, ), ], ), ), - SizedBox(height: 50,), + SizedBox( + height: 50, + ), Padding( padding: EdgeInsets.symmetric(vertical: 5.0), child: GridView.builder( shrinkWrap: true, primary: false, physics: NeverScrollableScrollPhysics(), - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 3, - childAspectRatio: MediaQuery.of(context).size.width / (MediaQuery.of(context).size.height / 2.40), + childAspectRatio: MediaQuery.of(context) + .size + .width / + (MediaQuery.of(context).size.height / 2.20), ), itemCount: myMedicalList.length, itemBuilder: (BuildContext context, int index) { - return myMedicalList[index]; }, ), @@ -123,8 +133,7 @@ class _MedicalProfilePageState extends State { ], ), SizedBox( - height: - MediaQuery.of(context).size.height * 0.12, + height: MediaQuery.of(context).size.height * 0.12, ), if (model.user != null && model.isLogin) Positioned( @@ -135,7 +144,7 @@ class _MedicalProfilePageState extends State { width: double.infinity, height: 80, decoration: BoxDecoration( - color: Theme.of(context).primaryColor, + color: Colors.grey[500], shape: BoxShape.rectangle, border: Border.all( color: Colors.transparent, width: 0.5), @@ -187,20 +196,13 @@ class _MedicalProfilePageState extends State { ), ); } - - fullMedicalData(){ - if(projectViewModel.havePrivilege(5)) - {} - } } -class Medical{ - - final String title; - final String imagePath; - final String subTitle; - final Widget page; - - Medical({this.title, this.imagePath, this.subTitle, this.page}); +class Medical { + final String title; + final String imagePath; + final String subTitle; + final Widget page; + Medical({this.title, this.imagePath, this.subTitle, this.page}); } diff --git a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart index a7b23191..71799084 100644 --- a/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart +++ b/lib/pages/medical/my_trackers/Weight/AddWeightPage.dart @@ -1,188 +1,283 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:feather_icons_flutter/feather_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:provider/provider.dart'; class AddWeightPage extends StatefulWidget { + final WeightPressureViewModel model; + final bool isUpdate; + final DateTime dayWeightDate; + final int lineItemNo; + final String weightValue; + final String measureTimeSelectedType; + final int weightUnit; + + AddWeightPage( + {Key key, + this.model, + this.isUpdate = false, + this.dayWeightDate, + this.lineItemNo, + this.weightValue, + this.measureTimeSelectedType, + this.weightUnit}) + : super(key: key); + @override _AddWeightPageState createState() => _AddWeightPageState(); } class _AddWeightPageState extends State { TextEditingController _weightValueController = TextEditingController(); - DateTime bloodSugarDate = DateTime.now(); - DateTime timeSugarDate = DateTime.now(); + DateTime dayWeightDate = DateTime.now(); + DateTime timeWeightDate = DateTime.now(); int weightUnit = 1; final List measureUnitEnList = [ 'Kg', 'Pound', ]; - final List measureUnitArList = [ - 'Kg', - 'Pound', - ]; - String measureTimeSelectedType = 'Kg'; + final List measureUnitArList = ["كيلو جرام", "باوند"]; + String measureTimeSelectedType; + @override + void initState() { + super.initState(); + if (widget.isUpdate) { + dayWeightDate = widget.dayWeightDate; + timeWeightDate = widget.dayWeightDate; + measureTimeSelectedType = widget.measureTimeSelectedType; + if (measureUnitEnList.contains(widget.measureTimeSelectedType)) + weightUnit = measureUnitEnList.indexOf(widget.measureTimeSelectedType); + else if (measureUnitArList.contains(widget.measureTimeSelectedType)) + weightUnit = measureUnitArList.indexOf(widget.measureTimeSelectedType); + _weightValueController.text = widget.weightValue; + } + } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return BaseView( - builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - appBarTitle: 'Add', - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: 'Enter Weight Value', - controller: _weightValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureUnitEnList - : measureUnitArList); + return AppScaffold( + isShowAppBar: true, + appBarTitle: widget.isUpdate + ? TranslationBase.of(context).update + : TranslationBase.of(context).add, + appBarIcons:widget.isUpdate? [ + IconButton( + icon: Icon(Icons.delete), + color: Colors.white, + onPressed: () { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: 'Remove this measure', + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () async { + ConfirmDialog.closeAlertDialog(context); + + GifLoaderDialogUtils.showMyDialog(context); + widget.model + .deleteWeightResult(lineItemNo: widget.lineItemNo) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.ErrorLocal) + AppToast.showErrorToast( + message: widget.model.error); + else + Navigator.pop(context); + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast( + message: widget.model.error); + }); }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureTimeSelectedType), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }, + ) + ]:null, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.all(15), + child: Column( + children: [ + SizedBox( + height: 15, + ), + NewTextFields( + hintText: TranslationBase.of(context).weightAdd, + controller: _weightValueController, + keyboardType: TextInputType.number, + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectMeasureTimeDialog(projectViewModel.isArabic + ? measureUnitArList + : measureUnitEnList); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureTimeSelectedType ?? + TranslationBase.of(context).other), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], ), ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime(DateTime.now().year - 1, 1, 1), - maxTime: DateTime.now(), onConfirm: (date) { - print('confirm $date'); + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showDatePicker( + context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), + onConfirm: (date) { setState(() { - bloodSugarDate = date; + dayWeightDate = date; }); }, - currentTime: bloodSugarDate, - locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Date'), - Texts(getDate()), - ], - ), + currentTime: dayWeightDate, + locale: projectViewModel.localeType, + ); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).date), + Texts(getDate()), + ], ), ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showTimePicker(context, showTitleActions: true, - onConfirm: (date) { - print('confirm $date'); + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showTimePicker( + context, + showTitleActions: true, + onConfirm: (date) { setState(() { - timeSugarDate = date; + timeWeightDate = date; }); }, - currentTime: timeSugarDate, - locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts('Time'), Texts(getTime())], - ), + currentTime: timeWeightDate, + locale: projectViewModel.localeType, + ); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).time), + Texts(getTime()) + ], ), ), - ], - ), + ), + ], ), ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery.of(context).size.width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: model.state == ViewState.BusyLocal, - label: 'SAVE', - textColor: Colors.white, - onTap: () { - if (_weightValueController.text.isNotEmpty ) { - model.addWeightResult( - weightDate: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + ), + bottomSheet: Container( + color: Colors.transparent, + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.2, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: SecondaryButton( + loading: widget.model.state == ViewState.BusyLocal, + label: TranslationBase.of(context).save.toUpperCase(), + textColor: Colors.white, + onTap: () { + if (_weightValueController.text.isNotEmpty) { + if (widget.isUpdate) { + GifLoaderDialogUtils.showMyDialog(context); + widget.model.updateWeightResult( + weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', weightMeasured: _weightValueController.text.toString(), weightUnit: weightUnit, - ); - } - }), - ), + lineItemNo: widget.lineItemNo + ) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.Error) + AppToast.showErrorToast(message: widget.model.error); + else + Navigator.pop(context); + }); + } else + widget.model.addWeightResult( + weightDate: '${dayWeightDate.year}-${dayWeightDate.month}-${dayWeightDate.day} ${timeWeightDate.hour}:${timeWeightDate.minute}:00', + weightMeasured: _weightValueController.text.toString(), + weightUnit: weightUnit, + ) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.Error) + AppToast.showErrorToast(message: widget.model.error); + else + Navigator.pop(context); + }); + } + }), ), ), ); } String getDate() { - return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate.day}, ${bloodSugarDate.year}"; + return "${DateUtil.getMonth(dayWeightDate.month)} ${dayWeightDate.day}, ${dayWeightDate.year}"; } String getTime() { - return " ${timeSugarDate.hour}:${timeSugarDate.minute}"; + return " ${timeWeightDate.hour}:${timeWeightDate.minute}"; } void confirmSelectMeasureTimeDialog(List list) { @@ -190,7 +285,7 @@ class _AddWeightPageState extends State { context: context, child: RadioStringDialog( radioList: list, - title: 'Measure unit', + title: TranslationBase.of(context).measureUnit, selectedValue: measureTimeSelectedType, onValueSelected: (value) { setState(() { diff --git a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart index 8e6f808c..c90b29a7 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart @@ -1,12 +1,15 @@ -import 'dart:ui'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; import 'AddWeightPage.dart'; import 'WeightMonthlyPage.dart'; import 'WeightYeaPage.dart'; @@ -35,73 +38,42 @@ class _WeightHomePageState extends State @override Widget build(BuildContext context) { - return BaseView( + return BaseView( onModelReady: (model) => model.getWeight(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: 'Weight', + appBarTitle: TranslationBase.of(context).weight, + appBarIcons: [IconButton( + icon: Icon(Icons.email), + color: Colors.white, + onPressed: () { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: model.user.emailAddress, + onTapSendEmail: () async{ + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + }else{ + AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); + } + }).catchError((e){ + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: model.error); + }); + }, + ), + ); + }, + ),], baseViewModel: model, body: Scaffold( extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(60.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 55.0, - color: Colors.white, - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - indicatorColor: Colors.red[800], - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Weekly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Monthly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Yearly'), - ), - ), - ], - ), - ), - ), - ), - ], - ), + appBar: TabBarWidget( + tabController: _tabController, ), body: Column( children: [ @@ -111,16 +83,13 @@ class _WeightHomePageState extends State controller: _tabController, children: [ WeightWeeklyPage( - data: model.getWeightWeeklySeries(), - diabtecPatientResult: model.weekWeightMeasurementResult, + model: model, ), WeightMonthlyPage( - data: model.getWeightMonthlyTimeSeriesSales(), - diabtecPatientResult: model.monthWeightMeasurementResult, + model: model, ), WeightYearPage( - data: model.getWeightYearTimeSeriesSales(), - diabtecPatientResult: model.yearWeightMeasurementResult, + model: model, ) ], ), @@ -129,13 +98,15 @@ class _WeightHomePageState extends State ), floatingActionButton: InkWell( onTap: () { - Navigator.push(context, FadePage(page: AddWeightPage())); + Navigator.push(context, FadePage(page: AddWeightPage(model: model,))); }, child: Container( width: 55, height: 55, decoration: BoxDecoration( - shape: BoxShape.circle, color: HexColor('515B5D')), + shape: BoxShape.circle, + color: Theme.of(context).primaryColor, + ), child: Center( child: Icon( Icons.add, diff --git a/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart b/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart index 9f7063f1..6f64bacb 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightMonthlyPage.dart @@ -3,41 +3,48 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPa import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthLineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class WeightMonthlyPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final WeightPressureViewModel model; - const WeightMonthlyPage({Key key, this.data, this.diabtecPatientResult}) - : super(key: key); + const WeightMonthlyPage({ + Key key, + this.model, + }) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body: model.weighMonthTimeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( children: [ Container( - width: double.maxFinite, - height: 180, - color: Colors.white, - child: charts.LineChart(data, - //animate: animate, - defaultRenderer: - new charts.LineRendererConfig(includePoints: true)), - ), + width: double.maxFinite, + color: Colors.white, + child: MonthLineChartCurved( + horizontalInterval: 1.0, + title: TranslationBase.of(context).weight, + timeSeries: model.weighMonthTimeSeriesData, + indexes: model.weighMonthTimeSeriesData.length ~/ 5.5, + )), SizedBox( height: 12, ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -49,7 +56,7 @@ class WeightMonthlyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel, model), ), ], ), @@ -59,21 +66,27 @@ class WeightMonthlyPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context, + ProjectViewModel projectViewModel, WeightPressureViewModel model) { List tableRow = []; tableRow.add( TableRow( children: [ Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +95,11 @@ class WeightMonthlyPage extends StatelessWidget { ), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -94,11 +107,19 @@ class WeightMonthlyPage extends StatelessWidget { height: 40), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.only( + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -107,7 +128,7 @@ class WeightMonthlyPage extends StatelessWidget { ], ), ); - diabtecPatientResult.forEach( + model.monthWeightMeasurementResult.forEach( (diabtec) { tableRow.add( TableRow( @@ -119,7 +140,7 @@ class WeightMonthlyPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', textAlign: TextAlign.center, fontSize: 12, ), diff --git a/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart b/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart index 9c3363dd..866c2b5b 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightWeeklyPage.dart @@ -1,32 +1,41 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; + +import 'AddWeightPage.dart'; class WeightWeeklyPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final WeightPressureViewModel model; - const WeightWeeklyPage({Key key, this.data, this.diabtecPatientResult}) - : super(key: key); + const WeightWeeklyPage({Key key, this.model}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( - body: ListView( + body: model.weightWeekTimeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( children: [ Container( - width: double.maxFinite, - height: 180, + margin: EdgeInsets.only(top: 12, left: 8, right: 8), color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), + child: LineChartCurved( + horizontalInterval: 1.0, + title: TranslationBase.of(context).weight, + timeSeries: model.weightWeekTimeSeriesData, + indexes: model.weightWeekTimeSeriesData.length ~/ 5.5, ), ), SizedBox( @@ -34,7 +43,7 @@ class WeightWeeklyPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +55,7 @@ class WeightWeeklyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel, model), ), ], ), @@ -56,21 +65,27 @@ class WeightWeeklyPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context, + ProjectViewModel projectViewModel, WeightPressureViewModel model) { List tableRow = []; tableRow.add( TableRow( children: [ Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -79,11 +94,11 @@ class WeightWeeklyPage extends StatelessWidget { ), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -91,37 +106,40 @@ class WeightWeeklyPage extends StatelessWidget { height: 40), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), ), height: 40), Container( - child: Container( - decoration: BoxDecoration( - color: HexColor('#515B5D'), - borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), - ), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.only( + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), - child: Center( - child: Texts( - 'Edit', - color: Colors.white, - fontSize: 15, - ), + ), + child: Center( + child: Texts( + TranslationBase.of(context).edit, + color: Colors.white, + fontSize: 15, ), - height: 40), - ), + ), + height: 40), ], ), ); - diabtecPatientResult.forEach( + model.weekWeightMeasurementResult.forEach( (diabtec) { tableRow.add( TableRow( @@ -133,7 +151,7 @@ class WeightWeeklyPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', textAlign: TextAlign.center, fontSize: 12, ), @@ -166,12 +184,30 @@ class WeightWeeklyPage extends StatelessWidget { ), ), ), - Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddWeightPage( + isUpdate: true, + dayWeightDate: diabtec.weightDate, + measureTimeSelectedType: 'Kg', + weightValue: diabtec.weightMeasured.toString(), + lineItemNo: diabtec.lineItemNo, + weightUnit: int.parse(diabtec.unit), + model: model, + ), + ), + ); + }, + child: Container( + height: 70, + padding: EdgeInsets.all(10), + color: Colors.white, + child: Center( + child: Icon(Icons.edit), + ), ), ), ], diff --git a/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart b/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart index 587cc3f6..7fa03819 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightYeaPage.dart @@ -2,41 +2,48 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPr import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/weight/WeightMeasurementResult.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/weight_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class WeightYearPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final WeightPressureViewModel model; - const WeightYearPage({Key key, this.data, this.diabtecPatientResult}) + + const WeightYearPage({Key key, this.model, }) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body: model.weightYearTimeSeriesData.isEmpty ? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),) : ListView( children: [ Container( - width: double.maxFinite, - height: 180, - color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), - ), + width: double.maxFinite, + color: Colors.white, + child: LineChartCurved( + horizontalInterval: 2.0, + title: TranslationBase.of(context).weight, + timeSeries: model.weightYearTimeSeriesData, + indexes: model.weightYearTimeSeriesData.length ~/ 5.5, + ) ), SizedBox( height: 12, ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -48,7 +55,7 @@ class WeightYearPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel, model), ), ], ), @@ -58,21 +65,27 @@ class WeightYearPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context, + ProjectViewModel projectViewModel, WeightPressureViewModel model) { List tableRow = []; tableRow.add( TableRow( children: [ Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -81,11 +94,11 @@ class WeightYearPage extends StatelessWidget { ), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -93,11 +106,19 @@ class WeightYearPage extends StatelessWidget { height: 40), Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.only( + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -106,8 +127,8 @@ class WeightYearPage extends StatelessWidget { ], ), ); - diabtecPatientResult.forEach( - (diabtec) { + model.yearWeightMeasurementResult.forEach( + (diabtec) { tableRow.add( TableRow( children: [ @@ -118,7 +139,7 @@ class WeightYearPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.weightDate) : DateUtil.getMonthDayYearDateFormatted(diabtec.weightDate)} ', textAlign: TextAlign.center, fontSize: 12, ), diff --git a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart index b8d9a557..678ef7dc 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/AddBloodPressurePage.dart @@ -1,21 +1,41 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:feather_icons_flutter/feather_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:provider/provider.dart'; class AddBloodPressurePage extends StatefulWidget { + final DateTime bloodSugarDate; + final String measureTimeSelectedType; + final bool isUpdate; + final int lineItemNo; + final String bloodSystolicValue; + final String bloodDiastolicValue; + final BloodPressureViewMode model; + + const AddBloodPressurePage( + {Key key, + this.bloodSugarDate, + this.measureTimeSelectedType, + this.isUpdate=false, + this.lineItemNo, + this.model, + this.bloodSystolicValue, + this.bloodDiastolicValue}) + : super(key: key); + @override _AddBloodPressurePageState createState() => _AddBloodPressurePageState(); } @@ -28,8 +48,8 @@ class _AddBloodPressurePageState extends State { DateTime timeSugarDate = DateTime.now(); int measuredArm = 1; final List measureTimeEnList = [ - 'Left Arm', - 'Right Arm', + 'Left', + 'Right', ]; final List measureTimeArList = [ 'الذراع الأيسر', @@ -37,152 +57,220 @@ class _AddBloodPressurePageState extends State { ]; String measureTimeSelectedType = 'Left Arm'; + @override + void initState() { + super.initState(); + if (widget.isUpdate) { + bloodSugarDate = widget.bloodSugarDate; + bloodSugarDate = widget.bloodSugarDate; + measureTimeSelectedType = widget.measureTimeSelectedType; + if (measureTimeEnList.contains(widget.measureTimeSelectedType)) + measuredArm = measureTimeEnList.indexOf(widget.measureTimeSelectedType); + else if (measureTimeArList.contains(widget.measureTimeSelectedType)) + measuredArm = measureTimeArList.indexOf(widget.measureTimeSelectedType); + _bloodSystolicValueController.text = widget.bloodSystolicValue; + _bloodDiastolicValueController.text = widget.bloodDiastolicValue; + } + } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - return BaseView( - builder: (_, model, w) => AppScaffold( - isShowAppBar: true, - appBarTitle: 'Add', - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: 'Enter Systolic Value', - controller: _bloodSystolicValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - NewTextFields( - hintText: 'Blood Diastolic Value', - controller: _bloodDiastolicValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureTimeEnList - : measureTimeArList); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureTimeSelectedType), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), + return AppScaffold( + isShowAppBar: true, + appBarTitle: widget.isUpdate + ? TranslationBase.of(context).update + : TranslationBase.of(context).add, + appBarIcons: widget.isUpdate?[ + IconButton( + icon: Icon(Icons.delete), + color: Colors.white, + onPressed: () { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: 'Remove this measure', + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () async { + ConfirmDialog.closeAlertDialog(context); + + GifLoaderDialogUtils.showMyDialog(context); + widget.model + .deactivateDiabeticStatus(lineItemNo: widget.lineItemNo) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.model.state == ViewState.ErrorLocal) + AppToast.showErrorToast(message: widget.model.error); + else + Navigator.pop(context); + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: widget.model.error); + }); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }, + ) + ]:null, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.all(15), + child: Column( + children: [ + SizedBox( + height: 15, + ), + NewTextFields( + hintText: TranslationBase.of(context).systolicAdd, + controller: _bloodSystolicValueController, + keyboardType: TextInputType.number, + ), + SizedBox( + height: 8, + ), + NewTextFields( + hintText: TranslationBase.of(context).diastolicAdd, + controller: _bloodDiastolicValueController, + keyboardType: TextInputType.number, + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectMeasureTimeDialog(projectViewModel.isArabic + ? measureTimeEnList + : measureTimeArList); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureTimeSelectedType), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], ), ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime(DateTime.now().year - 1, 1, 1), - maxTime: DateTime.now(), onConfirm: (date) { - print('confirm $date'); - setState(() { + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showDatePicker(context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), onConfirm: (date) { + setState( + () { bloodSugarDate = date; - }); - }, - currentTime: bloodSugarDate, - locale: projectViewModel.localeType); + }, + ); }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Date'), - Texts(getDate()), - ], - ), + currentTime: bloodSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).date), + Texts(getDate()), + ], ), ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showTimePicker(context, showTitleActions: true, - onConfirm: (date) { - print('confirm $date'); - setState(() { + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showTimePicker(context, showTitleActions: true, + onConfirm: (date) { + setState( + () { timeSugarDate = date; - }); - }, - currentTime: timeSugarDate, - locale: projectViewModel.localeType); + }, + ); }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts('Time'), Texts(getTime())], - ), + currentTime: timeSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).time), + Texts(getTime()) + ], ), ), - ], - ), + ), + ], ), ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery.of(context).size.width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: model.state == ViewState.BusyLocal, - label: 'SAVE', - textColor: Colors.white, - onTap: () { - if (_bloodSystolicValueController.text.isNotEmpty && - _bloodDiastolicValueController.text.isNotEmpty) { - model.addDiabtecResult( - bloodPressureDate: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - diastolicPressure: _bloodDiastolicValueController.text.toString(), - systolicePressure: _bloodSystolicValueController.text.toString(), - measuredArm: measuredArm, - ); - } - }), - ), + ), + bottomSheet: Container( + color: Colors.transparent, + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.2, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: SecondaryButton( + loading: widget.model.state == ViewState.BusyLocal, + label: TranslationBase.of(context).save.toUpperCase(), + textColor: Colors.white, + onTap: () async { + if (_bloodSystolicValueController.text.isNotEmpty && + _bloodDiastolicValueController.text.isNotEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + + widget.model.addORUpdateDiabtecResult( + isUpdate: widget.isUpdate, + bloodPressureDate: + '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + diastolicPressure: + _bloodDiastolicValueController.text.toString(), + systolicePressure: + _bloodSystolicValueController.text.toString(), + measuredArm: measuredArm, + ).then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(widget.model.state == ViewState.BusyLocal) + AppToast.showErrorToast(message: widget.model.error); + else + Navigator.pop(context); +; + }).catchError((e){ + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: widget.model.error); + }); + } + }), ), ), ); diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart index e6bb3ed4..723871cb 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart @@ -1,15 +1,15 @@ -import 'dart:ui'; - +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:hexcolor/hexcolor.dart'; - import 'AddBloodPressurePage.dart'; import 'BloodPressureMonthly.dart'; import 'BloodPressureYeaPage.dart'; @@ -42,69 +42,37 @@ class _BloodPressureHomePageState extends State onModelReady: (model) => model.getBloodPressure(), builder: (_, model, w) => AppScaffold( isShowAppBar: true, - appBarTitle: 'Blood Pressure', + appBarTitle: TranslationBase.of(context).bloodPressure, baseViewModel: model, + appBarIcons: [IconButton( + icon: Icon(Icons.email), + color: Colors.white, + onPressed: () { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: model.user.emailAddress, + onTapSendEmail: () async{ + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + }else{ + AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); + } + }).catchError((e){ + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: model.error); + }); + }, + ), + ); + }, + ),], body: Scaffold( extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(60.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 55.0, - color: Colors.white, - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Weekly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Monthly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Yearly'), - ), - ), - ], - ), - ), - ), - ), - ], - ), - ), + appBar: TabBarWidget(tabController: _tabController,), body: Column( children: [ Expanded( @@ -113,16 +81,13 @@ class _BloodPressureHomePageState extends State controller: _tabController, children: [ BloodPressureWeeklyPage( - data: model.getBloodWeeklySeries(), - diabtecPatientResult: model.weekDiabtecPatientResult, + model: model, ), BloodPressureMonthlyPage( - data: model.getBloodMonthlyTimeSeriesSales(), - diabtecPatientResult: model.monthDiabtecPatientResult, + model: model, ), BloodPressureYearPage( - data: model.getBloodYearTimeSeriesSales(), - diabtecPatientResult: model.yearDiabtecPatientResult, + model: model, ) ], ), @@ -131,13 +96,13 @@ class _BloodPressureHomePageState extends State ), floatingActionButton: InkWell( onTap: () { - Navigator.push(context, FadePage(page: AddBloodPressurePage())); + Navigator.push(context, FadePage(page: AddBloodPressurePage(model: model,))); }, child: Container( width: 55, height: 55, decoration: BoxDecoration( - shape: BoxShape.circle, color: HexColor('515B5D')), + shape: BoxShape.circle, color: Theme.of(context).primaryColor), child: Center( child: Icon( Icons.add, diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart index 8b9e504f..04853689 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureMonthly.dart @@ -1,43 +1,45 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodPressureMonthlyPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final BloodPressureViewMode model; + + const BloodPressureMonthlyPage({Key key, this.model}) : super(key: key); - const BloodPressureMonthlyPage( - {Key key, this.data, this.diabtecPatientResult}) - : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return AppScaffold( - body: ListView( + body: model.weighMonthTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( children: [ - Container( - width: double.maxFinite, - height: 180, - color: Colors.white, - child: charts.LineChart(data, - //animate: animate, - defaultRenderer: - new charts.LineRendererConfig(includePoints: true)), - ), + Container( + margin: EdgeInsets.only(top: 12, left: 8, right: 8), + color: Colors.white, + child: MonthCurvedChartBloodPressure( + horizontalInterval: 20.0, + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model.weighMonthTimeSeriesDataTop, + timeSeries2: model.weighMonthTimeSeriesDataLow, + indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, + ), + ), SizedBox( height: 12, ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -49,7 +51,7 @@ class BloodPressureMonthlyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context,projectViewModel,model), ), ], ), @@ -59,7 +61,8 @@ class BloodPressureMonthlyPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context, + ProjectViewModel projectViewModel, BloodPressureViewMode model) { List tableRow = []; tableRow.add( TableRow( @@ -67,7 +70,7 @@ class BloodPressureMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( topLeft: Radius.circular(10.0), ), @@ -85,7 +88,7 @@ class BloodPressureMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( @@ -99,11 +102,11 @@ class BloodPressureMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + 'Arm', color: Colors.white, fontSize: 15, ), @@ -113,14 +116,14 @@ class BloodPressureMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( topRight: Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + 'SBP/DBP', color: Colors.white, fontSize: 15, ), @@ -130,68 +133,50 @@ class BloodPressureMonthlyPage extends StatelessWidget { ], ), ); - diabtecPatientResult.forEach( + model.monthDiabtecPatientResult.reversed.forEach( (diabtec) { tableRow.add( TableRow( children: [ Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.bloodPressureDate)} ', - textAlign: TextAlign.center, - fontSize: 12, - ), + color: Colors.white, + child: Center( + child: Texts( + '${projectViewModel.isArabic? DateUtil.getMonthDayYearDateFormattedAr(diabtec.bloodPressureDate):DateUtil.getMonthDayYearDateFormatted(diabtec.bloodPressureDate)}', + fontSize: 15, + textAlign: TextAlign.center, ), ), + height: 40, ), Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), color: Colors.white, child: Center( child: Texts( '${diabtec.bloodPressureDate.hour}:${diabtec.bloodPressureDate.minute}', - textAlign: TextAlign.center, - fontSize: 12, + fontSize: 15, ), ), - ), - ), + height: 40), Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), color: Colors.white, child: Center( child: Texts( - '${diabtec.measuredArmDesc}', - textAlign: TextAlign.center, - fontSize: 12, + diabtec.measuredArmDesc, + fontSize: 15, ), ), - ), - ), + height: 40), Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), color: Colors.white, child: Center( child: Texts( '${diabtec.systolicePressure}/${diabtec.diastolicPressure}', - textAlign: TextAlign.center, - fontSize: 12, color: Colors.red, + fontSize: 15, ), ), - ), - ), + height: 40), ], ), ); diff --git a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart index 0c67be7c..b5b01f06 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureYeaPage.dart @@ -1,33 +1,34 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodPressureYearPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final BloodPressureViewMode model; - const BloodPressureYearPage({Key key, this.data, this.diabtecPatientResult}) - : super(key: key); + const BloodPressureYearPage({Key key, this.model}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body: model.weightYearTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),):ListView( children: [ Container( - width: double.maxFinite, - height: 180, + margin: EdgeInsets.only(top: 12, left: 8, right: 8), color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), + child: CurvedChartBloodPressure( + horizontalInterval: 3.0,// model.weightWeekTimeSeriesDataLow.length==1 ?1 :20.0, + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model.weightYearTimeSeriesDataTop, + timeSeries2: model.weightYearTimeSeriesDataLow, + indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, ), ), SizedBox( @@ -35,7 +36,7 @@ class BloodPressureYearPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -47,7 +48,7 @@ class BloodPressureYearPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel, model), ), ], ), @@ -57,7 +58,10 @@ class BloodPressureYearPage extends StatelessWidget { ); } - List fullData() { + List fullData( + BuildContext context, + ProjectViewModel projectViewModel, + BloodPressureViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( @@ -65,14 +69,19 @@ class BloodPressureYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -83,11 +92,11 @@ class BloodPressureYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -97,11 +106,11 @@ class BloodPressureYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -111,14 +120,19 @@ class BloodPressureYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -128,7 +142,7 @@ class BloodPressureYearPage extends StatelessWidget { ], ), ); - diabtecPatientResult.forEach( + model.yearDiabtecPatientResult.reversed.forEach( (diabtec) { tableRow.add( TableRow( diff --git a/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart b/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart index 52313483..e4ff7332 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/bloodPressureWeeklyPage.dart @@ -1,33 +1,37 @@ -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_pressur/BloodPressureResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; -import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_pressure_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; + +import 'AddBloodPressurePage.dart'; class BloodPressureWeeklyPage extends StatelessWidget { - final List> data; - final List diabtecPatientResult; + final BloodPressureViewMode model; - const BloodPressureWeeklyPage({Key key, this.data, this.diabtecPatientResult}) - : super(key: key); + const BloodPressureWeeklyPage({Key key, this.model}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body: model.weightWeekTimeSeriesDataTop.isEmpty? Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( children: [ Container( - width: double.maxFinite, - height: 180, + margin: EdgeInsets.only(top: 12, left: 8, right: 8), color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), + child: CurvedChartBloodPressure( + horizontalInterval:3.0, + title: TranslationBase.of(context).bloodPressure, + timeSeries1: model.weightWeekTimeSeriesDataTop, + timeSeries2: model.weightWeekTimeSeriesDataLow, + indexes: model.weightWeekTimeSeriesDataLow.length ~/ 5.5, ), ), SizedBox( @@ -35,7 +39,7 @@ class BloodPressureWeeklyPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -47,7 +51,7 @@ class BloodPressureWeeklyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context, projectViewModel, model), ), ], ), @@ -57,7 +61,10 @@ class BloodPressureWeeklyPage extends StatelessWidget { ); } - List fullData() { + List fullData( + BuildContext context, + ProjectViewModel projectViewModel, + BloodPressureViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( @@ -65,14 +72,19 @@ class BloodPressureWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -83,11 +95,11 @@ class BloodPressureWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -97,11 +109,11 @@ class BloodPressureWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -111,11 +123,11 @@ class BloodPressureWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -125,14 +137,19 @@ class BloodPressureWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Edit', + TranslationBase.of(context).edit, color: Colors.white, fontSize: 15, ), @@ -142,7 +159,7 @@ class BloodPressureWeeklyPage extends StatelessWidget { ], ), ); - diabtecPatientResult.forEach( + model.weekDiabtecPatientResult.reversed.forEach( (diabtec) { tableRow.add( TableRow( @@ -202,7 +219,23 @@ class BloodPressureWeeklyPage extends StatelessWidget { ), ), ), - Container( + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodPressurePage( + model: model, + isUpdate: true, + lineItemNo: diabtec.lineItemNo, + bloodSugarDate: diabtec.bloodPressureDate, + bloodDiastolicValue: diabtec.diastolicPressure.toString(), + bloodSystolicValue: diabtec.systolicePressure.toString(), + measureTimeSelectedType: diabtec.measuredArmDesc, + ), + ), + ); + }, child: Container( height: 70, padding: EdgeInsets.all(10), diff --git a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart index 00f06a25..94e48b92 100644 --- a/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/AddBloodSugarPage.dart @@ -1,20 +1,41 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/balance/new_text_Field.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/RadioStringDialog.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:feather_icons_flutter/feather_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:provider/provider.dart'; class AddBloodSugarPage extends StatefulWidget { + final DateTime bloodSugarDate; + final String measureUnitSelectedType; + final bool isUpdate; + final String measuredTime; + final String bloodSugarValue; + final int lineItemNo; + final BloodSugarViewMode bloodSugarViewMode; + + AddBloodSugarPage( + {Key key, + this.bloodSugarDate, + this.measureUnitSelectedType, + this.isUpdate = false, + this.measuredTime, + this.bloodSugarValue, + this.lineItemNo, + this.bloodSugarViewMode}) + : super(key: key); + @override _AddBloodSugarPageState createState() => _AddBloodSugarPageState(); } @@ -24,7 +45,7 @@ class _AddBloodSugarPageState extends State { DateTime bloodSugarDate = DateTime.now(); DateTime timeSugarDate = DateTime.now(); String measureUnitSelectedType = 'mg/dlt'; - int measuredTime=1; + int measuredTime = 1; final List measureUnitList = ['mg/dlt', 'mol/L']; final List measureTimeEnList = [ 'Before Breakfast', @@ -39,270 +60,268 @@ class _AddBloodSugarPageState extends State { 'Other', ]; final List measureTimeArList = [ - 'Before Breakfast', - 'After Breakfast', - 'Before Lunch', - 'After Lunch', - 'Before Dinner', - 'After Dinner', - 'Before Sleep', - 'After Sleep', - 'Fasting', - 'Other', + "قبل الإفطار", + "بعد الإفطار", + "بعد الغداء", + "بعد الغداء", + "قبل العشاء", + "بعد العشاء", + "قبل النوم", + "بعد النوم", + "صائم", + "آخر", ]; String measureTimeSelectedType; + @override + void initState() { + super.initState(); + if (widget.isUpdate) { + bloodSugarDate = widget.bloodSugarDate; + timeSugarDate = widget.bloodSugarDate; + measureUnitSelectedType = widget.measureUnitSelectedType; + if (measureTimeEnList.contains(widget.measuredTime)) + measuredTime = measureTimeEnList.indexOf(widget.measuredTime); + else if (measureTimeArList.contains(widget.measuredTime)) + measuredTime = measureTimeArList.indexOf(widget.measuredTime); + _bloodSugarValueController.text = widget.bloodSugarValue; + } + } @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); - showTaskOptions() { - showModalBottomSheet( - backgroundColor: Colors.white, - context: context, - builder: (BuildContext bc) { - return Container( - padding: EdgeInsets.symmetric(vertical: 12.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.only( - topLeft: Radius.circular(16.0), - topRight: Radius.circular(16.0))), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(3.0)), - width: 40.0, - height: 6.0, - ), - InkWell( - onTap: () { + return AppScaffold( + isShowAppBar: true, + appBarTitle: widget.isUpdate + ? TranslationBase.of(context).update + : TranslationBase.of(context).add, + appBarIcons: widget.isUpdate?[ + IconButton( + icon: Icon(Icons.delete), + color: Colors.white, + onPressed: () { + ConfirmDialog dialog = new ConfirmDialog( + context: context, + confirmMessage: 'Remove this measure', + okText: TranslationBase.of(context).ok, + cancelText: TranslationBase.of(context).cancel, + okFunction: () async { + ConfirmDialog.closeAlertDialog(context); + + GifLoaderDialogUtils.showMyDialog(context); + widget.bloodSugarViewMode + .deactivateDiabeticStatus(lineItemNo: widget.lineItemNo) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) + AppToast.showErrorToast( + message: widget.bloodSugarViewMode.error); + else Navigator.pop(context); - }, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 18.0, vertical: 18.0), - child: Row( - children: [ - Icon( - FeatherIcons.share, - color: Theme - .of(context) - .primaryColor, - size: 18.0, - ), - SizedBox(width: 24.0), - Texts('Share Task', - variant: "body2Link", color: Colors.grey[800]), - ], - ), - ), + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast( + message: widget.bloodSugarViewMode.error); + }); + }, + cancelFunction: () => {}); + dialog.showAlertDialog(context); + }, + ) + ]:null, + body: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Container( + margin: EdgeInsets.all(15), + child: Column( + children: [ + SizedBox( + height: 15, + ), + NewTextFields( + hintText: TranslationBase.of(context).sugarAdd, + controller: _bloodSugarValueController, + keyboardType: TextInputType.number, + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectMeasureUnitDialog(); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureUnitSelectedType), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], ), - InkWell( - onTap: () { - Navigator.pop(context); - // Navigator.of(context).push(SlideUpPageRoute(widget: PostTaskIndex(task: new Task(category: task?.category, description: task?.description, title: task?.title)))); - }, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: 18.0, vertical: 18.0), - child: Row( - children: [ - Icon( - FeatherIcons.copy, - color: Theme - .of(context) - .primaryColor, - size: 18.0, - ), - SizedBox(width: 24.0), - Texts('Post Similar Task', - variant: "body2Link", color: Colors.grey[800]), - ], - ), - ), + ), + ), + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showDatePicker(context, + showTitleActions: true, + minTime: DateTime(DateTime.now().year - 1, 1, 1), + maxTime: DateTime.now(), onConfirm: (date) { + setState(() { + bloodSugarDate = date; + }); + }, + currentTime: bloodSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).date), + Texts(getDate()), + ], ), - ], + ), ), - ); - }); - } - - return BaseView( - builder: (_, model, w) => - AppScaffold( - isShowAppBar: true, - appBarTitle: 'Add', - body: SingleChildScrollView( - physics: BouncingScrollPhysics(), - child: Container( - margin: EdgeInsets.all(15), - child: Column( - children: [ - SizedBox( - height: 15, - ), - NewTextFields( - hintText: 'Enter Blood Sugar Value', - controller: _bloodSugarValueController, - keyboardType: TextInputType.number, - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureUnitDialog(); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureUnitSelectedType), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showDatePicker(context, - showTitleActions: true, - minTime: DateTime(DateTime - .now() - .year - 1, 1, 1), - maxTime: DateTime.now(), - onConfirm: (date) { - print('confirm $date'); - setState(() { - bloodSugarDate = date; - }); - }, - currentTime: bloodSugarDate, - locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts('Date'), - Texts(getDate()), - ], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - DatePicker.showTimePicker( - context, showTitleActions: true, - onConfirm: (date) { - print('confirm $date'); - setState(() { - timeSugarDate = date; - }); - }, - currentTime: timeSugarDate, - locale: projectViewModel.localeType); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [Texts('Time'), Texts(getTime())], - ), - ), - ), - SizedBox( - height: 8, - ), - InkWell( - onTap: () { - confirmSelectMeasureTimeDialog(projectViewModel.isArabic - ? measureTimeEnList - : measureTimeArList); - }, - child: Container( - padding: EdgeInsets.all(12), - width: double.infinity, - height: 65, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts(measureTimeSelectedType ?? 'Others'), - Icon( - Icons.arrow_drop_down, - color: Colors.grey, - ) - ], - ), - ), - ), - ], + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + DatePicker.showTimePicker(context, showTitleActions: true, + onConfirm: (date) { + setState(() { + timeSugarDate = date; + }); + }, + currentTime: timeSugarDate, + locale: projectViewModel.localeType); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(TranslationBase.of(context).time), + Texts(getTime()) + ], + ), ), ), - ), - bottomSheet: Container( - color: Colors.transparent, - width: double.infinity, - height: MediaQuery - .of(context) - .size - .width * 0.2, - child: Padding( - padding: const EdgeInsets.all(15.0), - child: SecondaryButton( - loading: model.state == ViewState.BusyLocal, - label: 'SAVE', textColor: Colors.white, onTap: () { - if (_bloodSugarValueController.text.isNotEmpty) { - model.addDiabtecResult(diabtecUnit: measureUnitSelectedType, - measuredTime: measuredTime, - bloodSugerResult:_bloodSugarValueController.text.toString(), - bloodSugerDateChart: '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', - - ); - } - }), + SizedBox( + height: 8, ), - ), + InkWell( + onTap: () { + confirmSelectMeasureTimeDialog(projectViewModel.isArabic + ? measureTimeArList + : measureTimeEnList); + }, + child: Container( + padding: EdgeInsets.all(12), + width: double.infinity, + height: 65, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12), + color: Colors.white), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts(measureTimeSelectedType ?? + TranslationBase.of(context).other), + Icon( + Icons.arrow_drop_down, + color: Colors.grey, + ) + ], + ), + ), + ), + ], ), + ), + ), + bottomSheet: Container( + color: Colors.transparent, + width: double.infinity, + height: MediaQuery.of(context).size.width * 0.2, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: SecondaryButton( + label: TranslationBase.of(context).save.toUpperCase(), + textColor: Colors.white, + onTap: () { + if (_bloodSugarValueController.text.isNotEmpty) { + if (widget.isUpdate) { + GifLoaderDialogUtils.showMyDialog(context); + widget.bloodSugarViewMode + .updateDiabtecResult( + month: bloodSugarDate, + hour: timeSugarDate, + diabtecUnit: measureUnitSelectedType, + measuredTime: measuredTime, + lineItemNo: widget.lineItemNo, + bloodSugerResult: + _bloodSugarValueController.text.toString()) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.ErrorLocal) + AppToast.showErrorToast( + message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + }); + } else + widget.bloodSugarViewMode + .addDiabtecResult( + diabtecUnit: measureUnitSelectedType, + measuredTime: measuredTime, + bloodSugerResult: + _bloodSugarValueController.text.toString(), + bloodSugerDateChart: + '${bloodSugarDate.year}-${bloodSugarDate.month}-${bloodSugarDate.day} ${timeSugarDate.hour}:${timeSugarDate.minute}:00', + ) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (widget.bloodSugarViewMode.state == ViewState.Error) + AppToast.showErrorToast( + message: widget.bloodSugarViewMode.error); + else + Navigator.pop(context); + }); + } + }), + ), + ), ); } String getDate() { - return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate - .day}, ${bloodSugarDate.year}"; + return "${DateUtil.getMonth(bloodSugarDate.month)} ${bloodSugarDate.day}, ${bloodSugarDate.year}"; } String getTime() { @@ -314,7 +333,7 @@ class _AddBloodSugarPageState extends State { context: context, child: RadioStringDialog( radioList: measureUnitList, - title: 'Measure unit', + title: TranslationBase.of(context).measureUnit, selectedValue: measureUnitSelectedType, onValueSelected: (value) { setState(() { @@ -330,7 +349,7 @@ class _AddBloodSugarPageState extends State { context: context, child: RadioStringDialog( radioList: list, - title: 'Measure time', + title: TranslationBase.of(context).measureTime, selectedValue: measureTimeSelectedType, onValueSelected: (value) { setState(() { diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart index fdd7b348..1294c5dd 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodMonthly.dart @@ -1,40 +1,47 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/YearMonthlyChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/MonthLineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodMonthlyPage extends StatelessWidget { - final List> data; final List diabtecPatientResult; + final List timeSeriesData ; - const BloodMonthlyPage({Key key, this.data, this.diabtecPatientResult}) + const BloodMonthlyPage({Key key, this.diabtecPatientResult, this.timeSeriesData}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body: timeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( children: [ Container( - width: double.maxFinite, - height: 180, - color: Colors.white, - child: charts.LineChart(data, - //animate: animate, - defaultRenderer: - new charts.LineRendererConfig(includePoints: true)), + width: double.maxFinite, + color: Colors.white, + child: MonthLineChartCurved( + title: 'Sugar', + timeSeries: timeSeriesData, + indexes: timeSeriesData.length ~/ 5.5, + ) ), SizedBox( height: 12, ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +53,7 @@ class BloodMonthlyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: fullData(context,projectViewModel), ), ], ), @@ -56,7 +63,7 @@ class BloodMonthlyPage extends StatelessWidget { ); } - List fullData() { + List fullData(BuildContext context,ProjectViewModel projectViewModel) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +71,15 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), + topRight: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +90,11 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +104,11 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,20 +118,22 @@ class BloodMonthlyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic? Radius.circular(10.0):Radius.circular(0.0), + topRight: projectViewModel.isArabic? Radius.circular(0.0):Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), ), height: 40), ), + ], ), ); @@ -139,7 +149,7 @@ class BloodMonthlyPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart):DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', textAlign: TextAlign.center, fontSize: 12, ), diff --git a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart index 47f87847..842d55f1 100644 --- a/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart +++ b/lib/pages/medical/my_trackers/blood_suger/BloodYeaPage.dart @@ -1,62 +1,75 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; class BloodYearPage extends StatelessWidget { - final List> data; final List diabtecPatientResult; + final List timeSeriesData; - const BloodYearPage({Key key, this.data, this.diabtecPatientResult}) + const BloodYearPage({Key key, this.diabtecPatientResult, this.timeSeriesData}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( - children: [ - Container( - width: double.maxFinite, - height: 180, - color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), - ), - ), - SizedBox( - height: 12, - ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Texts('Details'), - ), - Container( - padding: EdgeInsets.all(10), - color: Colors.transparent, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Table( - border: TableBorder.symmetric( - inside: BorderSide(width: 2.0, color: Colors.grey[300]), - ), - children: fullData(), + body: timeSeriesData.isEmpty + ? Container( + child: Center( + child: Texts(TranslationBase.of(context).noDataAvailable), + ), + ) + : ListView( + children: [ + Container( + width: double.maxFinite, + color: Colors.white, + child: LineChartCurved( + title: 'Sugar', + timeSeries: timeSeriesData, + indexes: timeSeriesData.length ~/ 5.5, + )), + SizedBox( + height: 12, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Texts(TranslationBase.of(context).details), ), + Container( + padding: EdgeInsets.all(10), + color: Colors.transparent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Table( + border: TableBorder.symmetric( + inside: + BorderSide(width: 2.0, color: Colors.grey[300]), + ), + children: fullData(context, projectViewModel), + ), + ], + ), + ) ], ), - ) - ], - ), ); } - List fullData() { + List fullData( + BuildContext context, ProjectViewModel projectViewModel) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +77,19 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +100,11 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +114,11 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,14 +128,19 @@ class BloodYearPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -139,7 +162,7 @@ class BloodYearPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart) : DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', textAlign: TextAlign.center, fontSize: 12, ), diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart index 9259e286..7abbcceb 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_home_page.dart @@ -1,9 +1,14 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/TabBarWidget.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/confirm_send_email_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -42,70 +47,38 @@ class _BloodSugarHomePageState extends State return BaseView( onModelReady: (model) => model.getBloodSugar(), builder: (_, model, w) => AppScaffold( + appBarIcons: [IconButton( + icon: Icon(Icons.email), + color: Colors.white, + onPressed: () { + showDialog( + context: context, + child: ConfirmSendEmailDialog( + email: model.user.emailAddress, + onTapSendEmail: () async{ + GifLoaderDialogUtils.showMyDialog(context); + model.sendReportByEmail().then((value) { + GifLoaderDialogUtils.hideDialog(context); + if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + }else{ + AppToast.showSuccessToast(message:TranslationBase.of(context).emailSentSuccessfully, ); + } + }).catchError((e){ + GifLoaderDialogUtils.hideDialog(context); + AppToast.showErrorToast(message: model.error); + }); + }, + ), + ); + }, + ),], isShowAppBar: true, - appBarTitle: 'Blood Sugar', + appBarTitle: TranslationBase.of(context).bloodSugar, baseViewModel: model, body: Scaffold( extendBodyBehindAppBar: true, - appBar: PreferredSize( - preferredSize: Size.fromHeight(60.0), - child: Stack( - children: [ - Positioned( - bottom: 1, - left: 0, - right: 0, - child: BackdropFilter( - filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), - child: Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.8), - height: 70.0, - ), - ), - ), - Center( - child: Container( - height: 55.0, - color: Colors.white, - child: Center( - child: TabBar( - isScrollable: true, - controller: _tabController, - indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, - labelColor: Theme.of(context).primaryColor, - labelPadding: - EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), - unselectedLabelColor: Colors.grey[800], - tabs: [ - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Weekly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Monthly'), - ), - ), - Container( - width: MediaQuery.of(context).size.width * 0.27, - child: Center( - child: Texts('Yearly'), - ), - ), - ], - ), - ), - ), - ), - ], - ), - ), + appBar: TabBarWidget(tabController: _tabController,), body: Column( children: [ Expanded( @@ -114,15 +87,16 @@ class _BloodSugarHomePageState extends State controller: _tabController, children: [ BloodSugarWeeklyPage( - data: model.getBloodWeeklySeries(), + timeSeriesData: model.bloodWeekTimeSeriesData, diabtecPatientResult: model.weekDiabtecPatientResult, + bloodSugarViewMode: model, ), BloodMonthlyPage( - data: model.getBloodMonthlyTimeSeriesSales(), + timeSeriesData: model.monthTimeSeriesData, diabtecPatientResult: model.monthDiabtecPatientResult, ), BloodYearPage( - data: model.getBloodYearTimeSeriesSales(), + timeSeriesData: model.yearTimeSeriesData, diabtecPatientResult: model.yearDiabtecPatientResult, ) ], @@ -132,13 +106,13 @@ class _BloodSugarHomePageState extends State ), floatingActionButton: InkWell( onTap: () { - Navigator.push(context, FadePage(page: AddBloodSugarPage())); + Navigator.push(context, FadePage(page: AddBloodSugarPage(bloodSugarViewMode: model,))); }, child: Container( width: 55, height: 55, decoration: BoxDecoration( - shape: BoxShape.circle, color: HexColor('515B5D')), + shape: BoxShape.circle, color:Theme.of(context).primaryColor), child: Center( child: Icon( Icons.add, diff --git a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart index 4b007929..60f3293d 100644 --- a/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart +++ b/lib/pages/medical/my_trackers/blood_suger/blood_sugar_weekly_page.dart @@ -1,32 +1,45 @@ import 'package:diplomaticquarterapp/core/model/my_trakers/blood_sugar/DiabtecPatientResult.dart'; import 'package:diplomaticquarterapp/core/model/my_trakers/chartData/WeekChartDate.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/blood_sugar_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/widget/LineChartCurved.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:charts_flutter/flutter.dart' as charts; -import 'package:hexcolor/hexcolor.dart'; +import 'package:provider/provider.dart'; +import 'AddBloodSugarPage.dart'; class BloodSugarWeeklyPage extends StatelessWidget { - final List> data; final List diabtecPatientResult; + final BloodSugarViewMode bloodSugarViewMode; + final List timeSeriesData; - const BloodSugarWeeklyPage({Key key, this.data, this.diabtecPatientResult}) + BloodSugarWeeklyPage( + {Key key, + this.diabtecPatientResult, + this.bloodSugarViewMode, + this.timeSeriesData}) : super(key: key); @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); return AppScaffold( - body: ListView( + body:timeSeriesData.isEmpty?Container(child: Center(child: Texts(TranslationBase.of(context).noDataAvailable),),): ListView( children: [ Container( - width: double.maxFinite, - height: 180, + margin: EdgeInsets.only(top: 12, left: 8, right: 8), color: Colors.white, - child: charts.TimeSeriesChart( - data, - dateTimeFactory: const charts.LocalDateTimeFactory(), + child: LineChartCurved( + title: 'Sugar', + timeSeries: timeSeriesData, + indexes: timeSeriesData.length ~/ 5.5, ), ), SizedBox( @@ -34,7 +47,7 @@ class BloodSugarWeeklyPage extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(8.0), - child: Texts('Details'), + child: Texts(TranslationBase.of(context).details), ), Container( padding: EdgeInsets.all(10), @@ -46,7 +59,8 @@ class BloodSugarWeeklyPage extends StatelessWidget { border: TableBorder.symmetric( inside: BorderSide(width: 2.0, color: Colors.grey[300]), ), - children: fullData(), + children: + fullData(context, projectViewModel, bloodSugarViewMode), ), ], ), @@ -56,7 +70,10 @@ class BloodSugarWeeklyPage extends StatelessWidget { ); } - List fullData() { + List fullData( + BuildContext context, + ProjectViewModel projectViewModel, + BloodSugarViewMode bloodSugarViewMode) { List tableRow = []; tableRow.add( TableRow( @@ -64,14 +81,19 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topLeft: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), + topRight: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), ), ), child: Center( child: Texts( - 'Date', + TranslationBase.of(context).date, color: Colors.white, fontSize: 15, ), @@ -82,11 +104,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Time', + TranslationBase.of(context).time, color: Colors.white, fontSize: 15, ), @@ -96,11 +118,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Measured', + TranslationBase.of(context).measured, color: Colors.white, fontSize: 15, ), @@ -110,11 +132,11 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, ), child: Center( child: Texts( - 'Value', + TranslationBase.of(context).value, color: Colors.white, fontSize: 15, ), @@ -124,14 +146,19 @@ class BloodSugarWeeklyPage extends StatelessWidget { Container( child: Container( decoration: BoxDecoration( - color: HexColor('#515B5D'), + color: Theme.of(context).primaryColor, borderRadius: BorderRadius.only( - topRight: Radius.circular(10.0), + topLeft: projectViewModel.isArabic + ? Radius.circular(10.0) + : Radius.circular(0.0), + topRight: projectViewModel.isArabic + ? Radius.circular(0.0) + : Radius.circular(10.0), ), ), child: Center( child: Texts( - 'Edit', + TranslationBase.of(context).edit, color: Colors.white, fontSize: 15, ), @@ -153,7 +180,7 @@ class BloodSugarWeeklyPage extends StatelessWidget { color: Colors.white, child: Center( child: Texts( - '${DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)}', + '${projectViewModel.isArabic ? DateUtil.getMonthDayYearDateFormattedAr(diabtec.dateChart):DateUtil.getMonthDayYearDateFormatted(diabtec.dateChart)} ', textAlign: TextAlign.center, fontSize: 12, ), @@ -203,12 +230,30 @@ class BloodSugarWeeklyPage extends StatelessWidget { ), ), Container( - child: Container( - height: 70, - padding: EdgeInsets.all(10), - color: Colors.white, - child: Center( - child: Icon(Icons.edit), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: AddBloodSugarPage( + isUpdate: true, + bloodSugarDate: diabtec.dateChart, + measuredTime: diabtec.measuredDesc, + bloodSugarValue: diabtec.resultValue.toString(), + lineItemNo: diabtec.lineItemNo, + measureUnitSelectedType: diabtec.unit, + bloodSugarViewMode: bloodSugarViewMode, + ), + ), + ); + }, + child: Container( + height: 70, + padding: EdgeInsets.all(10), + color: Colors.white, + child: Center( + child: Icon(Icons.edit), + ), ), ), ), diff --git a/lib/pages/medical/my_trackers/my_trackers.dart b/lib/pages/medical/my_trackers/my_trackers.dart index ecdf5a53..5e5c4527 100644 --- a/lib/pages/medical/my_trackers/my_trackers.dart +++ b/lib/pages/medical/my_trackers/my_trackers.dart @@ -1,3 +1,5 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -11,7 +13,7 @@ class MyTrackers extends StatelessWidget { @override Widget build(BuildContext context) { return AppScaffold( - appBarTitle: 'My Tracker', + appBarTitle: TranslationBase.of(context).myTracker, isShowAppBar: true, body: SingleChildScrollView( child: Container( @@ -41,7 +43,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/blood-suger.png',width: 60.0,), SizedBox(height: 15,), - Text('Blood Sugar'), + Texts(TranslationBase.of(context).bloodSugar), ], ), ), @@ -65,7 +67,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/blood-pressure.png',width: 60.0,), SizedBox(height: 15,), - Text('Blood Pressure'), + Texts(TranslationBase.of(context).bloodPressure), ], ), ), @@ -94,7 +96,7 @@ class MyTrackers extends StatelessWidget { children: [ Image.asset('assets/tracker/weight.png',width: 60.0,), SizedBox(height: 15,), - Text('Weight'), + Texts(TranslationBase.of(context).weight), ], ), ), diff --git a/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart b/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart new file mode 100644 index 00000000..ac2349bc --- /dev/null +++ b/lib/pages/medical/my_trackers/widget/CurvedChartBloodPressure.dart @@ -0,0 +1,273 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../Constants.dart'; + +class CurvedChartBloodPressure extends StatelessWidget { + final String title; + final List timeSeries1; + final List timeSeries2; + final int indexes; + final double horizontalInterval; + + CurvedChartBloodPressure( + {this.title, + this.timeSeries1, + this.indexes, + this.timeSeries2, + this.horizontalInterval = 20.0}); + + List xAxixs = List(); + List yAxixs = List(); + + @override + Widget build(BuildContext context) { + getXaxix(); + return AspectRatio( + aspectRatio: 1.1, + child: Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18)), + // color: Colors.white, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 15, + ), + Text( + title, + style: TextStyle( + color: Colors.black, fontSize: 15, letterSpacing: 2), + textAlign: TextAlign.center, + ), + SizedBox( + height: 10, + ), + Expanded( + child: Padding( + padding: + const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), + child: LineChart( + sampleData1(context), + swapAnimationDuration: const Duration(milliseconds: 250), + ), + ), + ), + SizedBox( + height: 10, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Theme.of(context).primaryColor), + ), + SizedBox( + width: 5, + ), + Texts(TranslationBase.of(context).systolicLng) + ], + ), + SizedBox( + width: 15, + ), + Row( + children: [ + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + shape: BoxShape.rectangle, color: secondaryColor), + ), + SizedBox( + width: 5, + ), + Texts(TranslationBase.of(context).diastolicLng) + ], + ), + ], + ) + ], + ), + ], + ), + ), + ); + } + + getXaxix() { + for (int index = 0; index < timeSeries1.length; index++) { + int mIndex = indexes * index; + if (mIndex < timeSeries1.length) { + xAxixs.add(mIndex); + } + } + } + + LineChartData sampleData1(context) { + return LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.white, + ), + touchCallback: (LineTouchResponse touchResponse) {}, + handleBuiltInTouches: true, + ), + gridData: FlGridData( + show: true, drawVerticalLine: true, drawHorizontalLine: true), + titlesData: FlTitlesData( + bottomTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontSize: 10, + ), + + margin: 22, + getTitles: (value) { + if (timeSeries1.length < 15) { + if (timeSeries1.length > value.toInt()) { + return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + } else + return ''; + } else { + if (value.toInt() == 0) + return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + if (value.toInt() == timeSeries1.length - 1) + return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + if (xAxixs.contains(value.toInt())) { + return '${timeSeries1[value.toInt()].time.month}/ ${timeSeries1[value.toInt()].time.year}'; + } + } + return ''; + }, + ), + leftTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ), + getTitles: (value) { + if (value.toInt() == 0) + return '${value.toInt()}'; + else if (value.toInt() % horizontalInterval == 0) + return '${value.toInt()}'; + else + return ''; + }, + margin: 12, + ), + ), + borderData: FlBorderData( + show: true, + border: const Border( + bottom: BorderSide( + color: Colors.black, + width: 0.5, + ), + left: BorderSide( + color: Colors.black, + ), + right: BorderSide( + color: Colors.black, + ), + top: BorderSide( + color: Colors.transparent, + ), + ), + ), + minX: 0, + maxX: (timeSeries1.length - 1).toDouble(), + maxY: getMaxY() + 0.3, + minY: getMinY(), + lineBarsData: getData(context), + ); + } + + double getMaxY() { + double max = 0; + timeSeries1.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + timeSeries2.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + + return max.roundToDouble(); + } + + double getMinY() { + double min = timeSeries1[0].sales; + timeSeries1.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + timeSeries2.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + + int value = min.toInt(); + + return value.toDouble(); + } + + List getData(context) { + List spots = List(); + for (int index = 0; index < timeSeries1.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); + } + + List spots2 = List(); + for (int index = 0; index < timeSeries2.length; index++) { + spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales)); + } + + final LineChartBarData lineChartBarData1 = LineChartBarData( + spots: spots, + isCurved: true, + colors: [Colors.red], + barWidth: 5, + isStrokeCapRound: true, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + final LineChartBarData lineChartBarData2 = LineChartBarData( + spots: spots2, + isCurved: true, + colors: [Theme.of(context).primaryColor], + barWidth: 5, + isStrokeCapRound: true, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + + return [lineChartBarData1, lineChartBarData2]; + } +} diff --git a/lib/pages/medical/my_trackers/widget/LineChartCurved.dart b/lib/pages/medical/my_trackers/widget/LineChartCurved.dart new file mode 100644 index 00000000..eeff06dd --- /dev/null +++ b/lib/pages/medical/my_trackers/widget/LineChartCurved.dart @@ -0,0 +1,222 @@ +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../Constants.dart'; + +class LineChartCurved extends StatelessWidget { + final String title; + final List timeSeries; + final int indexes; + final double horizontalInterval; + + LineChartCurved( + {this.title, + this.timeSeries, + this.indexes, + this.horizontalInterval = 20.0}); + + List xAxixs = List(); + List yAxixs = List(); + + @override + Widget build(BuildContext context) { + getXaxix(); + getYaxix(); + return AspectRatio( + aspectRatio: 1.1, + child: Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18)), + // color: Colors.white, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 4, + ), + Text( + title, + style: TextStyle( + color: Colors.black, fontSize: 15, letterSpacing: 2), + textAlign: TextAlign.center, + ), + SizedBox( + height: 10, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + right: 18.0, left: 16.0, top: 15, bottom: 15), + child: LineChart( + sampleData1(context), + swapAnimationDuration: const Duration(milliseconds: 250), + ), + ), + ), + const SizedBox( + height: 10, + ), + ], + ), + ], + ), + ), + ); + } + + getXaxix() { + for (int index = 0; index < timeSeries.length; index++) { + int mIndex = indexes * index; + if (mIndex < timeSeries.length) { + xAxixs.add(mIndex); + } + } + } + + getYaxix() { + int indexess = (timeSeries.length * 0.30).toInt(); + for (int index = 0; index < timeSeries.length; index++) { + int mIndex = indexess * index; + if (mIndex < timeSeries.length) { + yAxixs.add(timeSeries[mIndex].sales); + } + } + } + + LineChartData sampleData1(context) { + return LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.white, + ), + touchCallback: (LineTouchResponse touchResponse) {}, + handleBuiltInTouches: true, + ), + gridData: FlGridData( + horizontalInterval: horizontalInterval, + show: true, + drawVerticalLine: true, + drawHorizontalLine: true), + titlesData: FlTitlesData( + bottomTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontSize: 10, + ), + // rotateAngle: 90, + //rotateAngle:-65, + margin: 22, + getTitles: (value) { + if (timeSeries.length < 15) { + if (timeSeries.length > value.toInt()) { + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + } else + return ''; + } else { + if (value.toInt() == 0) + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + if (value.toInt() == timeSeries.length - 1) + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + if (xAxixs.contains(value.toInt())) { + return '${timeSeries[value.toInt()].time.month}/ ${timeSeries[value.toInt()].time.year}'; + } + } + return ''; + }, + ), + leftTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ), + getTitles: (value) { + if (value.toInt() == 0) + return '${value.toInt()}'; + else if (value.toInt() % horizontalInterval == 0) + return '${value.toInt()}'; + else + return ''; + }, + margin: 12, + ), + ), + borderData: FlBorderData( + show: true, + border: const Border( + bottom: BorderSide( + color: Colors.black, + width: 0.5, + ), + left: BorderSide( + color: Colors.black, + ), + right: BorderSide( + color: Colors.black, + ), + top: BorderSide( + color: Colors.transparent, + ), + ), + ), + minX: 0, + maxX: (timeSeries.length - 1).toDouble(), + maxY: getMaxY() + 0.3, + minY: getMinY(), + lineBarsData: getData(context), + ); + } + + double getMaxY() { + double max = 0; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + + return max.roundToDouble(); + } + + double getMinY() { + double min = timeSeries[0].sales; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + int value = min.toInt(); + + return value.toDouble(); + } + + List getData(context) { + List spots = List(); + for (int index = 0; index < timeSeries.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries[index].sales)); + } + + final LineChartBarData lineChartBarData1 = LineChartBarData( + spots: spots, + isCurved: true, + colors: [secondaryColor], + barWidth: 5, + isStrokeCapRound: true, + curveSmoothness: 0.12, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + + return [ + lineChartBarData1, + ]; + } +} diff --git a/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart b/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart new file mode 100644 index 00000000..135d0a95 --- /dev/null +++ b/lib/pages/medical/my_trackers/widget/MonthCurvedChartBloodPressure.dart @@ -0,0 +1,252 @@ +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +class MonthCurvedChartBloodPressure extends StatelessWidget { + final String title; + final List timeSeries1; + final List timeSeries2; + final int indexes; + final double horizontalInterval; + + MonthCurvedChartBloodPressure( + {this.title, this.timeSeries1, this.indexes, this.timeSeries2, this.horizontalInterval = 20.0}); + + List xAxixs = List(); + List yAxixs = List(); + + @override + Widget build(BuildContext context) { + getXaxix(); + return AspectRatio( + aspectRatio: 1.1, + child: Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18)), + // color: Colors.white, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 15, + ), + Text( + title, + style: TextStyle( + color: Colors.black, fontSize: 15, letterSpacing: 2), + textAlign: TextAlign.center, + ), + SizedBox( + height: 10, + ), + Expanded( + child: Padding( + padding: + const EdgeInsets.only(right: 18.0, left: 16.0, top: 15), + child: LineChart( + sampleData1(context), + swapAnimationDuration: const Duration(milliseconds: 250), + ), + ), + ), + SizedBox( + height: 10, + ), + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + shape: BoxShape.rectangle, + color: Theme.of(context).primaryColor), + ), + SizedBox( + width: 5, + ), + Texts(TranslationBase.of(context).systolicLng) + ], + ), + SizedBox( + width: 15, + ), + Row( + children: [ + Container( + width: 20, + height: 20, + decoration: BoxDecoration( + shape: BoxShape.rectangle, color: Colors.grey), + ), + SizedBox( + width: 5, + ), + Texts(TranslationBase.of(context).diastolicLng) + ], + ), + ], + ) + ], + ), + ], + ), + ), + ); + } + + getXaxix() { + for (int index = 0; index < timeSeries1.length; index++) { + int mIndex = indexes * index; + if (mIndex < timeSeries1.length) { + xAxixs.add(mIndex); + } + } + } + + LineChartData sampleData1(context) { + return LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.white, + ), + touchCallback: (LineTouchResponse touchResponse) {}, + handleBuiltInTouches: true, + ), + gridData: FlGridData( + show: true, drawVerticalLine: true, drawHorizontalLine: true), + titlesData: FlTitlesData( + bottomTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontSize: 10, + ), + margin: 22, + getTitles: (value) { + return ''; + }, + ), + leftTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ), + getTitles: (value) { + if (value.toInt() == 0) + return '${value.toInt()}'; + else if (value.toInt() % horizontalInterval == 0) + return '${value.toInt()}'; + else + return ''; + }, + margin: 12, + ), + ), + borderData: FlBorderData( + show: true, + border: const Border( + bottom: BorderSide( + color: Colors.black, + width: 0.5, + ), + left: BorderSide( + color: Colors.black, + ), + right: BorderSide( + color: Colors.black, + ), + top: BorderSide( + color: Colors.transparent, + ), + ), + ), + minX: 0, + maxX: (timeSeries1.length - 1).toDouble(), + maxY: getMaxY() + 0.3, + minY: getMinY(), + lineBarsData: getData(context), + ); + } + + double getMaxY() { + double max = 0; + timeSeries1.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + timeSeries2.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + + return max.roundToDouble(); + } + + double getMinY() { + double min = timeSeries1[0].sales; + timeSeries1.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + timeSeries2.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + + int value = min.toInt(); + + return value.toDouble(); + } + + List getData(context) { + List spots = List(); + for (int index = 0; index < timeSeries1.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries1[index].sales)); + } + + List spots2 = List(); + for (int index = 0; index < timeSeries2.length; index++) { + spots2.add(FlSpot(index.toDouble(), timeSeries2[index].sales)); + } + + final LineChartBarData lineChartBarData1 = LineChartBarData( + spots: spots, + isCurved: true, + colors: [Colors.red], + barWidth: 5, + isStrokeCapRound: true, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + final LineChartBarData lineChartBarData2 = LineChartBarData( + spots: spots2, + isCurved: true, + colors: [Theme.of(context).primaryColor], + barWidth: 5, + isStrokeCapRound: true, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + + return [lineChartBarData1, lineChartBarData2]; + } +} diff --git a/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart b/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart new file mode 100644 index 00000000..607f3ab0 --- /dev/null +++ b/lib/pages/medical/my_trackers/widget/MonthLineChartCurved.dart @@ -0,0 +1,206 @@ +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +import '../../../../Constants.dart'; + +class MonthLineChartCurved extends StatelessWidget { + final String title; + final List timeSeries; + final int indexes; + final double horizontalInterval; + + MonthLineChartCurved( + {this.title, + this.timeSeries, + this.indexes, + this.horizontalInterval = 15.0}); + + List xAxixs = List(); + List yAxixs = List(); + + @override + Widget build(BuildContext context) { + getXaxix(); + getYaxix(); + return AspectRatio( + aspectRatio: 1.1, + child: Container( + decoration: const BoxDecoration( + borderRadius: BorderRadius.all(Radius.circular(18)), + // color: Colors.white, + ), + child: Stack( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const SizedBox( + height: 4, + ), + Text( + title, + style: TextStyle( + color: Colors.black, fontSize: 15, letterSpacing: 2), + textAlign: TextAlign.center, + ), + SizedBox( + height: 10, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only( + right: 18.0, left: 16.0, top: 15, bottom: 15), + child: LineChart( + sampleData1(context), + swapAnimationDuration: const Duration(milliseconds: 250), + ), + ), + ), + const SizedBox( + height: 10, + ), + ], + ), + ], + ), + ), + ); + } + + getXaxix() { + for (int index = 0; index < timeSeries.length; index++) { + int mIndex = indexes * index; + if (mIndex < timeSeries.length) { + xAxixs.add(mIndex); + } + } + } + + getYaxix() { + int indexess = (timeSeries.length * 0.30).toInt(); + for (int index = 0; index < timeSeries.length; index++) { + int mIndex = indexess * index; + if (mIndex < timeSeries.length) { + yAxixs.add(timeSeries[mIndex].sales); + } + } + } + + LineChartData sampleData1(context) { + return LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + tooltipBgColor: Colors.white, + ), + touchCallback: (LineTouchResponse touchResponse) {}, + handleBuiltInTouches: true, + ), + gridData: FlGridData( + horizontalInterval: horizontalInterval, + show: true, + drawVerticalLine: true, + drawHorizontalLine: true), + titlesData: FlTitlesData( + bottomTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontSize: 10, + ), + margin: 22, + getTitles: (value) { + return '${value.toInt()}'; + }, + ), + leftTitles: SideTitles( + showTitles: true, + getTextStyles: (value) => const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 10, + ), + getTitles: (value) { + if (value.toInt() == 0) + return '${value.toInt()}'; + else if (value.toInt() % horizontalInterval == 0) + return '${value.toInt()}'; + else + return ''; + }, + margin: 12, + ), + ), + borderData: FlBorderData( + show: true, + border: const Border( + bottom: BorderSide( + color: Colors.black, + width: 0.5, + ), + left: BorderSide( + color: Colors.black, + ), + right: BorderSide( + color: Colors.black, + ), + top: BorderSide( + color: Colors.transparent, + ), + ), + ), + minX: 0, + maxX: (timeSeries.length - 1).toDouble(), + maxY: getMaxY() + 0.3, + minY: getMinY(), + lineBarsData: getData(context), + ); + } + + double getMaxY() { + double max = 0; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > max) max = resultValueDouble; + }); + + return max.roundToDouble(); + } + + double getMinY() { + double min = timeSeries[0].sales; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble < min) min = resultValueDouble; + }); + int value = min.toInt(); + + return value.toDouble(); + } + + List getData(context) { + List spots = List(); + for (int index = 0; index < timeSeries.length; index++) { + spots.add(FlSpot(index.toDouble(), timeSeries[index].sales)); + } + + final LineChartBarData lineChartBarData1 = LineChartBarData( + spots: spots, + isCurved: true, + colors: [secondaryColor], + barWidth: 5, + isStrokeCapRound: true, + curveSmoothness: 0.0, + dotData: FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: false, + ), + ); + + return [ + lineChartBarData1, + ]; + } +} diff --git a/lib/pages/medical/my_trackers/widget/TabBarWidget.dart b/lib/pages/medical/my_trackers/widget/TabBarWidget.dart new file mode 100644 index 00000000..199dbc54 --- /dev/null +++ b/lib/pages/medical/my_trackers/widget/TabBarWidget.dart @@ -0,0 +1,73 @@ +import 'dart:ui'; + +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class TabBarWidget extends StatelessWidget with PreferredSizeWidget{ + final TabController tabController; + + const TabBarWidget({Key key, this.tabController}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Positioned( + bottom: 1, + left: 0, + right: 0, + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: Container( + color: + Theme.of(context).scaffoldBackgroundColor.withOpacity(0.8), + height: 70.0, + ), + ), + ), + Center( + child: Container( + height: 55.0, + color: Colors.white, + child: Center( + child: TabBar( + isScrollable: true, + controller: tabController, + indicatorWeight: 5.0, + indicatorSize: TabBarIndicatorSize.tab, + labelColor: Theme.of(context).primaryColor, + labelPadding: + EdgeInsets.only(top: 4.0, left: 5.0, right: 5.0), + unselectedLabelColor: Colors.grey[800], + tabs: [ + Container( + width: MediaQuery.of(context).size.width * 0.33, + child: Center( + child: Texts(TranslationBase.of(context).weekly), + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.33, + child: Center( + child: Texts(TranslationBase.of(context).monthlyT), + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.34, + child: Center( + child: Texts(TranslationBase.of(context).yearly), + ), + ), + ], + ), + ), + ), + ), + ], + ); + } + @override + Size get preferredSize => Size(double.maxFinite, 60); +} diff --git a/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart new file mode 100644 index 00000000..8f04d3a0 --- /dev/null +++ b/lib/pages/medical/prescriptions/PrescriptionIDeliveryAddressPage.dart @@ -0,0 +1,337 @@ +import 'dart:async'; + +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/AlHabibMedicalService/add_new_address_Request_Model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/select_location_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:provider/provider.dart'; + +import 'PrescriptionOrderOverveiw.dart'; + +class PrescriptionDeliveryAddressPage extends StatefulWidget { + final Prescriptions prescriptions; + final List prescriptionReportList; + final List prescriptionReportEnhList; + + const PrescriptionDeliveryAddressPage( + {Key key, + this.prescriptions, + this.prescriptionReportList, + this.prescriptionReportEnhList}) + : super(key: key); + + @override + _PrescriptionDeliveryAddressPageState createState() => + _PrescriptionDeliveryAddressPageState(); +} + +class _PrescriptionDeliveryAddressPageState + extends State { + AddressInfo _selectedAddress; + Completer _controller = Completer(); + + CameraPosition _kGooglePlex = CameraPosition( + target: LatLng(24.665011045779107, 46.73502189439707), + zoom: 14.4746, + ); + Set markers = new Set(); + double latitude = 0; + double longitude = 0; + + @override + void initState() { + super.initState(); + _getCurrentLocation(); + } + + _getCurrentLocation() async { + await Geolocator.getLastKnownPosition().then((value) { + latitude = value.latitude; + latitude = value.longitude; + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + }).catchError((e) { + latitude = 24.665011045779107; + latitude = 46.73502189439707; + }); + } + + @override + Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + return BaseView( + onModelReady: (model) => model.getCustomerInfo(), + builder: (_, model, w) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).shippingAddresss, + baseViewModel: model, + body: Container( + height: MediaQuery.of(context).size.height * 0.65, + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: 8, + ), + InkWell( + onTap: () { + confirmSelectLocationDialog(model.addressesList); + }, + child: Container( + margin: EdgeInsets.only(left: 10, right: 10, top: 15), + height: 50, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(7), + color: Colors.white, + shape: BoxShape.rectangle, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + child: Text( + getAddressName(), + ), + margin: EdgeInsets.only(left: 10, right: 10), + ), + ), + ), + Icon( + Icons.arrow_drop_down, + size: 22, + color: Colors.grey, + ) + ], + ), + ), + ), + SizedBox( + height: 10, + ), + _selectedAddress == null + ? Container( + child: Image.asset( + projectViewModel.isArabic + ? 'assets/images/pharmacy/shipping_image_ar.png' + : 'assets/images/pharmacy/shipping_image.png', + height: 300, + ), + ) + : Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.grey)), + height: 200, + child: GoogleMap( + mapType: MapType.normal, + markers: markers, + initialCameraPosition: _kGooglePlex, + onMapCreated: + (GoogleMapController controller) { + _controller.complete(controller); + }, + ), + ), + ), + SizedBox( + height: 10, + ), + Texts( + TranslationBase.of(context).shippingAddresss), + SizedBox( + height: 10, + ), + Texts( + '${model.user.firstName} ${model.user.lastName}'), + SizedBox( + height: 10, + ), + Texts(_selectedAddress.address1), + SizedBox( + height: 10, + ), + Texts(_selectedAddress.address2), + SizedBox( + height: 10, + ), + Texts(_selectedAddress.city + + " " + + _selectedAddress.country), + ], + ), + ) + ], + ), + ), + ), + bottomSheet: Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.25, + color: Colors.grey[100], + child: Column( + children: [ + Divider(), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Button( + label: + TranslationBase.of(context).addNewAddress.toUpperCase(), + onTap: () { + Navigator.push( + context, + FadePage( + page: LocationPage( + latitude: latitude, + longitude: longitude, + )), + ).then((value) { + if (value != null && + value is AddNewAddressRequestModel) { + setState(() { + _selectedAddress = AddressInfo( + id: value.customer.id.toString(), + email: value.customer.email, + firstName: value.customer.addresses[0].firstName, + lastName: value.customer.addresses[0].lastName, + address1: value.customer.addresses[0].address1, + address2: value.customer.addresses[0].address2, + city: value.customer.addresses[0].city, + country: value.customer.addresses[0].country, + phoneNumber: value.customer.addresses[0].phoneNumber, + latLong: value.customer.addresses[0].latLong, + company: value.customer.addresses[0].company, + countryId: value.customer.addresses[0].countryId, + createdOnUtc: value.customer.addresses[0].createdOnUtc, + customerAttributes: value.customer.addresses[0].customerAttributes, + faxNumber: value.customer.addresses[0].faxNumber, + province: value.customer.addresses[0].province, + stateProvinceId: value.customer.addresses[0].stateProvinceId, + zipPostalCode: value.customer.addresses[0].zipPostalCode, + + ); + List latLongArr = _selectedAddress.latLong.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + markers = Set(); + markers.add( + Marker( + markerId: MarkerId( + _selectedAddress.latLong.hashCode.toString(), + ), + position: LatLng(latitude, longitude), + ), + ); + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + }); + } + }); + }, + ), + ), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: Button( + label: + TranslationBase.of(context).continues.toUpperCase(), + disabled: _selectedAddress == null, + backgroundColor: _selectedAddress == null + ? Colors.green[300] + : Colors.green[700], + onTap: () { + Navigator.push( + context, + FadePage( + page: PrescriptionOrderOverview( + latitude: latitude, + longitude: longitude, + prescriptionReportEnhList: + widget.prescriptionReportEnhList, + prescriptionReportList: + widget.prescriptionReportList, + prescriptions: widget.prescriptions, + selectedAddress: _selectedAddress, + ), + ), + ); + }, + )) + ], + ), + )), + ); + } + + void confirmSelectLocationDialog( + List addresses, + ) { + showDialog( + context: context, + child: SelectLocationDialog( + addresses: addresses, + selectedAddress: _selectedAddress, + onValueSelected: (value) { + setState(() { + _selectedAddress = value; + List latLongArr = value.latLong.split(','); + + latitude = double.parse(latLongArr[0]); + longitude = double.parse(latLongArr[1]); + markers = Set(); + markers.add( + Marker( + markerId: MarkerId( + _selectedAddress.latLong.hashCode.toString(), + ), + position: LatLng(latitude, longitude), + ), + ); + _kGooglePlex = CameraPosition( + target: LatLng(latitude, longitude), + zoom: 14.4746, + ); + }); + }, + ), + ); + } + + String getAddressName() { + if (_selectedAddress != null) + return _selectedAddress.address1; + else + return TranslationBase.of(context).selectAddress; + } +} diff --git a/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart new file mode 100644 index 00000000..bad43a02 --- /dev/null +++ b/lib/pages/medical/prescriptions/PrescriptionOrderOverveiw.dart @@ -0,0 +1,203 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/Prescriptions.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report_enh.dart'; +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.dart'; +import 'package:diplomaticquarterapp/core/viewModels/medical/PrescriptionDeliveryViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/ConfirmWithMessageDialog.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class PrescriptionOrderOverview extends StatelessWidget { + final Prescriptions prescriptions; + final List prescriptionReportList; + final List prescriptionReportEnhList; + final AddressInfo selectedAddress; + final double latitude; + final double longitude; + PrescriptionOrderOverview( + {Key key, + this.prescriptions, + this.prescriptionReportList, + this.prescriptionReportEnhList, this.selectedAddress, this.latitude, this.longitude}); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (_, model, widget) => AppScaffold( + isShowAppBar: true, + appBarTitle: TranslationBase.of(context).orderOverview, + baseViewModel: model, + body: Container( + height: MediaQuery.of(context).size.height * 0.8, + child: Column( + children: [ + if (!prescriptions.isInOutPatient) + ...List.generate( + prescriptionReportList.length, + (index) => Container( + width: double.infinity, + margin: EdgeInsets.only(top: 10, left: 10, right: 10), + padding: EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all( + Radius.circular(10.0), + ), + border: + Border.all(color: Colors.grey[200], width: 0.5), + ), + child: Row( + children: [ + ClipRRect( + borderRadius: + BorderRadius.all(Radius.circular(5)), + child: Image.network( + prescriptionReportList[index].imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 70, + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Texts(prescriptionReportList[index] + .itemDescription + .isNotEmpty + ? prescriptionReportList[index] + .itemDescription + : prescriptionReportList[index] + .itemDescriptionN)), + )), + Icon( + Icons.arrow_forward_ios, + size: 18, + color: Colors.grey[500], + ) + ], + ), + )) + else + ...List.generate( + prescriptionReportEnhList.length, + (index) => Container( + margin: EdgeInsets.all(8.0), + color: Colors.white, + child: Row( + children: [ + ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5)), + child: Image.network( + prescriptionReportEnhList[index].imageSRCUrl, + fit: BoxFit.cover, + width: 60, + height: 70, + ), + ), + SizedBox( + width: 10, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts(prescriptionReportEnhList[index] + .itemDescription), + ], + ), + ), + ), + Icon( + Icons.arrow_forward_ios, + size: 18, + color: Colors.grey[500], + ) + ], + ), + ), + ) + ], + ), + ), + bottomSheet: Container( + width: double.infinity, + height: MediaQuery.of(context).size.height * 0.15, + color: Colors.grey[100], + child: Column( + children: [ + SizedBox(height: 12,), + Container( + width: MediaQuery.of(context).size.width * 0.8, + child: SecondaryButton( + label: TranslationBase.of(context).submit.toUpperCase(), + color: Colors.green[800], + onTap: () async { + showDialog( + context: context, + child: ConfirmWithMessageDialog( + message: TranslationBase.of(context).confirmPrescription, + okTitle: TranslationBase.of(context).ok, + onTap: () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.insertDeliveryOrder(lineItemNo: 0, + longitude: longitude, + latitude: latitude,appointmentNo: prescriptions.appointmentNo, + dischargeID: prescriptions.dischargeNo,createdBy: model.user.patientID) + .then((value) { + GifLoaderDialogUtils.hideDialog(context); + if (model.state == ViewState.ErrorLocal) + showErrorDialog(context,model.error); + else + { + Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); + } + + }).catchError((e) { + GifLoaderDialogUtils.hideDialog(context); + }); + }, + ), + ); + + }, + )) + ], + ), + ), + ), + ); + } + + void showErrorDialog(BuildContext context,String error) { + showDialog( + context: context, + child: ConfirmWithMessageDialog( + message: TranslationBase.of(context).youAlreadyHaveOrder, + okTitle: TranslationBase.of(context).orderOverview, + onTap: () { + Navigator.pop(context); + Navigator.pop(context); + Navigator.pop(context); + + }, + ), + ); + + } + +} diff --git a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart index 1b1eaf3f..96227fba 100644 --- a/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart +++ b/lib/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart @@ -20,7 +20,7 @@ class PharmacyForPrescriptionsPage extends StatelessWidget { onModelReady: (model) => model.getListPharmacyForPrescriptions(itemId: prescriptionReport.itemID), builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).ports, + appBarTitle: TranslationBase.of(context).availability, baseViewModel: model, body: ListView.builder( itemBuilder: (context, index) => Container( diff --git a/lib/pages/medical/prescriptions/prescription_details_page.dart b/lib/pages/medical/prescriptions/prescription_details_page.dart index d59bc06d..f40999c2 100644 --- a/lib/pages/medical/prescriptions/prescription_details_page.dart +++ b/lib/pages/medical/prescriptions/prescription_details_page.dart @@ -1,4 +1,6 @@ import 'package:diplomaticquarterapp/core/model/prescriptions/prescription_report.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/MyAppointments/widgets/reminder_dialog.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/pharmacy_for_prescriptions_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -6,6 +8,7 @@ import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; class PrescriptionDetailsPage extends StatelessWidget { final PrescriptionReport prescriptionReport; @@ -59,40 +62,49 @@ class PrescriptionDetailsPage extends StatelessWidget { ), Container( margin: EdgeInsets.all(8), - child: InkWell( - onTap: () => Navigator.push( - context, - FadePage( - page: PharmacyForPrescriptionsPage( - prescriptionReport: prescriptionReport), - ), - ), - child: Center( - child: Column( - children: [ - Container( - width: 50, - decoration: BoxDecoration( - color: Colors.white, shape: BoxShape.rectangle), + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () => Navigator.push( + context, + FadePage( + page: PharmacyForPrescriptionsPage( + prescriptionReport: prescriptionReport), + ), + ), + child: Center( child: Column( children: [ - Icon( - Icons.pin_drop, - color: Colors.red[800], - size: 55, + Container( + width: 50, + decoration: BoxDecoration( + color: Colors.white, + shape: BoxShape.rectangle), + child: Column( + children: [ + Icon( + Icons.pin_drop, + color: Colors.red[800], + size: 55, + ), + ], + ), + ), + SizedBox( + height: 5, ), + Texts(TranslationBase.of(context).availability) ], ), - ), - SizedBox( - height: 5, - ), - Texts(TranslationBase.of(context).ports) - ], - ), - )), + )), + ), + _addReminderButton(context) + ], + ), ), Container( + color: Colors.white, margin: EdgeInsets.only(top: 10, left: 10, right: 10), child: Table( border: TableBorder.symmetric( @@ -106,28 +118,28 @@ class PrescriptionDetailsPage extends StatelessWidget { height: 30, width: double.infinity, child: Center( - child: Texts(TranslationBase.of(context).way))), + child: Texts(TranslationBase.of(context).route, fontSize: 14,))), Container( color: Colors.white, height: 30, width: double.infinity, child: Center( child: - Texts(TranslationBase.of(context).average))), + Texts(TranslationBase.of(context).frequency, fontSize: 14,))), Container( color: Colors.white, - height: 30, width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 4), child: Center( child: Texts( - TranslationBase.of(context).dailyDoses))), + "${TranslationBase.of(context).dailyDoses}", fontSize: 14,))), Container( color: Colors.white, height: 30, width: double.infinity, child: Center( child: - Texts(TranslationBase.of(context).period))), + Texts(TranslationBase.of(context).duration, fontSize: 14,))), ], ), TableRow( @@ -192,4 +204,96 @@ class PrescriptionDetailsPage extends StatelessWidget { ), ); } + + Widget _addReminderButton(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + + return GestureDetector( + onTap: () { + DateTime startDate = DateTime.now(); + DateTime endDate = DateTime(startDate.year, startDate.month, + startDate.day + prescriptionReport.days); + + print(prescriptionReport); + showGeneralDialog( + barrierColor: Colors.black.withOpacity(0.5), + transitionBuilder: (context, a1, a2, widget) { + final curvedValue = + Curves.easeInOutBack.transform(a1.value) - 1.0; + return Transform( + transform: + Matrix4.translationValues(0.0, curvedValue * 200, 0.0), + child: Opacity( + opacity: a1.value, + child: ReminderDialog( + eventId: prescriptionReport.itemID.toString(), + title: "Prescription Reminder", + description: + "${prescriptionReport.itemDescriptionN} ${prescriptionReport.frequencyN} ${prescriptionReport.routeN} ", + startDate: + "/Date(${startDate.millisecondsSinceEpoch}+0300)/", + endDate: "/Date(${endDate.millisecondsSinceEpoch}+0300)/", + location: prescriptionReport.remarks, + ), + ), + ); + }, + transitionDuration: Duration(milliseconds: 500), + barrierDismissible: true, + barrierLabel: '', + context: context, + pageBuilder: (context, animation1, animation2) {}); + }, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Container( + // height: 100.0, + margin: EdgeInsets.all(7.0), + padding: EdgeInsets.only(bottom: 4.0), + decoration: BoxDecoration(boxShadow: [ + BoxShadow( + color: Colors.grey[400], blurRadius: 2.0, spreadRadius: 0.0) + ], borderRadius: BorderRadius.circular(10), color: Colors.white), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.max, + children: [ + Container( + margin: EdgeInsets.fromLTRB(5.0, 5.0, 5.0, 0.0), + child: Text("add", + overflow: TextOverflow.clip, + style: TextStyle( + color: new Color(0xffB8382C), + letterSpacing: 1.0, + fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.fromLTRB(5.0, 0.0, 5.0, 0.0), + child: Text("reminder", + overflow: TextOverflow.clip, + style: TextStyle( + color: Colors.black, + letterSpacing: 1.0, + fontSize: 15.0)), + ), + Container( + alignment: projectViewModel.isArabic + ? Alignment.bottomLeft + : Alignment.bottomRight, + margin: projectViewModel.isArabic + ? EdgeInsets.fromLTRB(10.0, 7.0, 0.0, 8.0) + : EdgeInsets.fromLTRB(0.0, 7.0, 10.0, 8.0), + child: Image.asset( + "assets/images/new-design/reminder_icon.png", + width: 45.0, + height: 45.0), + ), + ], + ), + ), + ], + ), + ); + } } diff --git a/lib/pages/medical/prescriptions/prescription_items_page.dart b/lib/pages/medical/prescriptions/prescription_items_page.dart index 6fb07f68..c6581493 100644 --- a/lib/pages/medical/prescriptions/prescription_items_page.dart +++ b/lib/pages/medical/prescriptions/prescription_items_page.dart @@ -7,6 +7,7 @@ import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescription_details_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; @@ -14,12 +15,13 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../../widgets/dialogs/confirm_send_email_dialog.dart'; +import 'PrescriptionIDeliveryAddressPage.dart'; class PrescriptionItemsPage extends StatelessWidget { final Prescriptions prescriptions; PrescriptionItemsPage({Key key, this.prescriptions}); - + //TODO @override Widget build(BuildContext context) { ProjectViewModel projectViewModel = Provider.of(context); @@ -181,7 +183,7 @@ class PrescriptionItemsPage extends StatelessWidget { ), bottomSheet: Container( width: double.infinity, - height: MediaQuery.of(context).size.height * 0.14, + height: MediaQuery.of(context).size.height * 0.25, color: Colors.grey[100], child: Column( children: [ @@ -197,12 +199,24 @@ class PrescriptionItemsPage extends StatelessWidget { loading: model.state == ViewState.BusyLocal, ), ), - if (false) Container( width: MediaQuery.of(context).size.width * 0.8, child: Button( label: TranslationBase.of(context).resendOrder, - backgroundColor: Colors.green[200], + backgroundColor: Colors.green[800], + onTap: (){ + + Navigator.push( + context, + FadePage( + page: PrescriptionDeliveryAddressPage( + prescriptions: prescriptions, + prescriptionReportList: model.prescriptionReportList, + prescriptionReportEnhList: model.prescriptionReportEnhList, + ), + ), + ); + }, )) ], ), diff --git a/lib/pages/medical/prescriptions/prescriptions_home_page.dart b/lib/pages/medical/prescriptions/prescriptions_home_page.dart index 96d4aba0..380d6284 100644 --- a/lib/pages/medical/prescriptions/prescriptions_home_page.dart +++ b/lib/pages/medical/prescriptions/prescriptions_home_page.dart @@ -71,12 +71,12 @@ class _HomePrescriptionsPageState extends State child: Container( height: 60.0, margin: EdgeInsets.only(top: 10.0), - width: MediaQuery.of(context).size.width * 0.9, + width: MediaQuery.of(context).size.width * 0.92, decoration: BoxDecoration( border: Border( bottom: BorderSide( color: Theme.of(context).dividerColor, - width: 0.7), + width: 0.9), //width: 0.7 ), color: Colors.white), child: Center( @@ -84,10 +84,10 @@ class _HomePrescriptionsPageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, labelColor: Theme.of(context).primaryColor, labelPadding: - EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), + EdgeInsets.only(top: 4.0, left: 35.0, right: 35.0), unselectedLabelColor: Colors.grey[800], tabs: [ Container( diff --git a/lib/pages/medical/reports/monthly_reports.dart b/lib/pages/medical/reports/monthly_reports.dart index ae9cc295..4484bd5f 100644 --- a/lib/pages/medical/reports/monthly_reports.dart +++ b/lib/pages/medical/reports/monthly_reports.dart @@ -2,10 +2,12 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/medical/reports_monthly_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/medical/reports/user_agreement_page.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/input/custom_switch.dart'; +import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; @@ -19,6 +21,8 @@ class MonthlyReportsPage extends StatefulWidget { class _MonthlyReportsPageState extends State { bool isAgree = false; bool isSummary = false; + String email = ""; + final formKey = GlobalKey(); @override Widget build(BuildContext context) { @@ -29,135 +33,161 @@ class _MonthlyReportsPageState extends State { body: SingleChildScrollView( child: Container( padding: EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: EdgeInsets.all(9), - height: 55, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.all(Radius.circular(8)), - shape: BoxShape.rectangle, - border: Border.all(color: Colors.grey)), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).patientHealthSummaryReport, - bold: true, - ), - CustomSwitch( - value: isSummary, - activeColor: Colors.red, - inactiveColor: Colors.grey, - onChanged: () async { - setState(() { - isSummary = !isSummary; - }); - }, - ) - ], + child: Form( + key: formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.all(9), + height: 55, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.all(Radius.circular(8)), + shape: BoxShape.rectangle, + border: Border.all(color: Colors.grey)), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + + Texts( + TranslationBase.of(context).patientHealthSummaryReport, + bold: true, + ), + CustomSwitch( + value: isSummary, + activeColor: Colors.red, + inactiveColor: Colors.grey, + onChanged: () async { + setState(() { + isSummary = !isSummary; + }); + if(!isSummary) { + GifLoaderDialogUtils.showMyDialog(context); + await model.updatePatientHealthSummaryReport( + message: TranslationBase + .of(context) + .updateSuccessfully, isSummary: isSummary); + GifLoaderDialogUtils.hideDialog(context); + } + }, + ) + ], + ), ), - ), - SizedBox( - height: 15, - ), - Container( - margin: EdgeInsets.all(8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Texts( - model.user.emailAddress, - bold: true, - ), - ], + SizedBox( + height: 15, ), - ), - Divider( - height: 10.4, - thickness: 1.0, - ), - SizedBox( - height: 15, - ), - Container( - margin: EdgeInsets.all(8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + Container( + margin: EdgeInsets.all(8), + child: TextFields( + fillColor: Colors.red, + hintText: 'email@email.com', + fontSize: 20, + initialValue: model.user.emailAddress, + fontWeight: FontWeight.w600, + onChanged: (text) { + email = text; + }, + validator: (value) { + if (value.isEmpty) + return TranslationBase.of(context).enterEmail; + else + return null; + }, + ), + ), + Divider( + height: 10.4, + thickness: 1.0, + ), + SizedBox( + height: 15, + ), + Container( + margin: EdgeInsets.all(8), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Expanded( + child: Texts(TranslationBase.of(context) + .toViewTheTermsAndConditions), + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: UserAgreementContent(), + ), + ); + }, + child: Texts( + TranslationBase.of(context).clickHere, + color: Colors.blue, + ), + ) + ], + ), + ), + SizedBox( + height: 5, + ), + Row( crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, children: [ - Expanded( - child: Texts(TranslationBase.of(context) - .toViewTheTermsAndConditions), - ), - InkWell( - onTap: () { - Navigator.push( - context, - FadePage( - page: UserAgreementContent(), - ), - ); + Checkbox( + value: isAgree, + onChanged: (value) { + setState(() { + isAgree = !isAgree; + }); }, - child: Texts( - TranslationBase.of(context).clickHere, - color: Colors.blue, - ), - ) + activeColor: Colors.red, + ), + Texts(TranslationBase.of(context).iAgreeToTheTermsAndConditions), ], ), - ), - SizedBox( - height: 5, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Checkbox( - value: isAgree, - onChanged: (value) { - setState(() { - isAgree = !isAgree; - }); + Container( + margin: EdgeInsets.all(8), + width: double.infinity, + child: SecondaryButton( + textColor: Colors.white, + label: TranslationBase.of(context).save, + disabled: (!isAgree || !isSummary ), + onTap: () async { + final form = formKey.currentState; + if (form.validate()) { + GifLoaderDialogUtils.showMyDialog(context); + await model.updatePatientHealthSummaryReport( + message: TranslationBase + .of(context) + .updateSuccessfully, + isSummary: isSummary, + isUpdateEmail: true, + email: email.isNotEmpty ? email : model.user + .emailAddress); + GifLoaderDialogUtils.hideDialog(context); + } }, - activeColor: Colors.red, ), - Texts(TranslationBase.of(context) - .iAgreeToTheTermsAndConditions), - ], - ), - Container( - margin: EdgeInsets.all(8), - width: double.infinity, - child: SecondaryButton( - textColor: Colors.white, - label: TranslationBase.of(context).save, - disabled: !isAgree, - loading: model.state == ViewState.BusyLocal, - onTap: () { - model.updatePatientHealthSummaryReport( - message: TranslationBase.of(context) - .updateSuccessfully, - isSummary: isSummary); - }, ), - ), - Padding( - padding: const EdgeInsets.all(5.0), - child: Texts( - TranslationBase.of(context) - .iAgreeToTheTermsAndConditionsSubtitle, - fontWeight: FontWeight.normal, + Padding( + padding: const EdgeInsets.all(5.0), + child: Texts( + TranslationBase.of(context) + .instructionAgree, + fontWeight: FontWeight.normal, + ), + ), + SizedBox( + height: 12, ), - ), - SizedBox( - height: 12, - ), - Center(child: Image.asset('assets/images/report.jpg')) - ], + Center(child: Image.asset('assets/images/report.jpg')) + ], + ), ), ), ), diff --git a/lib/pages/medical/reports/report_home_page.dart b/lib/pages/medical/reports/report_home_page.dart index d3c818ff..f9efb1a1 100644 --- a/lib/pages/medical/reports/report_home_page.dart +++ b/lib/pages/medical/reports/report_home_page.dart @@ -101,31 +101,31 @@ class _HomeReportPageState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.label, + indicatorSize: TabBarIndicatorSize.tab, labelColor: Theme.of(context).primaryColor, unselectedLabelColor: Colors.grey[800], tabs: [ Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).requested,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).ready,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).completed,fontSize: 11,), ), ), Container( - width: MediaQuery.of(context).size.width * 0.15, + width: MediaQuery.of(context).size.width * 0.20, child: Center( child: Texts(TranslationBase.of(context).cancelled,fontSize: 11,), diff --git a/lib/pages/medical/reports/reports_page.dart b/lib/pages/medical/reports/reports_page.dart index d8cb2ca0..11d5fc82 100644 --- a/lib/pages/medical/reports/reports_page.dart +++ b/lib/pages/medical/reports/reports_page.dart @@ -48,16 +48,13 @@ class MedicalReports extends StatelessWidget { )), child: Row( children: [ - Expanded( - flex: 1, - child: Container( - margin: EdgeInsets.only(left: 5, right: 5), - child: LargeAvatar( - width: 50, - height: 50, - name: model.appointHistoryList[index].doctorNameObj, - url: model.appointHistoryList[index].doctorImageURL, - ), + Container( + margin: EdgeInsets.only(left: 5, right: 5), + child: LargeAvatar( + width: 50, + height: 50, + name: model.appointHistoryList[index].doctorNameObj, + url: model.appointHistoryList[index].doctorImageURL, ), ), Expanded( @@ -85,29 +82,26 @@ class MedicalReports extends StatelessWidget { ), ), ), - Expanded( - flex: 1, - child: InkWell( - onTap: () => - confirmBox(model.appointHistoryList[index], model), - child: Container( - width: 85, - height: 50, - decoration: BoxDecoration( - color: Colors.black54, - border: - Border.all(color: Colors.transparent, width: 2), - shape: BoxShape.rectangle, - borderRadius: BorderRadius.all( - Radius.circular(8.0), - ), + InkWell( + onTap: () => + confirmBox(model.appointHistoryList[index], model), + child: Container( + width: 120, + height: 50, + decoration: BoxDecoration( + color: Colors.black54, + border: + Border.all(color: Colors.transparent, width: 2), + shape: BoxShape.rectangle, + borderRadius: BorderRadius.all( + Radius.circular(8.0), ), - child: Center( - child: Texts( - TranslationBase.of(context).requestReport, - fontSize: 12, - color: Colors.white, - ), + ), + child: Center( + child: Texts( + TranslationBase.of(context).requestReport, + fontSize: 12, + color: Colors.white, ), ), ), diff --git a/lib/pages/medical/smart_watch_health_data/health_data_list.dart b/lib/pages/medical/smart_watch_health_data/health_data_list.dart index 2f9a3e60..ea8746e9 100644 --- a/lib/pages/medical/smart_watch_health_data/health_data_list.dart +++ b/lib/pages/medical/smart_watch_health_data/health_data_list.dart @@ -1,5 +1,8 @@ +import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/stepsTracker.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +// import 'package:fit_kit/fit_kit.dart'; import 'package:flutter/material.dart'; class HealthDataList extends StatefulWidget { @@ -8,13 +11,30 @@ class HealthDataList extends StatefulWidget { } class _HealthDataListState extends State { + + // List dataTypes = List(); + + @override + void initState() { + // dataTypes.add(DataType.DISTANCE); + // dataTypes.add(DataType.STEP_COUNT); + // dataTypes.add(DataType.HEART_RATE); + // dataTypes.add(DataType.SLEEP); + // dataTypes.add(DataType.ENERGY); + + super.initState(); + } + @override Widget build(BuildContext context) { return AppScaffold( appBarTitle: "Smartwatches", isShowAppBar: true, body: Container( - height: MediaQuery.of(context).size.height, + height: MediaQuery + .of(context) + .size + .height, margin: EdgeInsets.all(20.0), child: SingleChildScrollView( child: Column( @@ -58,21 +78,31 @@ class _HealthDataListState extends State { Divider( color: Colors.grey[500], ), - Row( - children: [ - Container( - child: Image.asset( - "assets/images/SmartWatches/heartrate_icon.png", - width: 60.0, - height: 60.0), - ), - Container( - margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), - child: Text("Steps", - style: TextStyle( - fontSize: 20.0, fontWeight: FontWeight.bold)), - ), - ], + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: StepsTracker(), + ), + ); + }, + child: Row( + children: [ + Container( + child: Image.asset( + "assets/images/SmartWatches/heartrate_icon.png", + width: 60.0, + height: 60.0), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 0.0), + child: Text("Steps", + style: TextStyle( + fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), ), Divider( color: Colors.grey[500], @@ -121,25 +151,68 @@ class _HealthDataListState extends State { ), bottomSheet: Container( width: double.infinity, - height: MediaQuery.of(context).size.height * 0.1, + height: MediaQuery + .of(context) + .size + .height * 0.1, color: Colors.grey[100], child: Column( children: [ Divider( color: Colors.transparent, ), - Container( - width: MediaQuery.of(context).size.width * 0.8, - child: Button( - onTap: () { -// launch(model.radImageURL); - }, - label: 'Sync Health Data', - backgroundColor: Colors.grey[800], - ), - ), + InkWell( + onTap: () { + print("ReadLast"); + // readLast(); + }, + child:Container( + height: (MediaQuery + .of(context) + .size + .height/2)*0.12, + width: MediaQuery + .of(context) + .size + .width * 0.8, + decoration: BoxDecoration( + color: Colors.grey[800], + borderRadius: BorderRadius.circular(6.0), + ), + child: Container( + padding: EdgeInsets.only(top: 10.0), + child: Text( + 'Sync Health Data' , textAlign: TextAlign.center,style: TextStyle( + color: Colors.white , fontSize: 18.0 + ), + ), + ),),), ], ), )); } -} + + + // void readLast() async { + // print("ReadLast"); + // final result = await FitKit.readLast(DataType.DISTANCE); + // print(result); + // print(result); + // } + // + // void readAll() async { + // if (await FitKit.requestPermissions(dataTypes)) { + // for (DataType type in dataTypes) { + // final results = await FitKit.read( + // type, + // dateFrom: DateTime.now().subtract(Duration(days: 7)), + // dateTo: DateTime.now(), + // limit: 100, + // ); + // print(results); + // print(results.length); + // } + // readLast(); + // } + // } +} \ No newline at end of file diff --git a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart index eb0c1675..977b99df 100644 --- a/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart +++ b/lib/pages/medical/smart_watch_health_data/smart_watch_instructions.dart @@ -3,9 +3,10 @@ import 'dart:io'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/health_data_list.dart'; import 'package:diplomaticquarterapp/services/smartwatch_integration/SmartWatchIntegrationService.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:smart_progress_bar/smart_progress_bar.dart'; import 'package:url_launcher/url_launcher.dart'; class SmartWatchInstructions extends StatefulWidget { @@ -88,8 +89,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 1", + "Apple Watch Series 1", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -108,8 +110,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 2", + "Apple Watch Series 2", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -135,8 +138,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 3", + "Apple Watch Series 3", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -155,8 +159,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 4", + "Apple Watch Series 4", overflow: TextOverflow.clip , style: TextStyle( fontSize: 12.0)), ) @@ -182,8 +187,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 5", + "Apple Watch Series 5", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -202,8 +208,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Apple Watch Series 6", + "Apple Watch Series 6", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -229,7 +236,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Mi Band 3", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -248,7 +256,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Mi Band 4", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -417,9 +426,9 @@ class _SmartWatchInstructionsState extends State { child: CarouselSlider( carouselController: buttonCarouselController, options: CarouselOptions( - enableInfiniteScroll: false, - viewportFraction: 0.95, - height: MediaQuery.of(context).size.height * 0.9), + // enableInfiniteScroll: true, + viewportFraction: 0.99, + height: MediaQuery.of(context).size.height*1.02 ), items: [1, 2].map((i) { return Builder( builder: (BuildContext context) { @@ -427,7 +436,8 @@ class _SmartWatchInstructionsState extends State { width: MediaQuery.of(context).size.width, margin: EdgeInsets.symmetric(horizontal: 5.0), child: Card( - margin: EdgeInsets.fromLTRB(8.0, 16.0, 8.0, 8.0), + margin: EdgeInsets.only(top:16.0 , bottom: 8.0), + // fromLTRB(8.0, 16.0, 8.0, 8.0), color: Colors.white.withOpacity(1.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), @@ -457,8 +467,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "Huawei Watch 2", + "Huawei Watch 2", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -477,8 +488,10 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( "Mobovi TicWatch E2", + overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -504,7 +517,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Huawei Watch", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Huawei Watch", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -523,7 +537,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Fossil Sport", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Fossil Sport", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -549,8 +564,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "MisFit Vapor 2", + "MisFit Vapor 2", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -569,8 +585,9 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( + width: MediaQuery.of(context).size.width*0.22, child: Text( - "LG Watch Sport", + "LG Watch Sport", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -596,7 +613,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Mi Band 3", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Mi Band 3", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -615,7 +633,8 @@ class _SmartWatchInstructionsState extends State { width: 70.0, height: 70.0), Container( - child: Text("Mi Band 4", + width: MediaQuery.of(context).size.width*0.22, + child: Text("Mi Band 4", overflow: TextOverflow.clip, style: TextStyle( fontSize: 12.0)), ) @@ -735,7 +754,7 @@ class _SmartWatchInstructionsState extends State { ), Container( margin: EdgeInsets.fromLTRB( - 15.0, 95.0, 15.0, 15.0), + 15.0, 75.0, 15.0, 15.0), child: ButtonTheme( shape: RoundedRectangleBorder( borderRadius: @@ -796,7 +815,9 @@ class _SmartWatchInstructionsState extends State { getLastPatientRecord(BuildContext context) { SmartWatchIntegrationService service = new SmartWatchIntegrationService(); + GifLoaderDialogUtils.showMyDialog(context); service.getLastPatientRecord(context).then((res) { + GifLoaderDialogUtils.hideDialog(context); if (res['MessageStatus'] == 1) { print(res['Med_GetPatientLastRecordList']); setState(() { @@ -807,9 +828,9 @@ class _SmartWatchInstructionsState extends State { }); } else {} }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); print(err); - }).showProgressBar( - text: "Loading", backgroundColor: Colors.blue.withOpacity(0.6)); + }); } _openHealthDataList() { diff --git a/lib/pages/medical/smart_watch_health_data/stepsTracker.dart b/lib/pages/medical/smart_watch_health_data/stepsTracker.dart new file mode 100644 index 00000000..3fe1a4ba --- /dev/null +++ b/lib/pages/medical/smart_watch_health_data/stepsTracker.dart @@ -0,0 +1,249 @@ +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:diplomaticquarterapp/models/SmartWatch/YearlyStepsResModel.dart'; +import 'package:diplomaticquarterapp/services/appointment_services/GetDoctorsList.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; + +class StepsTracker extends StatefulWidget { + @override + _StepsTrackerState createState() => _StepsTrackerState(); +} + +class _StepsTrackerState extends State + with SingleTickerProviderStateMixin { + TabController _tabController; + + int weeklyStatsAvgValue = 0; + int monthlyStatsAvgValue = 0; + int yearlyStatsAvgValue = 0; + + int avgStepsValue = 0; + int dataLength = 0; + + List yearlyStepsList = List(); + + List yearlyTimeSeriesData = []; + + bool isDataLoaded = false; + + @override + void initState() { + _tabController = new TabController(length: 3, vsync: this); + WidgetsBinding.instance.addPostFrameCallback((_) { + getYearlyStepsData(); + }); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + isShowAppBar: true, + appBarTitle: "Steps", + isShowDecPage: false, + body: Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TabBar( + tabs: [ + Tab(text: TranslationBase.of(context).weekly), + Tab(text: TranslationBase.of(context).monthly), + Tab(text: TranslationBase.of(context).yearly), + ], + controller: _tabController, + ), + Expanded( + child: new TabBarView( + physics: NeverScrollableScrollPhysics(), + children: [ + isDataLoaded ? getWeeklyStepsDetails() : Container(), + isDataLoaded ? getMonthlyStepsDetails() : Container(), + isDataLoaded ? getYearlyStepsDetails() : Container() + ], + controller: _tabController, + ), + ), + ], + ), + ), + ); + } + + getYearlyStepsData() { + avgStepsValue = 0; + dataLength = 0; + + DoctorsListService service = new DoctorsListService(); + GifLoaderDialogUtils.showMyDialog(context); + service.getPatientHealthDataStats(6, 3, context).then((res) { + GifLoaderDialogUtils.hideDialog(context); + print(res['Med_GetYearStepsTransactionsStsList']); + yearlyStepsList.clear(); + res['Med_GetYearStepsTransactionsStsList'].forEach((element) { + print('in forEach'); + yearlyStepsList.add(new YearlyStepsResModel.fromJson(element)); + if (element['ValueSum'] != null) { + double value = element['ValueSum']; + avgStepsValue += value.toInt(); + dataLength++; + } + }); + print("innnnnnnnnnnnnnnnn"); + print(avgStepsValue); + print(dataLength); + setState(() { + yearlyStatsAvgValue = avgStepsValue ~/ dataLength; + isDataLoaded = true; + }); + }).catchError((err) { + GifLoaderDialogUtils.hideDialog(context); + // AppToast.showErrorToast(message: err); + print(err); + }); + } + + generateData() { + if (yearlyStepsList.length > 0) { + yearlyTimeSeriesData.clear(); + yearlyStepsList.forEach( + (element) { + yearlyTimeSeriesData.add( + TimeSeriesSales( + new DateTime(element.year, element.month, 1), + element.valueSum != null ? element.valueSum.toInt() : 0, + ), + ); + }, + ); + yearlyTimeSeriesData.forEach((element) { + print(element.sales); + print(element.time); + }); + } + return [ + new charts.Series( + id: 'Sales', + colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, + domainFn: (TimeSeriesSales sales, _) => sales.time, + measureFn: (TimeSeriesSales sales, _) => sales.sales, + data: yearlyTimeSeriesData, + ) + ]; + } + + getWeeklyStepsDetails() { + return Container( + child: Text("Weekly"), + ); + } + + getMonthlyStepsDetails() { + return Container( + child: Text("Monthly"), + ); + } + + getYearlyStepsDetails() { + return Container( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + child: AppTimeSeriesChart( + seriesList: generateData(), + chartName: "Steps", + startDate: DateTime( + yearlyStepsList[0].year, yearlyStepsList[0].month, 1), + endDate: DateTime( + yearlyStepsList[yearlyStepsList.length - 1].year, + yearlyStepsList[yearlyStepsList.length - 1].month, + 1), + ), + ), + Container( + margin: EdgeInsets.only(top: 5.0), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.grey[400], width: 0.6)), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + child: + Text("Average Steps", style: TextStyle(fontSize: 18.0)), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0), + child: Text(yearlyStatsAvgValue.toString() + " Steps", + style: TextStyle( + fontSize: 20.0, fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + Container( + margin: EdgeInsets.all(10.0), + child: Divider( + color: Colors.grey[500], + ), + ), + Container( + transform: Matrix4.translationValues(0.0, -10.0, 0.0), + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 5.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("History", style: TextStyle(fontSize: 14.0)), + Row( + children: [ + Text("view more", style: TextStyle(fontSize: 14.0)), + Container( + margin: EdgeInsets.only(left: 3.0, right: 3.0), + transform: Matrix4.translationValues(0.0, 1.5, 0.0), + width: 30.0, + height: 30.0, + child: Image.asset( + "assets/images/new-design/view_more.png", + fit: BoxFit.contain), + ), + ], + ), + ], + ), + ), + Container( + margin: EdgeInsets.fromLTRB(20.0, 0.0, 20.0, 5.0), + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + side: BorderSide(color: Colors.grey[400], width: 0.6)), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Container( + padding: EdgeInsets.fromLTRB(30.0, 15.0, 30.0, 15.0), + child: Text("Date", + style: TextStyle( + fontSize: 18.0, fontWeight: FontWeight.bold)), + ), + Container( + padding: EdgeInsets.fromLTRB(30.0, 0.0, 30.0, 0.0), + child: Text("Steps", style: TextStyle(fontSize: 18.0)), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/medical/vital_sign/LineChartCurved.dart b/lib/pages/medical/vital_sign/LineChartCurved.dart index 7b7449a8..fe112767 100644 --- a/lib/pages/medical/vital_sign/LineChartCurved.dart +++ b/lib/pages/medical/vital_sign/LineChartCurved.dart @@ -2,6 +2,8 @@ import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; +import '../../../Constants.dart'; + class LineChartCurved extends StatelessWidget { final String title; final List timeSeries; @@ -12,10 +14,18 @@ class LineChartCurved extends StatelessWidget { List xAxixs = List(); List yAxixs = List(); + double minY = 0; + double maxY = 0; + + double minX = 0; + double maxX = 0; + double increasingY = 0; + @override Widget build(BuildContext context) { getXaxix(); getYaxix(); + calculateMaxAndMin(); return AspectRatio( aspectRatio: 1.1, child: Container( @@ -68,10 +78,18 @@ class LineChartCurved extends StatelessWidget { } } } + getYaxix() { - int indexess= (timeSeries.length*0.30).toInt(); + // int indexess= (timeSeries.length*0.30).toInt(); + // for (int index = 0; index < timeSeries.length; index++) { + // int mIndex = indexess * index; + // if (mIndex < timeSeries.length) { + // yAxixs.add(timeSeries[mIndex].sales); + // } + // } + for (int index = 0; index < timeSeries.length; index++) { - int mIndex = indexess * index; + int mIndex = indexes * index; if (mIndex < timeSeries.length) { yAxixs.add(timeSeries[mIndex].sales); } @@ -98,7 +116,6 @@ class LineChartCurved extends StatelessWidget { fontSize: 10, ), rotateAngle:-65, - //rotateAngle:-65, margin: 22, getTitles: (value) { if (timeSeries.length < 15) { @@ -126,18 +143,18 @@ class LineChartCurved extends StatelessWidget { fontSize: 10, ), getTitles: (value) { - // if (timeSeries.length < 10) { - // return '${value.toInt()}'; - // } else { - // if (value == getMinY()) - // return '${value.toInt()}'; - // if (value == getMaxY()) - // return '${value.toInt()}'; - // if (yAxixs.contains(value)) { - // return '${value.toInt()}'; - // } - // return ''; - // } + if (timeSeries.length < 15) { + return '${value.toInt()}'; + } else { + if (value == minY) + return '${value.toInt()}'; + if (value == getMaxY()) + return '${value.toInt()}'; + //if (yAxixs.contains(value)) { + return '${value.toInt()}'; + + return ''; + } return '${value.toInt()}'; }, margin: 12, @@ -161,31 +178,55 @@ class LineChartCurved extends StatelessWidget { ), ), ), - minX: 0, - maxX: (timeSeries.length - 1).toDouble(), - maxY: getMaxY()+0.3, - minY: getMinY(), + minX: minX, + maxX: maxX, + maxY: maxY, + minY: minY, lineBarsData: getData(context), ); } + calculateMaxAndMin(){ + getMaxY(); + getMaxX(); + getMin(); + getMinY(); + increasingY = ((maxY-minY)/timeSeries.length - 1)*15; + maxY += increasingY.abs(); + minY -= increasingY.abs(); + } + double getMaxY() { - double max = 0; + maxY = 0; + timeSeries.forEach((element) { + double resultValueDouble = element.sales; + if (resultValueDouble > maxY) maxY = resultValueDouble; + }); + + return maxY.roundToDouble() ; + } + + getMaxX(){ + maxX = (timeSeries.length - 1).toDouble(); + } + + double getMin(){ + minX = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; - if (resultValueDouble > max) max = resultValueDouble; + if (resultValueDouble < minX) minX = resultValueDouble; }); - return max.roundToDouble() ; + return minX.roundToDouble() ; } double getMinY() { - double min = timeSeries[0].sales; + minY = 0; timeSeries.forEach((element) { double resultValueDouble = element.sales; - if (resultValueDouble < min) min = resultValueDouble; + if (resultValueDouble < minY) minY = resultValueDouble; }); - int value = min.toInt(); + int value = minY.toInt(); return value.toDouble(); } @@ -199,8 +240,8 @@ class LineChartCurved extends StatelessWidget { final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [Theme.of(context).primaryColor], - barWidth: 5, + colors: [secondaryColor], + barWidth: 3, isStrokeCapRound: true, dotData: FlDotData( show: false, diff --git a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart index e8cb8b24..2d95f08c 100644 --- a/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart +++ b/lib/pages/medical/vital_sign/LineChartCurvedBloodPressure.dart @@ -81,7 +81,7 @@ class LineChartCurvedBloodPressure extends StatelessWidget { height: 20, decoration: BoxDecoration( shape: BoxShape.rectangle, - color: Colors.grey), + color: Colors.red), ), SizedBox(width: 5,), Texts(TranslationBase.of(context).diastolicLng) @@ -125,7 +125,6 @@ class LineChartCurvedBloodPressure extends StatelessWidget { fontSize: 10, ), rotateAngle: -65, - //rotateAngle:-65, margin: 22, getTitles: (value) { if (timeSeries1.length < 15) { @@ -178,8 +177,8 @@ class LineChartCurvedBloodPressure extends StatelessWidget { ), minX: 0, maxX: (timeSeries1.length - 1).toDouble(), - maxY: getMaxY() + 0.3, - minY: getMinY(), + maxY: getMaxY() + 15, + minY: getMinY()-15, lineBarsData: getData(context), ); } @@ -228,7 +227,7 @@ class LineChartCurvedBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData1 = LineChartBarData( spots: spots, isCurved: true, - colors: [Theme.of(context).primaryColor], + colors: [Colors.red], barWidth: 5, isStrokeCapRound: true, dotData: FlDotData( @@ -241,7 +240,7 @@ class LineChartCurvedBloodPressure extends StatelessWidget { final LineChartBarData lineChartBarData2 = LineChartBarData( spots: spots2, isCurved: true, - colors: [Colors.grey], + colors: [Theme.of(context).primaryColor], barWidth: 5, isStrokeCapRound: true, dotData: FlDotData( diff --git a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart index 43bc9f0a..b09a579d 100644 --- a/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart +++ b/lib/pages/medical/vital_sign/vital_sing_chart_and_detials.dart @@ -1,5 +1,6 @@ import 'package:diplomaticquarterapp/core/model/vital_sign/vital_sign_res_model.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_wideget.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/widgets/charts/app_time_series_chart.dart'; import 'package:diplomaticquarterapp/widgets/others/app_expandable_notifier.dart'; import 'package:flutter/material.dart'; diff --git a/lib/pages/offers_categorise_page.dart b/lib/pages/offers_categorise_page.dart index 782ea018..f3875d1a 100644 --- a/lib/pages/offers_categorise_page.dart +++ b/lib/pages/offers_categorise_page.dart @@ -34,587 +34,675 @@ class _OffersCategorisePageState extends State { builder: (BuildContext context, OffersCategoriseViewModel model, Widget child) => PharmacyAppScaffold( - appBarTitle: 'Offers', - isShowAppBar: true, - backgroundColor: Colors.white, - isShowDecPage: false, - baseViewModel: model, - body: Container( - //height: MediaQuery.of(context).size.height * 0.57, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: Container( - child: Texts( - 'Categories', - fontWeight: FontWeight.w800, - ), - ), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - //Expanded widget heree if nassery - Container( - height: MediaQuery.of(context).size.height * 0.20, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: model.categorise.length, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.all(8.0), - child: Row( - children: [ - InkWell( - child: Column( - children: [ - Container( - height: 60.0, - width: 65.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors.orange.shade200 - .withOpacity(0.45), - ), - child: Icon( - Icons.apps_sharp, - size: 32.0, - ), - ), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.2, - height: MediaQuery.of(context) - .size - .height * - 0.09, - child: Center( - child: Texts( - model.categorise[index].name, - fontWeight: FontWeight.w600, - fontSize: 13.8, - ), - ), - ), - ], - ), - onTap: () { - model.getOffersProducts( - i: model.categorise[index].id); - String ids = model.categorise[index].id; - - categoriseName = - model.categorise[index].name; - }), - ], - ), - ); - }), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.all(8.0), - child: Texts( - categoriseName, - fontWeight: FontWeight.w800, - ), - ), - Row( + appBarTitle: 'Offers', + isShowAppBar: true, + backgroundColor: Colors.white, + isShowDecPage: false, + baseViewModel: model, + body: model.categorise.length != 0 + ? Container( + //height: MediaQuery.of(context).size.height * 0.57, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Container( - height: 44.0, - child: VerticalDivider( - color: Colors.black45, - thickness: 0.7, - //width: 0.3, - // indent: 0.0, - ), - ), Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: styleIcon, - onTap: () { - setState(() { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } - }); - }, + padding: EdgeInsets.all(10.0), + child: Container( + child: Texts( + 'Categories', + fontWeight: FontWeight.w800, + ), ), ), - ], - ), - ], - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - styleOne == true - ? Expanded( - child: Container( - height: MediaQuery.of(context).size.height * 0.50, - child: GridView.builder( - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 0.85, - ), - itemCount: model.products.length, - itemBuilder: (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: Card( - color: model.products[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - height: 250.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), - ), - color: Colors.white, - ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + //Expanded widget heree if nassery + Container( + height: MediaQuery.of(context).size.height * 0.20, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: model.categorise.length, + itemBuilder: + (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.all(8.0), + child: Row( + children: [ + InkWell( + child: Column( children: [ - if (model.products[index] - .discountName != - null) - RotatedBox( - quarterTurns: 4, - child: Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - right: 5.0, - top: 20.0, - bottom: 5.0, - ), - child: Texts( - 'offer' - .toUpperCase(), - color: Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight.w900, - ), - ), - transform: new Matrix4 - .rotationZ( - 5.837200), - ), - ), Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.products[index] - .images.isNotEmpty - ? model - .products[index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, + height: 60.0, + width: 65.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors + .orange.shade200 + .withOpacity(0.45), + ), + child: Icon( + Icons.apps_sharp, + size: 32.0, ), ), Container( - width: model.products[index] - .rxMessage != - null - ? MediaQuery.of(context) + width: + MediaQuery.of(context) .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), - ), - child: Texts( - model.products[index] - .rxMessage != - null - ? model - .products[index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, + .width * + 0.2, + height: + MediaQuery.of(context) + .size + .height * + 0.09, + child: Center( + child: Texts( + model.categorise[index] + .name, + fontWeight: + FontWeight.w600, + fontSize: 13.8, + ), ), ), ], ), - Container( + onTap: () { + model.getOffersProducts( + i: model + .categorise[index].id); + String ids = + model.categorise[index].id; + + categoriseName = model + .categorise[index].name; + }), + ], + ), + ); + }), + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: EdgeInsets.all(8.0), + child: Texts( + categoriseName, + fontWeight: FontWeight.w800, + ), + ), + Row( + children: [ + Container( + height: 44.0, + child: VerticalDivider( + color: Colors.black45, + thickness: 0.7, + //width: 0.3, + // indent: 0.0, + ), + ), + Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: styleIcon, + onTap: () { + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); + }, + ), + ), + ], + ), + ], + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + styleOne == true + ? Expanded( + child: Container( + height: + MediaQuery.of(context).size.height * + 0.50, + child: GridView.builder( + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 0.85, + ), + itemCount: model.products.length, + itemBuilder: + (BuildContext context, int index) { + return NetworkBaseView( + baseViewModel: model, + child: Card( + color: model.products[index] + .discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, + horizontal: 8, + vertical: 4, ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (model.products[index] - .discountName != - null) + child: Container( + height: 250.0, + decoration: BoxDecoration( + borderRadius: + BorderRadius.only( + topLeft: Radius.circular( + 110.0), + ), + color: Colors.white, + ), + padding: EdgeInsets.symmetric( + horizontal: 0), + width: MediaQuery.of(context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Stack( + children: [ + if (model + .products[ + index] + .discountName != + null) + RotatedBox( + quarterTurns: 4, + child: Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets + .only( + right: 5.0, + top: 20.0, + bottom: 5.0, + ), + child: Texts( + 'offer' + .toUpperCase(), + color: Colors + .red, + fontSize: + 13.0, + fontWeight: + FontWeight + .w900, + ), + ), + transform: new Matrix4 + .rotationZ( + 5.837200), + ), + ), + Container( + margin: EdgeInsets + .fromLTRB(0, 16, + 0, 0), + alignment: Alignment + .center, + child: + Image.network( + model + .products[ + index] + .images + .isNotEmpty + ? model + .products[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), + ), + Container( + width: model + .products[ + index] + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, + padding: + EdgeInsets.all( + 4), + decoration: + BoxDecoration( + color: Color( + 0xffb23838), + borderRadius: BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), + child: Texts( + model + .products[ + index] + .rxMessage != + null + ? model + .products[ + index] + .rxMessage + : "", + color: + Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight + .w400, + ), + ), + ], + ), Container( - width: double.infinity, - height: 22.0, - decoration: - BoxDecoration( - color: - Color(0xff5AB145), + margin: EdgeInsets + .symmetric( + horizontal: 6, + vertical: 0, ), - child: Center( - child: Texts( - model - .products[index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 12.0, - fontWeight: - FontWeight.w700, - ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + if (model + .products[ + index] + .discountName != + null) + Container( + width: double + .infinity, + height: 22.0, + decoration: + BoxDecoration( + color: Color( + 0xff5AB145), + ), + child: Center( + child: Texts( + model + .products[ + index] + .discountName, + regular: + true, + color: Colors + .white, + fontSize: + 12.0, + fontWeight: + FontWeight + .w700, + ), + ), + ), + Texts( + model + .products[ + index] + .name, + regular: true, + fontSize: 12.58, + fontWeight: + FontWeight + .w600, + ), + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: + 4), + child: Texts( + "SAR ${model.products[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model.products[index].approvedRatingSum > + 0 + ? (model.products[index].approvedRatingSum.toDouble() / model.products[index].approvedRatingSum.toDouble()) + .toDouble() + : 0, + forceStars: + true), + Texts( + "(${model.products[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight + .w400, + ) + ], + ), + ], ), ), - Texts( - model - .products[index].name, - regular: true, - fontSize: 12.58, - fontWeight: - FontWeight.w600, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.products[index].price}", - bold: true, - fontSize: 14, + ], + ), + ), + )); + }, + ), + ), + ) + : Expanded( + child: Container( + child: ListView.builder( + itemCount: model.products.length, + itemBuilder: (BuildContext context, + int index) { + return Card( + // color: + // model.products[index].discountName != + // null + // ? Color(0xffFFFF00) + // : Colors.white, + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + if (model + .products[ + index] + .discountName != + null) + Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets + .only( + left: 9.0, + top: 8.0, + right: 10.0, + ), + child: + Container( + color: Colors + .yellow, + height: 25.0, + width: 70.0, + child: Center( + child: + Texts( + 'offer' + .toUpperCase(), + color: Colors + .red, + fontSize: + 13.0, + fontWeight: + FontWeight + .w900, + ), + ), + ), + ), + transform: new Matrix4 + .rotationZ( + 6.15099), + ), + Container( + margin: EdgeInsets + .fromLTRB( + 0, 0, 0, 0), + alignment: Alignment + .center, + child: + Image.network( + model + .products[ + index] + .images + .isNotEmpty + ? model + .products[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), + ), + ], ), - ), - Row( - children: [ - StarRating( - totalAverage: model + Column( + children: [ + Container( + width: model .products[ index] - .approvedRatingSum > - 0 - ? (model.products[index].approvedRatingSum - .toDouble() / - model - .products[index] - .approvedRatingSum - .toDouble()) - .toDouble() + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 : 0, - forceStars: true), - Texts( - "(${model.products[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), - ], - ), - ), - ], - ), - ), - )); - }, - ), - ), - ) - : Expanded( - child: Container( - child: ListView.builder( - itemCount: model.products.length, - itemBuilder: - (BuildContext context, int index) { - return Card( - // color: - // model.products[index].discountName != - // null - // ? Color(0xffFFFF00) - // : Colors.white, - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - if (model.products[index] - .discountName != - null) - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, - ), - child: Container( - color: Colors.yellow, - height: 25.0, - width: 70.0, - child: Center( + padding: + EdgeInsets.all( + 4), + decoration: + BoxDecoration( + color: Color( + 0xffb23838), + borderRadius: BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), child: Texts( - 'offer' - .toUpperCase(), - color: Colors.red, - fontSize: 13.0, + model + .products[ + index] + .rxMessage != + null + ? model + .products[ + index] + .rxMessage + : "", + color: + Colors.white, + regular: true, + fontSize: 10, fontWeight: FontWeight - .w900, + .w400, ), ), - ), + ], ), - transform: - new Matrix4.rotationZ( - 6.15099), - ), - Container( - margin: EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.products[index] - .images.isNotEmpty - ? model - .products[index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), + ], ), - ], - ), - Column( - children: [ Container( - width: model.products[index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), + margin: + EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - child: Texts( - model.products[index] - .rxMessage != - null - ? model - .products[index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + if (model + .products[index] + .discountName != + null) + Container( + width: 250.0, + height: 22.5, + decoration: + BoxDecoration( + color: Color( + 0xff5AB145), + ), + child: Padding( + padding: EdgeInsets + .symmetric( + horizontal: 5.5, + ), + child: Texts( + model + .products[ + index] + .discountName, + regular: true, + color: Colors + .white, + fontSize: 12.0, + fontWeight: + FontWeight + .w700, + ), + ), + ), + SizedBox( + height: 4.0, + ), + Texts( + model.products[index] + .name, + regular: true, + fontSize: 14.0, + fontWeight: + FontWeight.w600, + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: 4), + child: Texts( + "SAR ${model.products[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .products[ + index] + .approvedRatingSum > + 0 + ? (model.products[index].approvedRatingSum.toDouble() / + model.products[index].approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: + true), + Texts( + "(${model.products[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight + .w500, + ) + ], + ), + ], ), ), ], ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - if (model.products[index] - .discountName != - null) - Container( - width: 250.0, - height: 22.5, - decoration: BoxDecoration( - color: Color(0xff5AB145), - ), - child: Padding( - padding: - EdgeInsets.symmetric( - horizontal: 5.5, - ), - child: Texts( - model.products[index] - .discountName, - regular: true, - color: Colors.white, - fontSize: 12.0, - fontWeight: - FontWeight.w700, - ), - ), - ), - SizedBox( - height: 4.0, - ), - Texts( - model.products[index].name, - regular: true, - fontSize: 14.0, - fontWeight: FontWeight.w600, - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.products[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .products[ - index] - .approvedRatingSum > - 0 - ? (model - .products[ - index] - .approvedRatingSum - .toDouble() / - model - .products[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.products[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w500, - ) - ], - ), - ], - ), - ), - ], - ), - ); - }), - ), - ) - ], - ), - ), - )); + ); + }), + ), + ) + ], + ), + ) + : Center( + child: Texts( + "SORRY , there's no listed offers now :(", + color: Colors.green, + )))); } } diff --git a/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart new file mode 100644 index 00000000..76688606 --- /dev/null +++ b/lib/pages/packages_offers/ClinicOfferAndPackagesPage.dart @@ -0,0 +1,108 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.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/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; + +import 'CreateCustomerDailogPage.dart'; + +dynamic languageID; + +class ClinicPackagesPage extends StatefulWidget { + List products; + ClinicPackagesPage({@required this.products}); + + @override + _ClinicPackagesPageState createState() => _ClinicPackagesPageState(); + + +} + +class _ClinicPackagesPageState extends State with AfterLayoutMixin{ + AppScaffold appScaffold; + + List get _products => widget.products; + PackagesViewModel viewModel; + + + onProductCartClick(PackagesResponseModel product) async { + if(viewModel.service.customer == null) + viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); + + if(viewModel.service.customer != null) { + var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); + await viewModel.service.addProductToCart(request, context: context).then((response){ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + }).catchError((error) { + utils.Utils.showErrorToast(error); + }); + } + } + + + @override + void afterFirstLayout(BuildContext context) async{ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + } + + @override + void initState() { + super.initState(); + } + + + @override + Widget build(BuildContext context) { + + return BaseView( + allowAny: true, + onModelReady: (model){ + viewModel = model; + }, + builder: (_, model, wi) => appScaffold = AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: Padding( + padding: const EdgeInsets.all(5), + child: StaggeredGridView.countBuilder( + crossAxisCount:4, + itemCount: _products.length, + itemBuilder: (BuildContext context, int index) => new Container( + color: Colors.transparent, + child: PackagesItemCard( itemContentPadding: 10,itemModel: _products[index], onCartClick: onProductCartClick,) + ), + staggeredTileBuilder: (int index) => StaggeredTile.fit(2), + mainAxisSpacing: 20, + crossAxisSpacing: 10, + ) + ), + ), + ); + } + +} diff --git a/lib/pages/packages_offers/CreateCustomerDailogPage.dart b/lib/pages/packages_offers/CreateCustomerDailogPage.dart new file mode 100644 index 00000000..73e95d09 --- /dev/null +++ b/lib/pages/packages_offers/CreateCustomerDailogPage.dart @@ -0,0 +1,198 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.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/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/AnimatedTextFields.dart'; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/LoadingButton.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; + +dynamic languageID; +var emailRegex = RegExp(r'^[^\s@]+@[^\s@]+\.[^\s@]+$'); + +class CreateCustomerDialogPage extends StatefulWidget { + final BuildContext context; + CreateCustomerDialogPage({this.context}); + PackagesViewModel viewModel; + + Future show() async{ + await showDialog(context: context, builder: (context ){ + return AlertDialog(content: this, shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(20) + ), elevation: 5, ); + }); + return viewModel.service.customer; + } + + @override + _CreateCustomerDialogPageState createState() => _CreateCustomerDialogPageState(); + +} + +class _CreateCustomerDialogPageState extends State with AfterLayoutMixin, TickerProviderStateMixin{ + AnimationController _loadingController; + AnimationController _submitController; + bool _enableInput = true; + + Interval _nameTextFieldLoadingAnimationInterval = const Interval(0, .85); + + final _phoneFocusNode = FocusNode(); + + @override + void initState() { + _submitController = AnimationController(vsync: this, duration: Duration(milliseconds: 1000),); + super.initState(); + } + + @override + void afterFirstLayout(BuildContext context) async{ + } + + // Controllers + TextEditingController _emailTextController = TextEditingController(); + TextEditingController _phoneTextController = TextEditingController(); + TextEditingController _emailPinTextController = TextEditingController(); + TextEditingController _phonePinTextController = TextEditingController(); + + bool verifyPin = false; + + PackagesViewModel viewModel() => widget.viewModel; + + @override + Widget build(BuildContext context) { + + return BaseView( + allowAny: true, + onModelReady: (model) => widget.viewModel = model, + builder: (_, model, wi) => verifyPin ? verifyPinWidget() : userDetailWidget() + ); + } + + Widget verifyPinWidget(){ + + } + + + Widget userDetailWidget(){ + return + Container( + width: SizeConfig.realScreenWidth * 0.8, + height: 270, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Align( + alignment: Alignment.center, + child: Texts("Create Guest Customer", textAlign: TextAlign.center, fontSize: 18, fontWeight: FontWeight.bold,) + ), + SizedBox(height: 30,), + AnimatedTextFormField( + enabled: _enableInput, + controller: _emailTextController, + width: 100, + loadingController: _loadingController, + interval: _nameTextFieldLoadingAnimationInterval, + labelText: "Email", + prefixIcon: Icon(Icons.email), + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.next, + onFieldSubmitted: (value) { + FocusScope.of(context).requestFocus(_phoneFocusNode); + }, + validator: (value){ + return (value.isEmpty || !emailRegex.hasMatch(value)) + ? 'Invalid email!' + : null; + }, + ), + + SizedBox(height: 30,), + AnimatedTextFormField( + enabled: _enableInput, + controller: _phoneTextController, + width: 100, + loadingController: _loadingController, + interval: _nameTextFieldLoadingAnimationInterval, + labelText: "Mobile Number", + prefixIcon: Icon(Icons.phone_android), + keyboardType: TextInputType.phone, + textInputAction: TextInputAction.next, + onFieldSubmitted: (value) { + FocusScope.of(context).requestFocus(_phoneFocusNode); + }, + validator: (value){ + return (value.isEmpty || !emailRegex.hasMatch(value)) + ? 'Invalid email!' + : null; + }, + ), + Spacer(flex: 1,), + + AnimatedButton( + color: Theme.of(context).primaryColor, + loadingColor: Theme.of(context).primaryColor, + controller: _submitController, + text: TranslationBase.of(context).done, + onPressed: (){ + createCustomer(); + }, + ) + + , + ], + ), + ); + } + + createCustomer() async{ + setState(() => _enableInput = false); + + loading(true); + var request = PackagesCustomerRequestModel(email: _emailTextController.text, phoneNumber: _phoneTextController.text); + viewModel().service + .createCustomer(request, context: context, showLoading: false) + .then((value) => success()) + .catchError((error) => showError(error)); + + } + + success() async{ + loading(false); + await Future.delayed(Duration(seconds: 2)); + Navigator.of(context).pop(); + } + + showError(String errorMessage) async{ + loading(false); + setState(() => _enableInput = true); + } + + loading(bool can){ + can ? _submitController.forward() : _submitController.reverse(); + } + +} diff --git a/lib/pages/packages_offers/OfferAndPackageDetailPage.dart b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart new file mode 100644 index 00000000..d0e69d14 --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackageDetailPage.dart @@ -0,0 +1,221 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCategoriesResponseModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/ProductCheckTypeWidget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +import 'ClinicOfferAndPackagesPage.dart'; + +class OfferAndPackagesDetail extends StatefulWidget{ + final dynamic model; + + const OfferAndPackagesDetail({@required this.model, Key key}) : super(key: key); + + @override + State createState() => OfferAndPackagesDetailState(); +} + + +class OfferAndPackagesDetailState extends State{ + + PackagesViewModel viewModel; + + @override + Widget build(BuildContext context) { + getLanguageID(); + + return BaseView( + onModelReady: (model){ + viewModel = model; + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: Stack( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 60), + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.all(5), + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.all(10), + child: AspectRatio( + aspectRatio: 1/1, + child: utils.applyShadow( + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) + ), + ) + ), + ), + Align( + alignment: Alignment.topLeft, + child: Image.asset( + 'assets/images/discount_${'en'}.png', + height: 70, + width: 70, + ), + ), + + ], + + ), + ), + + Padding( + padding: const EdgeInsets.only(left: 20, right: 20, bottom: 20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + "Child Dental Offer", + fontSize: 25, + fontWeight: FontWeight.normal, + color: Colors.black, + ), + + Stack( + children: [ + Texts( + "200 SAR", + fontWeight: FontWeight.normal, + decoration: TextDecoration.lineThrough, + color: Colors.grey, + fontSize: 12 + ), + Padding( + padding: const EdgeInsets.only(top: 15), + child: Texts( + "894.99 SAR", + fontWeight: FontWeight.bold, + color: Colors.green, + fontSize: 18 + ), + ), + ], + ), + + StarRating( + size: 20, + totalCount: null, + totalAverage: 5, + forceStars: true), + + + SizedBox(height: 20,), + + + Texts( + "Details", + fontWeight: FontWeight.bold, + color: Colors.grey, + fontSize: 20 + ), + + + + AspectRatio( + aspectRatio: 2/1, + child: Container( + color: Colors.grey[300], + child: Padding( + padding: const EdgeInsets.all(10), + child: Texts("Detail of offers written here"), + ) + ), + ), + + + SizedBox(height: 10,), + ], + ), + ), + ], + ), + ), + + Padding( + padding: const EdgeInsets.all(10), + child: Align( + alignment: Alignment.bottomRight, + child: Row( + children: [ + + Expanded( + child: RaisedButton.icon( + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + side: BorderSide(color: Colors.red, width: 0.5) + ), + color: Colors.red, + icon: Icon( + Icons.add_shopping_cart_outlined, + size: 25, + color: Colors.white, + ), + label: Texts( + "Add to Cart", + fontSize: 17, color: Colors.white, fontWeight: FontWeight.normal, + ), + onPressed: (){},), + ), + + SizedBox(width: 15,), + + Expanded( + child: OutlineButton.icon( + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + borderSide: BorderSide(width: 1.0, color: Colors.red), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ), + color: Colors.white, + icon: Icon( + Icons.favorite_rounded, + size: 25, + color: Colors.red, + ), + label: Texts( + "Add to Favorites", + fontSize: 17, color: Colors.red, fontWeight: FontWeight.normal + ), + onPressed: (){ + + },), + ), + + ], + ), + ), + ) + + + + ], + ) + ), + ); + } +} + diff --git a/lib/pages/packages_offers/OfferAndPackagesCartPage.dart b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart new file mode 100644 index 00000000..d39f726d --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackagesCartPage.dart @@ -0,0 +1,405 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/enum/PaymentOptions.dart'; +import 'package:diplomaticquarterapp/core/model/ResponseModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesCartItemCard.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +dynamic languageID; +const _columnCount = 1; + +AnimationController _animationController; + +class PackagesCartPage extends StatefulWidget { + PackagesCartPage(); + + @override + _PackagesCartPageState createState() => _PackagesCartPageState(); +} + +class _PackagesCartPageState extends State with AfterLayoutMixin, SingleTickerProviderStateMixin { + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + @override + void initState() { + _agreeTerms = false; + _selectedPaymentMethod = null; + _animationController = AnimationController(vsync: this, duration: Duration(seconds: 500)); + super.initState(); + } + + @override + void dispose() { + _animationController.dispose(); + viewModel.cartItemList.clear(); + super.dispose(); + } + + PackagesViewModel viewModel; + + bool loadWidgets = false; + + onTermsClick(bool isAgree) { + setState(() => _agreeTerms = isAgree); + } + + onTermsInfoClick() { + Navigator.push(context, FadePage(page: PharmacyTermsConditions())); + } + + onPayNowClick() async{ + await viewModel.service.placeOrder(context: context,paymentOption: _selectedPaymentMethod.toUpperCase()).then((orderId){ + if(orderId.runtimeType == int){ // result == order_id + var browser = MyInAppBrowser( + context: context, + onExitCallback: (data, isDone) => paymentClosed(orderId: orderId, withStatus: isDone, data: data) + ); + browser.openPackagesPaymentBrowser(customer_id: viewModel.service.customer.id, order_id: orderId); + + }else{ + utils.Utils.showErrorToast('Failed to place order, please try again later'); + } + + }).catchError((error){ + utils.Utils.showErrorToast(error); + }); + } + + @override + void afterFirstLayout(BuildContext context) { + fetchData(); + } + + @override + Widget build(BuildContext context) { + return BaseView( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi) { + return AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: false, + isShowDecPage: false, + body: Column( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.all(5), + child: StaggeredGridView.countBuilder( + crossAxisCount: (_columnCount * _columnCount), + itemCount: viewModel.cartItemList.length, + itemBuilder: (BuildContext context, int index) { + + var item = viewModel.cartItemList[index]; + return Dismissible( + key: Key(index.toString()), + direction: DismissDirection.startToEnd, + background: _cartItemDeleteContainer(), + secondaryBackground: _cartItemDeleteContainer(), + confirmDismiss: (direction) async { + bool status = await viewModel.service.deleteProductFromCart(item.id, context: context, showLoading: false); + return status; + }, + onDismissed: (direction) { + debugPrint('Index: $index'); + viewModel.cartItemList.removeAt(index); + }, + child: PackagesCartItemCard( + itemModel: item, + shouldStepperChangeApply: (apply,total) async{ + var request = AddProductToCartRequestModel(product_id: item.productId, quantity: apply); + ResponseModel response = await viewModel.service.addProductToCart(request, context: context, showLoading: false).catchError((error){ + utils.Utils.showErrorToast(error); + }); + return response.status ?? false; + }, + ) + ); + }, + staggeredTileBuilder: (int index) => StaggeredTile.fit(_columnCount), + mainAxisSpacing: 0, + crossAxisSpacing: 10, + )), + ), + Container( + height: 0.25, + color: Theme.of(context).primaryColor, + ), + Container( + color: Colors.white, + child: Column( + children: [ + Texts( + TranslationBase.of(context).selectPaymentOption, + fontSize: 10, + fontWeight: FontWeight.bold + ), + + Container(height: 0.25, width: 100, color: Colors.grey[300],), + + _paymentOptions(context, (paymentMethod) { + setState(() => _selectedPaymentMethod = paymentMethod); + }), + + Container(height: 0.25, color: Colors.grey[300],), + + Container(height: 40, + child: _termsAndCondition(context, onSelected: onTermsClick, onInfoClick: onTermsInfoClick) + ), + + Container(height: 0.25, color: Colors.grey[300],), + _payNow(context, onPayNowClick: onPayNowClick) + ], + ), + ) + ], + ), + ); + }); + } + + fetchData() async { + await viewModel.service.cartItems(context: context).catchError((error) {}); + setState((){}); + } + + paymentClosed({@required int orderId, @required bool withStatus, dynamic data}) async{ + viewModel.service.getOrderById(orderId, context: context).then((value){ + var heading = withStatus ? "Success" : "Failed"; + var title = "Your order has been placed successfully"; + var subTitle = "Order# ${value.data.customOrderNumber}"; + Navigator.of(context).pushReplacement( + MaterialPageRoute(builder: (context) => PackageOrderCompletedPage(heading: heading, title: title, subTitle: subTitle)) + ); + + }).catchError((error){ + debugPrint(error); + }); + } +} + +// /* Payment Footer Widgets */ +// --------------------------- +String _selectedPaymentMethod; +Widget _paymentOptions(BuildContext context, Function(String) onSelected) { + double height = 30; + + Widget buttonContent(bool isSelected, String imageName) { + return Container( + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: isSelected ? Colors.green[50] : Colors.grey[200], + blurRadius: 1, + spreadRadius: 2, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5)), + border: Border.all(color: isSelected ? Colors.green : Colors.grey, width: isSelected ? 1 : 0.5) + ), + child: Padding( + padding: const EdgeInsets.all(4), + child: Image.asset('assets/images/new-design/$imageName'), + ) + ); + } + + return Padding( + padding: const EdgeInsets.all(5), + child: Container( + height: height, + color: Colors.transparent, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + InkWell( + child: buttonContent(_selectedPaymentMethod == "mada", 'mada.png'), + onTap: () { + onSelected("mada"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "visa", 'visa.png'), + onTap: () { + onSelected("visa"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "mastercard", 'mastercard.png'), + onTap: () { + onSelected("mastercard"); + }, + ), + SizedBox( + width: 5, + ), + InkWell( + child: buttonContent(_selectedPaymentMethod == "installment", 'installment.png'), + onTap: () { + onSelected("installment"); + }, + ), + ], + ), + ), + ); +} + +bool _agreeTerms = false; +Widget _termsAndCondition(BuildContext context, {@required Function(bool) onSelected, @required VoidCallback onInfoClick}) { + return Padding( + padding: const EdgeInsets.all(5), + child: Row( + children: [ + InkWell( + child: Icon( + _agreeTerms ? Icons.check_circle : Icons.radio_button_unchecked_sharp, + size: 20, + color: _agreeTerms ? Colors.green[600] : Colors.grey[400], + ), + onTap: () { + onSelected(!_agreeTerms); + }, + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Texts( + TranslationBase.of(context).pharmacyServiceTermsCondition, + fontWeight: FontWeight.normal, fontSize: 13, + ), + )), + InkWell( + child: Icon( + Icons.info, + size: 20, + color: Colors.grey[600], + ), + onTap: () { + onInfoClick(); + }, + ), + ], + ), + ); +} + +Widget _payNow(BuildContext context, {@required VoidCallback onPayNowClick}) { + bool isPayNowAQctive = (_agreeTerms && (_selectedPaymentMethod != null)); + + return Padding( + padding: const EdgeInsets.all(5), + child: Container( + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.all(5), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts('${TranslationBase.of(context).subtotal}: ${'999.9'} ${TranslationBase.of(context).sar}', + heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), + Texts('${TranslationBase.of(context).vat}: ${'14.9'} ${TranslationBase.of(context).sar}', heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.grey, fontSize: 8), + Padding( + padding: const EdgeInsets.all(3), + child: Container( + height: 0.25, + width: 120, + color: Colors.grey[300], + ), + ), + Texts('${TranslationBase.of(context).total}: 999.99 ${TranslationBase.of(context).sar}', + heightFactor: 1.5, fontWeight: FontWeight.bold, color: Colors.black54, fontSize: 15) + ], + ), + ), + Expanded(child: Container()), + RaisedButton( + child: Texts( + TranslationBase.of(context).payNow, + fontSize: 15, color: Colors.white, fontWeight: FontWeight.bold, + ), + padding: EdgeInsets.only(top: 5, bottom: 5, left: 0, right: 0), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(5), side: BorderSide(color: Theme.of(context).primaryColor, width: 0.5)), + color: Theme.of(context).primaryColor, + onPressed: isPayNowAQctive ? onPayNowClick : null, + ), + ], + )), + ); +} +// ------------------- + +Widget _cartItemDeleteContainer() { + _animationController.duration = Duration(milliseconds: 500); + _animationController.repeat(reverse: true); + return FadeTransition( + opacity: _animationController, + child: Padding( + padding: const EdgeInsets.all(5), + child: Container( + decoration: BoxDecoration( + color: Colors.red, + boxShadow: [ + BoxShadow( + color: Colors.grey[500], + blurRadius: 2, + spreadRadius: 1, + ), + ], + borderRadius: BorderRadius.all(Radius.circular(5)), + ), + child: Center( + child: Texts( + "Deleting...", + fontWeight: FontWeight.normal, + fontSize: 15, + color: Colors.white, + )), + ), + ), + ); +} diff --git a/lib/pages/packages_offers/OfferAndPackagesPage.dart b/lib/pages/packages_offers/OfferAndPackagesPage.dart new file mode 100644 index 00000000..c09e10ea --- /dev/null +++ b/lib/pages/packages_offers/OfferAndPackagesPage.dart @@ -0,0 +1,418 @@ +import 'package:after_layout/after_layout.dart'; +import 'package:carousel_slider/carousel_slider.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/AddProductToCartRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/CreateCustomerRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersCategoriesRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/requests/OffersProductsRequestModel.dart'; +import 'package:diplomaticquarterapp/core/model/packages_offers/responses/PackagesCustomerResponseModel.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/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/ClinicOfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/CreateCustomerDailogPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackageDetailPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart' as utils; +import 'package:diplomaticquarterapp/widgets/Loader/gif_loader_container.dart'; +import 'package:diplomaticquarterapp/widgets/carousel_indicator/carousel_indicator.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/loadings/ShimmerLoading.dart'; +import 'package:diplomaticquarterapp/widgets/offers_packages/PackagesOfferCard.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_material_pickers/flutter_material_pickers.dart'; + +dynamic languageID; + +class PackagesHomePage extends StatefulWidget { + dynamic offersModel; + PackagesHomePage({@required this.offersModel}); + + @override + _PackagesHomePageState createState() => _PackagesHomePageState(); + +} + +class _PackagesHomePageState extends State with AfterLayoutMixin{ + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + @override + void initState() { + super.initState(); + getLanguageID(); + } + + @override + void afterFirstLayout(BuildContext context) async{ + viewModel.service.loadOffersPackagesDataForMainPage(context: context, completion: (){ + setState((){}); + }); + } + + // Controllers + var _searchTextController = TextEditingController(); + var _filterTextController = TextEditingController(); + var _carouselController = CarouselController(); + + + int carouselIndicatorIndex = 0; + CarouselSlider _bannerCarousel; + TextField _textFieldSearch; + TextField _textFieldFilterSelection; + + ListView _listViewLatestOffers; + ListView _listViewBestSeller; + + PackagesViewModel viewModel; + + onCartClick(){ + if (viewModel.service.customer == null){ + utils.Utils.showErrorToast("Cart is empty for your current session"); + return; + } + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => PackagesCartPage() + ) + ); + } + + onProductCartClick(PackagesResponseModel product) async { + if(viewModel.service.customer == null) + viewModel.service.customer = await CreateCustomerDialogPage(context: context).show(); + + if(viewModel.service.customer != null) { + var request = AddProductToCartRequestModel(product_id: product.id, customer_id: viewModel.service.customer.id); + await viewModel.service.addProductToCart(request, context: context).then((response){ + appScaffold.appBar.badgeUpdater(viewModel.service.cartItemCount); + }).catchError((error) { + utils.Utils.showErrorToast(error); + }); + } + } + + AppScaffold appScaffold; + @override + Widget build(BuildContext context) { + return BaseView( + allowAny: true, + onModelReady: (model) => viewModel = model, + builder: (_, model, wi){ + return + appScaffold = + AppScaffold( + appBarTitle: TranslationBase.of(context).offerAndPackages, + isShowAppBar: true, + isPharmacy: false, + showPharmacyCart: false, + showHomeAppBarIcon: false, + isOfferPackages: true, + showOfferPackagesCart: true, + isShowDecPage: false, + body: ListView( + children: [ + + // Top Banner Carousel + AspectRatio( + aspectRatio: 2.2/1, + child: bannerCarousel() + ), + + Center( + child: CarouselIndicator( + activeColor: Theme.of(context).appBarTheme.color, + color: Colors.grey[300], + cornerRadius: 15, + width: 15, height: 15, + count: _bannerCarousel.itemCount, + index: carouselIndicatorIndex, + onClick: (index){ + debugPrint('onClick at ${index}'); + }, + ), + ), + + SizedBox(height: 10,), + + Padding( + padding: const EdgeInsets.all(15), + child: Column( + children: [ + // Search Textfield + searchTextField(), + + SizedBox(height: 10,), + + // Filter Selection + filterOptionSelection(), + + SizedBox(height: 20,), + + // Horizontal Scrollable Cards + Texts( + "Latest offers", + fontWeight: FontWeight.bold, + color: Colors.black87, + fontSize: 20 + ), + + // Latest Offers Horizontal Scrollable List + AspectRatio( + aspectRatio: 1.3/1, + child: LayoutBuilder(builder: (context, constraints){ + double itemContentPadding = 10; + double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2); + return latestOfferListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); + }), + ), + + SizedBox(height: 10,), + + Texts( + "Best sellers", + fontWeight: FontWeight.bold, + color: Colors.black87, + fontSize: 20 + ), + + + // Best Seller Horizontal Scrollable List + AspectRatio( + aspectRatio: 1.3/1, + child: LayoutBuilder(builder: (context, constraints){ + double itemContentPadding = 10; // 10 is content padding in each item + double itemWidth = (constraints.maxWidth/2) - (itemContentPadding*2 /* 2 = LeftRight */); + return bestSellerListView(itemWidth: itemWidth, itemContentPadding: itemContentPadding); + }), + ) + + ],), + ), + ], + ), + ) + .setOnAppBarCartClick(onCartClick); + } + ); + } + + + + + showClinicSelectionList() async { + var clinics = viewModel.service.categoryList; + if(clinics.isEmpty) { + GifLoaderDialogUtils.showMyDialog(context); + clinics = await viewModel.service.getAllCategories(OffersCategoriesRequestModel()); + GifLoaderDialogUtils.hideDialog(context); + } + + List options = clinics.map((e) => e.toString()).toList(); + + showMaterialSelectionPicker( + context: context, + title: "Select Clinic", + items: options, + selectedItem: options.first, + onChanged: (value) async { + var selectedClinic = clinics.firstWhere((element) => element.toString() == value); + var clinicProducts = await viewModel.service.getAllProducts(request: OffersProductsRequestModel(categoryId: selectedClinic.id), context: context, showLoading: true); + if(clinicProducts.isNotEmpty) + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => ClinicPackagesPage(products: clinicProducts) + ) + ); + else + utils.Utils.showErrorToast("No offers available for this clinic"); + }, + ); + } + + //---------------------------------- + // Main Widgets of Page + //---------------------------------- + + CarouselSlider bannerCarousel(){ + _bannerCarousel = CarouselSlider.builder( + carouselController: _carouselController, + itemCount: 10, + itemBuilder: (BuildContext context, int itemIndex) { + return Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10, left: 15, right: 15), + child: FractionallySizedBox( + widthFactor: 1, + heightFactor: 1, + child: utils.applyShadow( + spreadRadius: 1, + blurRadius: 5, + child: InkWell( + child: ClipRRect( + borderRadius: BorderRadius.circular(10), + child: utils.Utils.loadNetworkImage(url: "https://wallpaperaccess.com/full/30103.jpg",) + ), + onTap: (){ + Navigator.of(context).push( + MaterialPageRoute( + builder: (BuildContext context) => OfferAndPackagesDetail(model: "",) + ) + ); + }, + ) + ), + ), + ); + }, + options: CarouselOptions( + autoPlayInterval: Duration(milliseconds: 3500), + enlargeStrategy: CenterPageEnlargeStrategy.scale, + enlargeCenterPage: true, + autoPlay: false, + autoPlayCurve: Curves.fastOutSlowIn, + enableInfiniteScroll: true, + autoPlayAnimationDuration: Duration(milliseconds: 1500), + viewportFraction: 1, + onPageChanged: (page, reason){ + setState(() { + carouselIndicatorIndex = page; + }); + }, + ), + ); + return _bannerCarousel; + } + + TextField searchTextField(){ + return _textFieldSearch = + TextField( + controller: _searchTextController, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( width: 0.5, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( width: 1, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + filled: true, + fillColor: Colors.white, + hintText: "Search", + hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), + suffixIcon: IconButton( + onPressed: (){ + // viewModel.search(text: _searchTextController.text); + }, + icon: Icon(Icons.search_rounded, size: 35,), + ), + ), + ); + + } + + Widget filterOptionSelection(){ + _textFieldFilterSelection = + TextField( + enabled: false, + controller: _searchTextController, + decoration: InputDecoration( + contentPadding: EdgeInsets.only(top: 0.0, bottom: 0.0, left: 10, right: 10), + border: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey, width: 1), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + disabledBorder: OutlineInputBorder( + borderSide: BorderSide( width: 0.5, color: Colors.grey), + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all( + const Radius.circular(10.0), + ), + ), + filled: true, + fillColor: Colors.white, + hintText: "Browse offers by Clinic", + hintStyle: TextStyle(color: Colors.grey[350], fontWeight: FontWeight.bold), + suffixIcon: IconButton( + onPressed: (){ + showClinicSelectionList(); + }, + icon: Icon(Icons.keyboard_arrow_down_rounded, size: 35, color: Colors.grey,), + ), + ), + ); + + return InkWell( + child: _textFieldFilterSelection, + onTap: (){ + showClinicSelectionList(); + }, + ); + + } + + Widget latestOfferListView({@required double itemWidth, @required double itemContentPadding}){ + return _listViewLatestOffers = + ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); + }, + separatorBuilder: separator, + ); + + } + + Widget bestSellerListView({@required double itemWidth, @required double itemContentPadding}){ + return _listViewLatestOffers = + ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: viewModel.bestSellerList.length, + itemBuilder: (BuildContext context, int index) { + return PackagesItemCard(itemWidth: itemWidth, itemContentPadding: itemContentPadding, itemModel: viewModel.bestSellerList[index], onCartClick: onProductCartClick,); + }, + separatorBuilder: separator, + ); + + } + + + Widget separator(BuildContext context, int index){ + return Container( + width: 1, + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment(-1.0, -2.0), + end: Alignment(1.0, 4.0), + colors: [ + Colors.grey, + Colors.grey[100], + Colors.grey[200], + Colors.grey[300], + Colors.grey[400], + Colors.grey[500] + ] + )), + ); + } +} diff --git a/lib/pages/packages_offers/PackageOrderCompletedPage.dart b/lib/pages/packages_offers/PackageOrderCompletedPage.dart new file mode 100644 index 00000000..73baca4b --- /dev/null +++ b/lib/pages/packages_offers/PackageOrderCompletedPage.dart @@ -0,0 +1,136 @@ +import 'package:diplomaticquarterapp/core/viewModels/packages_offers/PackagesOffersViewModel.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/svg.dart'; + +dynamic languageID; + +class PackageOrderCompletedPage extends StatelessWidget{ + double buttonHeight; + double buttonWidth; + Widget icon; + String heading; + String title; + String subTitle; + String actionTitle; + + PackageOrderCompletedPage({this.buttonWidth, this.buttonHeight, @required this.heading, @required this.title, @required this.subTitle, this.actionTitle }); + + @override + Widget build(BuildContext context) { + assert((heading != null || title != null || subTitle != null), "Data missing in properties"); + + buttonWidth = buttonWidth ?? MediaQuery.of(context).size.width/2; + buttonHeight = buttonHeight ?? 40; + actionTitle = actionTitle ?? TranslationBase.of(context).done; + + return BaseView( + allowAny: true, + onModelReady: (model){}, + builder: (_, model, wi){ + return Container( + color: Colors.white, + child: Padding( + padding: const EdgeInsets.all(15), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + + AspectRatio( + aspectRatio: 1.2/1, + child: + iconWidget(context), + ), + + headingWidget(context), + + + AspectRatio( + aspectRatio: 1/1, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + titleWidget(context), + SizedBox(height: 20,), + subTitleWidget(context), + SizedBox(height: 50,), + actionWidget(context) + ], + ), + ), + ) + + ], + ), + ), + ); + } + ); + } + + Widget iconWidget(BuildContext context){ + return Padding( + padding: const EdgeInsets.all(50), + child: icon ?? SvgPicture.asset( + "assets/images/svg/success.svg", + semanticsLabel: 'icon' + ), + ); + } + + Widget headingWidget(BuildContext context) => Texts( + heading, + textAlign: TextAlign.center, + maxLines: 1, + color: Theme.of(context).primaryColor, + fontSize: 35.0, + fontWeight: FontWeight.bold, + ); + + Widget titleWidget(BuildContext context) => Texts( + title, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 25.0, + fontWeight: FontWeight.w200, + ); + + Widget subTitleWidget(BuildContext context) => Texts( + subTitle, + textAlign: TextAlign.center, + maxLines: 2, + color: Theme.of(context).primaryColor, + fontSize: 15.0, + fontWeight: FontWeight.normal, + ); + + + Widget actionWidget(BuildContext context) => Container( + height: buttonHeight, + width: buttonWidth, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + + shape:RoundedRectangleBorder( + borderRadius: new BorderRadius.circular(buttonHeight/2), + ) + ), + child: Texts( + actionTitle, + color: Colors.white, + fontSize: 18.0, + fontWeight: FontWeight.normal, + ), + onPressed: (){ + Navigator.of(context).pop(); + }, + ), + ); + +} diff --git a/lib/pages/parent_categorise_page.dart b/lib/pages/parent_categorise_page.dart index 414106b1..a7e43241 100644 --- a/lib/pages/parent_categorise_page.dart +++ b/lib/pages/parent_categorise_page.dart @@ -1,24 +1,28 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; import 'package:diplomaticquarterapp/pages/sub_categorise_page.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/entity_checkbox_list.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:giffy_dialog/giffy_dialog.dart'; import 'base/base_view.dart'; -import 'final_products_page.dart'; class ParentCategorisePage extends StatefulWidget { String id; String titleName; + ParentCategorisePage({this.id, this.titleName}); + @override _ParentCategorisePageState createState() => _ParentCategorisePageState(id: id, titleName: titleName); @@ -27,7 +31,9 @@ class ParentCategorisePage extends StatefulWidget { class _ParentCategorisePageState extends State { String id; String titleName; + _ParentCategorisePageState({this.id, this.titleName}); + Map values = {'huusam': false, 'ali': false, 'noor': false}; bool checkedBrands = false; bool checkedCategorise = false; @@ -39,8 +45,14 @@ class _ParentCategorisePageState extends State { color: Colors.blue, size: 29.0, ); + + List entityList = List(); + List entityListBrands = List(); + @override Widget build(BuildContext context) { + TextEditingController minField = TextEditingController(); + TextEditingController maxField = TextEditingController(); ProjectViewModel projectViewModel = Provider.of(context); return BaseView( onModelReady: (model) => model.getCategoriseParent(i: id), @@ -53,959 +65,988 @@ class _ParentCategorisePageState extends State { backgroundColor: Colors.white, isShowDecPage: false, baseViewModel: model, - body: Container( - child: ListView( - scrollDirection: Axis.vertical, - children: [ - Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Image.network( - id == '1' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089188_personal-care_2.png' - : id == '2' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089189_skin-care_2.png' - : id == '3' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089190_health-care_2.png' - : id == '4' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089191_sexual-health_2.png' - : id == '5' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089192_beauty_2.png' - : id == '6' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089193_baby-child_2.png' - : id == '7' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089194_vitamins-supplements_2.png' - : id == '8' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089195_diet-nutrition_2.png' - : id == '9' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089196_household_2.png' - : id == '10' - ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089197_home-care-appliances_2.png' - : '', - fit: BoxFit.fill, - height: 160.0, - width: double.infinity), - ), - if (model.categoriseParent.length > 8) - Column( - crossAxisAlignment: CrossAxisAlignment.start, + body: SingleChildScrollView( + child: Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + child: Image.network( + id == '1' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089188_personal-care_2.png' + : id == '2' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089189_skin-care_2.png' + : id == '3' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089190_health-care_2.png' + : id == '4' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089191_sexual-health_2.png' + : id == '5' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089192_beauty_2.png' + : id == '6' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089193_baby-child_2.png' + : id == '7' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089194_vitamins-supplements_2.png' + : id == '8' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089195_diet-nutrition_2.png' + : id == '9' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089196_household_2.png' + : id == '10' + ? 'https://uat.hmgwebservices.com/epharmacy/content/images/thumbs/0089197_home-care-appliances_2.png' + : '', + fit: BoxFit.fill, + height: 160.0, + width: double.infinity), + ), + if (model.categoriseParent.length > 8) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: EdgeInsets.all(10.0), - child: InkWell( - child: Container( - child: Texts( - 'View All Categories', - fontWeight: FontWeight.w300, - ), - ), - onTap: () { - showModalBottomSheet( - isScrollControlled: true, - context: context, - builder: (BuildContext context) { - return Container( - height: MediaQuery.of(context) - .size - .height * - 0.89, - color: Colors.white, - child: Center( - child: ListView.builder( - scrollDirection: - Axis.vertical, - itemCount: model - .categoriseParent - .length, - itemBuilder: - (BuildContext context, - int index) { - return Container( - child: Padding( - padding: - EdgeInsets.all( - 8.0), - child: InkWell( - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - Texts(model - .categoriseParent[ - index] - .name), - Divider( - thickness: - 0.6, - color: Colors - .black12, - ) - ], - ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: - (context) => - SubCategorisePage( - title: model.categoriseParent[index].name, - id: model.categoriseParent[index].id, - parentId: id, - )), - ); - }, - ), + Padding( + padding: EdgeInsets.all(10.0), + child: InkWell( + child: Container( + child: Texts( + 'View All Categories', + fontWeight: FontWeight.w300, + ), + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return Container( + // height: MediaQuery.of(context) + // .size + // .height * + // 0.89, + color: Colors.white, + child: Center( + child: ListView.builder( + scrollDirection: + Axis.vertical, + itemCount: model + .categoriseParent.length, + itemBuilder: + (BuildContext context, + int index) { + return Container( + child: Padding( + padding: + EdgeInsets.all(4.0), + child: InkWell( + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Texts(model + .categoriseParent[ + index] + .name), + Divider( + thickness: 0.6, + color: Colors + .black12, + ) + ], ), - ); - }), - ), - ); - }, + onTap: () { + Navigator.push( + context, + FadePage( + page: + SubCategorisePage( + title: model + .categoriseParent[ + index] + .name, + id: model + .categoriseParent[ + index] + .id, + parentId: id, + )), + ); + }, + ), + ), + ); + }), + ), ); }, - ), - ), - Icon(Icons.arrow_forward) - ], - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, + ); + }, + ), ), + Icon(Icons.arrow_forward) ], ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + ], + ), //Expanded widget heree if nassery - Padding( - padding: EdgeInsets.only(top: 35.0), - child: Container( - height: MediaQuery.of(context).size.height * 0.2, - child: Center( - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: model.categoriseParent.length > 8 - ? 8 - : model.categoriseParent.length, - itemBuilder: - (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.symmetric( - horizontal: 8.0), - child: InkWell( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - Padding( - padding: EdgeInsets.symmetric( - horizontal: 13.0), - child: Container( - height: 60.0, - width: 65.0, - decoration: BoxDecoration( - shape: BoxShape.circle, - color: Colors - .orange.shade200 - .withOpacity(0.45), - ), - child: Center( - child: Icon( - Icons.apps_sharp, - size: 32.0, - ), - ), - ), + Padding( + padding: EdgeInsets.only(top: 35.0), + child: Container( + height: MediaQuery.of(context).size.height * 0.2, + child: Center( + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: model.categoriseParent.length > 8 + ? 8 + : model.categoriseParent.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: + EdgeInsets.symmetric(horizontal: 8.0), + child: InkWell( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + Padding( + padding: EdgeInsets.symmetric( + horizontal: 13.0), + child: Container( + height: 60.0, + width: 65.0, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.orange.shade200 + .withOpacity(0.45), ), - Container( - width: MediaQuery.of(context) - .size - .width * - 0.197, - height: MediaQuery.of(context) - .size - .height * - 0.08, - child: Center( - child: Texts( - projectViewModel.isArabic - ? model - .categoriseParent[ - index] - .namen - : model - .categoriseParent[ - index] - .name, - fontSize: 13.4, - fontWeight: FontWeight.w600, - maxLines: 3, - ), + child: Center( + child: Icon( + Icons.apps_sharp, + size: 32.0, ), ), - ], + ), ), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - SubCategorisePage( - title: model - .categoriseParent[ - index] - .name, - id: model - .categoriseParent[ - index] - .id, - parentId: id, - )), - ); - print(id); - }, - ), - ); - }), - ), - ), + Container( + width: MediaQuery.of(context) + .size + .width * + 0.197, + // height: MediaQuery.of(context) + // .size + // .height * + // 0.08, + child: Center( + child: Texts( + projectViewModel.isArabic + ? model + .categoriseParent[index] + .namen + : model + .categoriseParent[index] + .name, + fontSize: 13.4, + fontWeight: FontWeight.w600, + maxLines: 3, + ), + ), + ), + ], + ), + onTap: () { + Navigator.push( + context, + FadePage( + page: SubCategorisePage( + title: model + .categoriseParent[index].name, + id: model + .categoriseParent[index].id, + parentId: id, + )), + ); + print(id); + }, + ), + ); + }), ), + ), + ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - Padding( - padding: EdgeInsets.symmetric(horizontal: 8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - InkWell( - child: Row( - children: [ - Icon( - Icons.wrap_text, - ), - SizedBox( - width: 10.0, - ), - Texts( - 'Refine', - fontWeight: FontWeight.w600, - ), - ], + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + child: Row( + children: [ + Icon( + Icons.wrap_text, ), - onTap: () { - showModalBottomSheet( - isScrollControlled: true, - context: context, - builder: (BuildContext context) { - return DraggableScrollableSheet( - initialChildSize: 0.95, - maxChildSize: 0.95, - minChildSize: 0.9, - builder: (BuildContext context, - ScrollController - scrollController) { - return SingleChildScrollView( - controller: scrollController, - child: Container( - height: MediaQuery.of(context) - .size - .height * - 1.95, - child: Column( - children: [ - Padding( - padding: - EdgeInsets.all(8.0), - child: Row( - children: [ - Icon( - Icons.wrap_text, - ), - SizedBox( - width: 10.0, - ), - Texts( - 'Refine', - fontWeight: - FontWeight - .w600, - ), - SizedBox( - width: 250.0, - ), - InkWell( - child: Texts( - 'Close', - color: - Colors.red, - fontWeight: - FontWeight - .w600, - fontSize: 15.0, - ), - onTap: () { - Navigator.pop( - context); - }, - ), - ], + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: FontWeight.w600, + ), + ], + ), + onTap: () { + showModalBottomSheet( + isScrollControlled: true, + context: context, + builder: (BuildContext context) { + return DraggableScrollableSheet( + initialChildSize: 0.95, + maxChildSize: 0.95, + minChildSize: 0.9, + builder: (BuildContext context, + ScrollController scrollController) { + return SingleChildScrollView( + controller: scrollController, + child: Container( + color: Colors.white, + height: MediaQuery.of(context) + .size + .height * + 1.95, + child: Column( + children: [ + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + children: [ + Icon( + Icons.wrap_text, + ), + SizedBox( + width: 10.0, + ), + Texts( + 'Refine', + fontWeight: + FontWeight.w600, ), + SizedBox( + width: 250.0, + ), + InkWell( + child: Texts( + 'Close', + color: Colors.red, + fontWeight: + FontWeight.w600, + fontSize: 15.0, + ), + onTap: () { + Navigator.pop( + context); + }, + ), + ], + ), + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + Column( + children: [ + ExpansionTile( + title: + Texts('Categorise'), + children: [ + ProcedureListWidget( + model: model, + masterList: model + .categoriseParent, + removeHistory: + (item) { + setState(() { + entityList + .remove( + item); + }); + }, + addHistory: + (history) { + setState(() { + entityList.add( + history); + }); + }, + addSelectedHistories: + () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: + (master) => + isEntityListSelected( + master), + ) + ], ), Divider( thickness: 1.0, color: Colors.black12, ), - Column( + ExpansionTile( + title: Texts('Brands'), children: [ - ExpansionTile( - title: Texts( - 'Categorise'), - children: [ - Container( - height: 350, - child: ListView - .builder( - controller: - scrollController, - scrollDirection: - Axis - .vertical, - shrinkWrap: - true, - itemCount: model - .categoriseParent - .length, - itemBuilder: - (BuildContext context, - int index) { - return CheckboxListTile( - tristate: - true, - title: - Texts(model.categoriseParent[index].name), - controlAffinity: - ListTileControlAffinity.leading, - value: - checkedCategorise, - onChanged: - (bool value) { - setState(() { - checkedCategorise = value; - }); - }, - ); - }), - ) - ], - ), - Divider( - thickness: 1.0, - color: - Colors.black12, - ), - ExpansionTile( - title: - Texts('Brands'), - children: [ - Container( - height: 350, - child: ListView - .builder( - scrollDirection: - Axis - .vertical, - shrinkWrap: - true, - itemCount: model - .brandsList - .length, - itemBuilder: - (BuildContext context, - int index) { - return CheckboxListTile( - tristate: - true, - title: - Texts(model.brandsList[index].name), - controlAffinity: - ListTileControlAffinity.leading, - value: - checkedBrands, - onChanged: - (bool value) { - setState(() { - checkedBrands = value; - }); - }, - autofocus: - true, - ); - }), - ) - ], - ), - Divider( - thickness: 1.0, - color: - Colors.black12, - ), - ExpansionTile( - title: - Texts('Price'), - children: [ - Container( - color: Color( - 0xffEEEEEE), - child: Row( + ProcedureListWidget( + model: model, + masterList: model + .brandsList, + removeHistory: + (item) { + setState(() { + entityListBrands + .remove( + item); + }); + }, + addHistory: + (history) { + setState(() { + entityListBrands + .add( + history); + }); + }, + addSelectedHistories: + () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: + (master) => + isEntityListSelectedBrands( + master), + ) + ], + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + ExpansionTile( + title: Texts('Price'), + children: [ + Container( + color: Color( + 0xffEEEEEE), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + children: [ + Column( mainAxisAlignment: MainAxisAlignment - .spaceAround, + .start, children: [ - Column( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Texts( - 'Min'), - Container( - color: - Colors.white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: OutlineInputBorder(), - ), - ), + Texts( + 'Min'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), ), - ], + controller: + minField, + ), ), - Column( - mainAxisAlignment: - MainAxisAlignment - .start, - children: [ - Texts( - 'Max'), - Container( - color: - Colors.white, - width: - 200, - height: - 40, - child: - TextFormField( - decoration: - InputDecoration( - border: OutlineInputBorder(), - ), - ), + ], + ), + Column( + mainAxisAlignment: + MainAxisAlignment + .start, + children: [ + Texts( + 'Max'), + Container( + color: Colors + .white, + width: + 200, + height: + 40, + child: + TextFormField( + decoration: + InputDecoration( + border: + OutlineInputBorder(), ), - ], + controller: + maxField, + ), ), ], ), - ) - ], - ), - Divider( - thickness: 1.0, - color: - Colors.black12, - ), - SizedBox( - height: MediaQuery.of( - context) - .size - .height * - 0.4, - ), - Padding( - padding: - EdgeInsets.all( - 8.0), - child: Row( - mainAxisAlignment: - MainAxisAlignment - .spaceEvenly, - children: [ - Container( - width: 100, - child: Button( - label: - 'Reset', - backgroundColor: - Colors - .red, - ), - ), - SizedBox( - width: 30, - ), - Container( - width: 200, - child: Button( - label: - 'Apply', - backgroundColor: - Colors - .green, - ), - ), ], ), - ), + ) ], ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + SizedBox( + height: MediaQuery.of( + context) + .size + .height * + 0.4, + ), + Padding( + padding: + EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + Container( + width: 100, + child: Button( + label: 'Reset', + backgroundColor: + Colors.red, + ), + ), + SizedBox( + width: 30, + ), + Container( + width: 200, + child: Button( + onTap: () { + String + categoriesId = + ""; + for (CategoriseParentModel category + in entityList) { + if (categoriesId == + "") { + categoriesId = + category + .id; + } else { + categoriesId = + "$categoriesId,${category.id}"; + } + } + String + brandIds = + ""; + for (CategoriseParentModel brand + in entityListBrands) { + if (brandIds == + "") { + brandIds = + brand + .id; + } else { + brandIds = + "$brandIds,${brand.id}"; + } + } + + model.getFilteredProducts( + min: minField + .text + .toString(), + max: maxField + .text + .toString(), + categoryId: + categoriesId, + brandId: + brandIds); + }, + label: 'Apply', + backgroundColor: + Colors + .green, + ), + ), + ], + ), + ), ], ), - ), - ); - }); - }, - ); + ], + ), + ), + ); + }); }, - ), - Row( - children: [ - Container( - height: 44.0, - child: VerticalDivider( - color: Colors.black45, - thickness: 1.0, + ); + }, + ), + Row( + children: [ + Container( + height: 44.0, + child: VerticalDivider( + color: Colors.black45, + thickness: 1.0, //width: 0.3, // indent: 0.0, - ), - ), - Padding( - padding: EdgeInsets.all(8.0), - child: InkWell( - child: styleIcon, - onTap: () { - setState(() { - if (styleOne == true) { - styleOne = false; - styleTwo = true; - styleIcon = Icon( - Icons.auto_awesome_mosaic, - color: Colors.blue, - size: 29.0, - ); - } else { - styleOne = true; - styleTwo = false; - styleIcon = Icon( - Icons.widgets_sharp, - color: Colors.blue, - size: 29.0, - ); - } - }); - }, - ), - ), - ], + ), + ), + Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: styleIcon, + onTap: () { + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); + }, + ), ), ], ), - ), - Divider( - thickness: 1.0, - color: Colors.grey.shade400, - ), - styleOne == true - ? Container( - height: SizeConfig.screenHeight * 7.8, - child: GridView.builder( - physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 0.9, - ), - itemCount: model.parentProducts.length, - itemBuilder: - (BuildContext context, int index) { - return NetworkBaseView( - baseViewModel: model, - child: Card( - color: model.parentProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), + ], + ), + ), + Divider( + thickness: 1.0, + color: Colors.grey.shade400, + ), + styleOne == true + ? Container( + height: model.parentProducts.length * + MediaQuery.of(context).size.height * + 0.15, + child: GridView.builder( + physics: NeverScrollableScrollPhysics(), + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 0.9, + ), + itemCount: model.parentProducts.length, + itemBuilder: (BuildContext context, int index) { + return NetworkBaseView( + baseViewModel: model, + child: InkWell( + child: Card( + color: model.parentProducts[index] + .discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, + left: BorderSide( + color: Colors.grey.shade300, + width: 1, ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: - Radius.circular(110.0), - ), - color: Colors.white, + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + ), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( - children: [ - if (model - .parentProducts[ - index] - .discountName != - null) - RotatedBox( - quarterTurns: 4, - child: Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets - .only( - right: 5.0, - top: 20.0, - bottom: 5.0, - ), - child: Texts( - 'offer' - .toUpperCase(), - color: - Colors.red, - fontSize: 13.0, - fontWeight: - FontWeight - .w900, - ), + color: Colors.white, + ), + padding: EdgeInsets.symmetric( + horizontal: 0), + width: MediaQuery.of(context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack( + children: [ + if (model + .parentProducts[ + index] + .discountName != + null) + RotatedBox( + quarterTurns: 4, + child: Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets.only( + right: 5.0, + top: 20.0, + bottom: 5.0, + ), + child: Texts( + 'offer' + .toUpperCase(), + color: Colors.red, + fontSize: 13.0, + fontWeight: + FontWeight + .w900, ), - transform: new Matrix4 - .rotationZ( - 5.837200), ), + transform: new Matrix4 + .rotationZ( + 5.837200), ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .parentProducts[ - index] - .images - .isNotEmpty - ? model + ), + Container( + margin: + EdgeInsets.fromLTRB( + 0, 16, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model + .parentProducts[ + index] + .images + .isNotEmpty + ? model + .parentProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), + ), + Container( + width: model .parentProducts[ index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), ), - Container( - width: model + child: Texts( + model .parentProducts[ index] .rxMessage != null - ? MediaQuery.of( - context) - .size - .width / - 5 - : 0, - padding: - EdgeInsets.all(4), - decoration: - BoxDecoration( - color: - Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular( - 6)), - ), - child: Texts( - model - .parentProducts[ - index] - .rxMessage != - null - ? model - .parentProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ], - ), - Container( - margin: - EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment - .start, - children: [ - if (model + ? model .parentProducts[ index] - .discountName != - null) - Container( - width: - double.infinity, - height: 13.0, - decoration: - BoxDecoration( - color: Color( - 0xff5AB145), - ), - child: Center( - child: Texts( - model - .parentProducts[ - index] - .discountName, - regular: true, - color: Colors - .white, - fontSize: 10.4, - ), - ), - ), - Texts( - model + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ), + ), + ], + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + if (model .parentProducts[ index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w700, - ), - Padding( - padding: - const EdgeInsets - .only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.parentProducts[index].price}", - bold: true, - fontSize: 14, + .discountName != + null) + Container( + width: + double.infinity, + height: 13.0, + decoration: + BoxDecoration( + color: Color( + 0xff5AB145), ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .parentProducts[ - index] - .approvedRatingSum > - 0 - ? (model.parentProducts[index].approvedRatingSum.toDouble() / - model.parentProducts[index].approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: - true), - Texts( - "(${model.parentProducts[index].approvedTotalReviews})", + child: Center( + child: Texts( + model + .parentProducts[ + index] + .discountName, regular: true, - fontSize: 10, - fontWeight: - FontWeight - .w400, - ) - ], + color: + Colors.white, + fontSize: 10.4, + ), + ), ), - ], - ), + Texts( + model + .parentProducts[ + index] + .name, + regular: true, + fontSize: 12, + fontWeight: + FontWeight.w700, + ), + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: 4), + child: Texts( + "SAR ${model.parentProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .parentProducts[ + index] + .approvedRatingSum > + 0 + ? (model.parentProducts[index].approvedRatingSum + .toDouble() / + model + .parentProducts[index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.parentProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], ), - ], - ), + ), + ], ), - )); - }, - ), - ) - : Container( - height: - MediaQuery.of(context).size.height * 5.0, - child: ListView.builder( - physics: NeverScrollableScrollPhysics(), - itemCount: model.parentProducts.length, - itemBuilder: - (BuildContext context, int index) { - return Card( - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - Container( - decoration: - BoxDecoration(), - child: Padding( - padding: - EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, - ), + ), + ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage(model + .parentProducts[index]), + )), + }, + )); + }, + ), + ) + : Container( + height: model.parentProducts.length * + MediaQuery.of(context).size.height * + 0.122, + child: ListView.builder( + physics: NeverScrollableScrollPhysics(), + itemCount: model.parentProducts.length, + itemBuilder: + (BuildContext context, int index) { + return InkWell( + child: Card( + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, ), ), - Container( - margin: - EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: - Alignment.center, - child: Image.network( - model - .parentProducts[ - index] - .images - .isNotEmpty - ? model + ), + Container( + margin: + EdgeInsets.fromLTRB( + 0, 0, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model + .parentProducts[ + index] + .images + .isNotEmpty + ? model + .parentProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, + height: 80, + ), + ), + ], + ), + Column( + children: [ + Container( + width: model .parentProducts[ index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.contain, - height: 80, - ), + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), ), - ], - ), - Column( - children: [ - Container( - width: model + child: Texts( + model .parentProducts[ index] .rxMessage != null - ? MediaQuery.of( - context) - .size - .width / - 5 - : 0, - padding: - EdgeInsets.all(4), - decoration: - BoxDecoration( - color: - Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular( - 6)), - ), - child: Texts( - model - .parentProducts[ - index] - .rxMessage != - null - ? model - .parentProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), + ? model + .parentProducts[ + index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, ), - ], - ), - ], - ), - Container( - height: 100.0, - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - mainAxisAlignment: - MainAxisAlignment - .spaceAround, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 4.0, ), - Texts( + ], + ), + ], + ), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + SizedBox( + height: 4.0, + ), + Container( + width: + MediaQuery.of(context) + .size + .width * + 0.65, + child: Texts( model .parentProducts[index] .name, @@ -1015,60 +1056,89 @@ class _ParentCategorisePageState extends State { FontWeight.w500, maxLines: 5, ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, - bottom: 4), - child: Texts( - "SAR ${model.parentProducts[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .parentProducts[ - index] - .approvedRatingSum > - 0 - ? (model.parentProducts[index].approvedRatingSum - .toDouble() / - model - .parentProducts[index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.parentProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], + ), + SizedBox( + height: 8.0, + ), + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.parentProducts[index].price}", + bold: true, + fontSize: 14, ), - ], - ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .parentProducts[ + index] + .approvedRatingSum > + 0 + ? (model + .parentProducts[ + index] + .approvedRatingSum + .toDouble() / + model + .parentProducts[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.parentProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], ), - ], - ), - ); - }), - ) - ], - ), - ), - ], + ), + ], + ), + ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.parentProducts[index]), + )), + }, + ); + }), + ) + ], + ), ), ), )); } + + bool isEntityListSelected(CategoriseParentModel masterKey) { + Iterable history = + entityList.where((element) => masterKey.id == element.id); + if (history.length > 0) { + return true; + } + return false; + } + + bool isEntityListSelectedBrands(CategoriseParentModel masterKey) { + Iterable history = + entityListBrands.where((element) => masterKey.id == element.id); + if (history.length > 0) { + return true; + } + return false; + } } diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index c3a19917..1b221454 100644 --- a/lib/pages/paymentService/payment_service.dart +++ b/lib/pages/paymentService/payment_service.dart @@ -74,7 +74,7 @@ class PaymentService extends StatelessWidget { ), ), ), - if(!projectViewModel.havePrivilege(33)) + //if(!projectViewModel.havePrivilege(33)) Expanded( child: InkWell( onTap: () => navigateToToDoPage(context), @@ -117,7 +117,7 @@ class PaymentService extends StatelessWidget { ) ], ), - if(!projectViewModel.havePrivilege(33)) + //if(!projectViewModel.havePrivilege(33)) Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -136,12 +136,12 @@ class PaymentService extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - 'My Balances', + TranslationBase.of(context).hmg, color: HexColor('#B61422'), bold: true, ), Texts( - TranslationBase.of(context).payment, + TranslationBase.of(context).wallet, fontSize: 14, fontWeight: FontWeight.normal, ), diff --git a/lib/pages/pharmacies/compare.dart b/lib/pages/pharmacies/compare.dart index d1872187..505533cb 100644 --- a/lib/pages/pharmacies/compare.dart +++ b/lib/pages/pharmacies/compare.dart @@ -196,7 +196,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[0].name, + text: widget.data[index].specifications != null ? + widget.data[index].specifications[0].name : + "No data", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black, @@ -211,7 +213,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[1].name, + text: widget.data[index].specifications != null ? + widget.data[index].specifications[1].name : + "No data", style: TextStyle( color: Colors.black54, fontSize: 15, @@ -234,7 +238,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[2].name, + text:widget.data[index].specifications != null ? + widget.data[index].specifications[2].name : + "No data", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black, @@ -249,7 +255,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[3].name, + text: widget.data[index].specifications != null ? + widget.data[index].specifications[3].name : + "No data", style: TextStyle( color: Colors.black54, fontSize: 15, @@ -272,7 +280,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[4].name, + text:widget.data[index].specifications != null ? + widget.data[index].specifications[4].name : + "No data", style: TextStyle( fontWeight: FontWeight.bold, color: Colors.black, @@ -287,7 +297,9 @@ class _slideDetailState extends State { alignment: Alignment.topLeft, child: RichText( text: TextSpan( - text: widget.data[index].specifications[5].name, + text:widget.data[index].specifications != null ? + widget.data[index].specifications[5].name : + "No data", style: TextStyle( color: Colors.black54, fontSize: 15, diff --git a/lib/pages/pharmacies/medicine_search_screen.dart b/lib/pages/pharmacies/medicine_search_screen.dart index 7a61dabe..5c31f2de 100644 --- a/lib/pages/pharmacies/medicine_search_screen.dart +++ b/lib/pages/pharmacies/medicine_search_screen.dart @@ -3,6 +3,7 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/cupertino.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/pharmacies_model.dart'; @@ -121,8 +122,8 @@ class MedicineSearch extends StatelessWidget { onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => PharmaciesList( + FadePage( + page: PharmaciesList( medicineID: model.pharmacy[index].itemID, imageURL: model diff --git a/lib/pages/pharmacies/product-brands.dart b/lib/pages/pharmacies/product-brands.dart index b9e6db95..e2fefab0 100644 --- a/lib/pages/pharmacies/product-brands.dart +++ b/lib/pages/pharmacies/product-brands.dart @@ -1,14 +1,15 @@ import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/pages/final_products_page.dart'; import 'package:diplomaticquarterapp/pages/login/register-info.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/search_brands_page.dart'; -import 'package:diplomaticquarterapp/pages/search_products_page.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; -import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/brand_view_model.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; class ProductBrandsPage extends StatefulWidget { @override @@ -16,8 +17,8 @@ class ProductBrandsPage extends StatefulWidget { } var languageID; -class _ProductBrandsPageState extends State { +class _ProductBrandsPageState extends State { @override void initState() { super.initState(); @@ -27,6 +28,7 @@ class _ProductBrandsPageState extends State { @override Widget build(BuildContext context) { return BaseView( + allowAny: true, onModelReady: (model) => model.getBrandsData(), builder: (_, model, wi) => AppScaffold( appBarTitle: 'Brands page', @@ -38,18 +40,11 @@ class _ProductBrandsPageState extends State { children: [ Container( color: Colors.white, - alignment: languageID == 'ar'? - Alignment.topRight : - Alignment.topLeft, - padding: languageID == 'ar' ? - EdgeInsets.only( - right: 10.0, - top: 10.0 - ): - EdgeInsets.only( - left: 10.0, - top: 10.0 - ), + alignment: + languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, + padding: languageID == 'ar' + ? EdgeInsets.only(right: 10.0, top: 10.0) + : EdgeInsets.only(left: 10.0, top: 10.0), child: Text( TranslationBase.of(context).topBrands, style: TextStyle( @@ -61,7 +56,7 @@ class _ProductBrandsPageState extends State { height: 220, width: double.infinity, color: Colors.white, - child: topBrand(), + child: topBrand(context), ), SizedBox( height: 10, @@ -93,8 +88,7 @@ class _ProductBrandsPageState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => SearchBrandsPage()), + FadePage(page: SearchBrandsPage()), ); }, ), @@ -103,7 +97,7 @@ class _ProductBrandsPageState extends State { height: 10, ), Container( - height: 230, + height: 290, width: double.infinity, color: Colors.white, child: ListView.builder( @@ -116,7 +110,9 @@ class _ProductBrandsPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start, children: [ - languageID == 'ar' ? Text(model.brandsListList[index].namen):Text(model.brandsListList[index].name), + languageID == 'ar' + ? Text(model.brandsListList[index].namen) + : Text(model.brandsListList[index].name), SizedBox( height: 3, ), @@ -124,8 +120,15 @@ class _ProductBrandsPageState extends State { ], ), ), - onTap: (){ - print("ENAD"); + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FinalProductsPage( + id: model.brandsListList[index].id + .toString(), + )), + ); }, ); }), @@ -138,9 +141,9 @@ class _ProductBrandsPageState extends State { } } - -topBrand() { +topBrand(BuildContext context) { return BaseView( + allowAny: true, onModelReady: (model) => model.getTopBrandsData(), builder: (_, model, wi) => GridView.count( crossAxisCount: 4, @@ -156,31 +159,39 @@ topBrand() { child: Container( // padding: EdgeInsets.only(left: 5), child: Container( - padding: EdgeInsets.symmetric( - horizontal: 10.0, vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), - border: Border( - top: BorderSide(width: 1.0, color: Colors.grey), - left: BorderSide(width: 1.0, color: Colors.grey), - right: BorderSide(width: 1.0, color: Colors.grey), - bottom: BorderSide(width: 1.0, color: Colors.grey), + padding: EdgeInsets.symmetric( + horizontal: 10.0, vertical: 10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10), + border: Border( + top: BorderSide(width: 1.0, color: Colors.grey), + left: BorderSide(width: 1.0, color: Colors.grey), + right: BorderSide(width: 1.0, color: Colors.grey), + bottom: + BorderSide(width: 1.0, color: Colors.grey), + ), + color: Colors.white, ), - color: Colors.white, - ), - child: model.topBrandsListList[index].image != null ?Image.network( - model.topBrandsListList[index].image.src, - fit: BoxFit.cover, - width: 60, - height: 40, - ): Text(model.topBrandsListList[index].name) - ), + child: model.topBrandsListList[index].image != null + ? Image.network( + model.topBrandsListList[index].image.src, + fit: BoxFit.cover, + width: 60, + height: 40, + ) + : Text(model.topBrandsListList[index].name)), ), ), ), ), - onTap: (){ - print("ENAD"); + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => FinalProductsPage( + id: model.topBrandsListList[index].id.toString(), + )), + ); }, ), ], diff --git a/lib/pages/pharmacies/product_detail.dart b/lib/pages/pharmacies/product_detail.dart index 2040db11..bd776355 100644 --- a/lib/pages/pharmacies/product_detail.dart +++ b/lib/pages/pharmacies/product_detail.dart @@ -1,31 +1,37 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scafold_detail_page.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; +import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:rating_bar/rating_bar.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; + import 'screens/cart-order-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/compare-list.dart'; int price = 0; var languageID; bool isOverQuantity = false; bool isInWishlit = false; -var itemID; -var product; +String itemID; var customerId; CompareList compareItems = new CompareList(); PharmacyProduct specificationData; class ProductDetailPage extends StatefulWidget { final PharmacyProduct product; + ProductDetailPage(this.product); + @override __ProductDetailPageState createState() => __ProductDetailPageState(); } @@ -36,16 +42,51 @@ class __ProductDetailPageState extends State { bool isReviews = false; bool isAvailabilty = false; dynamic wishlistItems; + var model; + + // String ProductId="4561"; + String productId = ""; + + checkWishlist() async { + GifLoaderDialogUtils.showMyDialog(context); + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.checkWishlistData(); + +// isInWishlit = x.wishListItems.map((e) => e.id.toString()).toList().contains(itemID); + + for (int i = 0; i < x.wishListItems.length; i++) { + if (itemID == x.wishListItems[i].product.id) { + isInWishlit = true; + break; + } else { + isInWishlit = false; + } + } + GifLoaderDialogUtils.hideDialog(context); + setState(() {}); + } void initState() { - price = 0; + price = 1; specificationData = widget.product; - setState(() { - customerId = userInfo(widget.product.id, widget.product); - }); + userInfo(); super.initState(); } + void userInfo() async { + print(specificationData); + customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + if (customerId != null) { + itemID = widget.product.id; + checkWishlist(); +// getSpecificationData(itemID); + } + print("customerId:$customerId"); + + setState(() {}); +// getSpecificationData(itemID); + } + Widget build(BuildContext context) { return customerId != null ? DetailPageScafold( @@ -159,7 +200,7 @@ class __ProductDetailPageState extends State { ), Container( width: 500, - margin: EdgeInsets.only(bottom: 100), + margin: EdgeInsets.only(bottom: 6), // height: 350, color: Colors.white, child: Column( @@ -264,34 +305,89 @@ class __ProductDetailPageState extends State { ? Padding( padding: const EdgeInsets.all(8.0), child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - child: Text( - TranslationBase.of(context).description, - style: TextStyle( - fontSize: 17, - color: Colors.grey, - fontWeight: FontWeight.w600), + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + child: Text( + TranslationBase.of(context) + .description, + style: TextStyle( + fontSize: 17, + color: Colors.grey, + fontWeight: FontWeight.w600), + ), ), - ), - SizedBox( - height: 10, - ), - Container( - child: Text( - languageID == 'ar' - ? widget.product.fullDescriptionn - : widget.product.fullDescription, - style: TextStyle( - fontSize: 16, - fontFamily: 'WorkSans-Regular'), + SizedBox( + height: 10, ), - ), - ], - ), + Divider(height: 1, color: Colors.grey), + SizedBox( + height: 15, + ), + Container( + child: Text( + languageID == 'ar' + ? widget.product.fullDescriptionn + : widget.product + .fullDescription ?? + "", + style: TextStyle( + fontSize: 16, + fontFamily: 'WorkSans-Regular'), + ), + ), + SizedBox( + height: 20, + ), + ]), ) + +// Container( +// child: Text( +// languageID == 'ar' +// ? widget.product.fullDescriptionn +// : widget.product.fullDescription, +// style: TextStyle( +// fontSize: 16, +// fontFamily: 'WorkSans-Regular'), +// ), +// ), +// SizedBox( +// height: 10, +// ), +// Container( +// child: Text( +// TranslationBase.of(context).howToUse, +// style: TextStyle( +// fontSize: 17, +// color: Colors.grey, +// fontWeight: FontWeight.w600), +// ), +// ), +// SizedBox( +// height: 6, +// ), +// Divider( +// height: 2, +// color: Colors.grey), +// SizedBox( +// height: 10, +// ), +// Container( +// child: Text( +// languageID == 'ar' +// ? widget.product.shortDescriptionn +// : widget.product.shortDescription, +// style: TextStyle( +// fontSize: 16, +// fontFamily: 'WorkSans-Regular'), +// ), +// ), + // ], + // ), + // ) : isReviews ? BaseView( onModelReady: (model) => @@ -509,7 +605,291 @@ class __ProductDetailPageState extends State { ], ), ), -// ListView(scrollDirection: Axis.vertical, shrinkWrap: true, children: [Text('ENAD')]), + Row( + children: [ +// Container( +// width: 500, +// height: 100, +// margin: EdgeInsets.only(bottom: 100), +// color: Colors.white, +// child: Text("ENAD TEST"), +// ), + Container( + width: 410, + height: 50, + // margin: EdgeInsets.only(bottom: 5), + color: Colors.white, + child: Texts( + TranslationBase.of(context).recommended, + bold: true, + ), + ), + ], + ), + SingleChildScrollView( + child: Container( + color: Colors.white, + child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.start, +// mainAxisSize: MainAxisSize.min, + children: [ + Container( + color: Colors.white, + height: 210, + margin: EdgeInsets.only(bottom: 75), + padding: EdgeInsets.only(bottom: 5), + // margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), + child: BaseView( + onModelReady: (model) => + model.getRecommendedProducts( + widget.product.id.toString()), + builder: (_, model, wi) => Container( + child: +// Text(model.recommendedProductList[0].id), + model.recommendedProductList.length != + null + ? Expanded( + child: ListView.builder( + scrollDirection: + Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: NeverScrollableScrollPhysics(), + itemCount: model + .recommendedProductList + .length, + itemBuilder: + (context, index) { + return Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Colors + .grey[ + 300], + width: 2), + borderRadius: + BorderRadius + .circular( + 10)), + margin: EdgeInsets + .symmetric( + horizontal: 8, + vertical: 0, + ), + child: Container( + decoration: + BoxDecoration( + borderRadius: + BorderRadius + .all( + Radius.circular( + 15), + ), + ), + padding: EdgeInsets + .symmetric( + horizontal: + 4), + width: MediaQuery.of( + context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Stack( + children: [ + Container( + child: Align( + alignment: Alignment.topRight, + child: //true + itemID.contains(model.recommendedProductList[index].id) + // !isInWishlist + ? IconButton( + icon: Icon(Icons.favorite_border), + color: Colors.grey, + iconSize: 30, + onPressed: () { + setState(() { + addToWishlistFunction(itemID); + }); + }, + ) + : IconButton( + icon: Icon(Icons.favorite), + color: Colors.red, + iconSize: 30, + onPressed: () { + setState(() { + deleteFromWishlistFunction(itemID); + }); + }, + ) +// + ), + ), + Container( + margin: EdgeInsets.fromLTRB( + 0, + 16, + 10, + 16), + alignment: + Alignment.center, +// padding: EdgeInsets.only(left: 25, bottom: 20), + child: (model.recommendedProductList[index].images != null && + model.recommendedProductList[index].images.length > 0) + ? Image.network( + model.recommendedProductList[index].images[0].src.toString(), +// item.images[0].src, + fit: BoxFit.cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 60, + ), + ), + Container( + width: model.recommendedProductList[index].rxMessage != + null + ? MediaQuery.of(context).size.width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: + BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only(topLeft: Radius.circular(6)), + ), + child: + Texts( + model.recommendedProductList[index].rxMessage != null + ? model.recommendedProductList[index].rxMessage + : "", + color: + Colors.white, + regular: + true, + fontSize: + 10, + fontWeight: + FontWeight.w400, + ), + ), + ]), + Container( + margin: EdgeInsets + .symmetric( + horizontal: + 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + languageID == + "ar" + ? model.recommendedProductList[index].namen + : model.recommendedProductList[index].name, + style: + TextStyle( + color: + Colors.black, + fontSize: + 13.0, +// fontWeight: FontWeight.bold, + ), + ), + Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), + padding: const EdgeInsets.only( + top: + 10, + bottom: + 5), + child: + Texts( + "SAR ${model.recommendedProductList[index].price}", + bold: + true, + fontSize: + 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: < + Widget>[ + Container( + padding: + EdgeInsets.only(right: 10), +// margin: EdgeInsets.only(left: 5), + child: + Align( + alignment: + Alignment.topLeft, + child: + RatingBar.readOnly( + initialRating: + model.recommendedProductList[index].approvedRatingSum.toDouble(), +// initialRating: productRate, + size: + 13.0, + filledColor: + Colors.yellow[700], + emptyColor: + Colors.grey[500], + isHalfAllowed: + true, + halfFilledIcon: + Icons.star_half, + filledIcon: + Icons.star, + emptyIcon: + Icons.star, + ), + ), + ), + Texts( + "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +// bold: true, + fontSize: + 12, + ), + ]), + ], + ), + ), + ); + }), + ) + : Container( +// child: Text("NO DATA"), + ), + )), + ), + ], + ), + ), + ) ], ), ), @@ -740,6 +1120,39 @@ class __ProductDetailPageState extends State { fontWeight: FontWeight.w600), ), ), + SizedBox( + height: 6, + ), + Divider(height: 1, color: Colors.grey), + SizedBox( + height: 10, + ), + Container( + child: Text( + languageID == 'ar' + ? widget.product.shortDescriptionn + : widget.product.shortDescription, + style: TextStyle( + fontSize: 16, + fontFamily: 'WorkSans-Regular'), + ), + ), + SizedBox( + height: 10, + ), + Container( + child: Text( + TranslationBase.of(context).howToUse, + style: TextStyle( + fontSize: 17, + color: Colors.grey, + fontWeight: FontWeight.w600), + ), + ), + SizedBox( + height: 6, + ), + Divider(height: 2, color: Colors.grey), SizedBox( height: 10, ), @@ -975,8 +1388,10 @@ class footerWidget extends StatefulWidget { final int minQuantity; final int quantityLimit; final PharmacyProduct item; + footerWidget(this.isAvailble, this.maxQuantity, this.minQuantity, this.quantityLimit, this.item); + @override _footerWidgetState createState() => _footerWidgetState(); } @@ -984,6 +1399,7 @@ class footerWidget extends StatefulWidget { class _footerWidgetState extends State { double quantityUI = 70; bool showUI = false; + @override Widget build(BuildContext context) { return Container( @@ -1366,7 +1782,9 @@ class _footerWidgetState extends State { }, ), ), - !widget.isAvailble && price > 0 || price > widget.quantityLimit + !widget.isAvailble && price > 0 || + price > widget.quantityLimit || + widget.item.rxMessage != null ? Container( width: 190, height: 46, @@ -1384,7 +1802,7 @@ class _footerWidgetState extends State { ) : InkWell( onTap: () { - addToCartFunction(price, widget.item.id); + addToCartFunction(price, widget.item.id, context); }, child: Container( alignment: Alignment.center, @@ -1403,7 +1821,9 @@ class _footerWidgetState extends State { SizedBox( width: 5, ), - !widget.isAvailble && price > 0 || price > widget.quantityLimit + !widget.isAvailble && price > 0 || + price > widget.quantityLimit || + widget.item.rxMessage != null ? Container( width: 120, height: 46, @@ -1422,11 +1842,10 @@ class _footerWidgetState extends State { : InkWell( onTap: () { print('buy now'); - addToCartFunction(price, widget.item.id); + addToCartFunction(price, widget.item.id, context); Navigator.push( context, - MaterialPageRoute( - builder: (context) => CartOrderPage()), + FadePage(page: CartOrderPage()), ); }, child: Container( @@ -1454,7 +1873,9 @@ class _footerWidgetState extends State { class productNameAndPrice extends StatefulWidget { BuildContext context; PharmacyProduct item; + productNameAndPrice(this.context, this.item); + @override _productNameAndPriceState createState() => _productNameAndPriceState(); } @@ -1470,7 +1891,7 @@ class _productNameAndPriceState extends State { child: Row( children: [ Text( - widget.item.price.toString(), + widget.item.price.toString() + " " + "SAR", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30), ), SizedBox( @@ -1484,53 +1905,55 @@ class _productNameAndPriceState extends State { fontWeight: FontWeight.bold, color: Colors.green), ), SizedBox(width: 20), - widget.item.stockAvailability == 'Out of stock' - ? Text( - TranslationBase.of(context).notifyMe, - style: TextStyle( - color: Colors.blue, - decoration: TextDecoration.underline, - ), - ) - : Container(), - widget.item.stockAvailability == 'Out of stock' - ? Icon( - FontAwesomeIcons.bell, - color: Colors.blue, - size: 15.0, - ) - : Container(), - Container( - margin: languageID == 'ar' - ? EdgeInsets.only(right: 25) - : EdgeInsets.only(left: 25), - width: 40, - height: 40, - decoration: BoxDecoration( - color: Colors.grey, - borderRadius: BorderRadius.circular(30), - ), - child: !isInWishlit - ? IconButton( - icon: Icon(Icons.favorite_border), - color: Colors.white, - onPressed: () { - setState(() { - addToWishlistFunction(widget.item.id); - }); -// MyStatelessWidget(); - }, + widget.item.stockAvailability == 'Out of stock' && + customerId != null + ? InkWell( + onTap: () => + notifyMeWhenAvailable(context, widget.item.id), + child: Row(children: [ + Text( + TranslationBase.of(context).notifyMe, + style: TextStyle( + color: Colors.blue, + decoration: TextDecoration.underline, + ), + ), + SizedBox(width: 4), + Icon( + FontAwesomeIcons.bell, + color: Colors.blue, + size: 15.0, ) - : IconButton( - icon: Icon(Icons.favorite), - color: Colors.red, - onPressed: () { - setState(() { - deleteFromWishlistFunction(widget.item.id); - }); -// MyStatelessWidget(); - }, - )), + ]), + ) + : Container( + margin: languageID == 'ar' + ? EdgeInsets.only(right: 25) + : EdgeInsets.only(left: 25), + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.grey, + borderRadius: BorderRadius.circular(30), + ), + child: IconButton( + icon: Icon(!isInWishlit + ? Icons.favorite_border + : Icons.favorite), + color: !isInWishlit ? Colors.white : Colors.red, + onPressed: () async { + if (customerId != null) { + if (!isInWishlit) { + await addToWishlistFunction(widget.item.id); + } else { + await deleteFromWishlistFunction(widget.item.id); + } + } else { + return; + } + setState(() {}); + }, + )), ], ), ), @@ -1597,135 +2020,6 @@ class _productNameAndPriceState extends State { } } -//productNameAndPrice(BuildContext context, item) { -// return Column( -// mainAxisAlignment: MainAxisAlignment.start, -// children: [ -// Padding( -// padding: const EdgeInsets.all(8.0), -// child: Row( -// children: [ -// Text( -// item.price.toString(), -// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30), -// ), -// SizedBox( -// width: 40, -// ), -// Text( -// item.stockAvailability, -// style: item.stockAvailability == 'Out of stock' -// ? TextStyle(fontWeight: FontWeight.bold, color: Colors.red) -// : TextStyle(fontWeight: FontWeight.bold, color: Colors.green), -// ), -// SizedBox(width: 20), -// item.stockAvailability == 'Out of stock' -// ? Text( -// TranslationBase.of(context).notifyMe, -// style: TextStyle( -// color: Colors.blue, -// decoration: TextDecoration.underline, -// ), -// ) -// : Container(), -// item.stockAvailability == 'Out of stock' -// ? Icon( -// FontAwesomeIcons.bell, -// color: Colors.blue, -// size: 15.0, -// ) -// : Container(), -// -// Container( -// margin: languageID=='ar' ? EdgeInsets.only(right: 25) : EdgeInsets.only(left: 25), -// width: 40, -// height: 40, -// decoration: BoxDecoration( -// color: Colors.grey, -// borderRadius: BorderRadius.circular(30), -// ), -// child: !isInWishlit ?IconButton( -// icon: Icon(Icons.favorite_border), -// color: Colors.white, -// onPressed: () { -// addToWishlistFunction(item.id); -//// MyStatelessWidget(); -// -// }, -// ):IconButton( -// icon: Icon(Icons.favorite), -// color: Colors.red, -// onPressed: () { -// deleteFromWishlistFunction(item.id); -//// MyStatelessWidget(); -// -// }, -// ) -// ), -// -// ], -// ), -// ), -// Padding( -// padding: const EdgeInsets.all(8.0), -// child: Container( -// margin: EdgeInsets.only(left: 5), -// child: Align( -// alignment: -// languageID == 'ar' ? Alignment.topRight : Alignment.topLeft, -// child: Text( -// languageID == 'ar' ? item.fullDescriptionn : item.fullDescription, -// style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15), -// ), -// ), -// ), -// ), -// Row( -// children: [ -// Expanded( -// flex: 2, -// child: Container( -// margin: EdgeInsets.only(right: 150), -// child: Align( -// alignment: Alignment.bottomLeft, -// child: RatingBar.readOnly( -// initialRating: 3, -// size: 15.0, -// filledColor: Colors.yellow[700], -// emptyColor: Colors.grey[500], -// isHalfAllowed: true, -// halfFilledIcon: Icons.star_half, -// filledIcon: Icons.star, -// emptyIcon: Icons.star, -// ), -// ), -// ), -// ), -// Expanded( -// flex: 1, -// child: Container( -// child: item.rxMessage != null -// ? Text( -// languageID == 'ar' -// ? item.rxMessagen.toString() -// : item.rxMessage.toString(), -// style: TextStyle(color: Colors.red, fontSize: 10), -// ) -// : Container()), -// ), -// item.rxMessage != null -// ? Icon( -// FontAwesomeIcons.questionCircle, -// color: Colors.red, -// size: 15.0, -// ) -// : Container(), -// ], -// ), -// ], -// ); -//} - slideDetail() { return Row( mainAxisAlignment: MainAxisAlignment.start, @@ -1771,9 +2065,17 @@ getSpecificationData(itemID) async { specificationData = await x.productSpecificationData(itemID); } -addToCartFunction(quantity, itemID) async { +addToCartFunction(quantity, itemID, BuildContext context) async { + GifLoaderDialogUtils.showMyDialog(context); ProductDetailViewModel x = new ProductDetailViewModel(); - await x.addToCartData(quantity, itemID); + await x.addToCartData(quantity, itemID).then((value) { + GifLoaderDialogUtils.hideDialog(context); + }); +} + +notifyMeWhenAvailable(context, itemId) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.notifyMe(customerId, itemId); } addToWishlistFunction(itemID) async { @@ -1785,22 +2087,21 @@ addToWishlistFunction(itemID) async { deleteFromWishlistFunction(itemID) async { ProductDetailViewModel x = new ProductDetailViewModel(); isInWishlit = false; - await x.addToWishlistData(itemID); + await x.deletWishlistData(itemID); } checkWishlist() async { ProductDetailViewModel x = new ProductDetailViewModel(); await x.checkWishlistData(); + +// isInWishlit = x.wishListItems.map((e) => e.id.toString()).toList().contains(itemID); + for (int i = 0; i < x.wishListItems.length; i++) { -// print(itemID); -// print(x.wishListItems[i].product.id); if (itemID == x.wishListItems[i].product.id) { isInWishlit = true; -// print('in wishlist'); break; } else { isInWishlit = false; -// print('not in wishlist'); } } } @@ -1820,25 +2121,25 @@ settingModalBottomSheet(context) { child: new Wrap( children: [ new ListTile( - leading: new Icon(Icons.shopping_cart), - title: new Text('Add to cart'), + leading: Icon(Icons.shopping_cart), + title: Text('Add to cart'), onTap: () => { if (price > 0) - {addToCartFunction(price, itemID)} + {addToCartFunction(price, itemID, context)} else { AppToast.showErrorToast( message: "you should add quantity") } }), - new ListTile( - leading: new Icon(Icons.favorite_border), - title: new Text('Add to wishlist'), + ListTile( + leading: Icon(Icons.favorite_border), + title: Text('Add to wishlist'), onTap: () => {addToWishlistFunction(itemID)}, ), - new ListTile( - leading: new Icon(Icons.compare), - title: new Text('Compare'), + ListTile( + leading: Icon(Icons.compare), + title: Text('Compare'), onTap: () => { Provider.of(context, listen: false) .addItem(specificationData), @@ -1849,14 +2150,3 @@ settingModalBottomSheet(context) { ); }); } - -userInfo(id, product) async { - customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); - if (customerId != null) { - itemID = id; - product = product; - checkWishlist(); - } - return customerId; -// getSpecificationData(itemID); -} diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index c5576900..f672cc66 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/ShoppingCartResponse.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; @@ -7,6 +8,7 @@ import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-preview import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderItem.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/GestureIconButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -19,23 +21,17 @@ class CartOrderPage extends StatelessWidget { Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - PreferredSizeWidget appBarWidget = - AppBarWidget(TranslationBase.of(context).shoppingCart, null, true); - final height = mediaQuery.size.height - - appBarWidget.preferredSize.height - - mediaQuery.padding.top; + final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; return BaseView( onModelReady: (model) => model.getOrderPreviewData(), builder: (_, model, wi) => ChangeNotifierProvider.value( value: model.cartResponse, child: AppScaffold( - title: TranslationBase.of(context).shoppingCart, + appBarTitle: TranslationBase.of(context).shoppingCart, isShowAppBar: true, - isShowDecPage: false, isPharmacy: true, baseViewModel: model, - appBarWidget: appBarWidget, backgroundColor: Colors.white, body: !(model.cartResponse.shoppingCarts == null || model.cartResponse.shoppingCarts.length == 0) @@ -76,8 +72,16 @@ class CartOrderPage extends StatelessWidget { cart.shoppingCarts[index], () { print(cart.shoppingCarts[index] .quantity); - model.changeProductQuantity( - cart.shoppingCarts[index]); + model + .changeProductQuantity( + cart.shoppingCarts[index]) + .then((value) { + if (model.state == + ViewState.ErrorLocal) { + Utils.showErrorToast( + model.error); + } + }); }, () => model.deleteProduct( cart.shoppingCarts[index]))) @@ -179,7 +183,29 @@ class CartOrderPage extends StatelessWidget { ), ), ) - : Container(), + : Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Image.asset( + 'assets/images/new-design/empty_box.png', + width: 100, + height: 100, + fit: BoxFit.cover, + ), + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + 'There is no data', + style: TextStyle(fontSize: 30), + ), + ) + ], + ), + ), bottomSheet: Container( height: !(model.cartResponse.shoppingCarts == null || model.cartResponse.shoppingCarts.length == 0) @@ -230,64 +256,62 @@ class _OrderBottomWidgetState extends State { height: widget.height * 0.070, color: Color(0xffe6ffe0), padding: EdgeInsets.symmetric(horizontal: 4), - child: Expanded( - child: Row( - children: [ - InkWell( - onTap: () { - setState(() { - isAgree = !isAgree; - }); - }, - child: Container( - width: 25.0, - height: widget.height * 0.070, - decoration: new BoxDecoration( - color: !isAgree - ? Color(0xffeeeeee) - : Colors.green, - shape: BoxShape.circle, + child: Row( + children: [ + InkWell( + onTap: () { + setState(() { + isAgree = !isAgree; + }); + }, + child: Container( + width: 25.0, + height: widget.height * 0.070, + decoration: new BoxDecoration( + color: !isAgree + ? Color(0xffeeeeee) + : Colors.green, + shape: BoxShape.circle, + ), + child: !isAgree + ? null + : Padding( + padding: const EdgeInsets.all(0.0), + child: Icon( + Icons.check, + color: Colors.white, + size: 25, ), - child: !isAgree - ? null - : Padding( - padding: const EdgeInsets.all(0.0), - child: Icon( - Icons.check, - color: Colors.white, - size: 25, - ), - ), ), ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(horizontal: 4), - margin: const EdgeInsets.symmetric(vertical: 4), - child: Texts( - TranslationBase.of(context) - .pharmacyServiceTermsCondition, - fontSize: 13, - color: Colors.grey.shade800, - fontWeight: FontWeight.normal, - ), + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(horizontal: 4), + margin: const EdgeInsets.symmetric(vertical: 4), + child: Texts( + TranslationBase.of(context) + .pharmacyServiceTermsCondition, + fontSize: 13, + color: Colors.grey.shade800, + fontWeight: FontWeight.normal, ), ), - InkWell( - onTap: () => { - Navigator.push(context, - FadePage(page: PharmacyTermsConditions())) - }, - child: Container( - child: Icon( - Icons.info, - size: 25, - color: Color(0xff005aff), - ), + ), + InkWell( + onTap: () => { + Navigator.push(context, + FadePage(page: PharmacyTermsConditions())) + }, + child: Container( + child: Icon( + Icons.info, + size: 25, + color: Color(0xff005aff), ), ), - ], - ), + ), + ], ), ), Container( diff --git a/lib/pages/pharmacies/screens/cart-order-preview.dart b/lib/pages/pharmacies/screens/cart-order-preview.dart index b4736d7a..5d271a1a 100644 --- a/lib/pages/pharmacies/screens/cart-order-preview.dart +++ b/lib/pages/pharmacies/screens/cart-order-preview.dart @@ -1,46 +1,45 @@ import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/Addresses.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/payment-checkout-data.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/OrderPreviewViewModel.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/address-select-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/payment-method-select-page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy_module_page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductOrderPreviewItem.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import 'package:flutter/scheduler.dart'; class OrderPreviewPage extends StatelessWidget { final List addresses; OrderPreviewPage(this.addresses); + MyInAppBrowser browser; + @override Widget build(BuildContext context) { - PreferredSizeWidget appBarWidget = - AppBarWidget("${TranslationBase.of(context).checkOut}", null, true); final mediaQuery = MediaQuery.of(context); - final height = mediaQuery.size.height - - appBarWidget.preferredSize.height - - mediaQuery.padding.top; + final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; return BaseView( onModelReady: (model) => model.getShoppingCart(), builder: (_, model, wi) => ChangeNotifierProvider.value( value: model.paymentCheckoutData, child: AppScaffold( - title: "${TranslationBase.of(context).checkOut}", + appBarTitle: "${TranslationBase.of(context).checkOut}", isShowAppBar: true, isPharmacy: true, isShowDecPage: false, - appBarWidget: appBarWidget, backgroundColor: Colors.white, baseViewModel: model, body: Container( @@ -60,18 +59,18 @@ class OrderPreviewPage extends StatelessWidget { ), Consumer( builder: (ctx, paymentData, _) => - paymentData.lacumInformation != null - ? Container( - child: Column( - children: [ - LakumWidget(model), - SizedBox( - height: 10, - ), - ], - ), - ) - : Container()), + paymentData.lacumInformation != null + ? Container( + child: Column( + children: [ + LakumWidget(model), + SizedBox( + height: 10, + ), + ], + ), + ) + : Container()), Container( color: Colors.white, width: double.infinity, @@ -80,7 +79,9 @@ class OrderPreviewPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - TranslationBase.of(context).reviewOrder, + TranslationBase + .of(context) + .reviewOrder, fontSize: 14, fontWeight: FontWeight.bold, color: Colors.black, @@ -89,8 +90,10 @@ class OrderPreviewPage extends StatelessWidget { model.cartResponse.shoppingCarts != null ? model.cartResponse.shoppingCarts.length : 0, - (index) => ProductOrderPreviewItem( - model.cartResponse.shoppingCarts[index]), + (index) => + ProductOrderPreviewItem( + model.cartResponse + .shoppingCarts[index]), ), ], ), @@ -100,117 +103,140 @@ class OrderPreviewPage extends StatelessWidget { padding: EdgeInsets.all(8), child: model.cartResponse.subtotal != null ? Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - TranslationBase.of(context) - .orderSummary, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - SizedBox( - height: 20, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).subtotal}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).shipping}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.totalAdditionalShippingCharge).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - "${TranslationBase.of(context).vat}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotalVatAmount).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.w500, - ), - ], - ), - const Divider( - color: Color(0xFFD6D6D6), - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Texts( - TranslationBase.of(context).total, - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - color: Colors.black, - fontWeight: FontWeight.bold, - ), - ], - ), - SizedBox( - height: 10, - ), - ], - ) + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .orderSummary, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + SizedBox( + height: 20, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .subtotal}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .shipping}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model + .totalAdditionalShippingCharge) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + "${TranslationBase + .of(context) + .vat}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse + .subtotalVatAmount).toStringAsFixed( + 2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.w500, + ), + ], + ), + const Divider( + color: Color(0xFFD6D6D6), + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, + ), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase + .of(context) + .total, + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + Texts( + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ], + ), + SizedBox( + height: 10, + ), + ], + ) : Container(), ) ], @@ -273,161 +299,172 @@ class _SelectAddressWidgetState extends State { @override Widget build(BuildContext context) { return Consumer( - builder: (ctx, paymentData, _) => Container( - color: Colors.white, - child: address == null - ? InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_address.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, + builder: (ctx, paymentData, _) => + Container( + color: Colors.white, + child: address == null + ? InkWell( + onTap: () => {_navigateToAddressPage()}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_address.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: + EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .selectAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), + ), + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) + : Container( + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_mark.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric( + vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .shippingAddress, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToAddressPage()}, child: Texts( - TranslationBase.of(context).selectAddress, - fontSize: 14, - fontWeight: FontWeight.bold, + TranslationBase + .of(context) + .changeAddress, + fontSize: 12, + fontWeight: FontWeight.normal, color: Color(0xff0000ff), ), ), + ], + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address.firstName} ${address.lastName}", + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Texts( + "${address.address1} ${address.address2} ${address + .address2},, ${address.city}, ${address + .country} ${address.zipPostalCode}", + fontSize: 12, + fontWeight: FontWeight.normal, + color: Colors.grey.shade500, ), - ], - ), - ), - ) - : Container( - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_mark.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - TranslationBase.of(context).shippingAddress, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToAddressPage()}, - child: Texts( - TranslationBase.of(context).changeAddress, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), + ), + Row( + children: [ + Container( + margin: const EdgeInsets.only(right: 8), + child: Icon( + Icons.phone, + size: 20, + color: Colors.black, ), - ], - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.firstName} ${address.lastName}", + ), + Texts( + "${address.phoneNumber}", fontSize: 14, fontWeight: FontWeight.bold, - color: Colors.black, + color: Colors.grey, ), - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Texts( - "${address.address1} ${address.address2} ${address.address2},, ${address.city}, ${address.country} ${address.zipPostalCode}", - fontSize: 12, - fontWeight: FontWeight.normal, - color: Colors.grey.shade500, + ], + ), + Container( + margin: EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + height: 2, + width: double.infinity, + child: Container( + color: Color(0xffefefef), ), ), - Row( - children: [ - Container( - margin: const EdgeInsets.only(right: 8), - child: Icon( - Icons.phone, - size: 20, - color: Colors.black, - ), - ), - Texts( - "${address.phoneNumber}", - fontSize: 14, + ), + Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_shipping_truck.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + padding: EdgeInsets.symmetric( + vertical: 0, horizontal: 6), + child: Texts( + "${TranslationBase + .of(context) + .shipBy}", + fontSize: 12, fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ], - ), - Container( - margin: EdgeInsets.symmetric(vertical: 8), - child: SizedBox( - height: 2, - width: double.infinity, - child: Container( - color: Color(0xffefefef), + color: Colors.black, ), ), - ), - Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_shipping_truck.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - padding: EdgeInsets.symmetric( - vertical: 0, horizontal: 6), - child: Texts( - "${TranslationBase.of(context).shipBy}", - fontSize: 12, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - Container( - child: Image.asset( - paymentData.shippingOption - .shippingRateComputationMethodSystemName == - "Shipping.FixedOrByWeight" - ? "assets/images/pharmacy_module/payment/hmg_shipping_logo.png" - : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", - fit: BoxFit.contain, - ), - margin: EdgeInsets.symmetric(horizontal: 8), + Container( + child: Image.asset( + paymentData.shippingOption + .shippingRateComputationMethodSystemName == + "Shipping.FixedOrByWeight" + ? "assets/images/pharmacy_module/payment/hmg_shipping_logo.png" + : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", + fit: BoxFit.contain, ), - ], - ), - ], - ), + margin: EdgeInsets.symmetric(horizontal: 8), + ), + ], + ), + ], ), - ), // ic_shipping_mark.png - ), + ), + ), // ic_shipping_mark.png + ), ); } } @@ -447,16 +484,17 @@ class _SelectPaymentOptionWidgetState extends State { _navigateToPaymentOption() { Navigator.push(context, FadePage(page: PaymentMethodSelectPage())) - .then((result) => { - setState(() { - if (result != null) { - paymentOption = result; - widget.model.paymentCheckoutData.paymentOption = - paymentOption; - widget.model.paymentCheckoutData.updateData(); - } - }) - }); + .then((result) => + { + setState(() { + if (result != null) { + paymentOption = result; + widget.model.paymentCheckoutData.paymentOption = + paymentOption; + widget.model.paymentCheckoutData.updateData(); + } + }) + }); } @override @@ -473,85 +511,89 @@ class _SelectPaymentOptionWidgetState extends State { color: Colors.white, child: paymentOption == null ? InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Expanded( - child: Container( - padding: - EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - TranslationBase.of(context).selectPaymentOption, - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff0000ff), - ), - ), - ), - Icon( - Icons.arrow_forward_ios, - size: 20, - color: Colors.grey.shade400, - ), - ], + onTap: () => {_navigateToPaymentOption()}, + child: Container( + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Expanded( + child: Container( + padding: + EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + TranslationBase + .of(context) + .selectPaymentOption, + fontSize: 14, + fontWeight: FontWeight.bold, + color: Color(0xff0000ff), + ), ), ), - ) + Icon( + Icons.arrow_forward_ios, + size: 20, + color: Colors.grey.shade400, + ), + ], + ), + ), + ) : Container( - margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), - child: Row( - children: [ - Image.asset( - "assets/images/pharmacy_module/ic_payment_option.png", - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - Container( - margin: EdgeInsets.symmetric(horizontal: 8), - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), - decoration: new BoxDecoration( - color: Colors.grey.shade100, - shape: BoxShape.rectangle, - ), - child: Image.asset( - widget.model.getPaymentOptionImage(paymentOption), - width: 30.0, - height: 30.0, - fit: BoxFit.scaleDown, - ), - ), - Expanded( - child: Container( - padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), - child: Texts( - widget.model.getPaymentOptionName(paymentOption), - fontSize: 14, - fontWeight: FontWeight.bold, - color: Colors.black, - ), - ), - ), - InkWell( - onTap: () => {_navigateToPaymentOption()}, - child: Texts( - TranslationBase.of(context).changeMethod, - fontSize: 12, - fontWeight: FontWeight.normal, - color: Color(0xff0000ff), - ), - ), - ], + margin: EdgeInsets.symmetric(vertical: 12, horizontal: 12), + child: Row( + children: [ + Image.asset( + "assets/images/pharmacy_module/ic_payment_option.png", + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 8), + padding: EdgeInsets.symmetric(horizontal: 4, vertical: 0), + decoration: new BoxDecoration( + color: Colors.grey.shade100, + shape: BoxShape.rectangle, + ), + child: Image.asset( + widget.model.getPaymentOptionImage(paymentOption), + width: 30.0, + height: 30.0, + fit: BoxFit.scaleDown, ), ), + Expanded( + child: Container( + padding: EdgeInsets.symmetric(vertical: 0, horizontal: 6), + child: Texts( + widget.model.getPaymentOptionName(paymentOption), + fontSize: 14, + fontWeight: FontWeight.bold, + color: Colors.black, + ), + ), + ), + InkWell( + onTap: () => {_navigateToPaymentOption()}, + child: Texts( + TranslationBase + .of(context) + .changeMethod, + fontSize: 12, + fontWeight: FontWeight.normal, + color: Color(0xff0000ff), + ), + ), + ], + ), + ), ); } } @@ -589,12 +631,15 @@ class _LakumWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "${TranslationBase.of(context).lakumPoints}", + "${TranslationBase + .of(context) + .lakumPoints}", fontSize: 12, fontWeight: FontWeight.bold, ), Texts( - "${widget.model.paymentCheckoutData.lacumInformation.lakumInquiryInformationObjVersion.pointsBalanceAmount}", + "${widget.model.paymentCheckoutData.lacumInformation + .lakumInquiryInformationObjVersion.pointsBalanceAmount}", fontSize: 12, fontWeight: FontWeight.normal, ), @@ -609,7 +654,9 @@ class _LakumWidgetState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ Texts( - "${TranslationBase.of(context).riyal}", + "${TranslationBase + .of(context) + .riyal}", fontSize: 12, fontWeight: FontWeight.bold, ), @@ -623,19 +670,19 @@ class _LakumWidgetState extends State { decoration: InputDecoration( border: OutlineInputBorder( borderSide: - BorderSide(color: Colors.black, width: 0.2), + BorderSide(color: Colors.black, width: 0.2), gapPadding: 0, borderRadius: projectProvider.isArabic ? BorderRadius.only( - topRight: Radius.circular(8), - bottomRight: Radius.circular(8)) + topRight: Radius.circular(8), + bottomRight: Radius.circular(8)) : BorderRadius.only( - topLeft: Radius.circular(8), - bottomLeft: Radius.circular(8)), + topLeft: Radius.circular(8), + bottomLeft: Radius.circular(8)), ), disabledBorder: OutlineInputBorder( borderSide: - BorderSide(color: Colors.black, width: 0.4), + BorderSide(color: Colors.black, width: 0.4), gapPadding: 0, borderRadius: BorderRadius.only( topLeft: Radius.circular(8), @@ -647,22 +694,22 @@ class _LakumWidgetState extends State { style: TextStyle( fontSize: 14, color: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount > - 0 + .model + .paymentCheckoutData + .lacumInformation + .lakumInquiryInformationObjVersion + .pointsBalanceAmount > + 0 ? Colors.black : Colors.grey, ), enabled: widget - .model - .paymentCheckoutData - .lacumInformation - .lakumInquiryInformationObjVersion - .pointsBalanceAmount == - 0 + .model + .paymentCheckoutData + .lacumInformation + .lakumInquiryInformationObjVersion + .pointsBalanceAmount == + 0 ? false : true, onChanged: (val) { @@ -681,7 +728,7 @@ class _LakumWidgetState extends State { widget.model.paymentCheckoutData.usedLakumPoints = 0; } _pointsController.text = - "${widget.model.paymentCheckoutData.usedLakumPoints}"; + "${widget.model.paymentCheckoutData.usedLakumPoints}"; }, ), ), @@ -693,18 +740,20 @@ class _LakumWidgetState extends State { shape: BoxShape.rectangle, borderRadius: projectProvider.isArabic ? BorderRadius.only( - topLeft: Radius.circular(6), - bottomLeft: Radius.circular(6)) + topLeft: Radius.circular(6), + bottomLeft: Radius.circular(6)) : BorderRadius.only( - topRight: Radius.circular(6), - bottomRight: Radius.circular(6)), + topRight: Radius.circular(6), + bottomRight: Radius.circular(6)), border: Border.fromBorderSide(BorderSide( color: Color(0xff3666E0), width: 0.8, )), ), child: Texts( - "${TranslationBase.of(context).use}", + "${TranslationBase + .of(context) + .use}", fontSize: 12, color: Colors.white, fontWeight: FontWeight.bold, @@ -723,113 +772,176 @@ class _LakumWidgetState extends State { class PaymentBottomWidget extends StatelessWidget { final OrderPreviewViewModel model; + BuildContext context; + MyInAppBrowser browser; + PaymentBottomWidget(this.model); @override Widget build(BuildContext context) { final scaffold = Scaffold.of(context); + this.context = context; return Container( margin: EdgeInsets.symmetric(horizontal: 10, vertical: 0), child: Consumer( - builder: (ctx, paymentData, _) => paymentData.cartDataVisible + builder: (ctx, paymentData, _) => + paymentData.cartDataVisible ? Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Container( + margin: + EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Row( children: [ - Container( - margin: - EdgeInsets.symmetric(horizontal: 0, vertical: 4), - child: Row( - children: [ - Texts( - "${TranslationBase.of(context).sar} ${(model.cartResponse.subtotal).toStringAsFixed(2)}", - fontSize: 14, - fontWeight: FontWeight.bold, - color: Color(0xff929295), - ), - Padding( - padding: - const EdgeInsets.symmetric(horizontal: 4), - child: Texts( - "${TranslationBase.of(context).inclusiveVat}", - fontSize: 8, - color: Color(0xff929295), - fontWeight: FontWeight.w600, - ), - ), - ], - ), - ), Texts( - "${model.cartResponse.quantityCount} ${TranslationBase.of(context).items}", - fontSize: 10, - color: Colors.grey, + "${TranslationBase + .of(context) + .sar} ${(model.cartResponse.subtotal) + .toStringAsFixed(2)}", + fontSize: 14, fontWeight: FontWeight.bold, + color: Color(0xff929295), ), - ], - ), - Container( - child: RaisedButton( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - side: BorderSide( + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 4), + child: Texts( + "${TranslationBase + .of(context) + .inclusiveVat}", + fontSize: 8, color: Color(0xff929295), - width: 1, + fontWeight: FontWeight.w600, ), ), - onPressed: (paymentData.address != null && - paymentData.paymentOption != null) - ? () => { - model.makeOrder().then((_) { - if (model.state != ViewState.Idle) { - SnackBar snackBar = SnackBar( - content: Text( - 'Order has been placed successfully!!')); - scaffold.showSnackBar(snackBar); - } - - // Navigator.pushAndRemoveUntil( - // context, - // MaterialPageRoute( - // builder: (context) => - // PharmacyPage()), - // (Route r) => false); - }) - } - : null, - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 16), - child: new Text( - "${TranslationBase.of(context).proceedPay}", - style: new TextStyle( - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.white - : Colors.grey.shade400, - fontWeight: FontWeight.bold, - fontSize: 12), - ), - ), - color: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - disabledColor: (paymentData.address != null && - paymentData.paymentOption != null) - ? Colors.green - : Color(0xff929295), - ), + ], ), - ], + ), + Texts( + "${model.cartResponse.quantityCount} ${TranslationBase + .of(context) + .items}", + fontSize: 10, + color: Colors.grey, + fontWeight: FontWeight.bold, + ), + ], + ), + Container( + child: RaisedButton( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: Color(0xff929295), + width: 1, + ), + ), + onPressed: (paymentData.address != null && + paymentData.paymentOption != null) + ? () async { + await model.makeOrder(); + if (model.state == ViewState.Idle) { + AppToast.showSuccessToast( + message: "Order has been placed successfully!!"); + openPayment(model.orderListModel[0], model.user); + } else { + AppToast.showErrorToast(message: model.error); + } + Navigator.pop(context); + Navigator.pop(context); + } + : null, + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16), + child: new Text( + "${TranslationBase + .of(context) + .proceedPay}", + style: new TextStyle( + color: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.white + : Colors.grey.shade400, + fontWeight: FontWeight.bold, + fontSize: 12), + ), + ), + color: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.green + : Color(0xff929295), + disabledColor: (paymentData.address != null && + paymentData.paymentOption != null) + ? Colors.green + : Color(0xff929295), ), - ) + ), + ], + ), + ) : Container(), ), ); } + + openPayment(OrderDetailModel order, + AuthenticatedUser authenticatedUser,) { + browser = new MyInAppBrowser( + onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); + + browser.openPharmacyPaymentBrowser( + order, + order.orderTotal, + 'ePharmacy Order', + order.id, + order.billingAddress.email, + order.customValuesXml, + "${authenticatedUser.firstName} ${authenticatedUser + .middleName} ${authenticatedUser.lastName}", + authenticatedUser.patientID, + authenticatedUser, + browser); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + if (isPaymentMade) { + AppToast.showSuccessToast( + message: "شكراً\nPayment status for your order is Paid"); + Navigator.pop(context); + Navigator.pop(context); + } else { + AppToast.showErrorToast( + message: + "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); + } + } } diff --git a/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart b/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart index fc1270c0..9e281694 100644 --- a/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart +++ b/lib/pages/pharmacies/screens/lacum-activitaion-vida-page.dart @@ -20,8 +20,9 @@ class LakumActivationVidaPage extends StatelessWidget { return BaseView( builder: (_, model, wi) => AppScaffold( - title: "Acount Activation", + appBarTitle: TranslationBase.of(context).accountActivation, isShowAppBar: true, + isPharmacy: true, isShowDecPage: false, backgroundColor: Colors.white, baseViewModel: model, @@ -35,7 +36,7 @@ class LakumActivationVidaPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Texts( - " This service allows you to activate your LAKUM account after registering through the Vida system. ", + TranslationBase.of(context).accountActivationDesc, fontSize: 14, ), Padding( @@ -43,8 +44,10 @@ class LakumActivationVidaPage extends StatelessWidget { child: TextField( controller: _identificationNumberController, decoration: new InputDecoration( - hintText: 'Enter Identification Number', + hintText: TranslationBase.of(context) + .enterIdentificationNumber, ), + keyboardType: TextInputType.number, style: TextStyle( fontSize: 16, color: Colors.grey.shade700, @@ -89,7 +92,7 @@ class LakumActivationVidaPage extends StatelessWidget { } }); } - : null, + : () {}, ), ), ], diff --git a/lib/pages/pharmacies/screens/lacum-registration-page.dart b/lib/pages/pharmacies/screens/lacum-registration-page.dart index 53b9705d..c40771b8 100644 --- a/lib/pages/pharmacies/screens/lacum-registration-page.dart +++ b/lib/pages/pharmacies/screens/lacum-registration-page.dart @@ -34,7 +34,6 @@ class _LakumRegistrationPageState extends State { @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - PreferredSizeWidget appBarWidget = AppBarWidget("Lakum", null, true); languages.clear(); languages.add(IdNamePair(1, TranslationBase.of(context).arabic)); languages.add(IdNamePair(2, TranslationBase.of(context).english)); @@ -49,19 +48,18 @@ class _LakumRegistrationPageState extends State { return BaseView( builder: (_, model, wi) => AppScaffold( - title: "Register Lakum", + appBarTitle: + "${TranslationBase.of(context).register} ${TranslationBase.of(context).lakum}", isShowAppBar: true, isShowDecPage: false, backgroundColor: Colors.white, - appBarWidget: appBarWidget, baseViewModel: model, body: Container( width: double.infinity, child: SingleChildScrollView( child: SizedBox( - height: mediaQuery.size.height - - appBarWidget.preferredSize.height - - mediaQuery.padding.top, + height: + mediaQuery.size.height - 60 - mediaQuery.padding.top, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/pages/pharmacies/screens/lacum-setting-page.dart b/lib/pages/pharmacies/screens/lacum-setting-page.dart index 91e4c965..4f7f5fd6 100644 --- a/lib/pages/pharmacies/screens/lacum-setting-page.dart +++ b/lib/pages/pharmacies/screens/lacum-setting-page.dart @@ -1,7 +1,10 @@ +import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/LacumAccountInformation.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/lacum-viewmodel.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/lacum-banner-widget.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -36,24 +39,23 @@ class _LakumSettingPageState extends State { @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - PreferredSizeWidget appBarWidget = AppBarWidget("Lakum", null, true); return BaseView( onModelReady: (model) => model.setLakumData( widget.lacumInformation, widget.lacumGroupInformation), builder: (_, model, wi) => AppScaffold( - title: "Lakum", + appBarTitle: "${TranslationBase.of(context).lakum}", isShowAppBar: true, isShowDecPage: false, + isPharmacy: true, backgroundColor: Colors.white, - appBarWidget: appBarWidget, baseViewModel: model, body: Container( width: double.infinity, child: SingleChildScrollView( child: SizedBox( height: mediaQuery.size.height - - appBarWidget.preferredSize.height - + 60 - mediaQuery.padding.top, child: _buildSettingScreen(mediaQuery, model), ), @@ -222,13 +224,18 @@ class _LakumSettingPageState extends State { hPadding: 8, vPadding: 12, handler: canUpdate - ? () { - model.createLakumAccount(_nameController.text, _phoneController.text).then((status) => { - if (status == 200) {Navigator.pop(context, "")} - // back to previous page - }); + ? () async { + GifLoaderDialogUtils.showMyDialog(context); + await model.createLakumAccount(_nameController.text, _phoneController.text); + GifLoaderDialogUtils.hideDialog(context); + if(model.state == ViewState.Idle){ + AppToast.showSuccessToast(message: model.successMsg); + Navigator.pop(context, ""); + } else if(model.state == ViewState.ErrorLocal){ + AppToast.showErrorToast(message: model.error); + } } - : null, + : (){}, ), ) ], diff --git a/lib/pages/pharmacies/screens/lacum-transfer-page.dart b/lib/pages/pharmacies/screens/lacum-transfer-page.dart index 0671f80a..f05c6da4 100644 --- a/lib/pages/pharmacies/screens/lacum-transfer-page.dart +++ b/lib/pages/pharmacies/screens/lacum-transfer-page.dart @@ -32,17 +32,16 @@ class _LacumTransferPageState extends State { @override Widget build(BuildContext context) { final mediaQuery = MediaQuery.of(context); - PreferredSizeWidget appBarWidget = AppBarWidget("Lakum", null, true); return BaseView( onModelReady: (model) => model.setLakumData( widget.lacumInformation, widget.lacumGroupInformation), builder: (_, model, wi) => AppScaffold( - title: "Lakum", + appBarTitle: "${TranslationBase.of(context).lakumTransfer}", isShowAppBar: true, + isPharmacy: true, isShowDecPage: false, backgroundColor: Colors.white, - appBarWidget: appBarWidget, baseViewModel: model, body: Container( width: double.infinity, @@ -85,7 +84,7 @@ class _LacumTransferPageState extends State { children: [ Container( child: Texts( - "Point Balance", + "${TranslationBase.of(context).point} ${TranslationBase.of(context).balance}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, @@ -145,7 +144,7 @@ class _LacumTransferPageState extends State { children: [ Container( child: Texts( - "Riyal Balance", + "${TranslationBase.of(context).riyal} ${TranslationBase.of(context).balance}", fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white, @@ -184,7 +183,7 @@ class _LacumTransferPageState extends State { child: TextField( controller: _beneficieryAccountController, decoration: new InputDecoration( - hintText: 'Enter Beneficiary Account No.', + hintText: TranslationBase.of(context).enterBeneficiaryAccountNo, ), style: TextStyle( fontSize: 16, @@ -211,7 +210,7 @@ class _LacumTransferPageState extends State { _beneficieryAccountController .text); } - : null, + : (){}, ), ), (model.lacumReceiverInformation != null && @@ -252,7 +251,7 @@ class _LacumTransferPageState extends State { width: double.infinity, ), Texts( - "Point's to Transfer :", + TranslationBase.of(context).pointsToTransfer, color: Colors.black, ), Padding( @@ -286,7 +285,7 @@ class _LacumTransferPageState extends State { Container( margin: EdgeInsets.all(8), child: BorderedButton( - "LACUM TRANSFER", + TranslationBase.of(context).lakumTransfer, backgroundColor: Color(0xff339933), textColor: Colors.white, fontSize: 18, diff --git a/lib/pages/pharmacies/screens/lakum-main-page.dart b/lib/pages/pharmacies/screens/lakum-main-page.dart index adbb07c2..fdf3cc78 100644 --- a/lib/pages/pharmacies/screens/lakum-main-page.dart +++ b/lib/pages/pharmacies/screens/lakum-main-page.dart @@ -22,7 +22,7 @@ class LakumMainPage extends StatelessWidget { return BaseView( onModelReady: (model) => model.getLacumData(), builder: (_, model, wi) => AppScaffold( - title: "Lakum", + appBarTitle: TranslationBase.of(context).lakum, isShowAppBar: true, isPharmacy: true, isShowDecPage: false, @@ -346,7 +346,7 @@ class LakumHomeButtons extends StatelessWidget { child: Container( padding: EdgeInsets.symmetric(horizontal: 16), child: Texts( - "Account Activation", + TranslationBase.of(context).accountActivation, fontSize: 14, fontWeight: FontWeight.bold, ), @@ -394,7 +394,7 @@ class LakumHomeButtons extends StatelessWidget { child: Container( padding: EdgeInsets.symmetric(horizontal: 16), child: Texts( - "Lakum Transfer", + TranslationBase.of(context).lakumTransfer, fontSize: 14, fontWeight: FontWeight.bold, ), diff --git a/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart b/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart index 30c3bb6e..228b0874 100644 --- a/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart +++ b/lib/pages/pharmacies/screens/lakum-terms-conditions-page.dart @@ -19,21 +19,14 @@ class LakumTermsConditions extends StatelessWidget { Widget build(BuildContext context) { ProjectViewModel projectProvider = Provider.of(context); - final mediaQuery = MediaQuery.of(context); - PreferredSizeWidget appBarWidget = AppBarWidget("Lakum", null, true); - double height = mediaQuery.size.height - - appBarWidget.preferredSize.height - - mediaQuery.padding.top; - return BaseView( onModelReady: (model) => model.getUserTermsAndConditionsForEPharmcy(), builder: (_, model, wi) => AppScaffold( - appBarTitle: "Register Lakum", + appBarTitle: "${TranslationBase.of(context).register} ${TranslationBase.of(context).lakum}", isShowAppBar: true, isShowDecPage: false, backgroundColor: Colors.white, baseViewModel: model, - appBarWidget: appBarWidget, body: Container( margin: EdgeInsets.all(8), width: double.infinity, diff --git a/lib/pages/pharmacies/screens/pharmacy_module_page.dart b/lib/pages/pharmacies/screens/pharmacy_module_page.dart index fd51d6ef..e4830583 100644 --- a/lib/pages/pharmacies/screens/pharmacy_module_page.dart +++ b/lib/pages/pharmacies/screens/pharmacy_module_page.dart @@ -1,25 +1,75 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/config/size_config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/landing/home_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/screens/cart-order-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/lacum-activitaion-vida-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/screens/recommended-product-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/BannerPager.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/ProductTileItem.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/widgets/manufacturerItem.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; +import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/borderedButton.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; - +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:rating_bar/rating_bar.dart'; +import '../../final_products_page.dart'; import 'lacum-activitaion-vida-page.dart'; -class PharmacyPage extends StatelessWidget { +bool isInWishlist = false; +int price = 0; +var itemID; +var product; +var customerId; +var item; +dynamic languageID; +List wishlistData; + +class PharmacyPage extends StatefulWidget { +// final PharmacyProduct product; +// PharmacyPage(this.product); + + @override + _PharmacyPageState createState() => _PharmacyPageState(); +} + +class _PharmacyPageState extends State { +// dynamic wishlistVar; + + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + List recommendedProductList = []; + List wishList = []; + + var model; +// String ProductId="4561"; + //String id ="3608"; + String productId = ""; + String id = ""; + @override + void initState() { + checkWishlist(); + // userInfo(widget.product.id, widget.product); + userInfo(id, product); + print("-------------this--------------"); + print(itemID); + } + @override Widget build(BuildContext context) { return BaseView( @@ -38,9 +88,494 @@ class PharmacyPage extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ BannerPager(model), - GridViewButtons(model), + // GridViewButtons(model), Container( - margin: EdgeInsets.fromLTRB(10, 0, 10, 0), + margin: EdgeInsets.fromLTRB(10, 10, 10, 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Texts( + TranslationBase.of(context).myPrescription, + bold: true, + ), + BorderedButton( + TranslationBase.of(context).viewAll, + hasBorder: true, + borderColor: Colors.green, + textColor: Colors.green, + vPadding: 6, + hPadding: 4, + handler: () { + Navigator.push( + context, FadePage(page: HomePrescriptionsPage())); + }, + ), + ], + ), + ), + Container( + height: model.prescriptionsList.length > 0 + ? MediaQuery.of(context).size.height * 0.28 + : 0, + padding: + EdgeInsets.symmetric(horizontal: 18.0, vertical: 14.0), +// height: MediaQuery.of(context).size.height * 0.28, +// width: 200.0, +// height: MediaQuery.of(context).size.height / 4 + 20, + margin: EdgeInsets.only(left: 10), + child: BaseView( + onModelReady: (model) => model.getPrescription(), + builder: (_, model, wi) => model.prescriptionsList.length != + 0 +// model.getPrescription(); + ? ListView.builder( + scrollDirection: Axis.horizontal, + shrinkWrap: true, + physics: ScrollPhysics(), + // physics: NeverScrollableScrollPhysics(), + itemCount: model.prescriptionsList.length, + itemBuilder: (context, index) { + return Container( +// width: 160.0, + height: + MediaQuery.of(context).size.height * 0.6, + padding: EdgeInsets.only( + bottom: 5.0, left: 5.0, right: 8.0), + margin: EdgeInsets.only(right: 10.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey, + style: BorderStyle.solid, + width: 1.0, + ), + color: Colors.white, + borderRadius: BorderRadius.circular(10.0)), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Column(children: [ + Container( + padding: EdgeInsets.only( + top: 10.0, + left: 10.0, + right: 10.0, + bottom: 15.0, + ), + child: CircleAvatar( + radius: 30, + backgroundColor: + Colors.transparent, + child: Image.network( + model.prescriptionsList[index] + .doctorImageURL, + width: 60, + height: 60, + ), + ), + ), + ]), +// Column( +// // crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Container( +// margin: EdgeInsets.only(left: 1), +// padding: EdgeInsets.only( +// top: 10.0, +// left: 10.0, +// right: 3.0, +// bottom: 15.0, +// ), +// child: Image.network( +// model.prescriptionsList[index] +// .doctorImageURL, +// width: 60, +// height: 60, +// ), +// ), +// ]), + Column( +// crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + margin: + EdgeInsets.only(left: 1), + padding: EdgeInsets.only( + left: 15.0, right: 15.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: + BorderStyle.solid, + width: 4.0, + ), + color: Colors.green, + borderRadius: + BorderRadius.circular( + 30.0)), + child: Text( + languageID == "ar" + ? model + .prescriptionsList[ + index] + .isInOutPatientDescriptionN + .toString() + : model + .prescriptionsList[ + index] + .isInOutPatientDescription + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + )), + Row(children: [ + Image.asset( + 'assets/images/Icon-awesome-calendar.png', + width: 30, + height: 30, + ), + Text( + DateUtil.convertStringToDate( + model + .prescriptionsList[ + index] + .appointmentDate + .toString()) + .toString() + .substring(0, 10), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + ) + ]), + ], + ), + ], + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Row(children: [ + Text( + model.prescriptionsList[index] + .doctorTitle + .toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + Text( + model.prescriptionsList[index] + .doctorName + .toString(), + style: TextStyle( + color: Colors.black, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ]), + ), + ], + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + model.prescriptionsList[index] + .clinicDescription + .toString(), + style: TextStyle( + color: Colors.green, + fontSize: 15.0, +// fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( + initialRating: model + .prescriptionsList[index] + .actualDoctorRate + .toDouble(), +// initialRating: productRate, + size: 15.0, + filledColor: + Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: + Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + ) + ]), + ]), + ); + }) + : Container(), + ), + ), +// Container( +// margin: EdgeInsets.fromLTRB(10, 10, 10, 10), +// child: Row( +// mainAxisAlignment: MainAxisAlignment.spaceBetween, +// children: [ +// Texts( +// TranslationBase.of(context).recommended, +// bold: true, +// ), +// BorderedButton( +// TranslationBase.of(context).viewAll, +// hasBorder: true, +// borderColor: Colors.green, +// textColor: Colors.green, +// vPadding: 6, +// hPadding: 4, +// handler: () { +// Navigator.push( +// context, +// MaterialPageRoute( +// builder: (context) => +// RecommendedProductPage(productId : "2316"))); +// }, +// ), +// ], +// ), +// ), +// Container( +// height: model.recommendedProductList.length > 0 +// ? MediaQuery.of(context).size.height * 0.32 +// : 0, +// margin: EdgeInsets.symmetric(horizontal: 6, vertical: 4), +//// padding: EdgeInsets.symmetric(horizontal: 5.0, vertical: 22.0), +//// margin: EdgeInsets.only(left: 10), +// child: BaseView( +// onModelReady: (model) => +// model.getRecommendedProducts(productId), +// builder: (_, model, wi) => model +// .recommendedProductList.length != +// null +// ? ListView.builder( +// scrollDirection: Axis.horizontal, +// shrinkWrap: true, +// physics: ScrollPhysics(), +// // physics: NeverScrollableScrollPhysics(), +// itemCount: model.recommendedProductList.length, +// itemBuilder: (context, index) { +// return Card( +// elevation: 2, +// shape: RoundedRectangleBorder( +// side: BorderSide( +// color: Colors.grey[300], width: 2), +// borderRadius: BorderRadius.circular(10)), +// margin: EdgeInsets.symmetric( +// horizontal: 8, +// vertical: 0, +// ), +// child: Container( +// decoration: BoxDecoration( +// borderRadius: BorderRadius.all( +// Radius.circular(15), +// ), +// ), +// padding: EdgeInsets.symmetric(horizontal: 4), +// width: MediaQuery.of(context).size.width / 3, +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Stack(children: [ +// Container( +// child: Align( +// alignment: Alignment.topRight, +// child: //true +// itemID.contains(model.recommendedProductList[index].id) +// // !isInWishlist +// ? IconButton( +// icon: Icon(Icons +// .favorite_border), +// color: Colors.grey, +// iconSize: 30, +// onPressed: () { +// setState(() { +// addToWishlistFunction( +// itemID); +// }); +// }, +// ) +// : IconButton( +// icon: Icon( +// Icons.favorite), +// color: Colors.red, +// iconSize: 30, +// onPressed: () { +// setState(() { +// deleteFromWishlistFunction( +// itemID); +// }); +// }, +// ) +//// +// ), +// ), +// Container( +// margin: EdgeInsets.fromLTRB( +// 0, 16, 10, 16), +// alignment: Alignment.center, +//// padding: EdgeInsets.only(left: 25, bottom: 20), +// child: (model.recommendedProductList[index].images != null && +// model.recommendedProductList[index].images.length > 0) +// ? Image.network( +// model.recommendedProductList[index].images[0].src.toString(), +//// item.images[0].src, +// fit: BoxFit.cover, +// height: 60, +// ) +// : Image.asset( +// "assets/images/no_image.png", +// fit: BoxFit.cover, +// height: 60, +// ), +// ), +// Container( +// width: model +// .recommendedProductList[ +// index] +// .rxMessage != +// null +// ? MediaQuery.of(context) +// .size +// .width / +// 5 +// : 0, +// padding: EdgeInsets.all(4), +// decoration: BoxDecoration( +// color: Color(0xffb23838), +// borderRadius: BorderRadius.only( +// topLeft: Radius.circular(6)), +// ), +// child: Texts( +// model.recommendedProductList[index] +// .rxMessage != +// null +// ? model +// .recommendedProductList[ +// index] +// .rxMessage +// : "", +// color: Colors.white, +// regular: true, +// fontSize: 10, +// fontWeight: FontWeight.w400, +// ), +// ), +// ]), +// Container( +// margin: EdgeInsets.symmetric( +// horizontal: 6, +// vertical: 0, +// ), +// child: Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Text( +// languageID == "ar" +// ? model.recommendedProductList[index].namen +// : model.recommendedProductList[index].name, +// style: TextStyle( +// color: Colors.black, +// fontSize: 13.0, +//// fontWeight: FontWeight.bold, +// ), +// ), +// Padding( +//// padding: const EdgeInsets.only(top: 15, bottom: 10), +// padding: const EdgeInsets.only( +// top: 10, bottom: 5), +// child: Texts( +// "SAR ${model.recommendedProductList[index].price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// ], +// ), +// ), +// Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Container( +// padding: +// EdgeInsets.only(right: 10), +//// margin: EdgeInsets.only(left: 5), +// child: Align( +// alignment: Alignment.topLeft, +// child: RatingBar.readOnly( +// initialRating: model +// .recommendedProductList[ +// index] +// .approvedRatingSum +// .toDouble(), +//// initialRating: productRate, +// size: 13.0, +// filledColor: +// Colors.yellow[700], +// emptyColor: Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: +// Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts( +// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +//// bold: true, +// fontSize: 12, +// ), +// ]), +// ], +// ), +// ), +// ); +// }) +// : Container( +//// child: Text("NO DATA"), +// ), +// ), +// ), + Container( + margin: EdgeInsets.fromLTRB(10, 10, 10, 0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -55,8 +590,9 @@ class PharmacyPage extends StatelessWidget { hPadding: 4, borderColor: Colors.green, textColor: Colors.green, - handler: () =>{ - Navigator.push(context,FadePage(page: ProductBrandsPage())), + handler: () => { + Navigator.push( + context, FadePage(page: ProductBrandsPage())), }, ), ], @@ -87,7 +623,17 @@ class PharmacyPage extends StatelessWidget { hPadding: 4, borderColor: Colors.green, textColor: Colors.green, - handler: () {}, + handler: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 3, + ), + ), + ); + }, ), ], ), @@ -119,8 +665,16 @@ class PharmacyPage extends StatelessWidget { textColor: Colors.green, vPadding: 6, hPadding: 4, - handler: () =>{ - Navigator.push(context,FadePage(page: ProductBrandsPage())), + handler: () => { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 4, + ), + ), + ), }, ), ], @@ -142,6 +696,49 @@ class PharmacyPage extends StatelessWidget { ), ); } + + addToWishlistFunction(itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + isInWishlist = true; + await x.addToWishlistData(itemID); + } + + deleteFromWishlistFunction(itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + isInWishlist = false; + await x.addToWishlistData(itemID); + } + + checkWishlist() async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.checkWishlistData(); + for (int i = 0; i < x.wishListItems.length; i++) { + // itemID = x.wishListItems[i].id; + print("-------------wishlist---------------"); + print(itemID); +// print(product.id); + print(x.wishListItems[i].productId); + if (itemID == x.wishListItems[i].productId) { + isInWishlist = true; +// print('in wishlist'); + break; + } else { + isInWishlist = false; +// print('not in wishlist'); + } + } + } + + Future userInfo(id, product) async { + customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + if (customerId != null) { + itemID = id; + product = product; + checkWishlist(); + } + print("customerId:$customerId"); + return customerId; + } } class GridViewButtons extends StatelessWidget { @@ -180,15 +777,15 @@ class GridViewButtons extends StatelessWidget { hasColorFilter: false, child: GridViewCard(TranslationBase.of(context).medicationRefill, 'assets/images/pharmacy_module/medication_icon.png', () { - model.checkUserIsActivated().then((isActivated) { - if (isActivated) { - Navigator.push(context, FadePage(page: LakumMainPage())); - } else { - Navigator.push( - context, FadePage(page: LakumActivationVidaPage())); - } - }); - }), + model.checkUserIsActivated().then((isActivated) { + if (isActivated) { + Navigator.push(context, FadePage(page: LakumMainPage())); + } else { + Navigator.push( + context, FadePage(page: LakumActivationVidaPage())); + } + }); + }), ), DashboardItem( imageName: 'pharmacy_module/bg_3.png', @@ -196,8 +793,9 @@ class GridViewButtons extends StatelessWidget { hasColorFilter: false, child: GridViewCard(TranslationBase.of(context).myPrescriptions, 'assets/images/pharmacy_module/prescription_icon.png', () { - Navigator.push(context, FadePage(page: PharmacyAddressesPage())); - }), + Navigator.push( + context, FadePage(page: PharmacyAddressesPage())); + }), ), DashboardItem( imageName: 'pharmacy_module/bg_4.png', @@ -206,7 +804,7 @@ class GridViewButtons extends StatelessWidget { child: GridViewCard( TranslationBase.of(context).searchAndScanMedication, 'assets/images/pharmacy_module/search_scan_icon.png', - () {}), + () {}), ), ], ), @@ -274,4 +872,41 @@ class GridViewCard extends StatelessWidget { ), ); } + + String getDate(String date) { + DateTime dateObj = DateUtil.convertStringToDate(date); + return DateUtil.getWeekDay(dateObj.weekday) + + ", " + + dateObj.day.toString() + + " " + + DateUtil.getMonth(dateObj.month) + + " " + + dateObj.year.toString(); + } } + +class test extends StatefulWidget { + @override + _testState createState() => _testState(); +} + +class _testState extends State { + @override + Widget build(BuildContext context) { + return Container(); + } +} +//addWishlistData() async { +// ProductDetailViewModel x = new ProductDetailViewModel(); +// await wishlistData.add(x.checkWishlistData()); +// print("-------------testWishlist---------------"); +// +//} + +// checkWishlist() async { +// ProductDetailViewModel x = new ProductDetailViewModel(); +// wishlistVar = await x.checkWishlistData(); +// print("wishlistVar>>>>>>>>>>>>>>>"); +// print(wishlistVar); +// +// } diff --git a/lib/pages/pharmacies/screens/recommended-product-page.dart b/lib/pages/pharmacies/screens/recommended-product-page.dart new file mode 100644 index 00000000..28e3cce3 --- /dev/null +++ b/lib/pages/pharmacies/screens/recommended-product-page.dart @@ -0,0 +1,997 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/product_detail_view_model.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:rating_bar/rating_bar.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; + +dynamic languageID; +bool isInWishlist = false; +int price = 0; +var itemID; +var product; +var customerId; + +class RecommendedProductPage extends StatefulWidget { + String productId ; + RecommendedProductPage({this.productId}); + + @override + _RecommendedProductPageState createState() => _RecommendedProductPageState(productId: productId); +} + +class _RecommendedProductPageState extends State + with SingleTickerProviderStateMixin { + List recommendedProductList = []; + String productId; + _RecommendedProductPageState({this.productId}); + String id = ""; + bool styleOne = true; + bool styleTwo = false; + Icon styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + + getLanguageID() async { + languageID = await sharedPref.getString(APP_LANGUAGE); + } + + // String productId = "4561"; + // String productId = ""; + + @override + void initState() { + checkWishlist(); + userInfo(id, product); + print("-------------this--------------"); + print(itemID); + } + + @override + Widget build(BuildContext context) { + var size = MediaQuery.of(context).size; + final double itemHeight = ((size.height - kToolbarHeight - 24) * 0.80) / 2; + final double itemWidth = size.width / 2; + return BaseView( + onModelReady: (model) => model.getRecommendedProducts(productId), + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).recommended, + baseViewModel: model, + isShowAppBar: true, + isPharmacy: true, + backgroundColor: Colors.white, + body: SingleChildScrollView( + child: Column(children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only( + top: 8, + bottom: 10, + left: 10, + ), + child: Text( + model.recommendedProductList.length.toString(), + style: TextStyle( + color: Colors.black, + fontSize: 14.0, + ), + ), + ), + Container( + padding: EdgeInsets.only(top: 8, bottom: 10, left: 8), + child: Text( + TranslationBase.of(context).result, + style: TextStyle( + color: Colors.black, + fontSize: 14.0, + ), + ), + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + child: Container( + width: 1, + color: Colors.grey, + ), + ), + ), + Container( + child: Image.asset( + 'assets/images/pharmacy/sort.png', + width: 20, + height: 20, +// color: Colors.red, + ), + ), + Container( + child: Text( + TranslationBase.of(context).sort, + style: TextStyle( + color: Colors.black, + fontSize: 14.0, + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: SizedBox( + child: Container( + width: 1, + color: Colors.grey, + ), + ), + ), + Divider( + thickness: 1.0, + color: Colors.black12, + ), + Padding( + padding: EdgeInsets.all(8.0), + child: InkWell( + child: styleIcon, + onTap: () { + setState(() { + if (styleOne == true) { + styleOne = false; + styleTwo = true; + styleIcon = Icon( + Icons.auto_awesome_mosaic, + color: Colors.blue, + size: 29.0, + ); + } else { + styleOne = true; + styleTwo = false; + styleIcon = Icon( + Icons.widgets_sharp, + color: Colors.blue, + size: 29.0, + ); + } + }); + }, + ), + ), + ], + ), + ]), + SizedBox( + height: 2, + ), + Divider( + color: Colors.grey[350], + height: 10, + thickness: 6, + indent: 0, + endIndent: 0, + ), + styleOne == true + ? Container( + margin: EdgeInsets.all(5.0), + child: model.recommendedProductList.length != null + ? CustomScrollView( + primary: false, + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + slivers: [ + SliverPadding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + sliver: SliverGrid.count( + crossAxisCount: 2, + childAspectRatio: (itemWidth / itemHeight), + children: model.recommendedProductList + .map((e) => Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: BorderSide( + color: Colors.grey[300], + width: 2), + borderRadius: + BorderRadius.circular( + 10)), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 11, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: + BorderRadius.all( + Radius.circular(15), + ), + ), + padding: EdgeInsets.symmetric( + horizontal: 4), + width: MediaQuery.of(context) + .size.width / 3, +// + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Stack(children: [ + Container( + child: Align( + alignment: + Alignment + .topRight, + child: + itemID.contains(e.id) + // !isInWishlist + ? IconButton( + icon: + Icon(Icons.favorite_border), + color: + Colors.grey, + iconSize: + 30, + onPressed: + () { + setState(() { + addToWishlistFunction(itemID); + }); + }, + ) + : + IconButton( + icon: + Icon(Icons.favorite), + color: + Colors.red, + iconSize: + 30, + onPressed: + () { + setState(() { + deleteFromWishlistFunction(itemID); + }); + }, + ) +// + ), + ), + Container( + margin: EdgeInsets + .fromLTRB(0, 16, + 10, 16), + alignment: + Alignment.center, +// padding: EdgeInsets.only(left: 25, bottom: 20), + child: (e.images != + null && + e.images.length > + 0) + ? Image.network( + e.images[0] + .src + .toString(), +// item.images[0].src, + fit: BoxFit + .cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit + .cover, + height: 60, + ), + ), + Container( + width: e.rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: + BoxDecoration( + color: Color( + 0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), + child: Texts( + e.rxMessage != null + ? e.rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ), + ), + ]), + Container( + margin: EdgeInsets + .symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Text( + languageID == "ar" + ? e.namen + : e.name, + style: TextStyle( + color: Colors + .black, + fontSize: 13.0, +// fontWeight: FontWeight.bold, + ), + ), + Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), + padding: + const EdgeInsets + .only( + top: 10, + bottom: + 5), + child: Texts( + "SAR ${e.price}", + bold: true, + fontSize: 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Container( + padding: EdgeInsets + .only( + right: + 10), +// margin: EdgeInsets.only(left: 5), + child: Align( + alignment: + Alignment + .topLeft, + child: RatingBar + .readOnly( + initialRating: e + .approvedRatingSum + .toDouble(), +// initialRating: productRate, + size: 13.0, + filledColor: + Colors.yellow[ + 700], + emptyColor: + Colors.grey[ + 500], + isHalfAllowed: + true, + halfFilledIcon: + Icons + .star_half, + filledIcon: + Icons + .star, + emptyIcon: + Icons + .star, + ), + ), + ), + Texts( + "(${e.approvedTotalReviews.toString()})", +// bold: true, + fontSize: 12, + ), + ]), + ], + ), + ), + ) +// Column( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Container( +// child: Align( +// alignment: Alignment.topRight, +// child: !isInWishlist +// ? IconButton( +// icon: Icon(Icons.favorite_border), +// color: Colors.grey, +// iconSize: 30, +// onPressed: () { +// setState(() { +// addToWishlistFunction(itemID); +// }); +// }, +// ) +// : IconButton( +// icon: Icon(Icons.favorite), +// color: Colors.red, +// iconSize: 30, +// onPressed: () { +// setState(() { +// deleteFromWishlistFunction(itemID); +// }); +// }, +// ) +//// +// ),), +// Container( +// padding: EdgeInsets.only( +// left: 25, bottom: 20), +//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), +//// alignment: Alignment.centerLeft, +// child: (e.images != null && +// e.images.length > 0) +// ? Image.network( +// e.images[0].src +// .toString(), +//// item.images[0].src, +// fit: BoxFit.cover, +// height: 80, +// ) +// : Image.asset( +// "assets/images/no_image.png", +// fit: BoxFit.cover, +// height: 80, +// ), +// ), +// Text( +// e.name, +//// model.recommendedProduct[0].products[index].shortDescription +//// .toString(), +// style: TextStyle( +// color: Colors.black, +// fontSize: 15.0, +//// fontWeight: FontWeight.bold, +// ), +// ), +// Padding( +// padding: const EdgeInsets.only( +// top: 15, bottom: 10), +// child: Texts( +// "SAR ${e.price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only( +// right: 10), +//// margin: EdgeInsets.only(left: 5), +// child: Align( +// alignment: +// Alignment.topLeft, +// child: RatingBar.readOnly( +// initialRating: e +// .approvedRatingSum +// .toDouble(), +//// initialRating: productRate, +// size: 15.0, +// filledColor: +// Colors.yellow[700], +// emptyColor: +// Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: +// Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts( +// "(${e.approvedTotalReviews.toString()})", +//// bold: true, +// fontSize: 12, +// ), +// ]), +// ], +// ), + ) + .toList(), +// children:[ +// ListView.builder( +// scrollDirection: Axis.vertical, +// shrinkWrap: true, +// physics: ScrollPhysics(), +// itemCount: model.recommendedProductList.length, +// itemBuilder: (context, index) { +// return Container( +// height: 30, +// padding: EdgeInsets.only( left: 15.0, top: 10, right: 10), +// margin: EdgeInsets.only(right: 10.0), +// decoration: BoxDecoration( +// border: Border.all( +// color: Colors.grey, +// style: BorderStyle.solid, +// width: 1.0, +// ), +// color: Colors.white, +// borderRadius: BorderRadius.circular(10.0)), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// child: Align( +// alignment: Alignment.topRight, +// child:!isInWishlist +// ? InkWell( +// onTap: () { +// }, +// child: SvgPicture.asset( +// 'assets/images/pharmacy/heart-empty.svg', +// width: 20, +// height: 20, +// color: Colors.grey, +// ), +// ) +// : InkWell( +// onTap: () { +// }, +// child: SvgPicture.asset( +// 'assets/images/pharmacy/Redheart.svg', +// width: 20, +// height: 20, +//// color: Colors.red, +// ), +// ) +// ), +// ), +// Container( +// padding: EdgeInsets.only(left: 25, bottom: 20), +//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), +//// alignment: Alignment.centerLeft, +// child: (model.recommendedProductList[index].images != null && +// model.recommendedProductList[index].images.length > 0) +// ? Image.network( +// model.recommendedProductList[index].images[0].src.toString(), +//// item.images[0].src, +// fit: BoxFit.cover, +// height: 80, +// ) +// : Image.asset( +// "assets/images/no_image.png", +// fit: BoxFit.cover, +// height: 80, +// ), +// ), +// Text( +// model.recommendedProductList[index].name, +//// model.recommendedProduct[0].products[index].shortDescription +//// .toString(), +// style: TextStyle( +// color: Colors.black, +// fontSize: 15.0, +//// fontWeight: FontWeight.bold, +// ), +// ), +// Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), +// child: Texts( +// "SAR ${model.recommendedProductList[index].price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only(right: 10), +//// margin: EdgeInsets.only(left: 5), +// child: Align( +// alignment: Alignment.topLeft, +// child: RatingBar.readOnly( +// initialRating: +// model.recommendedProductList[index].approvedRatingSum.toDouble(), +//// initialRating: productRate, +// size: 15.0, +// filledColor: Colors.yellow[700], +// emptyColor: Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts( +// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +//// bold: true, +// fontSize: 12, +// ), +// ]), +// ], +// ), +// ); +// } +// ), +// ] + ), + ), + ]) + : Container(), + ) + : Container( + height: model.recommendedProductList.length > 0 + ? MediaQuery.of(context).size.height * 0.60 + : 0, + child: ListView.builder( + physics: ScrollPhysics(), +// physics: NeverScrollableScrollPhysics(), + itemCount: model.recommendedProductList.length, + itemBuilder: (context, index) { + return Card( + elevation: 2, + shape: RoundedRectangleBorder( + side: + BorderSide(color: Colors.grey[300], width: 2), + borderRadius: BorderRadius.circular(10)), +// + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.all( + Radius.circular(15), + ), + ), + padding: EdgeInsets.symmetric(horizontal: 5), + width: MediaQuery.of(context).size.width / 3, +// + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack(children: [ + Container( + child: Align( + alignment: Alignment.topRight, + child: //true + //wishlistVar[index].id.contains(model.recommendedProductList[index].id) + !isInWishlist + ? IconButton( + icon: Icon( + Icons.favorite_border), + color: Colors.grey, + iconSize: 30, + onPressed: () { + setState(() { + addToWishlistFunction( + itemID); + }); + }, + ) + : IconButton( + icon: Icon(Icons.favorite), + color: Colors.red, + iconSize: 30, + onPressed: () { + setState(() { + deleteFromWishlistFunction( + itemID); + }); + }, + ) +// + ), + ), + Container( + margin: EdgeInsets.fromLTRB(0, 16, 10, 16), + alignment: Alignment.center, +// padding: EdgeInsets.only(left: 25, bottom: 20), + child: (model.recommendedProductList[index] + .images != + null && + model.recommendedProductList[index] + .images.length > + 0) + ? Image.network( + model.recommendedProductList[index] + .images[0].src + .toString(), +// item.images[0].src, + fit: BoxFit.cover, + height: 60, + ) + : Image.asset( + "assets/images/no_image.png", + fit: BoxFit.cover, + height: 60, + ), + ), + Container( + width: model.recommendedProductList[index] + .rxMessage != + null + ? MediaQuery.of(context).size.width / 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: BorderRadius.only( + topLeft: Radius.circular(6)), + ), + child: Texts( + model.recommendedProductList[index] + .rxMessage != + null + ? model.recommendedProductList[index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ), + ), + ]), + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 2, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + model + .recommendedProductList[index].name, + style: TextStyle( + color: Colors.black, + fontSize: 13.0, +// fontWeight: FontWeight.bold, + ), + ), + Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), + padding: const EdgeInsets.only( + top: 10, bottom: 5), + child: Texts( + "SAR ${model.recommendedProductList[index].price}", + bold: true, + fontSize: 14, + ), + ), + ], + ), + ), + Row( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Container( + padding: EdgeInsets.only( + right: 10, bottom: 10), +// margin: EdgeInsets.only(left: 5), + child: Align( + alignment: Alignment.topLeft, + child: RatingBar.readOnly( + initialRating: model + .recommendedProductList[index] + .approvedRatingSum + .toDouble(), +// initialRating: productRate, + size: 13.0, + filledColor: Colors.yellow[700], + emptyColor: Colors.grey[500], + isHalfAllowed: true, + halfFilledIcon: Icons.star_half, + filledIcon: Icons.star, + emptyIcon: Icons.star, + ), + ), + ), + Texts( + "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +// bold: true, + fontSize: 12, + ), + ]), + ], + ), + ), + ); +// Container( +// height: 30, +// padding: EdgeInsets.only( left: 10.0, top: 10, right: 10), +//// margin: EdgeInsets.only(right: 10.0), +// decoration: BoxDecoration( +// border: Border.all( +// color: Colors.grey, +// style: BorderStyle.solid, +// width: 1.0, +// ), +// color: Colors.white, +// borderRadius: BorderRadius.circular(10.0)), +// child: Column( +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Container( +// child: Align( +// alignment: Alignment.topRight, +// child:!isInWishlist +// ? InkWell( +// onTap: () { +// }, +// child: SvgPicture.asset( +// 'assets/images/pharmacy/heart-empty.svg', +// width: 20, +// height: 20, +// color: Colors.grey, +// ), +// ) +// : InkWell( +// onTap: () { +// }, +// child: SvgPicture.asset( +// 'assets/images/pharmacy/Redheart.svg', +// width: 20, +// height: 20, +//// color: Colors.red, +// ), +// ) +// ), +// ), +// Container( +// padding: EdgeInsets.only(left: 25, bottom: 20), +//// margin: EdgeInsets.fromLTRB(0, 16, 0, 0), +//// alignment: Alignment.centerLeft, +// child: (model.recommendedProductList[index].images != null && +// model.recommendedProductList[index].images.length > 0) +// ? Image.network( +// model.recommendedProductList[index].images[0].src.toString(), +//// item.images[0].src, +// fit: BoxFit.cover, +// height: 80, +// ) +// : Image.asset( +// "assets/images/no_image.png", +// fit: BoxFit.cover, +// height: 80, +// ), +// ), +// Text( +// model.recommendedProductList[index].name, +//// model.recommendedProduct[0].products[index].shortDescription +//// .toString(), +// style: TextStyle( +// color: Colors.black, +// fontSize: 15.0, +//// fontWeight: FontWeight.bold, +// ), +// ), +// Padding( +// padding: const EdgeInsets.only(top: 15, bottom: 10), +// child: Texts( +// "SAR ${model.recommendedProductList[index].price}", +// bold: true, +// fontSize: 14, +// ), +// ), +// Row( +// crossAxisAlignment: +// CrossAxisAlignment.start, +// children: [ +// Container( +// padding: EdgeInsets.only(right: 10), +//// margin: EdgeInsets.only(left: 5), +// child: Align( +// alignment: Alignment.topLeft, +// child: RatingBar.readOnly( +// initialRating: +// model.recommendedProductList[index].approvedRatingSum.toDouble(), +//// initialRating: productRate, +// size: 15.0, +// filledColor: Colors.yellow[700], +// emptyColor: Colors.grey[500], +// isHalfAllowed: true, +// halfFilledIcon: Icons.star_half, +// filledIcon: Icons.star, +// emptyIcon: Icons.star, +// ), +// ), +// ), +// Texts( +// "(${model.recommendedProductList[index].approvedTotalReviews.toString()})", +//// bold: true, +// fontSize: 12, +// ), +// ]), +// ], +// ), +// ); + }), + ), + ]), + ), + ), + ); + } + checkWishlist() async { + ProductDetailViewModel x = new ProductDetailViewModel(); + await x.checkWishlistData(); + for (int i = 0; i < x.wishListItems.length; i++) { + // itemID = x.wishListItems[i].id; + print("-------------wishlist---------------"); + print(itemID); +// print(product.id); + print(x.wishListItems[i].productId); + if (itemID == x.wishListItems[i].productId) { + isInWishlist = true; +// print('in wishlist'); + break; + } else { + isInWishlist = false; +// print('not in wishlist'); + } + } + } + + Future userInfo(id, product) async { + customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + if (customerId != null) { + itemID = id; + product = product; + checkWishlist(); + } + print("customerId:$customerId"); + return customerId; + } + + + addToWishlistFunction(itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + isInWishlist = true; + await x.addToWishlistData(itemID); + } + + deleteFromWishlistFunction(itemID) async { + ProductDetailViewModel x = new ProductDetailViewModel(); + isInWishlist = false; + await x.addToWishlistData(itemID); + } +} + diff --git a/lib/pages/pharmacies/widgets/BannerPager.dart b/lib/pages/pharmacies/widgets/BannerPager.dart index 989c7557..b088eefb 100644 --- a/lib/pages/pharmacies/widgets/BannerPager.dart +++ b/lib/pages/pharmacies/widgets/BannerPager.dart @@ -1,5 +1,7 @@ import 'package:carousel_slider/carousel_slider.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/pharmacy_module_view_model.dart'; +import 'package:diplomaticquarterapp/pages/offers_categorise_page.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; @@ -39,20 +41,25 @@ class _BannerPagerState extends State { items: widget._model .getBannerImagesUrl() .mapIndexed( - (item, index) => Container( - margin: EdgeInsets.symmetric(horizontal: 1.0), - child: ClipRRect( - borderRadius: BorderRadius.all(Radius.circular(5.0)), - child: Center( - child: index == 0 - ? Image.asset( - item, - fit: BoxFit.cover, - ) - : Image.network( - item, - fit: BoxFit.cover, - ), + (item, index) => InkWell( + onTap: () { + Navigator.push(context, FadePage(page: OffersCategorisePage())); + }, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 1.0), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5.0)), + child: Center( + child: index == 0 + ? Image.asset( + item, + fit: BoxFit.cover, + ) + : Image.network( + item, + fit: BoxFit.cover, + ), + ), ), ), ), diff --git a/lib/pages/pharmacies/widgets/ProductOrderItem.dart b/lib/pages/pharmacies/widgets/ProductOrderItem.dart index 92e2c39d..d7a82cc6 100644 --- a/lib/pages/pharmacies/widgets/ProductOrderItem.dart +++ b/lib/pages/pharmacies/widgets/ProductOrderItem.dart @@ -72,7 +72,7 @@ class _ProductOrderItemState extends State { child: Texts( projectProvider.isArabic ? widget.item.product.namen - : widget.item.product.name, + : "${widget.item.product.name}", regular: true, textAlign: TextAlign.justify, fontSize: 12, @@ -88,91 +88,90 @@ class _ProductOrderItemState extends State { ), margin: const EdgeInsets.only(bottom: 4), ), - Row( - children: [ - InkWell( - onTap: () => - {_quantityOnChangeClick(Operation.dec)}, - child: Container( - width: 25, - height: 25, - child: Center( - child: Texts( - "-", - color: Colors.grey.shade400, - )), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.shade400, - width: 1.0, + Container( + margin: EdgeInsets.symmetric(vertical: 4), + child: Row( + children: [ + InkWell( + onTap: () => + {_quantityOnChangeClick(Operation.dec)}, + child: Container( + width: 25, + height: 25, + child: Icon( + Icons.remove, color: Colors.grey.shade400, size: 20, + ), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.shade400, + width: 1.0, + ), ), ), ), - ), - Container( - margin: - const EdgeInsets.symmetric(horizontal: 4), - width: 25, - height: 25, - color: Colors.grey.shade300, - child: Center( - child: TextField( - cursorColor: Colors.black, - keyboardType: TextInputType.number, - controller: _quantityController, - textAlign: TextAlign.center, - onChanged: (text) { - setState(() { - var value = int.tryParse(text); - if (value == null) { - widget.item.quantity = 0; - } else { - widget.item.quantity = int.parse(text); - } - _totalPrice = - "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; - }); - }, - )), - ), - InkWell( - onTap: () => - {_quantityOnChangeClick(Operation.inc)}, - child: Container( + Container( + margin: + const EdgeInsets.symmetric(horizontal: 4), width: 25, height: 25, + color: Colors.grey.shade300, child: Center( - child: Texts( - "+", - color: Colors.grey.shade400, + child: TextField( + cursorColor: Colors.black, + keyboardType: TextInputType.number, + controller: _quantityController, + textAlign: TextAlign.center, + onChanged: (text) { + setState(() { + var value = int.tryParse(text); + if (value == null) { + widget.item.quantity = 0; + } else { + widget.item.quantity = int.parse(text); + } + _totalPrice = + "${(widget.item.product.price * widget.item.quantity).toStringAsFixed(2)}"; + }); + }, )), - decoration: BoxDecoration( - border: Border.all( - color: Colors.grey.shade400, - width: 1.0, - ), - ), ), - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Texts( - TranslationBase.of(context).total, - color: Colors.grey.shade500, - fontWeight: FontWeight.bold, - fontSize: 12, + InkWell( + onTap: () => + {_quantityOnChangeClick(Operation.inc)}, + child: Container( + width: 25, + height: 25, + child: Icon( + Icons.add, color: Colors.grey.shade400, size: 20, + ), + decoration: BoxDecoration( + border: Border.all( + color: Colors.grey.shade400, + width: 1.0, + ), ), - Texts( - "$_totalPrice ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", - fontSize: 12, - fontWeight: FontWeight.bold, - ) - ], + ), ), - ) - ], + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Texts( + TranslationBase.of(context).total, + color: Colors.grey.shade500, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + Texts( + "$_totalPrice ${projectProvider.isArabic ? widget.item.currencyn : widget.item.currency}", + fontSize: 12, + fontWeight: FontWeight.bold, + ) + ], + ), + ) + ], + ), ) ], ), diff --git a/lib/pages/pharmacies/widgets/manufacturerItem.dart b/lib/pages/pharmacies/widgets/manufacturerItem.dart index 7ffa3d89..574c37c5 100644 --- a/lib/pages/pharmacies/widgets/manufacturerItem.dart +++ b/lib/pages/pharmacies/widgets/manufacturerItem.dart @@ -1,6 +1,9 @@ import 'package:diplomaticquarterapp/core/model/pharmacies/Manufacturer.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; +import '../../final_products_page.dart'; + class ManufacturerItem extends StatelessWidget { final Manufacturer item; @@ -8,25 +11,38 @@ class ManufacturerItem extends StatelessWidget { @override Widget build(BuildContext context) { - return Card( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - border: Border( - right: BorderSide(color: Colors.grey.shade300, width: 1), - bottom: BorderSide(color: Colors.grey.shade300, width: 1), - left: BorderSide(color: Colors.grey.shade300, width: 1), - top: BorderSide(color: Colors.grey.shade300, width: 1)), + return InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: item.id, + productType: 2, + ), + ), + ); + }, + child: Card( + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 8), - child: Image.network( - item.image.src, - fit: BoxFit.cover, + child: Container( + decoration: BoxDecoration( + border: Border( + right: BorderSide(color: Colors.grey.shade300, width: 1), + bottom: BorderSide(color: Colors.grey.shade300, width: 1), + left: BorderSide(color: Colors.grey.shade300, width: 1), + top: BorderSide(color: Colors.grey.shade300, width: 1)), + ), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 8), + child: Image.network( + item.image.src, + fit: BoxFit.cover, + ), ), ), ), diff --git a/lib/pages/pharmacies/wishlist.dart b/lib/pages/pharmacies/wishlist.dart index 822dfe89..000e8404 100644 --- a/lib/pages/pharmacies/wishlist.dart +++ b/lib/pages/pharmacies/wishlist.dart @@ -5,6 +5,8 @@ import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; class WishlistPage extends StatefulWidget { + bool showBar; + WishlistPage(this.showBar); @override _WishlistPageState createState() => _WishlistPageState(); } @@ -17,9 +19,9 @@ class _WishlistPageState extends State { onModelReady: (model) => model.getWishlistData(), builder: (_, model, wi) => AppScaffold( appBarTitle: 'Wishlist page', - isShowAppBar: false, + isShowAppBar: widget.showBar, isShowDecPage: false, - isPharmacy: false, + isPharmacy: true, baseViewModel: model, body: model.wishListList.length == 0 ? Container( diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 576bf2a0..2ba92674 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -1,20 +1,17 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; -import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/order/OrderDetails.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/services/pharmacy_services/order_service.dart'; -import 'package:diplomaticquarterapp/pages/pharmacy/order/OrderDetails.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; dynamic languageID; -class OrderPage extends StatefulWidget { +class OrderPage extends StatefulWidget { // orderList({this.customerId, this.pageId}); String customerID; @@ -25,19 +22,22 @@ class OrderPage extends StatefulWidget { _OrderPageState createState() => _OrderPageState(); } -class _OrderPageState extends State with SingleTickerProviderStateMixin{ - - String pageID= "1"; +class _OrderPageState extends State + with SingleTickerProviderStateMixin { + String pageID = "1"; String customerId = ""; - String order =""; + String order = ""; + + List orderList = []; + + List deliveredOrderList = []; - List orderList = [] ; - List deliveredOrderList = [] ; - List processingOrderList = []; - List cancelledOrderList = []; - List pendingOrderList = []; + List processingOrderList = []; + List cancelledOrderList = []; + List pendingOrderList = []; TabController _tabController; + // AppSharedPreferences sharedPref = AppSharedPreferences(); getLanguageID() async { languageID = await sharedPref.getString(APP_LANGUAGE); @@ -48,26 +48,30 @@ class _OrderPageState extends State with SingleTickerProviderStateMix getLanguageID(); super.initState(); - - _tabController = new TabController(length: 4, vsync: this,); + _tabController = new TabController( + length: 4, + vsync: this, + ); } @override Widget build(BuildContext context) { - print( "customerID" + widget.customerID); + print("customerID" + widget.customerID); return BaseView( onModelReady: (model) => model.getOrder(widget.customerID, pageID), - builder: (_,model, wi )=> AppScaffold( - appBarTitle:TranslationBase.of(context).order, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).order, baseViewModel: model, - isShowAppBar: true, - isPharmacy:true , + isShowAppBar: true, + isPharmacy: true, body: Container( child: Column( children: [ TabBar( + labelPadding: EdgeInsets.only(left: 3.0, right: 3.0), + labelColor: Colors.black, tabs: [ - Tab(text: TranslationBase.of(context).delivered), + Tab(text: TranslationBase.of(context).delivered), Tab(text: TranslationBase.of(context).processing), Tab(text: TranslationBase.of(context).pending), Tab(text: TranslationBase.of(context).cancelled), @@ -100,432 +104,533 @@ class _OrderPageState extends State with SingleTickerProviderStateMix ); } - - - Widget getDeliveredOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 30 || model.order[i].orderStatusId == 997 - || model.order[i].orderStatusId == 994 - ){ - deliveredOrderList.add(model.order[i]); + Widget getDeliveredOrder(OrderModelViewModel model) { + for (int i = 0; i < model.orders.length; i++) { + if (model.orders[i].orderStatusId == 30 || + model.orders[i].orderStatusId == 997 || + model.orders[i].orderStatusId == 994) { + deliveredOrderList.add(model.orders[i]); } } return Container( width: MediaQuery.of(context).size.width, - child: model.order.length != 0 - ? SingleChildScrollView( - child: Column( - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: deliveredOrderList.length, - itemBuilder: (context, index){ - return Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderNumber, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), - ), - ), - Container( - child: Text(deliveredOrderList[index].id.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + child: model.orders.length != 0 + ? SingleChildScrollView( + child: Column( + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: deliveredOrderList.length, + itemBuilder: (context, index) { + return Container( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + child: Text( + deliveredOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderDate, - style: TextStyle(fontSize: 14.0, - ), + SizedBox( + height: 5, ), - ), - Container( - child: Text(deliveredOrderList[index].createdOnUtc.toString().substring(0,11), - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + child: Text( + deliveredOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), + ], + ), + ), + Container( + margin: EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + deliveredOrderList[ + index]), + )); + }, + child: SvgPicture.asset( + languageID == "ar" + ? 'assets/images/pharmacy/arrow_left.svg' + : 'assets/images/pharmacy/arrow_right.svg', + height: 20, + width: 20, ), - ], + ), ), ], ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:deliveredOrderList[index]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - :'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20,), - ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - padding: EdgeInsets.only(left: 13.0, right: 13.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.blue[700], - style: BorderStyle.solid, - width: 5.0, - ), - color: Colors.blue[700], - borderRadius: BorderRadius.circular(30.0) + Divider( + color: Colors.grey[350], + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, ), - child: deliveredOrderList[index].orderStatusId == 30 - ? Text( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.only( + left: 8, right: 8, top: 1, bottom: 8), + padding: EdgeInsets.only( + left: 13.0, right: 13.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.blue[700], + style: BorderStyle.solid, + width: 5.0, + ), + color: Colors.blue[700], + borderRadius: + BorderRadius.circular(30.0)), + child: deliveredOrderList[index] + .orderStatusId == + 30 + ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), - TranslationBase.of(context).deliveredOrder, - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - : Text( - languageID == "ar" - ? deliveredOrderList[index].orderStatusn.toString(): - deliveredOrderList[index].orderStatus.toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - ), - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - child: Column( + TranslationBase.of(context) + .deliveredOrder, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ) + : Text( + languageID == "ar" + ? deliveredOrderList[index] + .orderStatusn + .toString() + : deliveredOrderList[index] + .orderStatus + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + )), + Container( + margin: EdgeInsets.only( + left: 8, right: 8, top: 1, bottom: 8), + child: Column( // crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Text(deliveredOrderList[index].orderTotal.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), - ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).sar, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + deliveredOrderList[index] + .orderTotal + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - child: Text(deliveredOrderList[index].orderItems.length.toString(), - style: TextStyle(fontSize: 14.0, - ), + SizedBox( + height: 5, ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).itemsNo, - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + child: Text( + deliveredOrderList[index] + .productCount + .toString(), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .itemsNo, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), - ), - ], + ], + ), ), ], ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, - ), - ], - ), - ); - } + Divider( + color: Colors.grey[350], + height: 20, + thickness: 8, + indent: 0, + endIndent: 0, + ), + ], + ), + ); + }) + ], + ), ) - ], - ), - ) : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/empty_box.svg'), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noOrder, - style: TextStyle( - fontSize: 16.0, - )), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/images/pharmacy/empty_box.svg'), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).noOrder, + style: TextStyle( + fontSize: 16.0, + )), + ), + ], + ), ), - ], - ), - ), - ), + ), ); } - Widget getProcessingOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 20 || model.order[i].orderStatusId == 995 || - model.order[i].orderStatusId == 998 || model.order[i].orderStatusId == 999){ - processingOrderList.add(model.order[i]); + Widget getProcessingOrder(OrderModelViewModel model) { + for (int i = 0; i < model.orders.length; i++) { + if (model.orders[i].orderStatusId == 20 || + model.orders[i].orderStatusId == 995 || + model.orders[i].orderStatusId == 998 || + model.orders[i].orderStatusId == 999) { + processingOrderList.add(model.orders[i]); } } return Container( width: MediaQuery.of(context).size.width, - child: model.order.length != 0 + child: model.orders.length != 0 ? SingleChildScrollView( - child: Column( - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: processingOrderList.length, - itemBuilder: (context, index){ - return Container( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderNumber, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), - ), - ), - Container( - child: Text(processingOrderList[index].id.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + child: Column( + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: processingOrderList.length, + itemBuilder: (context, index) { + return Container( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + child: Text( + processingOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderDate, - style: TextStyle(fontSize: 14.0, - ), + SizedBox( + height: 5, ), - ), - Container( - child: Text(processingOrderList[index].createdOnUtc.toString().substring(0,11), - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + child: Text( + processingOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), + ], + ), + ), + Container( + margin: EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + processingOrderList[ + index]))); + }, + child: SvgPicture.asset( + languageID == "ar" + ? 'assets/images/pharmacy/arrow_left.svg' + : 'assets/images/pharmacy/arrow_right.svg', + height: 20, + width: 20, ), - ], + ), ), ], ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:processingOrderList[index]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - :'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20,), + Divider( + color: Colors.grey[350], + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - padding: EdgeInsets.only(left: 13.0, right: 13.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 5.0, - ), - color: Colors.green, - borderRadius: BorderRadius.circular(30.0) - ), - child: processingOrderList[index].orderStatusId == 20 - ? Text( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.only( + left: 8, right: 8, top: 1, bottom: 8), + padding: EdgeInsets.only( + left: 13.0, right: 13.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 5.0, + ), + color: Colors.green, + borderRadius: + BorderRadius.circular(30.0)), + child: processingOrderList[index] + .orderStatusId == + 20 + ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), - TranslationBase.of(context).processingOrder, - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - : Text( - languageID == "ar" - ? processingOrderList[index].orderStatusn.toString(): - processingOrderList[index].orderStatus.toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - ), - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - child: Column( + TranslationBase.of(context) + .processingOrder, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ) + : Text( + languageID == "ar" + ? processingOrderList[index] + .orderStatusn + .toString() + : processingOrderList[index] + .orderStatus + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + )), + Container( + margin: EdgeInsets.only( + left: 8, right: 8, top: 1, bottom: 8), + child: Column( // crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Text(processingOrderList[index].orderTotal.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), - ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).sar, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + children: [ + Row( + children: [ + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + processingOrderList[index] + .orderTotal + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - child: Text(processingOrderList[index].orderItems.length.toString(), - style: TextStyle(fontSize: 14.0, - ), + SizedBox( + height: 5, ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).itemsNo, - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + child: Text( + processingOrderList[index] + .productCount + .toString(), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + margin: EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .itemsNo, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), - ), - ], + ], + ), ), ], ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, - ), - ], - ), - ); - } + Divider( + color: Colors.grey[350], + height: 20, + thickness: 8, + indent: 0, + endIndent: 0, + ), + ], + ), + ); + }) + ], + ), ) - ], - ), - ) : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/empty_box.svg'), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noOrder, - style: TextStyle( - fontSize: 16.0, - )), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/images/pharmacy/empty_box.svg'), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).noOrder, + style: TextStyle( + fontSize: 16.0, + )), + ), + ], + ), ), - ], - ), - ), - ), + ), ); // return Container( // child: model.order.length != 0 @@ -585,7 +690,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix // child: InkWell( // onTap: () { // Navigator.push(context, -// MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:processingOrderList[0]))); +// FadePage(page: OrderDetailsPage(orderModel:processingOrderList[0]))); // }, // child: SvgPicture.asset( // 'assets/images/pharmacy/arrow_right.svg', @@ -708,441 +813,552 @@ class _OrderPageState extends State with SingleTickerProviderStateMix // ); } - Widget getPendingOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 10){ - pendingOrderList.add(model.order[i]); + Widget getPendingOrder(OrderModelViewModel model) { + for (int i = 0; i < model.orders.length; i++) { + if (model.orders[i].orderStatusId == 10) { + pendingOrderList.add(model.orders[i]); } } return Container( - child: model.order.length != 0 - ? SingleChildScrollView( - child: Column( - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: pendingOrderList.length , - itemBuilder: (context, index){ - return Container( - child: SingleChildScrollView( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderNumber, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), - ), - ), - Container( - child: Text(pendingOrderList[index].id.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + child: model.orders.length != 0 + ? SingleChildScrollView( + child: Column( + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: pendingOrderList.length, + itemBuilder: (context, index) { + return Container( + child: SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + child: Text( + pendingOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderDate, - style: TextStyle(fontSize: 14.0, - ), + SizedBox( + height: 5, ), - ), - Container( - child: Text(pendingOrderList[index].createdOnUtc.toString().substring(0,11), - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + child: Text( + pendingOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), + ], + ), + ), + Container( + margin: EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + pendingOrderList[ + index]))); + }, + child: SvgPicture.asset( + languageID == "ar" + ? 'assets/images/pharmacy/arrow_left.svg' + : 'assets/images/pharmacy/arrow_right.svg', + height: 20, + width: 20, ), - ], + ), ), ], ), - ), - Container( - margin: EdgeInsets.all( 8.0), - child: InkWell( - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:pendingOrderList[index]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - :'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20,), - ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all(8.0), - padding: EdgeInsets.only(left: 13.0, right: 13.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.orange[300], - style: BorderStyle.solid, - width: 5.0, - ), - color: Colors.orange[300], - borderRadius: BorderRadius.circular(30.0) + Divider( + color: Colors.grey[350], + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, ), - child: pendingOrderList[index].orderStatusId == 10 - ? Text( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + padding: EdgeInsets.only( + left: 13.0, right: 13.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.orange[300], + style: BorderStyle.solid, + width: 5.0, + ), + color: Colors.orange[300], + borderRadius: + BorderRadius.circular(30.0)), + child: pendingOrderList[index] + .orderStatusId == + 10 + ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), - TranslationBase.of(context).pendingOrder, - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - : Text( - languageID == "ar" - ? pendingOrderList[index].orderStatusn.toString(): - pendingOrderList[index].orderStatus.toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - ), - Container( - margin: EdgeInsets.all(8.0), - child: Column( + TranslationBase.of(context) + .pendingOrder, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ) + : Text( + languageID == "ar" + ? pendingOrderList[index] + .orderStatusn + .toString() + : pendingOrderList[index] + .orderStatus + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + )), + Container( + margin: EdgeInsets.all(8.0), + child: Column( // crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Text(pendingOrderList[index].orderTotal.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + pendingOrderList[index] + .orderTotal + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .sar, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).sar, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + SizedBox( + height: 5, ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - child: Text(pendingOrderList[index].orderItems.length.toString(), - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + child: Text( + pendingOrderList[index] + .productCount + .toString(), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .itemsNo, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).itemsNo, - style: TextStyle(fontSize: 14.0, - ), - ), - ), - ], + ], + ), ), ], ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, + Divider( + color: Colors.grey[350], + height: 20, + thickness: 8, + indent: 0, + endIndent: 0, + ), + ], + ), ), - ], - ), - ), - - ); - } + ); + }) + ], + ), ) - ], - ), - ) : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/empty_box.svg'), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noOrder, - style: TextStyle( - fontSize: 16.0, - )), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/images/pharmacy/empty_box.svg'), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).noOrder, + style: TextStyle( + fontSize: 16.0, + )), + ), + ], + ), ), - ], - ), - ), - ), - + ), ); } - Widget getCancelledOrder(OrderModelViewModel model){ - for(int i=0 ; i< model.order.length; i++){ - if( model.order[i].orderStatusId == 40 || model.order[i].orderStatusId == 996 - || model.order[i].orderStatusId == 200){ - cancelledOrderList.add(model.order[i]); + Widget getCancelledOrder(OrderModelViewModel model) { + for (int i = 0; i < model.orders.length; i++) { + if (model.orders[i].orderStatusId == 40 || + model.orders[i].orderStatus == 996 || + model.orders[i].orderStatusId == 200) { + cancelledOrderList.add(model.orders[i]); } } return Container( - child: model.order.length != 0 - ? SingleChildScrollView( - child: Column( - children: [ - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount: cancelledOrderList.length, - itemBuilder: (context, index){ - return Container( - child: SingleChildScrollView( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.all( 8.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderNumber, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + child: model.orders.length != 0 + ? SingleChildScrollView( + child: Column( + children: [ + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: cancelledOrderList.length, + itemBuilder: (context, index) { + return Container( + child: SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.all(8.0), + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderNumber, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + child: Text( + cancelledOrderList[index] + .id + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - Container( - child: Text(cancelledOrderList[index].id.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + SizedBox( + height: 5, ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - margin: EdgeInsets.only(right: 5), - child: Text(TranslationBase.of(context).orderDate, - style: TextStyle(fontSize: 14.0, - ), - ), - ), - Container( - child: Text(cancelledOrderList[index].createdOnUtc.toString().substring(0,11), - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + margin: + EdgeInsets.only(right: 5), + child: Text( + TranslationBase.of(context) + .orderDate, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + child: Text( + cancelledOrderList[index] + .createdOnUtc + .toString() + .substring(0, 10), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), + ], + ), + ), + Container( + margin: EdgeInsets.all(8.0), + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: OrderDetailsPage( + orderModel: + cancelledOrderList[ + index]))); + }, + child: SvgPicture.asset( + languageID == "ar" + ? 'assets/images/pharmacy/arrow_left.svg' + : 'assets/images/pharmacy/arrow_right.svg', + height: 20, + width: 20, ), - ], + ), ), ], ), - ), - Container( - margin: EdgeInsets.all(8.0), - child: InkWell( - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => OrderDetailsPage(orderModel:cancelledOrderList[index]))); - }, - child: SvgPicture.asset( - languageID == "ar" - ? 'assets/images/pharmacy/arrow_left.svg' - :'assets/images/pharmacy/arrow_right.svg', - height: 20, - width: 20,), - ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - padding: EdgeInsets.only(left: 10.0, right: 10.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.red[900], - style: BorderStyle.solid, - width: 5.0, - ), - color: Colors.red[900], - borderRadius: BorderRadius.circular(30.0) + Divider( + color: Colors.grey[350], + height: 20, + thickness: 1, + indent: 0, + endIndent: 0, ), - child: cancelledOrderList[index].orderStatusId == 40 - ? Text( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Container( + margin: EdgeInsets.only( + left: 8, + right: 8, + top: 1, + bottom: 8), + padding: EdgeInsets.only( + left: 10.0, right: 10.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.red[900], + style: BorderStyle.solid, + width: 5.0, + ), + color: Colors.red[900], + borderRadius: + BorderRadius.circular(30.0)), + child: cancelledOrderList[index] + .orderStatusId == + 40 + ? Text( // deliveredOrderList[0].orderStatus.toString().substring(12), - TranslationBase.of(context).cancelledOrder, - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - : Text( - languageID == "ar" - ? cancelledOrderList[index].orderStatusn.toString(): - cancelledOrderList[index].orderStatus.toString(), - style: TextStyle( - color: Colors.white, - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ) - ), - Container( - margin: EdgeInsets.only(left: 8, right: 8, top: 1, bottom: 8), - child: Column( + TranslationBase.of(context) + .cancelledOrder, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ) + : Text( + languageID == "ar" + ? cancelledOrderList[index] + .orderStatusn + .toString() + : cancelledOrderList[index] + .orderStatus + .toString(), + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + )), + Container( + margin: EdgeInsets.only( + left: 8, right: 8, top: 1, bottom: 8), + child: Column( // crossAxisAlignment: CrossAxisAlignment.end, - children: [ - Row( - children: [ - Container( - margin: EdgeInsets.only(left: 5), - child: Text(cancelledOrderList[index].orderTotal.toString(), - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + children: [ + Row( + children: [ + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + cancelledOrderList[index] + .orderTotal + .toString(), + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .sar, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).sar, - style: TextStyle(fontSize: 16.0, fontWeight: FontWeight.bold, - ), + SizedBox( + height: 5, ), - ), - ], - ), - SizedBox( - height: 5,), - Row( - children: [ - Container( - child: Text(cancelledOrderList[index].orderItems.length.toString(), - style: TextStyle(fontSize: 14.0, - ), - ), - ), - Container( - margin: EdgeInsets.only(left: 5), - child: Text(TranslationBase.of(context).itemsNo, - style: TextStyle(fontSize: 14.0, - ), + Row( + children: [ + Container( + child: Text( + cancelledOrderList[index] + .productCount + .toString(), + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + Container( + margin: + EdgeInsets.only(left: 5), + child: Text( + TranslationBase.of(context) + .itemsNo, + style: TextStyle( + fontSize: 14.0, + ), + ), + ), + ], ), - ), - ], + ], + ), ), ], ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, + Divider( + color: Colors.grey[350], + height: 20, + thickness: 8, + indent: 0, + endIndent: 0, + ), + ], + ), ), - ], - ), - ), - - ); - } + ); + }) + ], + ), ) - ], - ), - ) : Container( - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/empty_box.svg'), - Container( - margin: EdgeInsets.only(top: 10.0), - child: Text(TranslationBase.of(context).noOrder, - style: TextStyle( - fontSize: 16.0, - )), - ), - ], - ), - ), - ), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SvgPicture.asset('assets/images/pharmacy/empty_box.svg'), + Container( + margin: EdgeInsets.only(top: 10.0), + child: Text(TranslationBase.of(context).noOrder, + style: TextStyle( + fontSize: 16.0, + )), + ), + ], + ), + ), + ), ); - } - + int test = Test()["1"]; + } } +class Test { + static const values = {"1": 1, "2": 2, "3": 3}; - - - - + int operator [](String key) => values[key]; +} diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 5438663d..2f113e50 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -1,31 +1,33 @@ +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; +import 'package:diplomaticquarterapp/models/Appointments/AppoimentAllHistoryResultList.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; -import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets//pharmacy/product_tile.dart'; +import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; +import 'package:diplomaticquarterapp/widgets/in_app_browser/InAppBrowser.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:diplomaticquarterapp/widgets//pharmacy/product_tile.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:flutter/src/widgets/image.dart' as flutterImage; - -import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; -import 'package:diplomaticquarterapp/uitl/app_toast.dart'; -import 'package:provider/provider.dart'; - - - +import 'package:flutter_svg/flutter_svg.dart'; dynamic languageID; + class OrderDetailsPage extends StatefulWidget { - OrderModel orderModel; + Orders orderModel; OrderDetailsPage({@required this.orderModel}); + // Orders orderModel; +// OrderModel orderModelDetails; +// OrderDetailsPage({@required this.orderModel, this.orderModelDetails}); + @override _OrderDetailsPageState createState() => _OrderDetailsPageState(); } @@ -36,209 +38,222 @@ class _OrderDetailsPageState extends State { } // AppSharedPreferences sharedPref = AppSharedPreferences(); - String orderId = ""; String customerId; - List orderList = []; + List ordersList = []; - List cancelledOrderList = []; + List cancelledOrderList = []; // String orderId="3516"; var model; var isCancel = false; var isRefund = false; + var isActiveDelivery = false; var dataIsCancel; var dataIsRefund; + BuildContext context; + + MyInAppBrowser browser; @override void initState() { getLanguageID(); super.initState(); - print(widget.orderModel.orderItems.length); +// print(widget.orderModel.orderItems.length); getCancelOrder(widget.orderModel.id); + + print("ID is" + widget.orderModel.id); // cancelOrderDetail(order) } @override Widget build(BuildContext context) { + this.context = context; return BaseView( - onModelReady: (model) => model.getOrderDetails(widget.orderModel.id), + onModelReady: (model) { + model.getOrderDetails(widget.orderModel.id).then((value) { + setState(() { + isActiveDelivery = (value.orderStatusId == 995 && + (value.driverID != null && value.driverID.isNotEmpty)); + }); + }); + }, builder: (_, model, wi) => AppScaffold( appBarTitle: TranslationBase.of(context).orderDetail, isShowAppBar: true, isPharmacy: true, - body: Container( - color: Colors.white, - child: SingleChildScrollView( - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.fromLTRB(10.0, 15.0, 1.0, 5.0), - child: Row( + baseViewModel: model, + body: model.orderListModel.length > 0 + ? Container( + color: Colors.white, + child: SingleChildScrollView( + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - SvgPicture.asset( - 'assets/images/pharmacy/shipping_mark_icon.svg', - width: 28, - height: 28, + Container( + margin: EdgeInsets.fromLTRB(10.0, 15.0, 1.0, 5.0), + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/shipping_mark_icon.svg', + width: 28, + height: 28, + ), + Text( + TranslationBase.of(context).shippingAddress, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), ), - Text( - TranslationBase.of(context).shippingAddress, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, + Container( + margin: EdgeInsets.only(top: 15.0, right: 10.0), + padding: EdgeInsets.only(left: 11.0, right: 11.0), + decoration: BoxDecoration( + border: Border.all( + color: getStatusBackgroundColor(), + style: BorderStyle.solid, + width: 5.0, + ), + color: getStatusBackgroundColor(), + borderRadius: BorderRadius.circular(30.0)), + child: Text( + languageID == "ar" + ? model.orderListModel[0].orderStatusn + : model.orderListModel[0].orderStatus, +// TranslationBase.of(context).delivered, + style: TextStyle( + color: Colors.white, + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), ), ), ], ), - ), - Container( - margin: EdgeInsets.only(top: 15.0, right: 10.0), - padding: EdgeInsets.only(left: 11.0, right: 11.0), - decoration: BoxDecoration( - border: Border.all( - color: getStatusBackgroundColor(), - style: BorderStyle.solid, - width: 5.0, - ), - color: getStatusBackgroundColor(), - borderRadius: BorderRadius.circular(30.0)), - child: Text( - languageID == "ar" - ? widget.orderModel.orderStatusn.toString(): - widget.orderModel.orderStatus.toString().substring(12) , -// TranslationBase.of(context).delivered, - style: TextStyle( - color: Colors.white, - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), + Container( + margin: EdgeInsets.only(left: 10.0, top: 13.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "${model.orderListModel[0].shippingAddress.firstName} ${model.orderListModel[0].shippingAddress.lastName}", + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ]), ), - ), - ], - ), - Container( - margin: EdgeInsets.only(left: 10.0, top: 13.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.orderModel.shippingAddress.firstName - .toString() - .substring(10) + - ' ' + - widget.orderModel.shippingAddress.lastName - .toString() - .substring(9), - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ]), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.orderModel.shippingAddress.address1 - .toString() - .substring(9), - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, + Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.orderListModel[0].shippingAddress.address1 + .toString() + , + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ), + ]), ), - ),] - ), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - widget.orderModel.shippingAddress.address2 - .toString() - .substring(9) + - ' ' + - widget.orderModel.shippingAddress.country - .toString() + - ' ' + - widget.orderModel.shippingAddress.zipPostalCode - .toString(), - style: TextStyle( - fontSize: 10.0, - fontWeight: FontWeight.bold, - color: Colors.grey, - ), - ), - ]), - ), - Container( - child: Row( - children: [ Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 8.0, 5.0), - child: SvgPicture.asset( - 'assets/images/pharmacy/mobile_number_icon.svg', - height: 13, - ), + margin: EdgeInsets.fromLTRB(10.0, 5.0, 1.0, 5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + model.orderListModel[0].shippingAddress.address2 + .toString() + + + ' ' + + model.orderListModel[0].shippingAddress + .country + .toString() + + ' ' + + model.orderListModel[0].shippingAddress + .zipPostalCode + .toString(), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ), + ]), ), Container( - margin: EdgeInsets.only(top: 5.0, bottom: 5.0), - child: Text( - widget.orderModel.shippingAddress.phoneNumber - .toString(), - style: TextStyle( - fontSize: 15.0, - ), + child: Row( + children: [ + Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 8.0, 5.0), + child: SvgPicture.asset( + 'assets/images/pharmacy/mobile_number_icon.svg', + height: 13, + ), + ), + Container( + margin: EdgeInsets.only(top: 5.0, bottom: 5.0), + child: Text( + model.orderListModel[0].shippingAddress + .phoneNumber + .toString(), + style: TextStyle( + fontSize: 15.0, + ), + ), + ), + ], ), ), - ], - ), - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 1, - indent: 0, - endIndent: 0, - ), - Row( - children: [ - Container( - margin: EdgeInsets.fromLTRB(10.0, 10.0, 5.0, 10.0), - child: SvgPicture.asset( - 'assets/images/pharmacy/shipping_truck_icon.svg', + Divider( + color: Colors.grey[350], height: 20, - width: 20, - ), - ), - Container( - margin: EdgeInsets.all(10.0), - child: Text( - TranslationBase.of(context).shippedMethod, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), + thickness: 1, + indent: 0, + endIndent: 0, ), - ), - Container( - child: flutterImage.Image.asset( - widget.orderModel.shippingRateComputationMethodSystemName != - "Shipping.Aramex" - ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" - : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", - fit: BoxFit.contain, + Row( + children: [ + Container( + margin: EdgeInsets.fromLTRB(10.0, 10.0, 5.0, 10.0), + child: SvgPicture.asset( + 'assets/images/pharmacy/shipping_truck_icon.svg', + height: 20, + width: 20, + ), + ), + Container( + margin: EdgeInsets.all(10.0), + child: Text( + TranslationBase.of(context).shippedMethod, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Container( + child: flutterImage.Image.asset( + model.orderListModel[0] + .shippingRateComputationMethodSystemName != + "Shipping.Aramex" + ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" + : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", + fit: BoxFit.contain, // height: 100, - width: 100, - ), - ), + width: 100, + ), + ), // Container( // child: widget.orderModel // .shippingRateComputationMethodSystemName == @@ -260,313 +275,348 @@ class _OrderDetailsPageState extends State { // ), // ), // ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, - ), - Row( - children: [ - Container( - margin: EdgeInsets.all(10.0), - child: SvgPicture.asset( - 'assets/images/pharmacy/credit_card_icon.svg', + ], + ), + Divider( + color: Colors.grey[350], height: 20, - width: 20, + thickness: 8, + indent: 0, + endIndent: 0, ), - ), - Container( - margin: EdgeInsets.only(bottom: 10.0, top: 10.0), - child: Text( - widget.orderModel.paymentName.toString().substring(12), - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), + Row( + children: [ + Container( + margin: EdgeInsets.all(10.0), + child: SvgPicture.asset( + 'assets/images/pharmacy/credit_card_icon.svg', + height: 20, + width: 20, + ), + ), + Container( + margin: EdgeInsets.only(bottom: 10.0, top: 10.0), + child: Text( + model.orderListModel[0].paymentName + .toString() + .substring(12), + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ), + ], ), - ), - ], - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 8, - indent: 0, - endIndent: 0, - ), - Container( - padding: EdgeInsets.only(bottom: 15.0), - margin: EdgeInsets.only(left: 10.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).orderDetail, - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), + Divider( + color: Colors.grey[350], + height: 20, + thickness: 8, + indent: 0, + endIndent: 0, ), - ], - ), - ), - ListView.builder( - scrollDirection: Axis.vertical, - shrinkWrap: true, - physics: ScrollPhysics(), - itemCount:widget.orderModel.orderItems.length, - itemBuilder: (context, index){ - return Container( - child: productTile(productName: widget.orderModel.orderItems[index].product.name.toString(), - productPrice: widget.orderModel.orderItems[index].product.price.toString(), - productRate: widget.orderModel.orderItems[index].product.approvedRatingSum.toDouble(), - productReviews:widget.orderModel.orderItems[index].product.approvedTotalReviews, - totalPrice: "${(widget.orderModel.orderItems[index].product.price - * widget.orderModel.orderItems[index].quantity).toStringAsFixed(2)}", - qyt: widget.orderModel.orderItems[index].quantity.toString(), - isOrderDetails:true, - imgs: widget.orderModel.orderItems[index].product.images != null && - widget.orderModel.orderItems[index].product.images.length != 0 - ? widget.orderModel.orderItems[index].product.images [0].src.toString() - : null, - status: widget.orderModel.orderStatusId, - product: widget.orderModel.orderItems[index].product, - ), - ); - }), - - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.only(left: 10.0, top: 5.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).orderSummary, - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, + Container( + padding: EdgeInsets.only(bottom: 15.0), + margin: EdgeInsets.only(left: 10.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).orderDetail, + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ], ), ), - ], - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.only(top: 5.0, left: 10.0), - child: Text( - TranslationBase.of(context).subtotal, - style: TextStyle( - fontSize: 13.0, + ListView.builder( + scrollDirection: Axis.vertical, + shrinkWrap: true, + physics: ScrollPhysics(), + itemCount: model.orderListModel[0].orderItems.length, + itemBuilder: (context, index) { + return Container( + child: productTile( + productName: model.orderListModel[0].orderItems[index].product.name.toString(), + productPrice: model.orderListModel[0].orderItems[index].product.price.toString(), + productRate: model.orderListModel[0].orderItems[index].product.approvedRatingSum.toDouble(), + productReviews: model.orderListModel[0].orderItems[index].product.approvedTotalReviews, + totalPrice: "${(model.orderListModel[0].orderItems[index].product.price * model.orderListModel[0].orderItems[index].quantity).toStringAsFixed(2)}", + qyt: model.orderListModel[0].orderItems[index].quantity.toString(), + isOrderDetails: true, + imgs: model.orderListModel[0].orderItems[index].product.images != null && + model.orderListModel[0].orderItems[index].product.images.length != 0 + ? model.orderListModel[0].orderItems[index].product.images[0].src.toString() : null, + status: model.orderListModel[0].orderStatusId, + product: model.orderListModel[0].orderItems[index].product, + ), + ); + }), + + Container( + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.only(left: 10.0, top: 5.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).orderSummary, + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ], ), ), - ), - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), - child: Row( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( - margin: EdgeInsets.only(right: 5.0), + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.only(top: 5.0, left: 10.0), child: Text( - TranslationBase.of(context).sar, + TranslationBase.of(context).subtotal, style: TextStyle( fontSize: 13.0, ), ), ), - Text( - widget.orderModel.orderSubtotalExclTax.toString(), - style: TextStyle( - fontSize: 13.0, + Container( + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5.0), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 13.0, + ), + ), + ), + Text( + model.orderListModel[0].orderSubtotalExclTax + .toString(), + style: TextStyle( + fontSize: 13.0, + ), + ), + ], ), ), ], ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.only(top: 5.0, left: 10.0), - child: Text( - TranslationBase.of(context).shipping, - style: TextStyle( - fontSize: 13.0, - ), - ), - ), - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), - child: Row( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( - margin: EdgeInsets.only(right: 5.0), + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.only(top: 5.0, left: 10.0), child: Text( - TranslationBase.of(context).sar, + TranslationBase.of(context).shipping, style: TextStyle( fontSize: 13.0, ), ), ), - Text( - widget.orderModel.orderShippingExclTax.toString(), - style: TextStyle( - fontSize: 13.0, + Container( + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5.0), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 13.0, + ), + ), + ), + Text( + model.orderListModel[0].orderShippingExclTax + .toString(), + style: TextStyle( + fontSize: 13.0, + ), + ), + ], ), ), ], ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.only(top: 5.0, left: 10.0), - child: Text( - TranslationBase.of(context).vat, - style: TextStyle( - fontSize: 13.0, - ), - ), - ), - Container( - padding: EdgeInsets.only(bottom: 10.0), - margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), - child: Row( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( - margin: EdgeInsets.only(right: 5.0), + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.only(top: 5.0, left: 10.0), child: Text( - TranslationBase.of(context).sar, + TranslationBase.of(context).vat, style: TextStyle( fontSize: 13.0, ), ), ), - Text( - widget.orderModel.orderTax.toString(), - style: TextStyle( - fontSize: 13.0, + Container( + padding: EdgeInsets.only(bottom: 10.0), + margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5.0), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 13.0, + ), + ), + ), + Text( + model.orderListModel[0].orderTax.toString(), + style: TextStyle( + fontSize: 13.0, + ), + ), + ], ), ), ], ), - ), - ], - ), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - margin: EdgeInsets.only(top: 5.0, left: 10.0), - child: Text( - TranslationBase.of(context).total, - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, - ), - ), - ), - Container( - margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), - child: Row( + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( - margin: EdgeInsets.only(right: 5.0), + margin: EdgeInsets.only(top: 5.0, left: 10.0), child: Text( - TranslationBase.of(context).sar, + TranslationBase.of(context).total, style: TextStyle( fontSize: 15.0, fontWeight: FontWeight.bold, ), ), ), - Text( - widget.orderModel.orderTotal.toString(), - style: TextStyle( - fontSize: 15.0, - fontWeight: FontWeight.bold, + Container( + margin: EdgeInsets.fromLTRB(10.0, 5.0, 5.0, 5.0), + child: Row( + children: [ + Container( + margin: EdgeInsets.only(right: 5.0), + child: Text( + TranslationBase.of(context).sar, + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ), + Text( + model.orderListModel[0].orderTotal.toString(), + style: TextStyle( + fontSize: 15.0, + fontWeight: FontWeight.bold, + ), + ), + ], ), ), ], ), - ), - ], - ), - widget.orderModel.orderStatusId == 10 - ? InkWell( - onTap: () { - model.makeOrder(); - }, - child: Container( + model.orderListModel[0].orderStatusId == 10 + ? InkWell( + onTap: () { + print(widget.orderModel.toString()); + print(model.orderListModel.toString()); + print("calc = ${5.9 * 3}"); + // TODO MOSA + openPayment( + model.orderListModel[0], model.user); + }, + child: Container( // margin: EdgeInsets.only(top: 20.0), - height: 50.0, - color: Colors.transparent, - child: Container( - padding: EdgeInsets.only(left: 130.0, right: 130.0), - decoration: BoxDecoration( - border: Border.all( - color: Colors.green, - style: BorderStyle.solid, - width: 4.0), - color: Colors.green, - borderRadius: BorderRadius.circular(5.0)), - child: Center( - child: Text( - TranslationBase.of(context).payOnline, - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, + height: 50.0, + color: Colors.transparent, + child: Container( + padding: EdgeInsets.only( + left: 130.0, right: 130.0), + decoration: BoxDecoration( + border: Border.all( + color: Colors.green, + style: BorderStyle.solid, + width: 4.0), + color: Colors.green, + borderRadius: BorderRadius.circular(5.0)), + child: Center( + child: Text( + TranslationBase.of(context).payOnline, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ), ), ), - ), - ), - ), - ) - : Container(), + ) + : Container(), // getCancelOrder(canCancel, canRefund), - isCancel - ? InkWell( - onTap: () { - presentConfirmDialog(model, - widget.orderModel.id); //(widget.orderModel.id)); + isCancel + ? InkWell( + onTap: () { + presentConfirmDialog( + model, widget.orderModel.id); + // model.orderListModel[0].id//(widget.orderModel.id)); // - }, - child: Container( + }, + child: Container( // padding: EdgeInsets.only(left: 13.0, right: 13.0, top: 5.0), - height: 50.0, - color: Colors.transparent, - child: Center( - child: Text( - TranslationBase.of(context).cancelOrder, - style: TextStyle( - color: Colors.red[900], - fontWeight: FontWeight.bold, - decoration: TextDecoration.underline), - ), - ), - ), - ) - : Container(), - ], - ), - ), - ), + height: 50.0, + color: Colors.transparent, + child: Center( + child: Text( + TranslationBase.of(context).cancelOrder, + style: TextStyle( + color: Colors.red[900], + fontWeight: FontWeight.bold, + decoration: TextDecoration.underline), + ), + ), + ), + ) + : Container(), + isActiveDelivery + ? InkWell( + onTap: () { + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => TrackDriver(order: widget.orderModel), + // )); + }, + child: Container( + height: 50.0, + color: Colors.transparent, + child: Center( + child: Text( + TranslationBase.of(context) + .trackDeliveryDriver, + style: TextStyle( + color: Colors.green[900], + fontWeight: FontWeight.normal, + decoration: TextDecoration.none), + ), + ), + ), + ) + : Container(), + ], + ), + ), + ) + : Container(), ), ); } @@ -628,8 +678,9 @@ class _OrderDetailsPageState extends State { // Navigator.pop(context); Navigator.push( context, - MaterialPageRoute( - builder: (context) => OrderPage( + FadePage( + page: OrderPage( +// customerID: model.ordersList[0].customerId.toString() customerID: widget.orderModel.customerId.toString())), ); }), @@ -647,4 +698,64 @@ class _OrderDetailsPageState extends State { } } + + /*** + * + * Online payment methods + */ + + openPayment( + OrderDetailModel order, + AuthenticatedUser authenticatedUser, + ) { + browser = new MyInAppBrowser( + onExitCallback: onBrowserExit, onLoadStartCallback: onBrowserLoadStart); + + browser.openPharmacyPaymentBrowser( + order, + order.orderTotal, + 'ePharmacy Order', + order.id, + order.billingAddress.email, + order.customValuesXml, + "${authenticatedUser.firstName} ${authenticatedUser.middleName} ${authenticatedUser.lastName}", + authenticatedUser.patientID, + authenticatedUser, + browser); + } + + onBrowserLoadStart(String url) { + print("onBrowserLoadStart"); + print(url); + + MyInAppBrowser.successURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = true; + return; + } + }); + + MyInAppBrowser.errorURLS.forEach((element) { + if (url.contains(element)) { + if (browser.isOpened()) browser.close(); + MyInAppBrowser.isPaymentDone = false; + return; + } + }); + } + + onBrowserExit(AppoitmentAllHistoryResultList appo, bool isPaymentMade) { + print("onBrowserExit Called!!!!"); + if (isPaymentMade) { + AppToast.showSuccessToast( + message: "شكراً\nPayment status for your order is Paid"); + Navigator.pop(context); + Navigator.pop(context); + } else { + AppToast.showErrorToast( + message: + "Transaction Failed!\Your transaction is field to some reason please try again or contact to the administration"); + } + } } diff --git a/lib/pages/pharmacy/order/ProductReview.dart b/lib/pages/pharmacy/order/ProductReview.dart index 4d09191c..7f58fa21 100644 --- a/lib/pages/pharmacy/order/ProductReview.dart +++ b/lib/pages/pharmacy/order/ProductReview.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/profile/profile.dart'; @@ -12,7 +13,7 @@ import 'package:rating_bar/rating_bar.dart'; import 'package:flutter/src/widgets/image.dart' as flutterImage; class ProductReviewPage extends StatefulWidget { - final Product product; + final PharmacyProduct product; ProductReviewPage(this.product); diff --git a/lib/pages/pharmacy/order/TrackDriver.dart b/lib/pages/pharmacy/order/TrackDriver.dart new file mode 100644 index 00000000..587ba9a6 --- /dev/null +++ b/lib/pages/pharmacy/order/TrackDriver.dart @@ -0,0 +1,344 @@ +import 'dart:async'; +import 'dart:typed_data'; +import 'dart:ui' as ui; + +import 'package:async/async.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/service/parmacyModule/order-preview-service.dart'; +import 'package:diplomaticquarterapp/locator.dart'; +import 'package:diplomaticquarterapp/uitl/gif_loader_dialog_utils.dart'; +import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_animarker/lat_lng_interpolation.dart'; +import 'package:flutter_animarker/models/lat_lng_delta.dart'; +import 'package:flutter_animarker/models/lat_lng_info.dart'; +import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:location/location.dart'; +import 'package:flutter_animarker/streams/lat_lng_stream.dart'; + +class TrackDriver extends StatefulWidget { + final OrderDetailModel order; + TrackDriver({this.order}); + + @override + State createState() => _TrackDriverState(); +} + +class _TrackDriverState extends State { + OrderPreviewService _orderServices = locator(); + OrderDetailModel _order; + + Completer _controller = Completer(); + + + double CAMERA_ZOOM = 14; + double CAMERA_TILT = 0; + double CAMERA_BEARING = 30; + LatLng SOURCE_LOCATION = null; + LatLng DEST_LOCATION = null; + + // for my drawn routes on the map + Set _polylines = Set(); + List polylineCoordinates = []; + PolylinePoints polylinePoints; + + Set _markers = Set(); + + BitmapDescriptor sourceIcon; // for my custom marker pins + BitmapDescriptor destinationIcon; // for my custom marker pins + Location location;// wrapper around the location API + + + int locationUpdateFreq = 2; + LatLngInterpolationStream _latLngStream; + StreamGroup subscriptions; + + @override + void initState() { + super.initState(); + + _order = widget.order; + DEST_LOCATION = _order.shippingAddress.getLocation(); + location = new Location(); + polylinePoints = PolylinePoints(); + setSourceAndDestinationIcons(); + + initMarkerUpdateStream(); + startUpdatingDriverLocation(); + + } + + @override + void dispose() { + super.dispose(); + subscriptions.close(); + _latLngStream.cancel(); + stopUpdatingDriverLocation(); + } + + initMarkerUpdateStream(){ + _latLngStream = LatLngInterpolationStream(movementDuration: Duration(seconds: locationUpdateFreq+1)); + subscriptions = StreamGroup(); + + subscriptions.add(_latLngStream.getAnimatedPosition('sourcePin')); + subscriptions.stream.listen((LatLngDelta delta) { + //Update the marker with animation + setState(() { + //Get the marker Id for this animation + var markerId = MarkerId(delta.markerId); + Marker sourceMarker = Marker( + markerId: markerId, + // rotation: delta.rotation, + icon: sourceIcon, + position: LatLng( + delta.from.latitude, + delta.from.longitude, + ), + onTap: onSourceMarkerTap + ); + + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); + _markers.add(sourceMarker); + }); + }); + } + + @override + Widget build(BuildContext context) { + + return AppScaffold( + appBarTitle: TranslationBase.of(context).deliveryDriverTrack, + isShowAppBar: true, + isPharmacy: true, + showPharmacyCart: false, + showHomeAppBarIcon: false, + body: GoogleMap( + myLocationEnabled: true, + compassEnabled: true, + markers: _markers, + polylines: _polylines, + mapType: MapType.normal, + initialCameraPosition: CameraPosition(target: DEST_LOCATION, zoom: 4), + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + // showPinsOnMap(); + }, + ), + // floatingActionButton: FloatingActionButton.extended( + // onPressed: _goToDriver, + // label: Text('To the lake!'), + // icon: Icon(Icons.directions_boat), + // ), + ); + } + + + void setSourceAndDestinationIcons() async { + final Uint8List srcMarkerBytes = await getBytesFromAsset('assets/images/map_markers/source_map_marker.png', getMarkerIconSize()); + final Uint8List destMarkerBytes = await getBytesFromAsset('assets/images/map_markers/destination_map_marker.png', getMarkerIconSize()); + sourceIcon = await BitmapDescriptor.fromBytes(srcMarkerBytes); + destinationIcon = await BitmapDescriptor.fromBytes(destMarkerBytes); + } + + CameraPosition _orderDeliveryLocationCamera(){ + if(DEST_LOCATION != null){ + final CameraPosition orderDeliveryLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: DEST_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return orderDeliveryLocCamera; + } + return null; + } + + CameraPosition _driverLocationCamera(){ + if(DEST_LOCATION != null) { + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return driverLocCamera; + } + return null; + } + + + Future _goToOrderDeliveryLocation() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition orderDeliveryLocCamera = _orderDeliveryLocationCamera(); + controller.animateCamera(CameraUpdate.newCameraPosition(orderDeliveryLocCamera)); + } + + Future _goToDriver() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition driverLocCamera = _driverLocationCamera(); + controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); + } + + + void showPinsOnMap() { + // source pin + if(SOURCE_LOCATION != null){ + setState(() { + var pinPosition = SOURCE_LOCATION; + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); + _markers.add(Marker( + markerId: MarkerId('sourcePin'), + position: pinPosition, + icon: sourceIcon, + infoWindow: InfoWindow(title: TranslationBase.of(context).driver), + onTap: onSourceMarkerTap + )); + }); + } + + // destination pin + if(DEST_LOCATION != null){ + setState(() { + var destPosition = DEST_LOCATION; + _markers.removeWhere((m) => m.markerId.value == 'destPin'); + _markers.add(Marker( + markerId: MarkerId('destPin'), + position: destPosition, + icon: destinationIcon, + infoWindow: InfoWindow(title: TranslationBase.of(context).deliveryLocation), + onTap: onDestinationMarkerTap + )); + }); + } + // set the route lines on the map from source to destination + // for more info follow this tutorial + // drawRoute(); + } + + void updatePinOnMap() async { + _latLngStream.addLatLng(LatLngInfo(SOURCE_LOCATION.latitude, SOURCE_LOCATION.longitude, "sourcePin")); + drawRoute(); + } + + void drawRoute() async { + return; // Ignore draw Route + + List result = await polylinePoints.getRouteBetweenCoordinates( + GOOGLE_API_KEY, + SOURCE_LOCATION.latitude, + SOURCE_LOCATION.longitude, + DEST_LOCATION.latitude, + DEST_LOCATION.longitude); + if(result.isNotEmpty){ + result.forEach((PointLatLng point){ + polylineCoordinates.add( + LatLng(point.latitude,point.longitude) + ); + }); + setState(() { + _polylines.add(Polyline( + width: 5, // set the width of the polylines + polylineId: PolylineId('poly'), + color: Color.fromARGB(255, 40, 122, 198), + points: polylineCoordinates + )); + }); + } + } + + bool isLocationUpdating = false; + startUpdatingDriverLocation({int frequencyInSeconds = 2}) async{ + isLocationUpdating = true; + int driverId = int.tryParse(_order.driverID); + + Future.doWhile(() async{ + if(isLocationUpdating){ + + await Future.delayed(Duration(seconds: frequencyInSeconds)); + + showLoading(); + LatLng driverLocation = (await _orderServices.getDriverLocation(driverId)); + hideLoading(); + + if(driverLocation != null){ + if(SOURCE_LOCATION == null || DEST_LOCATION == null){ + SOURCE_LOCATION = driverLocation; + DEST_LOCATION = _order.shippingAddress.getLocation(); + showPinsOnMap(); + } + SOURCE_LOCATION = driverLocation; + updatePinOnMap(); + updateMapCamera(); + }else{ + GifLoaderDialogUtils.hideDialog(context); + } + } + return isLocationUpdating; + + }); + } + + showLoading(){ + if(SOURCE_LOCATION == null){ + GifLoaderDialogUtils.showMyDialog(context); + } + } + + hideLoading(){ + if(SOURCE_LOCATION == null){ + GifLoaderDialogUtils.hideDialog(context); + } + } + + stopUpdatingDriverLocation(){ + isLocationUpdating = false; + } + + Future getBytesFromAsset(String path, int width) async { + ByteData data = await rootBundle.load(path); + ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(), targetWidth: width); + ui.FrameInfo fi = await codec.getNextFrame(); + return (await fi.image.toByteData(format: ui.ImageByteFormat.png)).buffer.asUint8List(); + } + + int getMarkerIconSize(){ + return 140; + } + + updateMapCamera() async{ + if(SOURCE_LOCATION != null && DEST_LOCATION != null){ + + // 'package:google_maps_flutter_platform_interface/src/types/location.dart': Failed assertion: line 72 pos 16: 'southwest.latitude <= northeast.latitude': is not true. + LatLngBounds bound; + if(SOURCE_LOCATION.latitude <= DEST_LOCATION.latitude){ + bound = LatLngBounds(southwest: SOURCE_LOCATION, northeast: DEST_LOCATION); + }else{ + bound = LatLngBounds(southwest: DEST_LOCATION, northeast: SOURCE_LOCATION); + } + + if(bound == null) + return; + + CameraUpdate camera = CameraUpdate.newLatLngBounds(bound, 50); + final GoogleMapController controller = await _controller.future; + controller.animateCamera(camera); + } + } + + bool showSrcMarkerTitle = false; + onSourceMarkerTap() async{ + // showSrcMarkerTitle = !showSrcMarkerTitle; + } + + bool showDestMarkerTitle = false; + onDestinationMarkerTap() async{ + // showDestMarkerTitle = !showDestMarkerTitle; + // Marker m = _markers.firstWhere((m) => m.markerId.value == 'destPin'); + // if(showDestMarkerTitle){ + // } + } +} diff --git a/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart b/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart index 7e8763e1..7569ed43 100644 --- a/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart +++ b/lib/pages/pharmacy/pharmacyAddresses/AddAddress.dart @@ -49,11 +49,9 @@ class _AddAddressPageState extends State { @override Widget build(BuildContext context) { - PreferredSizeWidget appBarWidget = AppBarWidget( - "${TranslationBase.of(context).changeAddress}", null, true); final mediaQuery = MediaQuery.of(context); final height = mediaQuery.size.height - - appBarWidget.preferredSize.height - + 60 - mediaQuery.padding.top; return BaseView( @@ -62,7 +60,6 @@ class _AddAddressPageState extends State { isShowAppBar: true, isPharmacy: true, backgroundColor: Colors.white, - appBarWidget: appBarWidget, body: Container( height: height * 1, child: PickupLocationFromMap( diff --git a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart index e3651e21..51256e11 100644 --- a/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart +++ b/lib/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart @@ -12,14 +12,12 @@ import 'package:flutter/material.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/AddAddress.dart'; - class PharmacyAddressesPage extends StatefulWidget { @override _PharmacyAddressesState createState() => _PharmacyAddressesState(); } class _PharmacyAddressesState extends State { - void navigateToAddressPage( BuildContext ctx, PharmacyAddressesViewModel model, Addresses address) { Navigator.push( @@ -31,12 +29,8 @@ class _PharmacyAddressesState extends State { } Widget build(BuildContext context) { - PreferredSizeWidget appBarWidget = AppBarWidget( - "${TranslationBase.of(context).changeAddress}", null, true); final mediaQuery = MediaQuery.of(context); - final height = mediaQuery.size.height - - appBarWidget.preferredSize.height - - mediaQuery.padding.top; + final height = mediaQuery.size.height - 60 - mediaQuery.padding.top; return BaseView( onModelReady: (model) => model.getAddressesList(), @@ -46,7 +40,6 @@ class _PharmacyAddressesState extends State { isPharmacy: true, baseViewModel: model, backgroundColor: Colors.white, - appBarWidget: appBarWidget, body: Container( height: height * 0.90, child: SingleChildScrollView( @@ -111,12 +104,12 @@ class _PharmacyAddressesState extends State { fontWeight: FontWeight.bold, backgroundColor: Color(0xFF5AB145), fontSize: 14, - vPadding: 12, + vPadding: 8, handler: () { model.saveSelectedAddressLocally( model.addresses[model.selectedAddressIndex]); - Navigator.pop(context, - model.addresses[model.selectedAddressIndex]); + Navigator.pop( + context, model.addresses[model.selectedAddressIndex]); }, ), ), diff --git a/lib/pages/pharmacy/profile/profile.dart b/lib/pages/pharmacy/profile/profile.dart index 1057a740..cd5c6ec7 100644 --- a/lib/pages/pharmacy/profile/profile.dart +++ b/lib/pages/pharmacy/profile/profile.dart @@ -4,30 +4,28 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/pages/ContactUs/LiveChat/livechat_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/findus/findus_page.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; +import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/medical/prescriptions/prescriptions_home_page.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/compare.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/my_reviews.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-main-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/lakum-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/screens/pharmacy-terms-conditions-page.dart'; import 'package:diplomaticquarterapp/pages/pharmacies/wishlist.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/pharmacyAddresses/PharmacyAddresses.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/avatar/large_avatar.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:diplomaticquarterapp/pages/base/base_view.dart'; -import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; -import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; -import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/my_reviews.dart'; -import 'package:diplomaticquarterapp/pages/pharmacies/compare.dart'; +dynamic languageID; -dynamic languageID ; class PharmacyProfilePage extends StatefulWidget { @override _ProfilePageState createState() => _ProfilePageState(); @@ -44,40 +42,41 @@ class _ProfilePageState extends State { String lastName, mobileNo, identificationNo; int languageId; - _ProfilePageState({this.customerId }); - getLanguageID() async { languageID = await sharedPref.getString(APP_LANGUAGE); } + getCustomer() async { String custID; custID = await sharedPref.getString(PHARMACY_CUSTOMER_ID); setState(() { customerId = custID; }); - print("customer Id is"+ customerId); + print("customer Id is" + customerId); return customerId; } getUser() async { var userData = await sharedPref.getObject(USER_PROFILE); - if (userData != null){ user = AuthenticatedUser.fromJson(userData); - setState(() { - firstName = user.firstName.toString(); - print("this is user" + user.firstName.toString()); - print("this is user" + user.firstNameN.toString()); - }); - } else{ - if(userData == null){ - Navigator.push(context, - MaterialPageRoute(builder: (context) => - WelcomeLogin()), + if (userData != null) { + user = AuthenticatedUser.fromJson(userData); + setState(() { + firstName = user.firstName.toString(); + print("this is user" + user.firstName.toString()); + print("this is user" + user.firstNameN.toString()); + }); + } else { + if (userData == null) { + Navigator.push( + context, + FadePage(page: WelcomeLogin()), ); } } // this.isLogin = user != null; } + void initState() { getCustomer(); getLanguageID(); @@ -88,539 +87,563 @@ class _ProfilePageState extends State { @override Widget build(BuildContext context) { return BaseView( - onModelReady: (model) => model.getOrder(customerId, page_id), - builder: (_, model, wi) => AppScaffold( - appBarTitle: TranslationBase.of(context).myAccount, - isShowAppBar:false, - isShowDecPage: false, - isPharmacy: true, - body: Container( - child: SingleChildScrollView( - child: Column( - children: [ - Container( - child: Row( - children: [ - Container( - padding: EdgeInsets.only( - top: 20.0, - left: 10.0, - right: 10.0, - bottom: 10.0, - ), - child: LargeAvatar( - name: "profile", - url: '', - ), - ), - Container( + onModelReady: (model) async { + var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); + model.getOrder(customerId, page_id); + }, + builder: (_, model, wi) => AppScaffold( + appBarTitle: TranslationBase.of(context).myAccount, + isShowAppBar: false, + isShowDecPage: false, + isPharmacy: true, + body: user != null + ? Container( + child: SingleChildScrollView( child: Column( - children: [ - Text( - TranslationBase.of(context).welcome, - style: TextStyle(fontSize: 14.0, - fontWeight: FontWeight.bold, - color:Colors.grey + children: [ + Container( + child: Row( + children: [ + Container( + child: Row( + children: [ + Container( + padding: EdgeInsets.only( + top: 20.0, + left: 10.0, + right: 10.0, + bottom: 10.0, + ), + child: LargeAvatar( + name: user.firstName.toString(), + url: '', + ), + ), + Column(children: [ + Row(children: [ + Text( + TranslationBase.of(context) + .welcome, + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.bold, + color: Colors.grey), + ), + ]), + SizedBox( + height: 10, + ), + Row(children: [ + Text( + languageID == "ar" + ? user.firstNameN.toString() + + " " + + user.lastNameN.toString() + : user.firstName.toString() + + " " + + user.lastName.toString(), + style: TextStyle( + fontSize: 14.0, + fontWeight: FontWeight.bold), + ), + ]), + ]), + ], + ), + ) + ], ), ), - Text( - languageID == "ar" - ? user.firstNameN.toString()+ " " + user.lastNameN.toString() - : user.firstName.toString()+ " " + user.lastName.toString(), - style: TextStyle( - fontSize: 14.0, fontWeight: FontWeight.bold), - ), - ], - ), - - ) - ], - ), - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 5, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 15, - ), - Container( - child: Row( - children: [ - Expanded( - child: InkWell( - onTap: () { - if(customerId == null){ - AppToast.showErrorToast(message: "Customer not found"); - return; - } - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => OrderPage(customerID: customerId))); - }, - child: Column( - children: [ -// Image(image: AssetImage('assets/images/pharmacy/orders_icon.svg')), - SvgPicture.asset( - 'assets/images/pharmacy/orders_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).orders, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, - ), - ), - ], - ), - ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => LakumMainPage())); - }, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/lakum_icon.svg', - width: 50, - height: 50, - ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).lakum, - style: TextStyle( - fontSize: 13.0, fontWeight: FontWeight.bold), - ), - ], - ), - ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => WishlistPage())); - }, - child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/wishlist_icon.svg', - width: 50, - height: 50, - - ),SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).wishlist, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, ), - ), - ], - ), - ), - ), - Expanded( - child: InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MyReviewsPage())); - },child: Column( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/review_icon.svg', - width: 50, - height: 50, + SizedBox( + height: 15, ), - SizedBox( - height: 5, - ), - Text( - TranslationBase.of(context).reviews, - style: TextStyle( - fontSize: 13.0, - fontWeight: FontWeight.bold, + Container( + child: Row( + children: [ + Expanded( + child: InkWell( + onTap: () { + if (customerId == null) { + AppToast.showErrorToast( + message: "Customer not found"); + return; + } + Navigator.push( + context, + FadePage( + page: OrderPage( + customerID: customerId))); + }, + child: Column( + children: [ +// Image(image: AssetImage('assets/images/pharmacy/orders_icon.svg')), + SvgPicture.asset( + 'assets/images/pharmacy/orders_icon.svg', + width: 50, + height: 50, + ), + SizedBox( + height: 5, + ), + Text( + TranslationBase.of(context).orders, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + Navigator.push(context, + FadePage(page: LakumMainPage())); + }, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/lakum_icon.svg', + width: 50, + height: 50, + ), + SizedBox( + height: 5, + ), + Text( + TranslationBase.of(context).lakum, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold), + ), + ], + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + WishlistPage(true))); + }, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/wishlist_icon.svg', + width: 50, + height: 50, + ), + SizedBox( + height: 5, + ), + Text( + TranslationBase.of(context).wishlist, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + Expanded( + child: InkWell( + onTap: () { + Navigator.push(context, + FadePage(page: MyReviewsPage())); + }, + child: Column( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/review_icon.svg', + width: 50, + height: 50, + ), + SizedBox( + height: 5, + ), + Text( + TranslationBase.of(context).reviews, + style: TextStyle( + fontSize: 13.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], + )), + SizedBox( + height: 15, ), - ), - ], - ), - ), - ), - ], - )), - SizedBox( - height: 15, - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 5, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 10, - ), - Container( - padding: EdgeInsets.only(left: 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).myAccount, - style: TextStyle( - fontSize: 16.0, fontWeight: FontWeight.bold), - ), - SizedBox( - height: 10, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => HomePrescriptionsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/my_prescription_icon.svg', - width: 28, - height: 28, - ), - SizedBox( - width: 15, - ), - Text( - TranslationBase.of(context).myPrescription, - style: TextStyle( - fontSize: 13.0, + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => ComparePage())); - }, - child: Row( - children: [ - Image.asset('assets/images/pharmacy/compare.png', - width: 35, height: 35), - SizedBox( - width: 15, - ), - Text( - TranslationBase.of(context).compare, - style: TextStyle( - fontSize: 13.0, + SizedBox( + height: 10, ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => HomePrescriptionsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/medication_refill_icon.svg', - width: 30, - height: 30, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).medicationsRefill, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => MyFamily())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/my_family_icon.svg', - width: 20, - height: 20, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).family, - style: TextStyle( - fontSize: 13.0, + Container( + padding: EdgeInsets.only(left: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).myAccount, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 10, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: HomePrescriptionsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/my_prescription_icon.svg', + width: 28, + height: 28, + ), + SizedBox( + width: 15, + ), + Text( + TranslationBase.of(context) + .myPrescription, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, + FadePage(page: ComparePage())); + }, + child: Row( + children: [ + Image.asset( + 'assets/images/pharmacy/compare.png', + width: 35, + height: 35), + SizedBox( + width: 15, + ), + Text( + TranslationBase.of(context).compare, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: HomePrescriptionsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/medication_refill_icon.svg', + width: 30, + height: 30, + ), + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context) + .medicationsRefill, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, FadePage(page: MyFamily())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/my_family_icon.svg', + width: 20, + height: 20, + ), + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context).family, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PharmacyAddressesPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/shipping_addresses_icon.svg', + width: 30, + height: 30, + ), + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context) + .shippingAddresses, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: PharmacyTermsConditions())); + }, + child: Row( + children: [ + Image.asset( + 'assets/images/pharmacy/terms.png', + width: 25, + height: 25, + ), + SizedBox( + width: 10, + ), + Text( + TranslationBase.of(context) + .conditionsHMG, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: LakumTermsConditions( + this.identificationNo, + this.firstName, + this.lastName, + this.mobileNo, + this.languageId))); + }, + child: Row( + children: [ + Image.asset( + 'assets/images/pharmacy/terms.png', + width: 25, + height: 25, + ), +// IconButton(icon: Icon(Icons.error_outline), iconSize: 30, +// color: Colors.black,), + SizedBox( + width: 10, + ), + Text( + TranslationBase.of(context) + .conditions, + style: TextStyle( + fontSize: 13.0, + ), + ), + ], + ), + ), + ], + ), ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PharmacyAddressesPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/shipping_addresses_icon.svg', - width: 30, - height: 30, + SizedBox( + height: 10, ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).shippingAddresses, - style: TextStyle( - fontSize: 13.0, + Divider( + color: Colors.grey[350], + height: 20, + thickness: 5, + indent: 0, + endIndent: 0, ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => PharmacyTermsConditions())); - }, - child: Row( - children: [ - Image.asset('assets/images/pharmacy/terms.png', - width: 25, - height: 25, - ), - - SizedBox( - width: 10, - ), - Text( - TranslationBase.of(context).conditionsHMG, - style: TextStyle( - fontSize: 13.0, + SizedBox( + height: 10, ), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => LakumTermsConditions(this.identificationNo, this.firstName, this.lastName, - this.mobileNo, this.languageId))); - }, - child: Row( - children: [ - Image.asset('assets/images/pharmacy/terms.png', - width: 25, - height: 25, - ), -// IconButton(icon: Icon(Icons.error_outline), iconSize: 30, -// color: Colors.black,), - SizedBox( - width: 10, - ), - Text( - TranslationBase.of(context).conditions, - style: TextStyle( - fontSize: 13.0, - ), - ), - ], - ), - ), - ], - ), - ), - SizedBox( - height: 10, - ), - Divider( - color: Colors.grey[350], - height: 20, - thickness: 5, - indent: 0, - endIndent: 0, - ), - SizedBox( - height: 10, - ), - Container( - padding: EdgeInsets.only(left: 10.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - TranslationBase.of(context).reachUs, - style: TextStyle( - fontSize: 16.0, fontWeight: FontWeight.bold), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => LiveChatPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/contact_us_icon.svg', - width: 20, - height: 20, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).contactUs, - style: TextStyle(fontSize: 13.0), - ), - ], - ), - ), - SizedBox( - height: 5, - ), - Divider( - color: Colors.grey, - height: 20, - ), - InkWell( - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FindUsPage())); - }, - child: Row( - children: [ - SvgPicture.asset( - 'assets/images/pharmacy/our_locations_icon.svg', - width: 30, - height: 30, - ), - SizedBox( - width: 20, - ), - Text( - TranslationBase.of(context).ourLocations, - style: TextStyle(fontSize: 13.0), - ), - ], + Container( + padding: EdgeInsets.only(left: 10.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + TranslationBase.of(context).reachUs, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, + FadePage(page: LiveChatPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/contact_us_icon.svg', + width: 20, + height: 20, + ), + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context).contactUs, + style: TextStyle(fontSize: 13.0), + ), + ], + ), + ), + SizedBox( + height: 5, + ), + Divider( + color: Colors.grey, + height: 20, + ), + InkWell( + onTap: () { + Navigator.push(context, + FadePage(page: FindUsPage())); + }, + child: Row( + children: [ + SvgPicture.asset( + 'assets/images/pharmacy/our_locations_icon.svg', + width: 30, + height: 30, + ), + SizedBox( + width: 20, + ), + Text( + TranslationBase.of(context) + .ourLocations, + style: TextStyle(fontSize: 13.0), + ), + ], + ), + ) + ], + ), + ) + ], + ), ), ) - ], - ), - ) - ], - ), - ), - ), - )); - }} - - - - + : Container(), + )); + } +} diff --git a/lib/pages/pharmacy_categorise.dart b/lib/pages/pharmacy_categorise.dart index 06bba8c3..ff1920dc 100644 --- a/lib/pages/pharmacy_categorise.dart +++ b/lib/pages/pharmacy_categorise.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:barcode_scan_fix/barcode_scan.dart'; -import 'package:charts_flutter/flutter.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; @@ -11,8 +10,10 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; + import 'base/base_view.dart'; import 'final_products_page.dart'; @@ -36,55 +37,56 @@ class _PharmacyCategorisePageState extends State { baseViewModel: model, body: Column( children: [ - Container( - height: 400, - margin: EdgeInsets.only(bottom: 22), - child: GridView.builder( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 1.0, - childAspectRatio: 3.2, - ), - itemCount: model.categorise.length, - itemBuilder: (BuildContext context, int index) { - return Padding( - padding: EdgeInsets.all(4.0), - child: InkWell( - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - color: Colors.grey.withOpacity(0.24), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? model.categorise[index].namen - : model.categorise[index].name, - fontWeight: FontWeight.w600, + Expanded( + child: Container( + height: 400, + margin: EdgeInsets.only(bottom: 22), + child: GridView.builder( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 1.0, + childAspectRatio: 3.2, + ), + itemCount: model.categorise.length, + itemBuilder: (BuildContext context, int index) { + return Padding( + padding: EdgeInsets.all(4.0), + child: InkWell( + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + color: Colors.grey.withOpacity(0.24), ), - ), - ), - onTap: () => { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - model.categorise[index].id != '12' - ? ParentCategorisePage( - id: model.categorise[index].id, - titleName: model.categorise[index].name, - ) - : FinalProductsPage( - id: model.categorise[index].id, - ), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? model.categorise[index].namen + : model.categorise[index].name, + fontWeight: FontWeight.w600, + ), ), ), - }, - ), - ); - }, + onTap: () => { + Navigator.push( + context, + FadePage( + page: model.categorise[index].id != '12' + ? ParentCategorisePage( + id: model.categorise[index].id, + titleName: model.categorise[index].name, + ) + : FinalProductsPage( + id: model.categorise[index].id, + ), + ), + ), + }, + ), + ); + }, + ), ), ), Container( @@ -103,20 +105,35 @@ class _PharmacyCategorisePageState extends State { Expanded( child: Padding( padding: EdgeInsets.all(4.0), - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Colors.green.shade300.withOpacity(0.34), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'الاكثر مبيعا' - : 'Best Sellers', - fontWeight: FontWeight.w600, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 6, + ), + ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: + Colors.green.shade300.withOpacity(0.34), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'الاكثر مبيعا' + : 'Best Sellers', + fontWeight: FontWeight.w600, + ), ), ), ), @@ -125,21 +142,35 @@ class _PharmacyCategorisePageState extends State { Expanded( child: Padding( padding: EdgeInsets.all(4.0), - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: Colors.orangeAccent.shade200 - .withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'الاكثر مشاهدة' - : 'Most Viewed', - fontWeight: FontWeight.w600, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 4, + ), + ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: Colors.orangeAccent.shade200 + .withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'الاكثر مشاهدة' + : 'Most Viewed', + fontWeight: FontWeight.w600, + ), ), ), ), @@ -152,20 +183,34 @@ class _PharmacyCategorisePageState extends State { Expanded( child: Padding( padding: EdgeInsets.all(4.0), - child: Container( - height: 50.0, - width: 55.0, - decoration: BoxDecoration( - color: Colors.blue.shade200.withOpacity(0.34), - borderRadius: BorderRadius.circular(5.0), - ), - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 10.0), - child: Texts( - projectViewModel.isArabic - ? 'منتجات جديدة' - : 'New Products', - fontWeight: FontWeight.w600, + child: InkWell( + onTap: () { + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 5, + ), + ), + ); + }, + child: Container( + height: 50.0, + width: 55.0, + decoration: BoxDecoration( + color: Colors.blue.shade200.withOpacity(0.34), + borderRadius: BorderRadius.circular(5.0), + ), + child: Padding( + padding: + EdgeInsets.symmetric(horizontal: 10.0), + child: Texts( + projectViewModel.isArabic + ? 'منتجات جديدة' + : 'New Products', + fontWeight: FontWeight.w600, + ), ), ), ), @@ -176,7 +221,15 @@ class _PharmacyCategorisePageState extends State { padding: EdgeInsets.all(4.0), child: InkWell( onTap: () { - _scanQrAndGetPatient(context, model); + Navigator.push( + context, + FadePage( + page: FinalProductsPage( + id: "", + productType: 3, + ), + ), + ); }, child: Container( height: 50.0, @@ -220,7 +273,7 @@ class _PharmacyCategorisePageState extends State { /// int patientID = get from qr result String result = await BarcodeScanner.scan(); var data = json.decode(result); - if (data!=null) { + if (data != null) { var qRParkingID = data['QRParkingID']; await model.scanQr(); if (model.state == ViewState.ErrorLocal) { @@ -230,7 +283,7 @@ class _PharmacyCategorisePageState extends State { { Navigator.push( context, - MaterialPageRoute(builder: (context) => LandingPagePharmacy()), + FadePage(page: LandingPagePharmacy()), ); } } diff --git a/lib/pages/rateAppointment/rate_appointment_clinic.dart b/lib/pages/rateAppointment/rate_appointment_clinic.dart index f5ec34c3..bf0f4b4e 100644 --- a/lib/pages/rateAppointment/rate_appointment_clinic.dart +++ b/lib/pages/rateAppointment/rate_appointment_clinic.dart @@ -208,8 +208,8 @@ class _RateAppointmentClinicState extends State { } }, label: TranslationBase.of(context).submit, - disabled: model.state == ViewState.BusyLocal, - loading: model.state == ViewState.BusyLocal, + disabled: (model.state == ViewState.Busy || rating==0), + // loading: model.state == ViewState.BusyLocal, textColor: Theme.of(context).backgroundColor), ), SizedBox( diff --git a/lib/pages/rateAppointment/rate_appointment_doctor.dart b/lib/pages/rateAppointment/rate_appointment_doctor.dart index b3349704..71aacae2 100644 --- a/lib/pages/rateAppointment/rate_appointment_doctor.dart +++ b/lib/pages/rateAppointment/rate_appointment_doctor.dart @@ -206,7 +206,7 @@ class _RateAppointmentDoctorState extends State { } }, label: TranslationBase.of(context).next, - disabled: model.state == ViewState.BusyLocal|| rating==0, + disabled: (model.state == ViewState.BusyLocal || rating==0), loading: model.state == ViewState.BusyLocal, textColor: Theme.of(context).backgroundColor), ), diff --git a/lib/pages/search_products_page.dart b/lib/pages/search_products_page.dart index 45cafd35..73b17558 100644 --- a/lib/pages/search_products_page.dart +++ b/lib/pages/search_products_page.dart @@ -1,6 +1,8 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/enum/viewstate.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product-brands.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; @@ -8,6 +10,7 @@ import 'package:diplomaticquarterapp/widgets/input/text_field.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; import 'base/base_view.dart'; @@ -45,13 +48,13 @@ class _SearchProductsPageState extends State { child: Row( children: [ Container( - width: MediaQuery.of(context).size.width * 0.79, + width: MediaQuery.of(context).size.width * 0.70, child: Form( key: _formKey, child: TextFields( autoFocus: true, hintText: 'Search', - fontSize: 19.0, + fontSize: 14.5, prefixIcon: Icon(Icons.search), inputAction: TextInputAction.search, onSaved: (value) { @@ -102,170 +105,192 @@ class _SearchProductsPageState extends State { child: NetworkBaseView( baseViewModel: model, child: model.searchList.isNotEmpty - ? Container( - height: MediaQuery.of(context).size.height * 0.80, - child: GridView.builder( - //physics: NeverScrollableScrollPhysics(), - gridDelegate: - SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - crossAxisSpacing: 0.5, - mainAxisSpacing: 2.0, - childAspectRatio: 1.0, - ), - itemCount: model.searchList.length, - itemBuilder: (BuildContext context, int index) { - return Card( - color: model.searchList[index].discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), + ? InkWell( + child: Container( + height: MediaQuery.of(context).size.height * 0.80, + child: GridView.builder( + //physics: NeverScrollableScrollPhysics(), + gridDelegate: + SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + crossAxisSpacing: 0.5, + mainAxisSpacing: 2.0, + childAspectRatio: 1.0, + ), + itemCount: model.searchList.length, + itemBuilder: (BuildContext context, int index) { + return InkWell( + child: Card( + color: model.searchList[index] + .discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), ), - color: Colors.white, - ), - padding: - EdgeInsets.symmetric(horizontal: 0), - width: - MediaQuery.of(context).size.width / 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, + ), + padding: + EdgeInsets.symmetric(horizontal: 0), + width: + MediaQuery.of(context).size.width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.searchList[index].images - .isNotEmpty - ? model.searchList[index] - .images[0].thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), + Stack( + children: [ + Container( + margin: EdgeInsets.fromLTRB( + 0, 16, 0, 0), + alignment: Alignment.center, + child: Image.network( + model.searchList[index] + .images.isNotEmpty + ? model + .searchList[index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), + ), + Container( + width: model.searchList[index] + .rxMessage != + null + ? MediaQuery.of(context) + .size + .width / + 5 + : 0, + padding: EdgeInsets.all(4), + decoration: BoxDecoration( + color: Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: + Radius.circular( + 6)), + ), + child: Texts( + model.searchList[index] + .rxMessage != + null + ? model + .searchList[index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: FontWeight.w400, + ), + ), + ], ), Container( - width: model.searchList[index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: BorderRadius.only( - topLeft: - Radius.circular(6)), + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - child: Texts( - model.searchList[index] - .rxMessage != - null - ? model.searchList[index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: FontWeight.w400, - ), - ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - model.searchList[index].name, - regular: true, - fontSize: 12, - fontWeight: FontWeight.w400, - ), - Padding( - padding: const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.searchList[index].price}", - bold: true, - fontSize: 14, - ), - ), - Row( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, children: [ - StarRating( - totalAverage: model - .searchList[ - index] - .approvedRatingSum > - 0 - ? (model - .searchList[ - index] - .approvedRatingSum - .toDouble() / - model - .searchList[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), Texts( - "(${model.searchList[index].approvedTotalReviews})", + model + .searchList[index].name, regular: true, - fontSize: 10, + fontSize: 12, fontWeight: FontWeight.w400, - ) + ), + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.searchList[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .searchList[ + index] + .approvedRatingSum > + 0 + ? (model + .searchList[ + index] + .approvedRatingSum + .toDouble() / + model + .searchList[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.searchList[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), ], ), - ], - ), + ), + ], ), - ], + ), ), - ), - ); - }, + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.searchList[index]), + )), + }, + ); + }, + ), ), ) : Texts(msg), diff --git a/lib/pages/settings/general_setting.dart b/lib/pages/settings/general_setting.dart index 7085150a..0a6b0e73 100644 --- a/lib/pages/settings/general_setting.dart +++ b/lib/pages/settings/general_setting.dart @@ -1,4 +1,5 @@ import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/services/permission/permission_service.dart'; import 'package:diplomaticquarterapp/theme/theme_notifier.dart'; import 'package:diplomaticquarterapp/theme/theme_value.dart'; @@ -20,10 +21,10 @@ class _GeneralSettings extends State with TickerProviderStateMixin { var themeNotifier; int blindValue = 0; - bool vibration =false; - bool accsibility =false; - bool camera =false; - bool location =false; + bool vibration = false; + bool accsibility = false; + bool camera = false; + bool location = false; var sharedPref = new AppSharedPreferences(); var permission = new PermissionService(); var mediaQueryData; @@ -33,22 +34,21 @@ class _GeneralSettings extends State super.initState(); } - Widget build(BuildContext context) { - mediaQueryData = MediaQuery.of(context); - themeNotifier = Provider.of(context); + mediaQueryData = MediaQuery.of(context); + themeNotifier = Provider.of(context); return Container( child: ListView(scrollDirection: Axis.vertical, children: [ Container( + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).modes, - color: Colors.black, fontWeight: FontWeight.bold, ), ), Container( - color: Colors.white, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -59,7 +59,6 @@ class _GeneralSettings extends State onChanged: (value) { setState(() { vibration = value; - }); setVibration(value); }, @@ -69,7 +68,7 @@ class _GeneralSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -81,7 +80,7 @@ class _GeneralSettings extends State setState(() { accsibility = value; }); - //setAccisibility(value); + //setAccisibility(value); }, activeTrackColor: Colors.lightGreenAccent, activeColor: Colors.green, @@ -89,15 +88,15 @@ class _GeneralSettings extends State ], )), Container( + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).blindMode, - color: Colors.black, fontWeight: FontWeight.bold, ), ), new Container( - color: Colors.white, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(8.0), child: new Column( mainAxisAlignment: MainAxisAlignment.center, @@ -180,15 +179,15 @@ class _GeneralSettings extends State ) ])), Container( + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: AppText( TranslationBase.of(context).permissions, - color: Colors.black, fontWeight: FontWeight.bold, ), ), Container( - color: Colors.white, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -207,7 +206,7 @@ class _GeneralSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).scaffoldBackgroundColor, padding: EdgeInsets.all(10), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -228,7 +227,7 @@ class _GeneralSettings extends State ])); } - setTheme(value) async{ + setTheme(value) async { switch (value) { case 0: { @@ -238,45 +237,9 @@ class _GeneralSettings extends State break; case 1: { - themeNotifier.setTheme(ThemeData( - fontFamily: await sharedPref.getString(APP_LANGUAGE) == 'ar' ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.grey, - visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - }, - ), - hintColor: Colors.grey[400], - cardColor: Colors.black, - buttonColor: Colors.grey[400], - disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Colors.grey, - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Colors.grey, - highlightColor: Colors.grey[100].withOpacity(0.4), - splashColor: Colors.transparent, - primaryColor: Colors.grey, - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, - - iconTheme: IconThemeData(), - appBarTheme: AppBarTheme( - color: Colors.grey, - brightness: Brightness.dark, - elevation: 10.0, - actionsIconTheme: IconThemeData( - color: Colors.grey, - ), - ), - )); - Screen.setBrightness(1.0); + themeNotifier.setTheme(await getTheme(value)); } + break; case 2: themeNotifier.setTheme(await getTheme(value)); @@ -295,140 +258,45 @@ class _GeneralSettings extends State } break; } - //permission.setTheme(value); - + permission.setTheme(value); } - setVibration(value){ + + setVibration(value) { permission.setVibrationPermission(value); } - setAccisibility(){ - if(!accsibility){ + setAccisibility() { + if (!accsibility) {} + // permission.setVibrationPermission(value); + } + getValues() async { + if (permission.isThemeEnabled() != null) { + blindValue = + permission.isThemeEnabled() == null ? 0 : permission.isThemeEnabled(); + vibration = permission.isVibrationEnabled() == null + ? false + : permission.isVibrationEnabled(); + accsibility = mediaQueryData.accessibleNavigation; + setTheme(blindValue); } - // permission.setVibrationPermission(value); - } - getValues() async{ - blindValue= permission.isThemeEnabled() == null ? 0 : permission.isThemeEnabled(); - vibration = permission.isVibrationEnabled() ==null ? false : permission.isVibrationEnabled(); - accsibility =mediaQueryData.accessibleNavigation; } - getTheme(value) async{ - if(value ==1){ - return ThemeData( - fontFamily: await sharedPref.getString(APP_LANGUAGE) == 'ar' ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.grey, - visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - }, - ), - hintColor: Colors.grey[400], - cardColor: Colors.black, - buttonColor: Colors.grey[400], - disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Colors.grey, - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Colors.grey, - highlightColor: Colors.grey[100].withOpacity(0.4), - splashColor: Colors.transparent, - primaryColor: Colors.grey, - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, - - iconTheme: IconThemeData(), - appBarTheme: AppBarTheme( - color: Colors.grey, - brightness: Brightness.dark, - elevation: 10.0, - actionsIconTheme: IconThemeData( - color: Colors.grey, - ), - ), - ); - - }else if(value ==3){ - return ThemeData( - fontFamily: await sharedPref.getString(APP_LANGUAGE) == 'ar' ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.grey, - visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - }, - ), - hintColor: Colors.grey[400], - cardColor: Colors.black, - buttonColor: Colors.grey[400], - disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Colors.grey, - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Colors.grey, - highlightColor: Colors.grey[100].withOpacity(0.4), - splashColor: Colors.transparent, - primaryColor: Colors.grey, - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, - iconTheme: IconThemeData(), - appBarTheme: AppBarTheme( - color: Colors.black45, - brightness: Brightness.dark, - elevation: 10.0, - actionsIconTheme: IconThemeData( - color: Colors.grey, - ), - ), - ); - - }else { - return ThemeData( - fontFamily: await sharedPref.getString(APP_LANGUAGE) == 'ar' ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.blue, - visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, - pageTransitionsTheme: const PageTransitionsTheme( - builders: { - TargetPlatform.android: ZoomPageTransitionsBuilder(), - TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), - }, - ), - hintColor: Colors.grey[400], - disabledColor: Colors.grey[300], - errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xffEEEEEE), - textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), - textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Colors.white, - highlightColor: Colors.grey[100].withOpacity(0.4), - splashColor: Colors.transparent, - primaryColor: Color(0xff40ACC9), - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, - cardColor: Colors.white, - iconTheme: IconThemeData(), - appBarTheme: AppBarTheme( - color: Color(0xff40ACC9), - brightness: Brightness.dark, - elevation: 10.0, - actionsIconTheme: IconThemeData( - color: Color(0xff40ACC9), - ), - ), - ); - - } + getTheme(value) async { + if (value == 1) { + return invertThemes( + fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' + ); + } else if (value == 3) { + return bwThemes( + fontName: Provider.of(context, listen: false).isArabic ? 'Cairo' : 'WorkSans' + ); + } else { + return defaultTheme( + fontName: + Provider.of(context, listen: false).isArabic + ? 'Cairo' + : 'WorkSans'); + } } } diff --git a/lib/pages/settings/profile_setting.dart b/lib/pages/settings/profile_setting.dart index dcfdb8a8..833cdf2b 100644 --- a/lib/pages/settings/profile_setting.dart +++ b/lib/pages/settings/profile_setting.dart @@ -14,7 +14,6 @@ import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:provider/provider.dart'; class ProfileSettings extends StatefulWidget { - @override _ProfileSettings createState() => _ProfileSettings(); } @@ -45,6 +44,7 @@ class _ProfileSettings extends State child: model.user != null ? ListView(scrollDirection: Axis.vertical, children: [ Container( + color: Theme.of(context).primaryColor, padding: EdgeInsets.all(15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -74,7 +74,7 @@ class _ProfileSettings extends State padding: EdgeInsets.all(10), ), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Row( @@ -93,7 +93,7 @@ class _ProfileSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Row( @@ -116,7 +116,7 @@ class _ProfileSettings extends State padding: EdgeInsets.all(10), ), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Row( @@ -136,7 +136,7 @@ class _ProfileSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Row( @@ -160,7 +160,7 @@ class _ProfileSettings extends State padding: EdgeInsets.all(10), ), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Column( @@ -175,7 +175,7 @@ class _ProfileSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Column( @@ -190,7 +190,7 @@ class _ProfileSettings extends State ], )), Container( - color: Colors.white, + color: Theme.of(context).primaryColor, padding: EdgeInsets.only( top: 0, left: 10, right: 10, bottom: 0), child: Column( diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index 0c63b900..b578eb3f 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -21,7 +21,7 @@ class _Settings extends State with TickerProviderStateMixin { _tabController = new TabController(length: 2, vsync: this, initialIndex: widget.type); - if(widget.type==1){ + if (widget.type == 1) { _tabController.animateTo(1); } @@ -51,7 +51,8 @@ class _Settings extends State with TickerProviderStateMixin { controller: _tabController, ), title: Text(TranslationBase.of(context).settings, - style: TextStyle(color: Colors.white)), + style: + TextStyle(color: Theme.of(context).textTheme.bodyText2.color)), leading: Builder( builder: (BuildContext context) { return ArrowBack(); diff --git a/lib/pages/sub_categorise_page.dart b/lib/pages/sub_categorise_page.dart index 45c9fd6c..cc374b96 100644 --- a/lib/pages/sub_categorise_page.dart +++ b/lib/pages/sub_categorise_page.dart @@ -1,12 +1,14 @@ +import 'package:diplomaticquarterapp/core/model/pharmacy/categorise_parent_model.dart'; import 'package:diplomaticquarterapp/core/viewModels/pharmacy_categorise_view_model.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; +import 'package:diplomaticquarterapp/pages/pharmacies/product_detail.dart'; import 'package:diplomaticquarterapp/widgets/buttons/button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/others/StarRating.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_pharmacy_widget.dart'; +import 'package:diplomaticquarterapp/widgets/others/entity_checkbox_list.dart'; import 'package:diplomaticquarterapp/widgets/others/network_base_view.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; import 'base/base_view.dart'; import 'final_products_page.dart'; @@ -17,6 +19,7 @@ class SubCategorisePage extends StatefulWidget { String parentId; SubCategorisePage({this.id, this.parentId, this.title}); + @override _SubCategorisePageState createState() => _SubCategorisePageState(id: id, title: title, parentId: parentId); @@ -28,7 +31,9 @@ class _SubCategorisePageState extends State { String id; String title; String parentId; + _SubCategorisePageState({this.title, this.parentId, this.id}); + String categoriseName = "Personal Care"; bool styleOne = true; bool styleTwo = false; @@ -37,8 +42,12 @@ class _SubCategorisePageState extends State { color: Colors.blue, size: 29.0, ); + List entityList = List(); + List entityListBrands = List(); @override Widget build(BuildContext context) { + TextEditingController minField = TextEditingController(); + TextEditingController maxField = TextEditingController(); return BaseView( onModelReady: (model) => model.getSubCategorise(i: id), builder: (BuildContext context, PharmacyCategoriseViewModel model, @@ -52,7 +61,6 @@ class _SubCategorisePageState extends State { baseViewModel: model, body: SingleChildScrollView( child: Container( - height: MediaQuery.of(context).size.height * 5.97, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -140,8 +148,8 @@ class _SubCategorisePageState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => + FadePage( + page: FinalProductsPage( id: model .subCategorise[ @@ -228,9 +236,8 @@ class _SubCategorisePageState extends State { onTap: () { Navigator.push( context, - MaterialPageRoute( - builder: (context) => - FinalProductsPage( + FadePage( + page: FinalProductsPage( id: model.subCategorise[index].id, ), ), @@ -279,6 +286,7 @@ class _SubCategorisePageState extends State { return SingleChildScrollView( controller: scrollController, child: Container( + color: Colors.white, height: MediaQuery.of(context) .size .height * @@ -330,45 +338,34 @@ class _SubCategorisePageState extends State { title: Texts('Categorise'), children: [ - Container( - height: 350, - child: ListView - .builder( - controller: - scrollController, - scrollDirection: - Axis - .vertical, - shrinkWrap: - true, - itemCount: model - .categoriseParent - .length, - itemBuilder: - (BuildContext - context, - int index) { - return CheckboxListTile( - tristate: - true, - title: Texts(model - .categoriseParent[index] - .name), - controlAffinity: - ListTileControlAffinity.leading, - value: - checkedCategorise, - onChanged: - (bool - value) { - setState( - () { - checkedCategorise = - value; - }); - }, - ); - }), + ProcedureListWidget( + model: model, + masterList: model + .subCategorise, + removeHistory: + (item) { + setState(() { + entityList + .remove( + item); + }); + }, + addHistory: + (history) { + setState(() { + entityList.add( + history); + }); + }, + addSelectedHistories: + () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: + (master) => + isEntityListSelected( + master), ) ], ), @@ -379,45 +376,35 @@ class _SubCategorisePageState extends State { ExpansionTile( title: Texts('Brands'), children: [ - Container( - height: 350, - child: ListView - .builder( - scrollDirection: - Axis - .vertical, - shrinkWrap: - true, - itemCount: model - .brandsList - .length, - itemBuilder: - (BuildContext - context, - int index) { - return CheckboxListTile( - tristate: - true, - title: Texts(model - .brandsList[index] - .name), - controlAffinity: - ListTileControlAffinity.leading, - value: - checkedBrands, - onChanged: - (bool - value) { - setState( - () { - checkedBrands = - value; - }); - }, - autofocus: - true, - ); - }), + ProcedureListWidget( + model: model, + masterList: model + .brandsList, + removeHistory: + (item) { + setState(() { + entityListBrands + .remove( + item); + }); + }, + addHistory: + (history) { + setState(() { + entityListBrands + .add( + history); + }); + }, + addSelectedHistories: + () { + //TODO build your fun herr + // widget.addSelectedHistories(); + }, + isEntityListSelected: + (master) => + isEntityListSelectedBrands( + master), ) ], ), @@ -457,6 +444,8 @@ class _SubCategorisePageState extends State { border: OutlineInputBorder(), ), + controller: + minField, ), ), ], @@ -482,6 +471,8 @@ class _SubCategorisePageState extends State { border: OutlineInputBorder(), ), + controller: + maxField, ), ), ], @@ -524,6 +515,50 @@ class _SubCategorisePageState extends State { Container( width: 200, child: Button( + onTap: () { + String + categoriesId = + ""; + for (CategoriseParentModel category + in entityList) { + if (categoriesId == + "") { + categoriesId = + category + .id; + } else { + categoriesId = + "$categoriesId,${category.id}"; + } + } + String + brandIds = + ""; + for (CategoriseParentModel brand + in entityListBrands) { + if (brandIds == + "") { + brandIds = + brand + .id; + } else { + brandIds = + "$brandIds,${brand.id}"; + } + } + + model.getFilteredProducts( + min: minField + .text + .toString(), + max: maxField + .text + .toString(), + categoryId: + categoriesId, + brandId: + brandIds); + }, label: 'Apply', backgroundColor: Colors @@ -593,7 +628,9 @@ class _SubCategorisePageState extends State { ), styleOne == true ? Container( - height: MediaQuery.of(context).size.height * 3.85, + height: model.subProducts.length * + MediaQuery.of(context).size.height * + 0.15, child: GridView.builder( physics: NeverScrollableScrollPhysics(), gridDelegate: @@ -601,337 +638,386 @@ class _SubCategorisePageState extends State { crossAxisCount: 2, crossAxisSpacing: 0.5, mainAxisSpacing: 2.0, - childAspectRatio: 1.0, + childAspectRatio: 0.9, ), itemCount: model.subProducts.length, itemBuilder: (BuildContext context, int index) { return NetworkBaseView( baseViewModel: model, - child: Card( - color: model.subProducts[index] - .discountName != - null - ? Color(0xffFFFF00) - : Colors.white, - elevation: 0, - shape: Border( - right: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - left: BorderSide( - color: Colors.grey.shade300, - width: 1, - ), - bottom: BorderSide( - color: Colors.grey.shade300, - width: 1, + child: InkWell( + child: Card( + color: model.subProducts[index] + .discountName != + null + ? Color(0xffFFFF00) + : Colors.white, + elevation: 0, + shape: Border( + right: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + left: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + bottom: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), + top: BorderSide( + color: Colors.grey.shade300, + width: 1, + ), ), - top: BorderSide( - color: Colors.grey.shade300, - width: 1, + margin: EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, ), - ), - margin: EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(110.0), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(110.0), + ), + color: Colors.white, ), - color: Colors.white, - ), - padding: EdgeInsets.symmetric( - horizontal: 0), - width: MediaQuery.of(context) - .size - .width / - 3, - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Stack( - children: [ - Container( - margin: EdgeInsets.fromLTRB( - 0, 16, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.subProducts[index] - .images.isNotEmpty - ? model - .subProducts[ - index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.cover, - height: 80, - ), - ), - Container( - width: model + padding: EdgeInsets.symmetric( + horizontal: 0), + width: MediaQuery.of(context) + .size + .width / + 3, + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Stack( + children: [ + Container( + margin: + EdgeInsets.fromLTRB( + 0, 16, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model .subProducts[ index] - .rxMessage != - null - ? MediaQuery.of(context) - .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), + .images + .isNotEmpty + ? model + .subProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.cover, + height: 80, + ), ), - child: Texts( - model.subProducts[index] + Container( + width: model + .subProducts[ + index] .rxMessage != null - ? model - .subProducts[ - index] - .rxMessage - : "", - color: Colors.white, - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ), - ), - ], - ), - Container( - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - model.subProducts[index] - .name, - regular: true, - fontSize: 12, - fontWeight: - FontWeight.w400, - ), - Padding( + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, padding: - const EdgeInsets.only( - top: 4, - bottom: 4), + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), child: Texts( - "SAR ${model.subProducts[index].price}", - bold: true, - fontSize: 14, + model.subProducts[index] + .rxMessage != + null + ? model + .subProducts[ + index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, ), ), - Row( - children: [ - StarRating( - totalAverage: model - .subProducts[ - index] - .approvedRatingSum > - 0 - ? (model.subProducts[index].approvedRatingSum - .toDouble() / - model - .subProducts[index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.subProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), ], ), - ), - ], + Container( + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, + ), + child: Column( + crossAxisAlignment: + CrossAxisAlignment + .start, + children: [ + Texts( + model.subProducts[index] + .name, + regular: true, + fontSize: 12, + fontWeight: + FontWeight.w400, + ), + Padding( + padding: + const EdgeInsets + .only( + top: 4, + bottom: 4), + child: Texts( + "SAR ${model.subProducts[index].price}", + bold: true, + fontSize: 14, + ), + ), + Row( + children: [ + StarRating( + totalAverage: model + .subProducts[ + index] + .approvedRatingSum > + 0 + ? (model.subProducts[index].approvedRatingSum + .toDouble() / + model + .subProducts[index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.subProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], + ), + ), + ], + ), ), ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.subProducts[index]), + )), + }, )); }, ), ) : Container( - height: MediaQuery.of(context).size.height * 5.0, + height: model.subProducts.length * + MediaQuery.of(context).size.height * + 0.122, child: ListView.builder( physics: NeverScrollableScrollPhysics(), itemCount: model.subProducts.length, itemBuilder: (BuildContext context, int index) { - return Card( - child: Row( - children: [ - Stack( - children: [ - Column( - children: [ - Container( - decoration: BoxDecoration(), - child: Padding( - padding: EdgeInsets.only( - left: 9.0, - top: 8.0, - right: 10.0, + return InkWell( + child: Card( + child: Row( + children: [ + Stack( + children: [ + Column( + children: [ + Container( + decoration: + BoxDecoration(), + child: Padding( + padding: + EdgeInsets.only( + left: 9.0, + top: 8.0, + right: 10.0, + ), ), ), - ), - Container( - margin: EdgeInsets.fromLTRB( - 0, 0, 0, 0), - alignment: Alignment.center, - child: Image.network( - model.subProducts[index] - .images.isNotEmpty - ? model - .subProducts[ - index] - .images[0] - .thumb - : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', - fit: BoxFit.contain, - height: 80, + Container( + margin: + EdgeInsets.fromLTRB( + 0, 0, 0, 0), + alignment: + Alignment.center, + child: Image.network( + model + .subProducts[ + index] + .images + .isNotEmpty + ? model + .subProducts[ + index] + .images[0] + .thumb + : 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6c/No_image_3x4.svg/1200px-No_image_3x4.svg.png', + fit: BoxFit.contain, + height: 80, + ), ), - ), - ], + ], + ), + Column( + children: [ + Container( + width: model + .subProducts[ + index] + .rxMessage != + null + ? MediaQuery.of( + context) + .size + .width / + 5 + : 0, + padding: + EdgeInsets.all(4), + decoration: BoxDecoration( + color: + Color(0xffb23838), + borderRadius: + BorderRadius.only( + topLeft: Radius + .circular( + 6)), + ), + child: Texts( + model.subProducts[index] + .rxMessage != + null + ? model + .subProducts[ + index] + .rxMessage + : "", + color: Colors.white, + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ), + ), + ], + ), + ], + ), + Container( + height: 100.0, + margin: EdgeInsets.symmetric( + horizontal: 6, + vertical: 0, ), - Column( + child: Column( + mainAxisAlignment: + MainAxisAlignment + .spaceAround, + crossAxisAlignment: + CrossAxisAlignment.start, children: [ + SizedBox( + height: 4.0, + ), Container( - width: model - .subProducts[ - index] - .rxMessage != - null - ? MediaQuery.of(context) + width: + MediaQuery.of(context) .size - .width / - 5 - : 0, - padding: EdgeInsets.all(4), - decoration: BoxDecoration( - color: Color(0xffb23838), - borderRadius: - BorderRadius.only( - topLeft: Radius - .circular(6)), - ), + .width * + 0.65, child: Texts( model.subProducts[index] - .rxMessage != - null - ? model - .subProducts[ - index] - .rxMessage - : "", - color: Colors.white, + .name, regular: true, - fontSize: 10, + fontSize: 13.2, fontWeight: - FontWeight.w400, + FontWeight.w500, + maxLines: 5, ), ), - ], - ), - ], - ), - Container( - height: 100.0, - margin: EdgeInsets.symmetric( - horizontal: 6, - vertical: 0, - ), - child: Column( - mainAxisAlignment: - MainAxisAlignment.spaceAround, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - SizedBox( - height: 4.0, - ), - Container( - height: 35.0, - width: 250.0, - child: Texts( - model.subProducts[index] - .name, - regular: true, - fontSize: 13.2, - fontWeight: FontWeight.w500, - maxLines: 2, + SizedBox( + height: 8.0, ), - ), - SizedBox( - height: 8.0, - ), - Padding( - padding: - const EdgeInsets.only( - top: 4, bottom: 4), - child: Texts( - "SAR ${model.subProducts[index].price}", - bold: true, - fontSize: 14, + Padding( + padding: + const EdgeInsets.only( + top: 4, bottom: 4), + child: Texts( + "SAR ${model.subProducts[index].price}", + bold: true, + fontSize: 14, + ), ), - ), - Row( - children: [ - StarRating( - totalAverage: model - .subProducts[ - index] - .approvedRatingSum > - 0 - ? (model - .subProducts[ - index] - .approvedRatingSum - .toDouble() / - model - .parentProducts[ - index] - .approvedRatingSum - .toDouble()) - .toDouble() - : 0, - forceStars: true), - Texts( - "(${model.subProducts[index].approvedTotalReviews})", - regular: true, - fontSize: 10, - fontWeight: - FontWeight.w400, - ) - ], - ), - ], + Row( + children: [ + StarRating( + totalAverage: model + .subProducts[ + index] + .approvedRatingSum > + 0 + ? (model + .subProducts[ + index] + .approvedRatingSum + .toDouble() / + model + .parentProducts[ + index] + .approvedRatingSum + .toDouble()) + .toDouble() + : 0, + forceStars: true), + Texts( + "(${model.subProducts[index].approvedTotalReviews})", + regular: true, + fontSize: 10, + fontWeight: + FontWeight.w400, + ) + ], + ), + ], + ), ), - ), - ], + ], + ), ), + onTap: () => { + Navigator.push( + context, + FadePage( + page: ProductDetailPage( + model.subProducts[index]), + )), + }, ); }), ) @@ -941,4 +1027,22 @@ class _SubCategorisePageState extends State { ), )); } + + bool isEntityListSelected(CategoriseParentModel masterKey) { + Iterable history = + entityList.where((element) => masterKey.id == element.id); + if (history.length > 0) { + return true; + } + return false; + } + + bool isEntityListSelectedBrands(CategoriseParentModel masterKey) { + Iterable history = + entityListBrands.where((element) => masterKey.id == element.id); + if (history.length > 0) { + return true; + } + return false; + } } diff --git a/lib/pages/vaccine/my_vaccines_screen.dart b/lib/pages/vaccine/my_vaccines_screen.dart index 169e5cd5..fb723a1f 100644 --- a/lib/pages/vaccine/my_vaccines_screen.dart +++ b/lib/pages/vaccine/my_vaccines_screen.dart @@ -169,29 +169,30 @@ class _MyVaccinesState extends State { width: double.infinity, // height: 80.0, child: Button( + disabled: true, label: TranslationBase.of(context).checkVaccineAvailability, backgroundColor: Color(0xff9EA3A4), - onTap: () => - Navigator.push(context, FadePage(page: MyVaccinesItemPage())), + onTap: () => Navigator.push( + context, FadePage(page: MyVaccinesItemPage())), ), ), - if(projectViewModel.havePrivilege(27)) - Container( - width: double.infinity, - // height: 80.0, - child: SecondaryButton( - label: TranslationBase.of(context).sendEmail, - color: Color(0xffF62426), - textColor: Colors.white, - disabled: model.vaccineList.length == 0, - loading: model.state == ViewState.BusyLocal, - onTap: () async { - model.sendEmail( - message: - TranslationBase.of(context).emailSentSuccessfully); - }, + if (projectViewModel.havePrivilege(27)) + Container( + width: double.infinity, + // height: 80.0, + child: SecondaryButton( + label: TranslationBase.of(context).sendEmail, + color: Color(0xffF62426), + textColor: Colors.white, + disabled: model.vaccineList.length == 0, + loading: model.state == ViewState.BusyLocal, + onTap: () async { + model.sendEmail( + message: TranslationBase.of(context) + .emailSentSuccessfully); + }, + ), ), - ), ], ), ), diff --git a/lib/pages/weather-indicator/health-indicator.dart b/lib/pages/weather-indicator/health-indicator.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/routes.dart b/lib/routes.dart index b11025c2..4f1f2364 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,6 +1,9 @@ +import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/health-weather/health-weather-indicator.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/add-family-member.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/add-family_type.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/family/my-family.dart'; +import 'package:diplomaticquarterapp/pages/TestPage.dart'; +import 'package:diplomaticquarterapp/pages/appUpdatePage/app_update_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/livecare/livecare_home.dart'; import 'package:diplomaticquarterapp/pages/login/confirm-login.dart'; @@ -10,6 +13,9 @@ import 'package:diplomaticquarterapp/pages/login/welcome.dart'; import 'package:diplomaticquarterapp/pages/login/login-type.dart'; import 'package:diplomaticquarterapp/pages/login/login.dart'; import 'package:diplomaticquarterapp/pages/login/register.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesCartPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/OfferAndPackagesPage.dart'; +import 'package:diplomaticquarterapp/pages/packages_offers/PackageOrderCompletedPage.dart'; import 'package:diplomaticquarterapp/pages/settings/settings.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/info.dart'; import 'package:diplomaticquarterapp/pages/symptom-checker/select-gender.dart'; @@ -35,6 +41,13 @@ const String SYMPTOM_CHECKER = 'symptom-checker'; const String SYMPTOM_CHECKER_INFO = 'symptom-checker-info'; const String SELECT_GENDER = 'select-gender'; const String SETTINGS = 'settings'; +const String PACKAGES_OFFERS = 'packages-offers'; +const String PACKAGES_OFFERS_CART = 'packages-offers-cart'; +const String PACKAGES_ORDER_COMPLETED = 'packages-offers-cart'; +const String TEST_PAGE = 'test-page'; + +const String HEALTH_WEATHER = 'health-weather'; +const APP_UPDATE = 'app-update'; var routes = { SPLASH: (_) => SplashScreen(), HOME: (_) => LandingPage(), @@ -52,5 +65,12 @@ var routes = { SYMPTOM_CHECKER: (_) => SymptomChecker(), SYMPTOM_CHECKER_INFO: (_) => SymptomInfo(), SELECT_GENDER: (_) => SelectGender(), - SETTINGS: (_) => Settings() + SETTINGS: (_) => Settings(), + PACKAGES_OFFERS: (_) => PackagesHomePage(), + PACKAGES_OFFERS_CART: (_) => PackagesCartPage(), + PACKAGES_ORDER_COMPLETED: (_) => PackageOrderCompletedPage(), + TEST_PAGE: (_) => TestPage(), + HEALTH_WEATHER: (_) => HealthWeatherIndicator(), + APP_UPDATE: (_) => AppUpdatePage(), + SETTINGS: (_) => Settings(), }; diff --git a/lib/services/appointment_services/GetDoctorsList.dart b/lib/services/appointment_services/GetDoctorsList.dart index d26c74ad..65fe2b04 100644 --- a/lib/services/appointment_services/GetDoctorsList.dart +++ b/lib/services/appointment_services/GetDoctorsList.dart @@ -10,6 +10,7 @@ import 'package:diplomaticquarterapp/models/Request.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; +import 'package:diplomaticquarterapp/uitl/utils.dart'; import 'package:flutter/cupertino.dart'; class DoctorsListService extends BaseService { @@ -41,7 +42,8 @@ class DoctorsListService extends BaseService { long = await this.sharedPref.getDouble(USER_LONG); } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -105,7 +107,8 @@ class DoctorsListService extends BaseService { long = await this.sharedPref.getDouble(USER_LONG); } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -145,7 +148,8 @@ class DoctorsListService extends BaseService { Future getDoctorsProfile( int docID, int clinicID, int projectID, context) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -177,10 +181,10 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getDoctorsRating( - int docID, context) async { + Future getDoctorsRating(int docID, context) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -203,17 +207,17 @@ class DoctorsListService extends BaseService { await baseAppClient.post(GET_DOCTOR_RATING_NOTES, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } - Future getDoctorsRatingDetails( - int docID, context) async { + Future getDoctorsRatingDetails(int docID, context) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "LanguageID": languageID == 'ar' ? 1 : 2, @@ -236,17 +240,18 @@ class DoctorsListService extends BaseService { await baseAppClient.post(GET_DOCTOR_RATING_DETAILS, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } Future getDoctorFreeSlots( int docID, int clinicID, int projectID, BuildContext context) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "DoctorID": docID, @@ -281,7 +286,8 @@ class DoctorsListService extends BaseService { Future getDoctorScheduledFreeSlots(int docID, int clinicID, int projectID, int serviceID, BuildContext context) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "DoctorID": docID, @@ -324,7 +330,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsForLiveCare": false, @@ -383,7 +390,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsForLiveCare": true, @@ -437,7 +445,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -481,7 +490,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -526,7 +536,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -560,7 +571,8 @@ class DoctorsListService extends BaseService { Future getPatientAppointmentCurfewHistory( bool isActiveAppointment) async { Map request; - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -601,7 +613,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -654,7 +667,8 @@ class DoctorsListService extends BaseService { long = await this.sharedPref.getDouble(USER_LONG); } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -701,7 +715,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -751,7 +766,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -802,7 +818,8 @@ class DoctorsListService extends BaseService { authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -847,7 +864,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "ClientRequestID": transactionID, @@ -886,7 +904,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AdvanceNumber": advanceNumber, @@ -916,6 +935,64 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } + Future addVIDARequest(String advanceNumber, + String paymentReference, dynamic apptData, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); + request = { + "AdvanceNumber": advanceNumber, + "PaymentReferenceNumber": paymentReference, + "AppointmentNo": apptData.AppointmentNo, + "AcceptedBy": apptData.DoctorID, + "ServiceID": apptData.ServiceID, + "ProjectID": apptData.ProjectID, + "ClinicID": apptData.ClinicID, + "ClientRequestID": Utils.getAppointmentTransID( + apptData.ProjectID, apptData.ClinicID, apptData.AppointmentNo), + "AppointmentDate": apptData.AppointmentDate, + "DeviceType": Platform.isIOS ? "iOS" : "Android", + "VersionID": req.VersionID, + "Channel": req.Channel, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "TokenID": "@dm!n", + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + + // request.DeviceToken = this.cs.sharedService.getSharedData(AuthenticationService.DEVICE_TOKEN, false); + // request.Latitude = this.cs.sharedService.getSharedData('userLat', false); + // request.Longitude = this.cs.sharedService.getSharedData('userLong', false); + // request.ServiceID = apptData.ServiceID; + // request.ProjectID = apptData.ProjectID; + // request.ClinicID = apptData.ClinicID; + // request.ClientRequestID = AppointmentModel.getAppointmentTransID(apptData); + // request.AppointmentDate = apptData.AppointmentDate; + // request.DeviceType = this.getDeviceType(); + // request.VoipToken = this.platform.is('ios') ? this.cs.sharedService.getSharedData(AuthenticationService.APNS_TOKEN, false) : ""; + dynamic localRes; + await baseAppClient.post(ADD_VIDA_REQUEST, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } + Future isAllowedToAskDoctor(int docID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { @@ -923,7 +1000,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "IsForAskYourDoctor": true, @@ -963,7 +1041,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "VersionID": req.VersionID, @@ -999,7 +1078,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -1058,7 +1138,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appoNo, @@ -1087,14 +1168,16 @@ class DoctorsListService extends BaseService { return Future.value(localRes); } - Future getPatientLabOrdersByAppoNo(dynamic appoNo, dynamic projID, dynamic clinicID, BuildContext context) async { + Future getPatientLabOrdersByAppoNo(dynamic appoNo, dynamic projID, + dynamic clinicID, BuildContext context) async { Map request; if (await this.sharedPref.getObject(USER_PROFILE) != null) { var data = AuthenticatedUser.fromJson( await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appoNo, @@ -1118,10 +1201,10 @@ class DoctorsListService extends BaseService { dynamic localRes; await baseAppClient.post(GET_PATIENT_LAB_ORDERS_BY_APPOINTMENT, onSuccess: (response, statusCode) async { - localRes = response; - }, onFailure: (String error, int statusCode) { - throw error; - }, body: request); + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); return Future.value(localRes); } @@ -1133,7 +1216,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentNo": appo.appointmentNo, @@ -1174,7 +1258,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "AppointmentDate": appoDate, @@ -1223,7 +1308,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { "ProjectID": projectID, @@ -1282,7 +1368,8 @@ class DoctorsListService extends BaseService { await this.sharedPref.getObject(USER_PROFILE)); authUser = data; } - var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { @@ -1320,4 +1407,42 @@ class DoctorsListService extends BaseService { }, body: request); return Future.value(localRes); } + + Future getPatientHealthDataStats( + int medCategoryId, int medCategoryStsId, BuildContext context) async { + Map request; + if (await this.sharedPref.getObject(USER_PROFILE) != null) { + var data = AuthenticatedUser.fromJson( + await this.sharedPref.getObject(USER_PROFILE)); + authUser = data; + } + var languageID = + await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + Request req = appGlobal.getPublicRequest(); + request = { + "MedCategoryID": medCategoryId, + "MedGetStsID": medCategoryStsId, + "VersionID": req.VersionID, + "Channel": req.Channel, + "LanguageID": languageID == 'ar' ? 1 : 2, + "IPAdress": req.IPAdress, + "generalid": req.generalid, + "PatientOutSA": authUser.outSA, + "SessionID": "YckwoXhUmWBsnHKEKig", + "isDentalAllowedBackend": false, + "DeviceTypeID": req.DeviceTypeID, + "PatientID": authUser.patientID, + "TokenID": "@dm!n", + "PatientTypeID": authUser.patientType, + "PatientType": authUser.patientType + }; + dynamic localRes; + await baseAppClient.post(GET_PATIENT_HEALTH_STATS, + onSuccess: (response, statusCode) async { + localRes = response; + }, onFailure: (String error, int statusCode) { + throw error; + }, body: request); + return Future.value(localRes); + } } diff --git a/lib/services/authentication/auth_provider.dart b/lib/services/authentication/auth_provider.dart index 8f0ea470..bd2006f8 100644 --- a/lib/services/authentication/auth_provider.dart +++ b/lib/services/authentication/auth_provider.dart @@ -378,24 +378,24 @@ class AuthProvider with ChangeNotifier { Future sendPatientIDSMS(mobileNo, context) async { Map request; - var languageID = - await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); + // var languageID = + // await sharedPref.getStringWithDefaultValue(APP_LANGUAGE, 'ar'); Request req = appGlobal.getPublicRequest(); request = { - "LanguageID": languageID == 'ar' ? 1 : 2, - "IPAdress": "10.20.10.20", - "VersionID": req.VersionID, - "Channel": req.Channel, - "generalid": 'Cs2020@2016\$2958', - "PatientOutSA": 0, - "PatientID": 0, - "TokenID": "", + // "LanguageID": languageID == 'ar' ? 1 : 2, + // "IPAdress": "10.20.10.20", + // "VersionID": req.VersionID, + // "Channel": req.Channel, + // "generalid": 'Cs2020@2016\$2958', + // "PatientOutSA": 0, + // "PatientID": 0, + // "TokenID": "", "PatientMobileNumber": mobileNo, "SearchType": 2, - "ZipCode": "966", - "PatientIdentificationID": "", + // "ZipCode": "966", + // "PatientIdentificationID": "", "DeviceTypeID": req.DeviceTypeID, - "SessionID": null + // "SessionID": null }; dynamic localRes; diff --git a/lib/services/pharmacy_services/cancelOrder_service.dart b/lib/services/pharmacy_services/cancelOrder_service.dart index f848c2ff..3804b19b 100644 --- a/lib/services/pharmacy_services/cancelOrder_service.dart +++ b/lib/services/pharmacy_services/cancelOrder_service.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; @@ -16,8 +17,8 @@ class CancelOrderService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _cancelOrderList = List(); - List get cancelOrderList => _cancelOrderList; + List _cancelOrderList = List(); + List get cancelOrderList => _cancelOrderList; String url =""; diff --git a/lib/services/pharmacy_services/orderDetails_service.dart b/lib/services/pharmacy_services/orderDetails_service.dart index a3bb9976..4178c50a 100644 --- a/lib/services/pharmacy_services/orderDetails_service.dart +++ b/lib/services/pharmacy_services/orderDetails_service.dart @@ -1,12 +1,13 @@ import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/PharmacyProduct.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_detail.dart'; import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; import 'package:diplomaticquarterapp/core/service/base_service.dart'; import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; -import 'package:flutter/material.dart'; class OrderDetailsService extends BaseService{ @@ -16,20 +17,18 @@ class OrderDetailsService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); + List _orderList = List(); + List get orderList => _orderList; - List get orderDetails => orderDetails; - List _orderList = List(); - List get orderList => _orderList; - - Future getOrderDetails(orderId) async { - print("step 2" + orderId); + Future getOrderDetails(OrderId) async { hasError = false; - await baseAppClient.getPharmacy(GET_ORDER_DETAILS+orderId, + await baseAppClient.getPharmacy(GET_ORDER_DETAILS+OrderId, onSuccess: (dynamic response, int statusCode) { _orderList.clear(); response['orders'].forEach((item) { - _orderList.add(OrderModel.fromJson(item)); + _orderList.add(OrderDetailModel.fromJson(item)); + print(response); }); }, onFailure: (String error, int statusCode) { hasError = true; @@ -37,7 +36,7 @@ class OrderDetailsService extends BaseService{ }); } - Future makeReview(Product product, double rating, String reviewText) async { + Future makeReview(PharmacyProduct product, double rating, String reviewText) async { hasError = false; super.error = ""; diff --git a/lib/services/pharmacy_services/order_service.dart b/lib/services/pharmacy_services/order_service.dart index e426b801..3f1ece78 100644 --- a/lib/services/pharmacy_services/order_service.dart +++ b/lib/services/pharmacy_services/order_service.dart @@ -5,7 +5,7 @@ import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.da import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:flutter/material.dart'; -import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/orders_model.dart'; class OrderService extends BaseService{ @@ -14,21 +14,23 @@ class OrderService extends BaseService{ AuthenticatedUser authUser = new AuthenticatedUser(); AuthProvider authProvider = new AuthProvider(); - List _orderList = List(); - List get orderList => _orderList; + List _orderList = List(); + List get orderList => _orderList; String url =""; Future getOrder(customerId, pageId) async { hasError = false; // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; - url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; + // url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$pageId&limit=200&customer_id=$customerId"; + url =GET_ORDER+"customer=1&fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc,product_count,can_cancel,can_refund&page=$pageId&limit=200&customer_id=$customerId"; print(url); await baseAppClient.getPharmacy(url, onSuccess: (dynamic response, int statusCode) { _orderList.clear(); + response['orders'].forEach((item) { - _orderList.add(OrderModel.fromJson(item)); + _orderList.add(Orders.fromJson(item)); }); print(_orderList.length); print(response); @@ -39,25 +41,27 @@ class OrderService extends BaseService{ } - Future getProductReview(orderId) async { - print("step 1"); - hasError = false; - url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; -// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$page_id&limit=200&customer_id=$custmerId"; - print(url); - await baseAppClient.getPharmacy(url, - onSuccess: (dynamic response, int statusCode) { - _orderList.clear(); - response['orders'].forEach((item) { - _orderList.add(OrderModel.fromJson(item)); - }); - print(_orderList.length); - print(response); - }, onFailure: (String error, int statusCode) { - hasError = true; - super.error = error; - }); - } +// Future getProductReview(orderId) async { +// print("step 1"); +// hasError = false; +// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=1&limit=200&customer_id=1367368"; +//// url =GET_ORDER+"customer=1,fields=id,order_total,order_status,order_statusn,order_status_id,created_on_utc&page=$page_id&limit=200&customer_id=$custmerId"; +// print(url); +// await baseAppClient.getPharmacy(url, +// onSuccess: (dynamic response, int statusCode) { +// _orderList.clear(); +// response['orders'].forEach((item) { +// _orderList.add(OrderModel.fromJson(item)); +// }); +// print(_orderList.length); +// print(response); +// }, onFailure: (String error, int statusCode) { +// hasError = true; +// super.error = error; +// }); +// } + + // Future getOrder(BuildContext context ) async { // // if (await this.sharedPref.getObject(USER_PROFILE) != null) { diff --git a/lib/services/pharmacy_services/pharmacyAddress_service.dart b/lib/services/pharmacy_services/pharmacyAddress_service.dart index 1bb6571c..592359ca 100644 --- a/lib/services/pharmacy_services/pharmacyAddress_service.dart +++ b/lib/services/pharmacy_services/pharmacyAddress_service.dart @@ -16,7 +16,7 @@ class PharmacyAddressService extends BaseService { hasError = false; Addresses selectedAddress; try { - await baseAppClient.get("$GET_CUSTOMERS_ADDRESSES$customerId", + await baseAppClient.getPharmacy("$GET_CUSTOMERS_ADDRESSES$customerId", onSuccess: (dynamic response, int statusCode) async { addresses.clear(); var savedAddress = @@ -45,7 +45,7 @@ class PharmacyAddressService extends BaseService { Future getCountries(String countryName) async { hasError = false; try { - await baseAppClient.get("$PHARMACY_GET_COUNTRY", + await baseAppClient.getPharmacy("$PHARMACY_GET_COUNTRY", onSuccess: (dynamic response, int statusCode) { // countries.clear(); response['countries'].forEach((item) { diff --git a/lib/services/pharmacy_services/product_detail_service.dart b/lib/services/pharmacy_services/product_detail_service.dart index 7a2947b0..f85faf2c 100644 --- a/lib/services/pharmacy_services/product_detail_service.dart +++ b/lib/services/pharmacy_services/product_detail_service.dart @@ -88,7 +88,7 @@ class ProductDetailService extends BaseService { "language_id": 1 } }; - await baseAppClient.post(GET_SHOPPING_CART, + await baseAppClient.pharmacyPost(GET_SHOPPING_CART, isExternal: false, onSuccess: (dynamic response, int statusCode) { _addToCartModel.clear(); response['shopping_carts'].forEach((item) { @@ -102,22 +102,26 @@ class ProductDetailService extends BaseService { }, body: request); } + Future notifyMe(customerId, itemID) async { + hasError = false; + await baseAppClient.getPharmacy(SUBSCRIBE_PRODUCT + "SinceId=$customerId&ProductId=$itemID", onSuccess: (dynamic response, int statusCode) { + AppToast.showSuccessToast(message: 'You will be notified when product available'); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + AppToast.showErrorToast(message: 'something went wrong please try again'); + }); + } + Future addToWishlist(itemID) async { var customerId = await sharedPref.getString(PHARMACY_CUSTOMER_ID); hasError = false; Map request; request = { - "shopping_cart_item": - { - "quantity": 1, - "shopping_cart_type": "Wishlist", - "product_id": itemID, - "customer_id": customerId, - "language_id": 1 - } + "shopping_cart_item": {"quantity": 1, "shopping_cart_type": "Wishlist", "product_id": itemID, "customer_id": customerId, "language_id": 1} }; - await baseAppClient.post(GET_SHOPPING_CART, + await baseAppClient.pharmacyPost(GET_SHOPPING_CART, onSuccess: (dynamic response, int statusCode) { _wishListProducts.clear(); response['shopping_carts'].forEach((item) { @@ -168,6 +172,7 @@ class ProductDetailService extends BaseService { _productSpecification.clear(); response['specification'].forEach((item) { _productSpecification.add(SpecificationModel.fromJson(item)); + print(_productSpecification); }); }, onFailure: (String error, int statusCode) { hasError = true; diff --git a/lib/services/pharmacy_services/recommendedProduct_service.dart b/lib/services/pharmacy_services/recommendedProduct_service.dart new file mode 100644 index 00000000..ad7222f8 --- /dev/null +++ b/lib/services/pharmacy_services/recommendedProduct_service.dart @@ -0,0 +1,40 @@ +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/recommendedProduct_model.dart'; +import 'package:diplomaticquarterapp/core/service/base_service.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; + + + + +class RecommendedProductService extends BaseService{ + AppSharedPreferences sharedPref = AppSharedPreferences(); + AppGlobal appGlobal = new AppGlobal(); + AuthenticatedUser authUser = new AuthenticatedUser(); + AuthProvider authProvider = new AuthProvider(); + + List _recommendedProductList = List(); + List get recommendedList => _recommendedProductList; + String url =""; + + Future getRecommendedProducts(productId) async { + hasError = false; + url =GET_RECOMMENDED_PRODUCT+productId; + await baseAppClient.getPharmacy(url, + onSuccess: (dynamic response, int statusCode) { + _recommendedProductList.clear(); + response['products'].forEach((item) { + _recommendedProductList.add(Products.fromJson(item)); + print("----------------------------------"); + print("Test data"); + print(_recommendedProductList[0]); + print(item['name']); + print(response); + }); + }, onFailure: (String error, int statusCode) { + hasError = true; + super.error = error; + }); + }} \ No newline at end of file diff --git a/lib/splashPage.dart b/lib/splashPage.dart index 20da2ba6..ef5db7f5 100644 --- a/lib/splashPage.dart +++ b/lib/splashPage.dart @@ -31,15 +31,14 @@ class _SplashScreenState extends State { super.initState(); Timer( Duration(seconds: 1, milliseconds: 500), - () { - loadPrivilege().then((value) { - Navigator.of(context).pushReplacement( - MaterialPageRoute( - builder: (BuildContext context) => LandingPage(), - ), - ); - }); - + () { + loadPrivilege().then((value) { + Navigator.of(context).pushReplacement( + MaterialPageRoute( + builder: (BuildContext context) => LandingPage(), + ), + ); + }); }, ); } @@ -47,14 +46,19 @@ class _SplashScreenState extends State { /// load the Privilege from service Future loadPrivilege() async { await _privilegeService.getPrivilege(); - Provider.of(context, listen: false).setPrivilegeModelList(privilege: _privilegeService.privilegeModelList); + Provider.of(context, listen: false) + .setPrivilegeModelList(privilege: _privilegeService.privilegeModelList); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, - body: Image.asset('assets/images/powerd-by.jpg',fit: BoxFit.fitWidth,width: MediaQuery.of(context).size.width,), + body: Image.asset( + 'assets/images/powerd-by.jpg', + fit: BoxFit.fitWidth, + width: MediaQuery.of(context).size.width, + ), ); } } diff --git a/lib/theme/colors.dart b/lib/theme/colors.dart new file mode 100644 index 00000000..893449f1 --- /dev/null +++ b/lib/theme/colors.dart @@ -0,0 +1,11 @@ +import 'package:flutter/material.dart'; + +class CustomColors { + static const Color lightPurple = Color(0xFFBB86FA); + static const Color purple = Color(0xFF6002EE); + static const Color deepPurple = Color(0xFF3900B1); + static const Color grey = Color(0xFF848484); + static const Color darkGrey = Color(0xFF222222); + static const Color black = Color(0xFF141414); + static const Color white = Color(0xFFFFFFFF); +} diff --git a/lib/theme/config.dart b/lib/theme/config.dart new file mode 100644 index 00000000..4c321fb8 --- /dev/null +++ b/lib/theme/config.dart @@ -0,0 +1,3 @@ +// import 'package:diplomaticquarterapp/theme/custom_theme.dart'; + +// CustomTheme currentTheme = CustomTheme(); diff --git a/lib/theme/custom_theme.dart b/lib/theme/custom_theme.dart new file mode 100644 index 00000000..8361ec4e --- /dev/null +++ b/lib/theme/custom_theme.dart @@ -0,0 +1,89 @@ +// import 'package:diplomaticquarterapp/Constants.dart'; +// import 'package:flutter/material.dart'; +// import 'package:hexcolor/hexcolor.dart'; + +// import 'colors.dart'; + +// class CustomTheme with ChangeNotifier { +// static bool _isDarkTheme = true; +// ThemeMode get currentTheme => +// _isDarkTheme ? ThemeMode.dark : ThemeMode.system; + +// void toggleTheme() { +// _isDarkTheme = !_isDarkTheme; +// notifyListeners(); +// } + +// static ThemeData get lightTheme { +// //1 +// return ThemeData( +// //2 +// primaryColor: CustomColors.purple, +// scaffoldBackgroundColor: Colors.white, +// fontFamily: 'Montserrat', //3 +// buttonTheme: ButtonThemeData( +// // 4 +// shape: +// RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.0)), +// buttonColor: CustomColors.lightPurple, +// )); +// } + +// static ThemeData get darkTheme { +// return ThemeData( +// primaryColor: CustomColors.darkGrey, +// scaffoldBackgroundColor: Colors.black, +// fontFamily: 'Montserrat', +// textTheme: ThemeData.dark().textTheme, +// buttonTheme: ButtonThemeData( +// shape: +// RoundedRectangleBorder(borderRadius: BorderRadius.circular(18.0)), +// buttonColor: CustomColors.lightPurple, +// )); +// } + +// static ThemeData get defaultTheme { +// return ThemeData( +// // fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', +// primarySwatch: Colors.blue, +// visualDensity: VisualDensity.adaptivePlatformDensity, +// brightness: Brightness.light, +// pageTransitionsTheme: const PageTransitionsTheme( +// builders: { +// TargetPlatform.android: ZoomPageTransitionsBuilder(), +// TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), +// }, +// ), +// hintColor: Colors.grey[400], +// textTheme: TextTheme( +// headline1: TextStyle( +// color: Color(0xffB8382C), +// ), +// ), +// disabledColor: Colors.grey[300], +// errorColor: Color.fromRGBO(235, 80, 60, 1.0), +// scaffoldBackgroundColor: Color(0xffE9E9E9), // Colors.grey[100], +// textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), +// textSelectionHandleColor: Colors.grey, +// canvasColor: Colors.white, +// backgroundColor: Color.fromRGBO(255, 255, 255, 1), +// highlightColor: Colors.grey[100].withOpacity(0.4), +// splashColor: Colors.transparent, +// primaryColor: Color(0xff515A5D), +// toggleableActiveColor: secondaryColor, +// indicatorColor: secondaryColor, +// bottomSheetTheme: +// BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), +// cursorColor: Colors.grey, +// iconTheme: IconThemeData(), +// appBarTheme: AppBarTheme( +// color: Color(0xff515A5D), +// brightness: Brightness.light, +// elevation: 0.0, +// actionsIconTheme: IconThemeData( +// color: Colors.grey[800], +// ), +// ), +// ); +// } +// } diff --git a/lib/theme/theme_notifier.dart b/lib/theme/theme_notifier.dart index e414d159..e61c73a6 100644 --- a/lib/theme/theme_notifier.dart +++ b/lib/theme/theme_notifier.dart @@ -1,15 +1,20 @@ -import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:diplomaticquarterapp/theme/theme_value.dart'; import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:diplomaticquarterapp/config/config.dart'; class ThemeNotifier with ChangeNotifier { - ThemeData _themeData = defaultTheme; + ThemeData _themeData; + ThemeNotifier(this._themeData); + getTheme() => _themeData; + getTheme_(String font) => _themeData; + setTheme(ThemeData themeData) async { _themeData = themeData; - notifyListeners(); } } diff --git a/lib/theme/theme_value.dart b/lib/theme/theme_value.dart index d19e13b2..65d6f81d 100644 --- a/lib/theme/theme_value.dart +++ b/lib/theme/theme_value.dart @@ -1,9 +1,8 @@ import 'dart:ui'; +import 'package:diplomaticquarterapp/Constants.dart'; import 'package:diplomaticquarterapp/config/config.dart'; -import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; -import 'package:diplomaticquarterapp/core/service/client/base_app_client.dart'; -import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; import 'package:flutter/material.dart'; +import 'package:hexcolor/hexcolor.dart'; import 'package:provider/provider.dart'; /// ---- Default Theme ---- @@ -13,11 +12,11 @@ import 'package:provider/provider.dart'; final bluePrimary = Color(0xFF3F51B5); final blueAccent = Color(0xFFFF9800); final blueBackground = Color(0xFFFFFFFF); +defaultTheme({fontName}) { + return ThemeData( + fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', -// ProjectViewModel projectProvider = Provider.of(AppGlobal.context); - final bwTheme = ThemeData( - //fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.grey, + primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, brightness: Brightness.light, pageTransitionsTheme: const PageTransitionsTheme( @@ -27,37 +26,96 @@ final blueBackground = Color(0xFFFFFFFF); }, ), hintColor: Colors.grey[400], - cardColor: Colors.black, - buttonColor: Colors.grey[400], disabledColor: Colors.grey[300], errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Colors.grey, + scaffoldBackgroundColor: Color(0xffE9E9E9), // Colors.grey[100], textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Colors.grey, canvasColor: Colors.white, - backgroundColor: Colors.grey, + backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Colors.grey, - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), + primaryColor: Color(0xff515A5D), + buttonColor: Colors.black, + toggleableActiveColor: secondaryColor, + indicatorColor: secondaryColor, + bottomSheetTheme: + BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), cursorColor: Colors.grey, + primaryTextTheme: TextTheme(bodyText2: TextStyle(color: Colors.white)), + iconTheme: IconThemeData(), + textTheme: TextTheme( + bodyText1: TextStyle(color: Colors.black), + headline1: TextStyle(color: Colors.white), + headline2: TextStyle(color: Colors.white)), + floatingActionButtonTheme: FloatingActionButtonThemeData(highlightElevation: 2, disabledElevation: 0, elevation: 2), + appBarTheme: AppBarTheme( + color: Color(0xff515A5D), + brightness: Brightness.light, + elevation: 0.0, + actionsIconTheme: IconThemeData( + color: Colors.grey[800], + ), + ), + ); +} + +invertThemes({fontName}) { + return ThemeData( + fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.blue, + + visualDensity: VisualDensity.adaptivePlatformDensity, + brightness: Brightness.dark, + pageTransitionsTheme: const PageTransitionsTheme( + builders: { + TargetPlatform.android: ZoomPageTransitionsBuilder(), + TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), + }, + ), + hintColor: Colors.grey[400], + textTheme: TextTheme( + bodyText1: TextStyle(color: Colors.white), + headline1: TextStyle(color: Colors.white), + headline2: TextStyle(color: Colors.white)), + disabledColor: Colors.grey[800], + errorColor: Color.fromRGBO(235, 80, 60, 1.0), + scaffoldBackgroundColor: Color(0xff000000), // Colors.grey[100], + textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), + textSelectionHandleColor: Colors.grey, + canvasColor: Colors.black, + backgroundColor: Color.fromRGBO(255, 255, 255, 1), + highlightColor: Colors.grey[100].withOpacity(0.4), + splashColor: Colors.transparent, + primaryColor: Color(0xff515A5D), + buttonColor: Colors.black, + toggleableActiveColor: secondaryColor, + indicatorColor: secondaryColor, + bottomSheetTheme: + BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), + cursorColor: Colors.black, iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Colors.black45, + color: Color(0xff000000), brightness: Brightness.dark, - elevation: 10.0, + elevation: 0.0, actionsIconTheme: IconThemeData( - color: Colors.grey, + color: Colors.grey[800], ), ), ); +} - final defaultTheme = ThemeData( - //fontFamily: ProjectViewModel().isArabic? 'Cairo' : 'WorkSans', +bwThemes({fontName}) { + return ThemeData( + fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', primarySwatch: Colors.blue, + visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, + brightness: Brightness.dark, + unselectedWidgetColor: Colors.red, + pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.android: ZoomPageTransitionsBuilder(), @@ -65,35 +123,51 @@ final blueBackground = Color(0xFFFFFFFF); }, ), hintColor: Colors.grey[400], - disabledColor: Colors.grey[300], + + textTheme: TextTheme( + bodyText1: TextStyle(color: Colors.red[900]), + headline1: TextStyle(color: Colors.red[900]), + headline2: TextStyle(color: Colors.white), + bodyText2: TextStyle(color: Colors.red[900]), + subtitle1: TextStyle(color: Colors.red[900]), + ), + + tabBarTheme: TabBarTheme(labelColor: Colors.red[900]), + + disabledColor: Colors.grey[800], errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Color(0xffEEEEEE), + scaffoldBackgroundColor: Color(0xffffffe4), // Colors.grey[100], textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Colors.grey, - canvasColor: Colors.white, - backgroundColor: Colors.white, + canvasColor: Colors.black, + backgroundColor: Color(0xffffffe4), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Color(0xff40ACC9), - bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), - cursorColor: Colors.grey, - cardColor: Colors.white, + primaryColor: Color(0xfffffff4), + toggleableActiveColor: secondaryColor, + indicatorColor: secondaryColor, + bottomSheetTheme: + BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), + cursorColor: Colors.black, iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Color(0xff40ACC9), + color: Color(0xffffffe4), brightness: Brightness.dark, - elevation: 10.0, + elevation: 0.0, actionsIconTheme: IconThemeData( - color: Color(0xff40ACC9), + color: Colors.grey[800], ), ), ); +} - final invertTheme = ThemeData( - //fontFamily: projectProvider.isArabic ? 'Cairo' : 'WorkSans', - primarySwatch: Colors.grey, +dimTheme({fontName}) { + return ThemeData( + fontFamily: fontName, //projectProvider.isArabic ? 'Cairo' : 'WorkSans', + primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, - brightness: Brightness.light, + brightness: Brightness.dark, + pageTransitionsTheme: const PageTransitionsTheme( builders: { TargetPlatform.android: ZoomPageTransitionsBuilder(), @@ -101,29 +175,26 @@ final blueBackground = Color(0xFFFFFFFF); }, ), hintColor: Colors.grey[400], - cardColor: Colors.black, - buttonColor: Colors.grey[400], disabledColor: Colors.grey[300], errorColor: Color.fromRGBO(235, 80, 60, 1.0), - scaffoldBackgroundColor: Colors.grey, + scaffoldBackgroundColor: Color(0xffEEEEEE), textSelectionColor: Color.fromRGBO(80, 100, 253, 0.5), textSelectionHandleColor: Colors.grey, canvasColor: Colors.white, - backgroundColor: Colors.grey, + backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Colors.grey, + primaryColor: Color(0xff40ACC9), bottomSheetTheme: BottomSheetThemeData(backgroundColor: Color(0xffE0E0E0)), cursorColor: Colors.grey, - iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Colors.grey, + color: Color(0xff40ACC9), brightness: Brightness.dark, elevation: 10.0, actionsIconTheme: IconThemeData( - color: Colors.grey, + color: Color(0xff40ACC9), ), ), ); - +} diff --git a/lib/uitl/HMGNetworkConnectivity.dart b/lib/uitl/HMGNetworkConnectivity.dart index 228edf93..c4044573 100644 --- a/lib/uitl/HMGNetworkConnectivity.dart +++ b/lib/uitl/HMGNetworkConnectivity.dart @@ -47,18 +47,28 @@ class HMGNetworkConnectivity { void confirmFromUser() { TranslationBase translator = TranslationBase.of(context); - ConfirmDialog( - context: context, - confirmMessage: translator.wantToConnectWithHmgNetwork, - okText: translator.yes, - okFunction: () { - ConfirmDialog.closeAlertDialog(context); - callBack(); - }, - cancelText: translator.no, - cancelFunction: () { - ConfirmDialog.closeAlertDialog(context); - }).showAlertDialog(context); + + void doIt() { + ConfirmDialog( + context: context, + confirmMessage: translator.wantToConnectWithHmgNetwork, + okText: translator.yes, + okFunction: () { + ConfirmDialog.closeAlertDialog(context); + callBack(); + }, + cancelText: translator.no, + cancelFunction: () { + ConfirmDialog.closeAlertDialog(context); + }).showAlertDialog(context); + } + + if (Platform.isAndroid) + Wifi.list(SSID).then((value) { + if (!value.indexWhere((element) => element.ssid == SSID).isNegative) doIt(); + }); + else + doIt(); } void showFailDailog(String message) { diff --git a/lib/uitl/date_uitl.dart b/lib/uitl/date_uitl.dart index 460a4066..9f959885 100644 --- a/lib/uitl/date_uitl.dart +++ b/lib/uitl/date_uitl.dart @@ -4,7 +4,7 @@ import 'package:intl/intl.dart'; class DateUtil { /// convert String To Date function /// [date] String we want to convert - static DateTime convertStringToDate(String date) { + static DateTime convertStringToDate(String date) { // /Date(1585774800000+0300)/ if (date != null) { const start = "/Date("; const end = "+0300)"; diff --git a/lib/uitl/gif_loader_dialog_utils.dart b/lib/uitl/gif_loader_dialog_utils.dart index ac37cdfb..785a6c6c 100644 --- a/lib/uitl/gif_loader_dialog_utils.dart +++ b/lib/uitl/gif_loader_dialog_utils.dart @@ -8,6 +8,10 @@ class GifLoaderDialogUtils { } static hideDialog(BuildContext context) { - Navigator.of(context).pop(); + try{ + Navigator.of(context).pop(); + }catch(error){ + Future.delayed(Duration(milliseconds: 250)).then((value) => Navigator.of(context).pop()); + } } } diff --git a/lib/uitl/location_util.dart b/lib/uitl/location_util.dart index c3799425..e2edb2a1 100644 --- a/lib/uitl/location_util.dart +++ b/lib/uitl/location_util.dart @@ -1,11 +1,26 @@ +import 'dart:io'; + +import 'package:connectivity/connectivity.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/uitl/app_shared_preferences.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:flutter/cupertino.dart'; +import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:geolocator/geolocator.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:huawei_location/permission/permission_handler.dart'; +import 'package:huawei_location/location/fused_location_provider_client.dart'; +import 'package:huawei_location/location/location_request.dart'; +import 'package:huawei_location/location/location_settings_request.dart'; +import 'package:huawei_location/location/location_callback.dart'; +import 'package:huawei_location/location/location.dart'; +import 'package:huawei_location/location/location_settings_states.dart'; +import 'package:huawei_location/location/location_availability.dart'; +import 'package:permission_handler/permission_handler.dart'; class LocationUtils { + AppSharedPreferences sharedPref = new AppSharedPreferences(); bool isShowConfirmDialog; @@ -13,31 +28,86 @@ class LocationUtils { LocationUtils({@required this.isShowConfirmDialog, @required this.context}); - void getCurrentLocation() async { + void getCurrentLocation({Function(LatLng) callBack}) async { print("current location"); - Geolocator.isLocationServiceEnabled().then((value) { - if (value) { - Geolocator.checkPermission().then((permission) { - if (permission == LocationPermission.always || - permission == LocationPermission.whileInUse) { - Geolocator.getLastKnownPosition() - .then((value) => setLocation(value)); - } - - if (permission == LocationPermission.denied || - permission == LocationPermission.deniedForever) { - setZeroLocation(); - if (isShowConfirmDialog) showErrorLocationDialog(false); - } - }).catchError((err) { - print(err); - }); - } else { - if (isShowConfirmDialog) showErrorLocationDialog(false); - } - }).catchError((err) { - print(err); - }); + if(Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) { + _getHMSCurrentLocation(callBack); + }else{ + Geolocator.isLocationServiceEnabled().then((value) { + if (value) { + Geolocator.checkPermission().then((permission) { + if (permission == LocationPermission.always || + permission == LocationPermission.whileInUse) { + Geolocator.getLastKnownPosition() + .then((value){ + setLocation(value); + if(callBack != null) + callBack(LatLng(value.latitude, value.longitude)); + }); + } + + if (permission == LocationPermission.denied || + permission == LocationPermission.deniedForever) { + setZeroLocation(); + if (isShowConfirmDialog) showErrorLocationDialog(false); + } + }).catchError((err) { + print(err); + }); + } else { + if (isShowConfirmDialog) showErrorLocationDialog(false); + } + }).catchError((err) { + print(err); + }); + } + } + + LocationCallback _locationCallback; + _getHMSCurrentLocation(Function(LatLng) callBack) async{ + PermissionHandler permissionHandler = PermissionHandler(); + + int _locationUpdateCbId = 0; + doIt(){ + FusedLocationProviderClient locationService = FusedLocationProviderClient(); + LocationRequest locationRequest = LocationRequest(); + locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY; + locationRequest.interval = 1000; + List locationRequestList = [locationRequest]; + LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList); + + locationService.checkLocationSettings(locationSettingsRequest).then((settings) async{ + + _locationUpdateCbId = await locationService.requestLocationUpdatesCb(locationRequest, LocationCallback(onLocationResult: (locationResult){ + Location location = locationResult.lastLocation; + locationService.removeLocationUpdatesCb(_locationUpdateCbId); + callBack(LatLng(location.latitude, location.longitude)); + setLocation(Position(latitude: location.latitude, longitude: location.longitude, altitude: location.altitude)); + }, onLocationAvailability: (locationAvailability){ + debugPrint("onLocationAvailability: $locationAvailability"); + })); + + }).catchError((error){ + + if(error.code == "LOCATION_SETTINGS_NOT_AVAILABLE"){ + // Location service not enabled. + } + + }); + + } + + + if(await permissionHandler.hasLocationPermission()){ + doIt(); + }else{ + bool has = await requestPermissions(); + if(has) + doIt(); + else if(isShowConfirmDialog) + showErrorLocationDialog(false); + + } } showErrorLocationDialog(bool isPermissionError) { @@ -70,4 +140,12 @@ class LocationUtils { this.sharedPref.setDouble(USER_LAT, 0.0); this.sharedPref.setDouble(USER_LONG, 0.0); } + + + Future requestPermissions() async { + var result = await [ + Permission.location, + ].request(); + return (result[Permission.location].isGranted || result[Permission.locationAlways].isGranted); + } } diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 63cf8a44..0e0058f9 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -18,7 +18,8 @@ class TranslationBase { return localizedValues[key][locale.languageCode]; } - String get dashboardScreenToolbarTitle => localizedValues['dashboardScreenToolbarTitle'][locale.languageCode]; + String get dashboardScreenToolbarTitle => + localizedValues['dashboardScreenToolbarTitle'][locale.languageCode]; String get settings => localizedValues['settings'][locale.languageCode]; @@ -89,19 +90,24 @@ class TranslationBase { String get bookSuccess => localizedValues['bookSuccess'][locale.languageCode]; - String get patientShare => localizedValues['patientShare'][locale.languageCode]; + String get patientShare => + localizedValues['patientShare'][locale.languageCode]; - String get patientShareWithTax => localizedValues['patientShareWithTax'][locale.languageCode]; + String get patientShareWithTax => + localizedValues['patientShareWithTax'][locale.languageCode]; String get confirmAppo => localizedValues['confirmAppo'][locale.languageCode]; String get confirm => localizedValues['confirm'][locale.languageCode]; - String get confirmLiveCare => localizedValues['confirmLiveCare'][locale.languageCode]; + String get confirmLiveCare => + localizedValues['confirmLiveCare'][locale.languageCode]; - String get waitingForDoctor => localizedValues['waitingForDoctor'][locale.languageCode]; + String get waitingForDoctor => + localizedValues['waitingForDoctor'][locale.languageCode]; - String get confirmLater => localizedValues['confirmLater'][locale.languageCode]; + String get confirmLater => + localizedValues['confirmLater'][locale.languageCode]; String get todoList => localizedValues['todoList'][locale.languageCode]; @@ -117,7 +123,8 @@ class TranslationBase { String get login => localizedValues['login'][locale.languageCode]; - String get loginregister => localizedValues['loginregister'][locale.languageCode]; + String get loginregister => + localizedValues['loginregister'][locale.languageCode]; String get poweredBy => localizedValues['poweredBy'][locale.languageCode]; @@ -126,7 +133,8 @@ class TranslationBase { String get welcomeText => localizedValues['welcome_text'][locale.languageCode]; - String get welcomeText2 => localizedValues['welcome_text2'][locale.languageCode]; + String get welcomeText2 => + localizedValues['welcome_text2'][locale.languageCode]; String get yes => localizedValues['yes'][locale.languageCode]; @@ -264,6 +272,7 @@ class TranslationBase { localizedValues['pharmaciesList'][locale.languageCode]; String get description => localizedValues['description'][locale.languageCode]; + String get howToUse => localizedValues['howToUse'][locale.languageCode]; String get price => localizedValues['price'][locale.languageCode]; @@ -288,17 +297,24 @@ class TranslationBase { String get appsetting => localizedValues['app-settings'][locale.languageCode]; String get rateApp => localizedValues['rate-app'][locale.languageCode]; - String get setReminder => localizedValues['set-reminder'][locale.languageCode]; + String get setReminder => + localizedValues['set-reminder'][locale.languageCode]; String get before => localizedValues['before'][locale.languageCode]; String get minute => localizedValues['minute'][locale.languageCode]; String get hour => localizedValues['hour'][locale.languageCode]; - String get reminderSuccess => localizedValues['reminderSuccess'][locale.languageCode]; - String get patientShareToDo => localizedValues['patientShareToDo'][locale.languageCode]; - String get patientTaxToDo => localizedValues['patientTaxToDo'][locale.languageCode]; - String get patientShareTotalToDo => localizedValues['patientShareTotalToDo'][locale.languageCode]; - String get paymentMethod => localizedValues['paymentMethod'][locale.languageCode]; - - String get moreVerification => localizedValues['more-verify'][locale.languageCode]; + String get reminderSuccess => + localizedValues['reminderSuccess'][locale.languageCode]; + String get patientShareToDo => + localizedValues['patientShareToDo'][locale.languageCode]; + String get patientTaxToDo => + localizedValues['patientTaxToDo'][locale.languageCode]; + String get patientShareTotalToDo => + localizedValues['patientShareTotalToDo'][locale.languageCode]; + String get paymentMethod => + localizedValues['paymentMethod'][locale.languageCode]; + + String get moreVerification => + localizedValues['more-verify'][locale.languageCode]; String get welcomeBack => localizedValues['welcome-back'][locale.languageCode]; @@ -328,11 +344,15 @@ class TranslationBase { String get booked => localizedValues['booked'][locale.languageCode]; String get confirmed => localizedValues['confirmed'][locale.languageCode]; String get arrived => localizedValues['arrived'][locale.languageCode]; - String get payNowBookSuccess => localizedValues['payNowBookSuccess'][locale.languageCode]; - String get payNowBookSuccesstext1 => localizedValues['payNowBookSuccesstext1'][locale.languageCode]; - String get payNowBookSuccesstext2 => localizedValues['payNowBookSuccesstext2'][locale.languageCode]; + String get payNowBookSuccess => + localizedValues['payNowBookSuccess'][locale.languageCode]; + String get payNowBookSuccesstext1 => + localizedValues['payNowBookSuccesstext1'][locale.languageCode]; + String get payNowBookSuccesstext2 => + localizedValues['payNowBookSuccesstext2'][locale.languageCode]; String get payLater => localizedValues['payLater'][locale.languageCode]; - String get askDocNotAllowed => localizedValues['askDocNotAllowed'][locale.languageCode]; + String get askDocNotAllowed => + localizedValues['askDocNotAllowed'][locale.languageCode]; String get firstName => localizedValues['first-name'][locale.languageCode]; String get middleName => localizedValues['middle-name'][locale.languageCode]; @@ -343,13 +363,15 @@ class TranslationBase { String get female => localizedValues['female'][locale.languageCode]; - String get prefferedLanguage => localizedValues['preferred-language'][locale.languageCode]; + String get prefferedLanguage => + localizedValues['preferred-language'][locale.languageCode]; String get english => localizedValues['english'][locale.languageCode]; String get arabic => localizedValues['arabic'][locale.languageCode]; - String get registrLocation => localizedValues['locations-register'][locale.languageCode]; + String get registrLocation => + localizedValues['locations-register'][locale.languageCode]; String get ksa => localizedValues['ksa'][locale.languageCode]; @@ -359,7 +381,8 @@ class TranslationBase { String get family => localizedValues['family'][locale.languageCode]; - String get myFamilyFiles => localizedValues['family-title'][locale.languageCode]; + String get myFamilyFiles => + localizedValues['family-title'][locale.languageCode]; String get myFamily => localizedValues['myFamily'][locale.languageCode]; String get oxygenation => localizedValues['oxygenation'][locale.languageCode]; @@ -369,7 +392,8 @@ class TranslationBase { String get bodyMeasurements => localizedValues['bodyMeasurements'][locale.languageCode]; String get height => localizedValues['height'][locale.languageCode]; - + String get heightUnit => localizedValues['heightUnit'][locale.languageCode]; + String get weightUnit => localizedValues['weightUnit'][locale.languageCode]; String get temperature => localizedValues['temperature'][locale.languageCode]; String get pulse => localizedValues['pulse'][locale.languageCode]; @@ -442,11 +466,15 @@ class TranslationBase { String get viewAll => localizedValues['viewAll'][locale.languageCode]; String get view => localizedValues['view'][locale.languageCode]; String get contactUs => localizedValues['ContactUs'][locale.languageCode]; - String get viewAllWaysReachUs => localizedValues['ViewAllWaysReachUs'][locale.languageCode]; - String get medicalProfile => localizedValues['medicalProfile'][locale.languageCode]; + String get viewAllWaysReachUs => + localizedValues['ViewAllWaysReachUs'][locale.languageCode]; + String get medicalProfile => + localizedValues['medicalProfile'][locale.languageCode]; String get parking => localizedValues['parking'][locale.languageCode]; - String get alhabiServices => localizedValues['alhabiServices'][locale.languageCode]; - String get parkingTitle => localizedValues['parkingTitle'][locale.languageCode]; + String get alhabiServices => + localizedValues['alhabiServices'][locale.languageCode]; + String get parkingTitle => + localizedValues['parkingTitle'][locale.languageCode]; String get readBarcode => localizedValues['readBarcode'][locale.languageCode]; String get showMyPark => localizedValues['showMyPark'][locale.languageCode]; String get clearMyData => localizedValues['clearMyData'][locale.languageCode]; @@ -454,7 +482,8 @@ class TranslationBase { String get gate => localizedValues['gate'][locale.languageCode]; String get building => localizedValues['building'][locale.languageCode]; String get branch => localizedValues['branch'][locale.languageCode]; - String get emergencyServices => localizedValues['emergencyServices'][locale.languageCode]; + String get emergencyServices => + localizedValues['emergencyServices'][locale.languageCode]; String get nearester => localizedValues['nearester'][locale.languageCode]; String get locationa => localizedValues['locationa'][locale.languageCode]; String get ambulancerequest => @@ -550,6 +579,8 @@ class TranslationBase { localizedValues['Prescriptions'][locale.languageCode]; String get history => localizedValues['History'][locale.languageCode]; String get orderNo => localizedValues['OrderNo'][locale.languageCode]; + String get trackDeliveryDriver => + localizedValues['trackDeliveryDriver'][locale.languageCode]; String get orderDetails => localizedValues['OrderDetails'][locale.languageCode]; String get vitalSign => localizedValues['VitalSign'][locale.languageCode]; @@ -581,6 +612,8 @@ class TranslationBase { localizedValues['UpdateSuccessfully'][locale.languageCode]; String get emailSentSuccessfully => localizedValues['EmailSentSuccessfully'][locale.languageCode]; + String get EmailSentError => + localizedValues['EmailSentError'][locale.languageCode]; String get checkVaccineAvailability => localizedValues['CHECK_VACCINE_AVAILABILITY'][locale.languageCode]; String get myVaccinesAvailability => @@ -613,6 +646,7 @@ class TranslationBase { localizedValues['SelectFamilyPatientName'][locale.languageCode]; String get selectHospital => localizedValues['SelectHospital'][locale.languageCode]; + String get selectCity => localizedValues['selectCity'][locale.languageCode]; String get myAccount => localizedValues['MyAccount'][locale.languageCode]; String get otherAccount => localizedValues['OtherAccount'][locale.languageCode]; @@ -625,6 +659,10 @@ class TranslationBase { String get mobileNumber => localizedValues['MobileNumber'][locale.languageCode]; String get ok => localizedValues['Ok'][locale.languageCode]; + String get waterConsumedInWeek => + localizedValues['WaterConsumedInWeek'][locale.languageCode]; + String get waterConsumedInMonth => + localizedValues['WaterConsumedInMonth'][locale.languageCode]; String get theVerificationCodeExpiresIn => localizedValues['TheVerificationCodeExpiresIn'][locale.languageCode]; String get pleaseEnterTheVerificationCode => @@ -714,6 +752,9 @@ class TranslationBase { String get shippedMethod => localizedValues['shippedMethod'][locale.languageCode]; String get orderDetail => localizedValues['orderDetail'][locale.languageCode]; + String get deliveryDriverTrack => localizedValues['DeliveryDriverTrack'][locale.languageCode]; + String get deliveryLocation => localizedValues['DeliveryLocation'][locale.languageCode]; + String get driver => localizedValues['Driver'][locale.languageCode]; String get subtotal => localizedValues['subtotal'][locale.languageCode]; String get shipping => localizedValues['shipping'][locale.languageCode]; String get shipBy => localizedValues['shipBy'][locale.languageCode]; @@ -721,7 +762,8 @@ class TranslationBase { String get use => localizedValues['use'][locale.languageCode]; String get proceedPay => localizedValues['proceedPay'][locale.languageCode]; String get vat => localizedValues['vat'][locale.languageCode]; - String get inclusiveVat => localizedValues['inclusiveVat'][locale.languageCode]; + String get inclusiveVat => + localizedValues['inclusiveVat'][locale.languageCode]; String get items => localizedValues['items'][locale.languageCode]; String get checkOut => localizedValues['checkOut'][locale.languageCode]; String get total => localizedValues['total'][locale.languageCode]; @@ -749,6 +791,7 @@ class TranslationBase { String get loginRegister => localizedValues['LoginRegister'][locale.languageCode]; String get orderLog => localizedValues['OrderLog'][locale.languageCode]; + // String get infoLab => localizedValues['info-lab'][locale.languageCode]; // String get infoRadiology => @@ -756,23 +799,30 @@ class TranslationBase { String get orderDate => localizedValues['orderDate'][locale.languageCode]; String get itemsNo => localizedValues['itemsNo'][locale.languageCode]; String get noOrder => localizedValues['noOrder'][locale.languageCode]; + + String get offersAndPromotions => + localizedValues['offersAndPromotions'][locale.languageCode]; String get review => localizedValues['review'][locale.languageCode]; - String get deliveredOrder => localizedValues['deliveredOrder'][locale.languageCode]; - String get pendingOrder => localizedValues['pendingOrder'][locale.languageCode]; - String get processingOrder => localizedValues['processingOrder'][locale.languageCode]; - String get cancelledOrder => localizedValues['cancelledOrder'][locale.languageCode]; + String get deliveredOrder => + localizedValues['deliveredOrder'][locale.languageCode]; + String get pendingOrder => + localizedValues['pendingOrder'][locale.languageCode]; + String get processingOrder => + localizedValues['processingOrder'][locale.languageCode]; + String get cancelledOrder => + localizedValues['cancelledOrder'][locale.languageCode]; String get compare => localizedValues['compare'][locale.languageCode]; - String get medicationsRefill => localizedValues['medicationsRefill'][locale.languageCode]; - String get myPrescription => localizedValues['myPrescription'][locale.languageCode]; + String get medicationsRefill => + localizedValues['medicationsRefill'][locale.languageCode]; + String get myPrescription => + localizedValues['myPrescription'][locale.languageCode]; String get quantity => localizedValues['quantity'][locale.languageCode]; - String get conditionsHMG => localizedValues['conditionsHMG'][locale.languageCode]; + String get conditionsHMG => + localizedValues['conditionsHMG'][locale.languageCode]; String get conditions => localizedValues['conditions'][locale.languageCode]; // pharmacy module - String get offersAndPromotions => - localizedValues['offersAndPromotions'][locale.languageCode]; - String get searchAndScanMedication => localizedValues['searchAndScanMedication'][locale.languageCode]; String get shopByBrands => @@ -780,6 +830,7 @@ class TranslationBase { String get recentlyViewed => localizedValues['recentlyViewed'][locale.languageCode]; String get bestSellers => localizedValues['bestSellers'][locale.languageCode]; + String get recommended => localizedValues['recommended'][locale.languageCode]; String get deleteAllItems => localizedValues['deleteAllItems'][locale.languageCode]; String get selectAddress => @@ -807,6 +858,9 @@ class TranslationBase { localizedValues['beneficiaryName'][locale.languageCode]; String get accountActivation => localizedValues['accountActivation'][locale.languageCode]; + + String get lakumTransfer => + localizedValues['lakumTransfer'][locale.languageCode]; String get acceptLbl => localizedValues['acceptLbl'][locale.languageCode]; String get termsService => @@ -934,8 +988,11 @@ class TranslationBase { String get average => localizedValues['Average'][locale.languageCode]; String get dailyDoses => localizedValues['DailyDoses'][locale.languageCode]; String get period => localizedValues['Period'][locale.languageCode]; + String get duration => localizedValues['duration'][locale.languageCode]; String get cm => localizedValues['cm'][locale.languageCode]; String get kg => localizedValues['kg'][locale.languageCode]; + String get lb => localizedValues['lb'][locale.languageCode]; + String get birth_date => localizedValues['birth_date'][locale.languageCode]; String get mass => localizedValues['mass'][locale.languageCode]; String get tempC => localizedValues['temp-c'][locale.languageCode]; String get bpm => localizedValues['bpm'][locale.languageCode]; @@ -973,11 +1030,23 @@ class TranslationBase { String get searchItemError => localizedValues['searchItemError'][locale.languageCode]; String get youCanFind => localizedValues['YouCanFind'][locale.languageCode]; - String get itemInSearch => localizedValues['ItemInSearch'][locale.languageCode]; - String get wantToConnectWithHmgNetwork => localizedValues['wantConnectHmgNetwork'][locale.languageCode]; - String get failedToAccessHmgServices => localizedValues['failedToAccessHmgServices'][locale.languageCode]; - String get enablingWifi => localizedValues['enablingWifi'][locale.languageCode]; - String get offerAndPackages => localizedValues['offerAndPackages'][locale.languageCode]; + String get itemInSearch => + localizedValues['ItemInSearch'][locale.languageCode]; + String get bloodDonation => + localizedValues['blood-donation'][locale.languageCode]; + String get bloodInstruction => + localizedValues['blood-instruction'][locale.languageCode]; + String get bloodTermsNcondition => + localizedValues['view-terms'][locale.languageCode]; + String get wantToConnectWithHmgNetwork => + localizedValues['wantConnectHmgNetwork'][locale.languageCode]; + String get failedToAccessHmgServices => + localizedValues['failedToAccessHmgServices'][locale.languageCode]; + String get enablingWifi => + localizedValues['enablingWifi'][locale.languageCode]; + String get offerAndPackages => + localizedValues['offerAndPackages'][locale.languageCode]; + String get invoiceNo => localizedValues['InvoiceNo'][locale.languageCode]; String get specialResult => localizedValues['SpecialResult'][locale.languageCode]; @@ -994,6 +1063,39 @@ class TranslationBase { String get openRad => localizedValues['open-rad'][locale.languageCode]; String get sendCopyRad => localizedValues['send-copy'][locale.languageCode]; String get appoSurvey => localizedValues['appoSurvey'][locale.languageCode]; + String get vaccination => localizedValues['vaccination'][locale.languageCode]; + String get welcomeBackV => + localizedValues['welcomeBack'][locale.languageCode]; + String get instructions => + localizedValues['instructions'][locale.languageCode]; + String get updateEmail => + localizedValues['update-email'][locale.languageCode]; + String get updatedEmail => + localizedValues['updated-email'][locale.languageCode]; + String get viewListChildren => + localizedValues['view-list-children'][locale.languageCode]; + String get addChild => localizedValues['add-child'][locale.languageCode]; + String get childName => localizedValues['child-name'][locale.languageCode]; + String get childDob => localizedValues['childDob'][locale.languageCode]; + String get deletedChildMes => + localizedValues['deleted-child-mes'][locale.languageCode]; + String get visit => localizedValues['visit'][locale.languageCode]; + String get descriptionVaccination => + localizedValues['description-vaccination'][locale.languageCode]; + String get dueDate => localizedValues['due-date'][locale.languageCode]; + String get validEmail => localizedValues['valid-email'][locale.languageCode]; + String get confirmSend => + localizedValues['confirm-send'][locale.languageCode]; + String get emailSuccess => + localizedValues['email-success'][locale.languageCode]; + String get deletedChild => + localizedValues['deleted-child'][locale.languageCode]; + String get addInstructions => + localizedValues['add-instructions'][locale.languageCode]; + String get addedChild => localizedValues['added-child'][locale.languageCode]; + String get appUpdate => localizedValues['appUpdate'][locale.languageCode]; + String get ereferralSaveSuccess => + localizedValues['ereferralSaveSuccess'][locale.languageCode]; String get labResults => localizedValues['labResults'][locale.languageCode]; String get doctorRating => localizedValues['doctorRating'][locale.languageCode]; @@ -1042,7 +1144,7 @@ class TranslationBase { String get selectAmbulate => localizedValues['select-ambulate'][locale.languageCode]; String get wheelchair => localizedValues['wheelchair'][locale.languageCode]; - String get walker => localizedValues['walker"'][locale.languageCode]; + String get walker => localizedValues['walker'][locale.languageCode]; String get stretcher => localizedValues['stretcher'][locale.languageCode]; String get none => localizedValues['none'][locale.languageCode]; String get RRTSummary => localizedValues['RRT-Summary'][locale.languageCode]; @@ -1082,6 +1184,9 @@ class TranslationBase { String get calculators => localizedValues['calculators'][locale.languageCode]; String get converters => localizedValues['converters'][locale.languageCode]; String get h2o => localizedValues['h2o'][locale.languageCode]; + String get waterTracker => + localizedValues['waterTracker'][locale.languageCode]; + String get ft => localizedValues['ft'][locale.languageCode]; String get vTour => localizedValues['v-tour'][locale.languageCode]; String get hmgNews => localizedValues['hmg-news'][locale.languageCode]; String get bloodD => localizedValues['blood-d'][locale.languageCode]; @@ -1109,12 +1214,11 @@ class TranslationBase { String get cardDetail => localizedValues['card-detail'][locale.languageCode]; String get dr => localizedValues['Dr'][locale.languageCode]; String get sendSuc => localizedValues['sendSuc'][locale.languageCode]; - String get instructions => - localizedValues['instructions'][locale.languageCode]; String get instructionsPharmacies => localizedValues['instructions-pharmacies'][locale.languageCode]; String get selectHospitalDec => localizedValues['select-hospital'][locale.languageCode]; + String get start => localizedValues['start'][locale.languageCode]; String get infoChat => localizedValues['info-chat'][locale.languageCode]; @@ -1130,8 +1234,6 @@ class TranslationBase { String get sendConfEmail => localizedValues['send-email'][locale.languageCode]; - String get updateEmail => - localizedValues['update-email'][locale.languageCode]; String get noDataAvailable => localizedValues['noDataAvailable'][locale.languageCode]; String get theName => localizedValues['thename'][locale.languageCode]; @@ -1153,25 +1255,40 @@ class TranslationBase { String get gallery => localizedValues['gallery'][locale.languageCode]; String get camera => localizedValues['camera'][locale.languageCode]; String get medReport => localizedValues['med-report'][locale.languageCode]; - String get newMedReport => localizedValues['new-med-report'][locale.languageCode]; - String get requestReport => localizedValues['requestReport'][locale.languageCode]; - String get confirmMsgReport => localizedValues['confirm-msg-report'][locale.languageCode]; - String get successSendReport => localizedValues['successSendReport'][locale.languageCode]; + String get newMedReport => + localizedValues['new-med-report'][locale.languageCode]; + String get requestReport => + localizedValues['requestReport'][locale.languageCode]; + String get confirmMsgReport => + localizedValues['confirm-msg-report'][locale.languageCode]; + String get successSendReport => + localizedValues['successSendReport'][locale.languageCode]; String get pulseTitle => localizedValues['pulseTitle'][locale.languageCode]; - String get systolicLng => localizedValues['systolic-lng'][locale.languageCode]; - String get diastolicLng => localizedValues['diastolic-lng'][locale.languageCode]; - String get policyHolder => localizedValues['policy-holder'][locale.languageCode]; + String get systolicLng => + localizedValues['systolic-lng'][locale.languageCode]; + String get diastolicLng => + localizedValues['diastolic-lng'][locale.languageCode]; + String get policyHolder => + localizedValues['policy-holder'][locale.languageCode]; String get policyNo => localizedValues['policy-no'][locale.languageCode]; - String get expiryDateTitle => localizedValues['expiry-date'][locale.languageCode]; + String get expiryDateTitle => + localizedValues['expiry-date'][locale.languageCode]; String get classTitle => localizedValues['class'][locale.languageCode]; String get approval => localizedValues['approval'][locale.languageCode]; String get agree => localizedValues['agree'][locale.languageCode]; String get disagree => localizedValues['disagree'][locale.languageCode]; - String get requestSent => localizedValues['request-sent'][locale.languageCode]; - String get attachInsuraceImage => localizedValues['attach-insurace-image'][locale.languageCode]; - String get infoInsurCards => localizedValues['info-insur-cards'][locale.languageCode]; + String get requestSent => + localizedValues['request-sent'][locale.languageCode]; + String get attachInsuraceImage => + localizedValues['attach-insurace-image'][locale.languageCode]; + String get infoInsurCards => + localizedValues['info-insur-cards'][locale.languageCode]; String get scanNow => localizedValues['scan-now'][locale.languageCode]; - String get pharmacyServiceTermsCondition => localizedValues['pharmacyServiceTermsCondition'][locale.languageCode]; + String get pharmacyServiceTermsCondition => + localizedValues['pharmacyServiceTermsCondition'][locale.languageCode]; + + String get recordDeleted => + localizedValues['recordDeleted'][locale.languageCode]; String get referralStatus => localizedValues['referralStatus'][locale.languageCode]; @@ -1199,42 +1316,23 @@ class TranslationBase { localizedValues['processDoneSuccessfully'][locale.languageCode]; String get selectHomeHealthCareServices => localizedValues['selectHomeHealthCareServices'][locale.languageCode]; + String get help => localizedValues['help'][locale.languageCode]; + String get habibRobotText => + localizedValues['habibRobotText'][locale.languageCode]; String get topBrands => localizedValues['topBrands'][locale.languageCode]; String get notifyMe => localizedValues['notifyMe'][locale.languageCode]; - String get specification => localizedValues['specification'][locale.languageCode]; - String get availability => localizedValues['availability'][locale.languageCode]; - String get quantitySize => localizedValues['quantitySize'][locale.languageCode]; + String get specification => + localizedValues['specification'][locale.languageCode]; + String get availability => + localizedValues['availability'][locale.languageCode]; + String get quantitySize => + localizedValues['quantitySize'][locale.languageCode]; String get addToCart => localizedValues['addToCart'][locale.languageCode]; String get buyNow => localizedValues['buyNow'][locale.languageCode]; - String get quantityShortcut => localizedValues['quantityShortcut'][locale.languageCode]; + String get quantityShortcut => + localizedValues['quantityShortcut'][locale.languageCode]; - String get updatedEmail => - localizedValues['updated-email'][locale.languageCode]; - String get viewListChildren => - localizedValues['view-list-children'][locale.languageCode]; - String get addChild => localizedValues['add-child'][locale.languageCode]; - String get childName => localizedValues['child-name'][locale.languageCode]; - String get childDob => localizedValues['childDob'][locale.languageCode]; - String get deletedChildMes => - localizedValues['deleted-child-mes'][locale.languageCode]; - String get visit => localizedValues['visit'][locale.languageCode]; - String get descriptionVaccination => - localizedValues['description-vaccination'][locale.languageCode]; - String get dueDate => localizedValues['due-date'][locale.languageCode]; - String get validEmail => localizedValues['valid-email'][locale.languageCode]; - String get confirmSend => - localizedValues['confirm-send'][locale.languageCode]; - String get emailSuccess => - localizedValues['email-success'][locale.languageCode]; - String get deletedChild => - localizedValues['deleted-child'][locale.languageCode]; - String get addInstructions => - localizedValues['add-instructions'][locale.languageCode]; - String get addedChild => localizedValues['added-child'][locale.languageCode]; - String get appUpdate => localizedValues['appUpdate'][locale.languageCode]; - String get ereferralSaveSuccess => - localizedValues['ereferralSaveSuccess'][locale.languageCode]; String get year => localizedValues['Year'][locale.languageCode]; String get month => localizedValues['Month'][locale.languageCode]; String get point => localizedValues['point'][locale.languageCode]; @@ -1243,8 +1341,270 @@ class TranslationBase { localizedValues['termOfService'][locale.languageCode]; String get shoppingCart => localizedValues['shoppingCart'][locale.languageCode]; - - + String get covidTest => localizedValues['covidTest'][locale.languageCode]; + String get driveThru => localizedValues['driveThru'][locale.languageCode]; + String get NearestErDesc => + localizedValues['NearestErDesc'][locale.languageCode]; + String get NearestEr => localizedValues['NearestEr'][locale.languageCode]; + String get infoCMC => localizedValues['infoCMC'][locale.languageCode]; + String get instructionAgree => + localizedValues['instructionAgree'][locale.languageCode]; + String get reqId => localizedValues['reqId'][locale.languageCode]; + String get ordersLog => + localizedValues['RRT-orders-log'][locale.languageCode]; + String get bloodSugar => localizedValues['blood-sugar'][locale.languageCode]; + String get myTracker => localizedValues['my-tracker'][locale.languageCode]; + String get weekly => localizedValues['weekly'][locale.languageCode]; + String get monthlyT => localizedValues['monthly'][locale.languageCode]; + String get yearly => localizedValues['yearly'][locale.languageCode]; + String get measured => localizedValues['measured'][locale.languageCode]; + String get sugarAdd => localizedValues['sugar-add'][locale.languageCode]; + String get other => localizedValues['other'][locale.languageCode]; + String get measureUnit => + localizedValues['measure-unit'][locale.languageCode]; + String get measureTime => + localizedValues['measure-time'][locale.languageCode]; + String get update => localizedValues['update'][locale.languageCode]; + String get covid19_driveThrueTest => + localizedValues['covid19_driveThrueTest'][locale.languageCode]; + String get eReferral => localizedValues['E-Referral'][locale.languageCode]; + + String get msg_email_address_up_to_date => + localizedValues["msg_email_address_up_to_date"][locale.languageCode]; + String get updateEmailMsg => + localizedValues["update-email-msg"][locale.languageCode]; + + String get addNewChild => + localizedValues["add-new-child"][locale.languageCode]; + String get sendChildEmailMsg => + localizedValues["send-child-email-msg"][locale.languageCode]; + String get vaccinationAddChildMsg => + localizedValues["vaccination-add-child-msg"][locale.languageCode]; + String get childAddedSuccessfully => + localizedValues["child_added_successfully"][locale.languageCode]; + + String get sugar => localizedValues["sugar"][locale.languageCode]; + String get bloodCholesterol => + localizedValues["bloodCholesterol"][locale.languageCode]; + String get cholesterol => localizedValues["cholesterol"][locale.languageCode]; + String get triglycerides => + localizedValues["triglycerides"][locale.languageCode]; + String get fatInBlood => localizedValues["fatInBlood"][locale.languageCode]; + String get calculate => localizedValues["calculate"][locale.languageCode]; + String get enterReadingValue => + localizedValues["enterReadingValue"][locale.languageCode]; + String get convertBloodSugarStatement => + localizedValues["convertBloodSugarStatement"][locale.languageCode]; + String get convertFrom => localizedValues["convertFrom"][locale.languageCode]; + String get result => localizedValues["result"][locale.languageCode]; + String get sort => localizedValues["sort"][locale.languageCode]; + String get bloodSugarConversion => + localizedValues["bloodSugarConversion"][locale.languageCode]; + String get convertCholesterolStatement => + localizedValues["convertCholesterolStatement"][locale.languageCode]; + String get triglyceridesConvertStatement => + localizedValues["triglyceridesConvertStatement"][locale.languageCode]; + String get bloodDEnterDesc => + localizedValues["bloodD-enter-desc"][locale.languageCode]; + String get viewTermsConditions => + localizedValues["viewTermsConditions"][locale.languageCode]; + String get generalHealth => + localizedValues["generalHealth"][locale.languageCode]; + String get womanHealth => localizedValues["womanHealth"][locale.languageCode]; + String get bmi => localizedValues["bmi"][locale.languageCode]; + String get calcHealth => localizedValues["calc-health"][locale.languageCode]; + String get calories => localizedValues["calories"][locale.languageCode]; + String get bmr => localizedValues["bmr"][locale.languageCode]; + String get idealBody => localizedValues["idealBody"][locale.languageCode]; + String get bodyWord => localizedValues["body_word"][locale.languageCode]; + String get fat => localizedValues["fat"][locale.languageCode]; + String get carbohydrate => + localizedValues["carbohydrate"][locale.languageCode]; + String get proteinFat => localizedValues["proteinFat"][locale.languageCode]; + String get ovulation => localizedValues["ovulation"][locale.languageCode]; + String get delivery => localizedValues["delivery"][locale.languageCode]; + String get bmiCalcDesc => localizedValues["bmiCalcDesc"][locale.languageCode]; + String get selectUnit => localizedValues["selectUnit"][locale.languageCode]; + String get feet => localizedValues["feet"][locale.languageCode]; + String get pound => localizedValues["pound"][locale.languageCode]; + String get seeListOfDoctor => + localizedValues["seeListOfDoctor"][locale.languageCode]; + String get obese => localizedValues["obese"][locale.languageCode]; + String get overWeight => localizedValues["overWeight"][locale.languageCode]; + String get healthy => localizedValues["healthy"][locale.languageCode]; + String get underWeight => localizedValues["underWeight"][locale.languageCode]; + String get bmiCalcMsgObese => + localizedValues["bmiCalcMsgObese"][locale.languageCode]; + String get bmiCalcMsgOverweight => + localizedValues["bmiCalcMsgOverweight"][locale.languageCode]; + String get bmiCalcMsgHealthy => + localizedValues["bmiCalcMsgHealthy"][locale.languageCode]; + String get bmiCalcMsgUnderWeight => + localizedValues["bmiCalcMsgUnderWeight"][locale.languageCode]; + String get bariatrics => localizedValues["bariatrics"][locale.languageCode]; + String get bariatricsHeaderMsg => + localizedValues["bariatricsHeaderMsg"][locale.languageCode]; + String get continues => localizedValues["continue"][locale.languageCode]; + String get skip => localizedValues["skip"][locale.languageCode]; + String get calorieCalcDesc => + localizedValues["calorieCalcDesc"][locale.languageCode]; + String get age11_120Years => + localizedValues["age11_120_years"][locale.languageCode]; + String get walkinAppo => localizedValues["WalkinAppo"][locale.languageCode]; + String get videoAppo => localizedValues["videoAppo"][locale.languageCode]; + String get weightAdd => localizedValues["weight-add"][locale.languageCode]; + String get systolicAdd => + localizedValues["systolic-add"][locale.languageCode]; + String get diastolicAdd => + localizedValues["systolic-add"][locale.languageCode]; + String get cmcHeading => localizedValues["cmc-heading"][locale.languageCode]; + String get selectLocation => + localizedValues["select-location"][locale.languageCode]; + String get resultHeader => + localizedValues["result-header"][locale.languageCode]; + String get covidInfo => localizedValues["covid-info"][locale.languageCode]; + String get selectAppo => localizedValues["select-appo"][locale.languageCode]; + String get covidAlertHeader => + localizedValues["covid-alert-header"][locale.languageCode]; + String get covidAlertInfo => + localizedValues["covid-alert-info"][locale.languageCode]; + String get covidAlertMins => + localizedValues["covid-alert-mins"][locale.languageCode]; + String get back => localizedValues["back"][locale.languageCode]; + String get getDirections => + localizedValues["get-directions"][locale.languageCode]; + String get selectedLocation => + localizedValues["selected-location"][locale.languageCode]; + String get testFee => localizedValues["test-fee"][locale.languageCode]; + String get payOptions => localizedValues["pay-options"][locale.languageCode]; + String get livecareService => + localizedValues["livecare-service"][locale.languageCode]; + String get livecareServiceDesc => + localizedValues["livecare-service-desc"][locale.languageCode]; + String get whyLivecare => + localizedValues["why-livecare"][locale.languageCode]; + String get livecarePoint1 => + localizedValues["livecare-point-1"][locale.languageCode]; + String get docVirtualAppoIns4 => + localizedValues["doc-virtual-appo-ins4"][locale.languageCode]; + String get docVirtualAppoIns5 => + localizedValues["doc-virtual-appo-ins5"][locale.languageCode]; + String get livecareSummary => + localizedValues["livecare-summary"][locale.languageCode]; + + String get livecareOption1 => + localizedValues["livecare-option-1"][locale.languageCode]; + String get livecareOption2 => + localizedValues["livecare-option-2"][locale.languageCode]; + String get livecareOption3 => + localizedValues["livecare-option-3"][locale.languageCode]; + String get livecareOption4 => + localizedValues["livecare-option-4"][locale.languageCode]; + + String get today => localizedValues["today"][locale.languageCode]; + String get week => localizedValues["week"][locale.languageCode]; + String get h2oAmountOfWater => + localizedValues["h2o-amount-of-water"][locale.languageCode]; + String get updateUser => localizedValues["update-user"][locale.languageCode]; + String get editname => localizedValues["editname"][locale.languageCode]; + String get activityLevel => + localizedValues["activity-level"][locale.languageCode]; + String get success => localizedValues["success"][locale.languageCode]; + String get enterNameHere => + localizedValues["enterNameHere"][locale.languageCode]; + String get lightActive => + localizedValues["light-active"][locale.languageCode]; + String get modActive => localizedValues["mod-active"][locale.languageCode]; + String get reminderLabel => + localizedValues["reminder-label"][locale.languageCode]; + String get reminderTimesLabel => + localizedValues["reminder-times-label"][locale.languageCode]; + String get times => localizedValues["times"][locale.languageCode]; + String get WaterCalculate => + localizedValues["WaterCalculate"][locale.languageCode]; + String get notifTitle => localizedValues["notif-title"][locale.languageCode]; + String get notifText => localizedValues["notif-text"][locale.languageCode]; + String get custom => localizedValues["custom"][locale.languageCode]; + String get undo => localizedValues["undo"][locale.languageCode]; + String get drinking => localizedValues["drinking"][locale.languageCode]; + String get remaining => localizedValues["remaining"][locale.languageCode]; + String get taken => localizedValues["taken"][locale.languageCode]; + String get ml => localizedValues["ml"][locale.languageCode]; + String get l => localizedValues["l"][locale.languageCode]; + String get customLabel => + localizedValues["custom-label"][locale.languageCode]; + + String get customLabelInLitres => + localizedValues["custom-label-in-litres"][locale.languageCode]; + String get customLabelInMililitres => + localizedValues["custom-label-in-mililitres"][locale.languageCode]; + String get amount_ => localizedValues["amount"][locale.languageCode]; + String get targetReach => + localizedValues["target-reach"][locale.languageCode]; + String get weekHeader => localizedValues["week-header"][locale.languageCode]; + String get monthHeader => + localizedValues["month-header"][locale.languageCode]; + String get notifPermissionTitle => + localizedValues["notif-permission-title"][locale.languageCode]; + String get notifPermissionMsg => + localizedValues["notif-permission-msg"][locale.languageCode]; + String get verification_message_code => + localizedValues["verification_message_code"][locale.languageCode]; + String get sms_code => localizedValues["sms_code"][locale.languageCode]; + String get code_failure => + localizedValues["code_failure"][locale.languageCode]; + String get resend => localizedValues["resend"][locale.languageCode]; + String get submitncontinue => + localizedValues["submitncontinue"][locale.languageCode]; + String get areyousure => localizedValues["areyousure"][locale.languageCode]; + + + // Offer And Packahes + String get subT=> localizedValues['OffersAndPackages'][locale.languageCode]; + String get totalWithColonRight => localizedValues['totalWithColonRight'][locale.languageCode]; + + String get preferredunit => + localizedValues["preferredunit"][locale.languageCode]; + String get trySaying => localizedValues["try-saying"][locale.languageCode]; + String get enterIdentificationNumber => + localizedValues["enterIdentificationNumber"][locale.languageCode]; + String get accountActivationDesc => + localizedValues["accountActivationDesc"][locale.languageCode]; + String get pointsToTransfer => + localizedValues["pointsToTransfer"][locale.languageCode]; + String get enterBeneficiaryAccountNo => + localizedValues["enterBeneficiaryAccountNo"][locale.languageCode]; + String get confirmPrescription => + localizedValues["confirm-prescription"][locale.languageCode]; + String get youAlreadyHaveOrder => + localizedValues["you-already-have-order"][locale.languageCode]; + String get orderOverview => + localizedValues["order-overview"][locale.languageCode]; + String get shippingAddresss => + localizedValues["shipping-address"][locale.languageCode]; + String get covidAlert => localizedValues["covid-alert"][locale.languageCode]; + String get pharmacyRelogin => + localizedValues["pharmacy-relogin"][locale.languageCode]; + String get onlineCheckInAgreement => + localizedValues["onlineCheckInAgreement"][locale.languageCode]; + String get chiefComplaints => + localizedValues["chiefComplaints"][locale.languageCode]; + String get errorChiefComplaints => + localizedValues["errorChiefComplaints"][locale.languageCode]; + String get expectedArrivalTime => + localizedValues["expectedArrivalTime"][locale.languageCode]; + String get errorExpectedArrivalTime => + localizedValues["errorExpectedArrivalTimes"][locale.languageCode]; + String get anicllaryOrders => + localizedValues["ancillary-orders"][locale.languageCode]; + String get mrn => localizedValues["MRN"][locale.languageCode]; + String get appointmentDate => + localizedValues["appointment-date"][locale.languageCode]; + String get appointmentNo => + localizedValues["appointment-no"][locale.languageCode]; + String get insuranceID => + localizedValues["insurance-id"][locale.languageCode]; + String get enterFile => localizedValues["enter-file"][locale.languageCode]; } class TranslationBaseDelegate extends LocalizationsDelegate { diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index 58ef9421..67e5c6b9 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -1,11 +1,14 @@ import 'dart:convert'; import 'dart:core'; +import 'dart:io'; import 'dart:typed_data'; import 'package:badges/badges.dart'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:connectivity/connectivity.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/viewModels/project_view_model.dart'; -import 'package:diplomaticquarterapp/pages/Blood/my_balance_page.dart'; +import 'package:diplomaticquarterapp/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_card_screen.dart'; @@ -13,6 +16,7 @@ import 'package:diplomaticquarterapp/pages/insurance/insurance_update_screen.dar import 'package:diplomaticquarterapp/pages/medical/active_medications/ActiveMedicationsPage.dart'; import 'package:diplomaticquarterapp/pages/medical/allergies_page.dart'; import 'package:diplomaticquarterapp/pages/medical/ask_doctor/ask_doctor_home_page.dart'; +import 'package:diplomaticquarterapp/pages/medical/balance/my_balance_page.dart'; import 'package:diplomaticquarterapp/pages/medical/doctor/doctor_home_page.dart'; import 'package:diplomaticquarterapp/pages/medical/eye/EyeMeasurementsPage.dart'; import 'package:diplomaticquarterapp/pages/medical/labs/labs_home_page.dart'; @@ -26,15 +30,19 @@ import 'package:diplomaticquarterapp/pages/medical/reports/report_home_page.dart import 'package:diplomaticquarterapp/pages/medical/smart_watch_health_data/smart_watch_instructions.dart'; import 'package:diplomaticquarterapp/pages/medical/vital_sign/vital_sign_details_screen.dart'; import 'package:diplomaticquarterapp/pages/vaccine/my_vaccines_screen.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/data_display/medical/medical_profile_item.dart'; +import 'package:diplomaticquarterapp/widgets/dialogs/alert_dialog.dart'; import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; - +import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../Constants.dart'; import 'app_shared_preferences.dart'; import 'app_toast.dart'; +import 'gif_loader_dialog_utils.dart'; AppSharedPreferences sharedPref = new AppSharedPreferences(); @@ -177,6 +185,14 @@ class Utils { // } } + static getPhoneNumberWithoutZero(String number) { + String newNumber = ""; + if (number.startsWith('0')) { + newNumber = number.substring(1); + } + return newNumber; + } + static Uint8List dataFromBase64String(String base64String) { return base64Decode(base64String); } @@ -187,7 +203,11 @@ class Utils { .hasMatch(email); } - static List myMedicalList({ProjectViewModel projectViewModel, BuildContext context, bool isLogin, count}) { + static List myMedicalList( + {ProjectViewModel projectViewModel, + BuildContext context, + bool isLogin, + count}) { List medical = List(); if (projectViewModel.havePrivilege(5)) { medical.add(InkWell( @@ -200,33 +220,30 @@ class Utils { ); }, child: isLogin - ? Container( - height: 120, - child: Stack(children: [ - MedicalProfileItem( - title: TranslationBase.of(context).myAppointments, - imagePath: 'my_appointment_icon.png', - subTitle: TranslationBase.of(context).myAppointmentsList, - hasBadge: true, - ), - Positioned( - right: 0.0, - child: Badge( - toAnimate: false, - position: BadgePosition.topEnd(), - shape: BadgeShape.circle, - badgeColor: secondaryColor.withOpacity(1.0), - borderRadius: BorderRadius.circular(8), - badgeContent: Container( - padding: EdgeInsets.all(2.0), - child: Text(count.toString(), - style: - TextStyle(color: Colors.white, fontSize: 16.0)), - ), + ? Stack(children: [ + MedicalProfileItem( + title: TranslationBase.of(context).myAppointments, + imagePath: 'my_appointment_icon.png', + subTitle: TranslationBase.of(context).myAppointmentsList, + hasBadge: true, + ), + Positioned( + right: 0.0, + child: Badge( + toAnimate: false, + position: BadgePosition.topEnd(), + shape: BadgeShape.circle, + badgeColor: secondaryColor.withOpacity(1.0), + borderRadius: BorderRadius.circular(8), + badgeContent: Container( + padding: EdgeInsets.all(2.0), + child: Text(count.toString(), + style: + TextStyle(color: Colors.white, fontSize: 16.0)), ), ), - ]), - ) + ), + ]) : MedicalProfileItem( title: TranslationBase.of(context).myAppointments, imagePath: 'my_appointment_icon.png', @@ -394,16 +411,16 @@ class Utils { )); } if (projectViewModel.havePrivilege(20)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: HomeReportPage())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).medical, - imagePath: 'medical_reports_icon.png', - subTitle: TranslationBase.of(context).medicalSubtitle, - ), - )); + medical.add(InkWell( + onTap: () { + Navigator.push(context, FadePage(page: HomeReportPage())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).medical, + imagePath: 'medical_reports_icon.png', + subTitle: TranslationBase.of(context).medicalSubtitle, + ), + )); if (projectViewModel.havePrivilege(19)) { medical.add(InkWell( @@ -465,16 +482,16 @@ class Utils { )); } if (projectViewModel.havePrivilege(30)) - medical.add(InkWell( - onTap: () { - Navigator.push(context, FadePage(page: SmartWatchInstructions())); - }, - child: MedicalProfileItem( - title: TranslationBase.of(context).smartWatches, - imagePath: 'smartwatch_icon.png', - subTitle: TranslationBase.of(context).smartWatchesSubtitle, - ), - )); + medical.add(InkWell( + onTap: () { + Navigator.push(context, FadePage(page: SmartWatchInstructions())); + }, + child: MedicalProfileItem( + title: TranslationBase.of(context).smartWatches, + imagePath: 'smartwatch_icon.png', + subTitle: TranslationBase.of(context).smartWatchesSubtitle, + ), + )); if (projectViewModel.havePrivilege(28)) { medical.add(InkWell( @@ -488,13 +505,29 @@ class Utils { ), )); } - if (projectViewModel.havePrivilege(32)) { + if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( - //TODO -// onTap: () { -// Navigator.push( -// context, FadePage(page: DoctorHomePage())); -// }, + onTap: () { + userData().then((userData_) { + if (projectViewModel.isLogin && userData_ != null) { + String patientID = userData_.patientID.toString(); + GifLoaderDialogUtils.showMyDialog(context); + projectViewModel + .platformBridge() + .connectHMGInternetWifi(patientID) + .then((value) => {GifLoaderDialogUtils.hideDialog(context)}); + } else { + AlertDialogBox( + context: context, + confirmMessage: + "Please login with your account first to use this feature", + okText: "OK", + okFunction: () { + AlertDialogBox.closeAlertDialog(context); + }).showAlertDialog(context); + } + }); + }, child: MedicalProfileItem( title: TranslationBase.of(context).internet, imagePath: 'insurance_card_icon.png', @@ -505,10 +538,9 @@ class Utils { if (projectViewModel.havePrivilege(40)) { medical.add(InkWell( -// onTap: () { -// Navigator.push( -// context, FadePage(page: InsuranceApproval())); -// }, + onTap: () { + launch('whatsapp://send?phone=18885521858&text='); + }, child: MedicalProfileItem( title: TranslationBase.of(context).chatbot, imagePath: 'insurance_approvals_icon.png', @@ -519,6 +551,48 @@ class Utils { return medical; } + + static Widget loadNetworkImage({@required String url, BoxFit fitting = BoxFit.cover}){ + return CachedNetworkImage( + placeholderFadeInDuration: Duration(milliseconds: 250), + fit: fitting, + imageUrl: url, + placeholder: (context, url) => Container( + child: Center( + child: CircularProgressIndicator() + ) + ), + errorWidget: (context, url, error){ + return Icon(Icons.error, color: Colors.red, size: 50,); + } + ); + } +} + + + + +Widget applyShadow({ Color color = Colors.grey, double shadowOpacity = 0.5, double spreadRadius = 2, double blurRadius = 7, Offset offset = const Offset(2, 2), @required Widget child}){ + return Container( + decoration: BoxDecoration( + boxShadow: [ + BoxShadow( + color: color.withOpacity(shadowOpacity), + spreadRadius: spreadRadius, + blurRadius: blurRadius, + offset: offset, // changes position of shadow + ), + ], + ), + child: child, + ); +} + + +Future userData() async { + var userData = AuthenticatedUser.fromJson( + await AppSharedPreferences().getObject(MAIN_USER)); + return userData; } // extension function that use in iterations(list.. etc) to iterate items and get index and item it self @@ -528,6 +602,20 @@ extension IndexedIterable on Iterable { return map((e) => f(e, i++)); } } + +openAppStore({String androidPackageName, String iOSAppID}) async{ + if(Platform.isAndroid){ + assert(!(androidPackageName == null), "Should have valid value in androidPackageName parameter"); + if((await FlutterHmsGmsAvailability.isGmsAvailable)) + launch("market://details?id=com.ejada.hmg"); + if((await FlutterHmsGmsAvailability.isHmsAvailable)) + launch("appmarket://details?id=com.ejada.hmg"); + + }else if(Platform.isIOS){ + assert((iOSAppID == null), "Should have valid value in iOSAppID parameter"); + launch("https://itunes.apple.com/kr/app/apple-store/$iOSAppID)"); + } +} /* userBoard.asMap().map((i, element) => MapEntry(i, Stack( GestureDetector(onTap: () { diff --git a/lib/widgets/AnimatedTextFields.dart b/lib/widgets/AnimatedTextFields.dart new file mode 100644 index 00000000..b4ad5f65 --- /dev/null +++ b/lib/widgets/AnimatedTextFields.dart @@ -0,0 +1,347 @@ +import 'dart:math'; + +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +enum TextFieldInertiaDirection { + left, + right, +} + +Interval _getInternalInterval( + double start, + double end, + double externalStart, + double externalEnd, [ + Curve curve = Curves.linear, + ]) { + return Interval( + start + (end - start) * externalStart, + start + (end - start) * externalEnd, + curve: curve, + ); +} + +class AnimatedTextFormField extends StatefulWidget { + AnimatedTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.width, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.prefixIcon, + this.suffixIcon, + this.keyboardType, + this.textInputAction, + this.obscureText = false, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double width; + final bool enabled; + final String labelText; + final Widget prefixIcon; + final Widget suffixIcon; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final bool obscureText; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedTextFormFieldState createState() => _AnimatedTextFormFieldState(); +} + +class _AnimatedTextFormFieldState extends State { + Animation scaleAnimation; + Animation sizeAnimation; + Animation suffixIconOpacityAnimation; + + Animation fieldTranslateAnimation; + Animation iconRotationAnimation; + Animation iconTranslateAnimation; + + @override + void initState() { + super.initState(); + + widget.inertiaController?.addStatusListener(handleAnimationStatus); + + final interval = widget.interval; + final loadingController = widget.loadingController; + + if (loadingController != null) { + scaleAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + 0, .2, interval.begin, interval.end, Curves.easeOutBack), + )); + suffixIconOpacityAnimation = + Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval(.65, 1.0, interval.begin, interval.end), + )); + _updateSizeAnimation(); + } + + final inertiaController = widget.inertiaController; + final inertiaDirection = widget.inertiaDirection; + final sign = inertiaDirection == TextFieldInertiaDirection.right ? 1 : -1; + + if (inertiaController != null) { + fieldTranslateAnimation = Tween( + begin: 0.0, + end: sign * 15.0, + ).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(0, .5, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconRotationAnimation = + Tween(begin: 0.0, end: sign * pi / 12 /* ~15deg */) + .animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconTranslateAnimation = + Tween(begin: 0.0, end: 8.0).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + } + } + + void _updateSizeAnimation() { + final interval = widget.interval; + final loadingController = widget.loadingController; + + sizeAnimation = Tween( + begin: 48.0, + end: widget.width, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + .2, 1.0, interval.begin, interval.end, Curves.linearToEaseOut), + reverseCurve: Curves.easeInExpo, + )); + } + + @override + void didUpdateWidget(AnimatedTextFormField oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.width != widget.width) { + _updateSizeAnimation(); + } + } + + @override + dispose() { + widget.inertiaController?.removeStatusListener(handleAnimationStatus); + super.dispose(); + } + + void handleAnimationStatus(status) { + if (status == AnimationStatus.completed) { + widget.inertiaController?.reverse(); + } + } + + Widget _buildInertiaAnimation(Widget child) { + if (widget.inertiaController == null) { + return child; + } + + return AnimatedBuilder( + animation: iconTranslateAnimation, + builder: (context, child) => Transform( + alignment: Alignment.center, + transform: Matrix4.identity() + ..translate(iconTranslateAnimation.value) + ..rotateZ(iconRotationAnimation.value), + child: child, + ), + child: child, + ); + } + + InputDecoration _getInputDecoration(ThemeData theme) { + return InputDecoration( + contentPadding: EdgeInsets.fromLTRB(0, 0, 0, 0), + border: OutlineInputBorder( + borderRadius: new BorderRadius.circular(10.0), + borderSide: new BorderSide(), + ), + labelText: widget.labelText, + prefixIcon: _buildInertiaAnimation(widget.prefixIcon), + suffixIcon: _buildInertiaAnimation(widget.loadingController != null + ? FadeTransition( + opacity: suffixIconOpacityAnimation, + child: widget.suffixIcon, + ) + : widget.suffixIcon), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + Widget textField = TextFormField( + controller: widget.controller, + focusNode: widget.focusNode, + decoration: _getInputDecoration(theme), + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + obscureText: widget.obscureText, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + validator: widget.validator, + enabled: widget.enabled, + ); + + if (widget.loadingController != null) { + textField = ScaleTransition( + scale: scaleAnimation, + child: AnimatedBuilder( + animation: sizeAnimation, + builder: (context, child) => ConstrainedBox( + constraints: BoxConstraints.tightFor(width: sizeAnimation.value), + child: child, + ), + child: textField, + ), + ); + } + + if (widget.inertiaController != null) { + textField = AnimatedBuilder( + animation: fieldTranslateAnimation, + builder: (context, child) => Transform.translate( + offset: Offset(fieldTranslateAnimation.value, 0), + child: child, + ), + child: textField, + ); + } + + return textField; + } +} + +class AnimatedPasswordTextFormField extends StatefulWidget { + AnimatedPasswordTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.animatedWidth, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.keyboardType, + this.textInputAction, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double animatedWidth; + final bool enabled; + final String labelText; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedPasswordTextFormFieldState createState() => + _AnimatedPasswordTextFormFieldState(); +} + +class _AnimatedPasswordTextFormFieldState + extends State { + var _obscureText = true; + + @override + Widget build(BuildContext context) { + return AnimatedTextFormField( + interval: widget.interval, + loadingController: widget.loadingController, + inertiaController: widget.inertiaController, + width: widget.animatedWidth, + enabled: widget.enabled, + labelText: widget.labelText, + prefixIcon: Icon(Icons.lock, size: 20), + suffixIcon: GestureDetector( + onTap: () => setState(() => _obscureText = !_obscureText), + dragStartBehavior: DragStartBehavior.down, + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 250), + firstCurve: Curves.easeInOutSine, + secondCurve: Curves.easeInOutSine, + alignment: Alignment.center, + layoutBuilder: (Widget topChild, _, Widget bottomChild, __) { + return Stack( + alignment: Alignment.center, + children: [bottomChild, topChild], + ); + }, + firstChild: Icon( + Icons.visibility, + size: 25.0, + semanticLabel: 'show password', + ), + secondChild: Icon( + Icons.visibility_off, + size: 25.0, + semanticLabel: 'hide password', + ), + crossFadeState: _obscureText + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + ), + ), + obscureText: _obscureText, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + controller: widget.controller, + focusNode: widget.focusNode, + validator: widget.validator, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + inertiaDirection: widget.inertiaDirection, + ); + } +} \ No newline at end of file diff --git a/lib/widgets/CounterView.dart b/lib/widgets/CounterView.dart new file mode 100644 index 00000000..6ba77c15 --- /dev/null +++ b/lib/widgets/CounterView.dart @@ -0,0 +1,188 @@ +import 'package:flutter/material.dart'; + +typedef StepperCallbackFuture = Future Function(int apply, int total); + +class StepperView extends StatefulWidget { + final double height; + final Color foregroundColor; + final Color backgroundColor; + final double buttonPadding; + + final int initialNumber; + final int maxNumber; + final int minNumber; + final StepperCallbackFuture counterCallback; + final Function increaseCallback; + final Function decreaseCallback; + + StepperView({this.initialNumber = 1, this.minNumber = 1, this.maxNumber, @required this.counterCallback, this.increaseCallback, this.decreaseCallback, this.height = 25, @required this.foregroundColor, @required this.backgroundColor, this.buttonPadding = 1}){ + assert((this.initialNumber >= this.minNumber && this.initialNumber <= this.maxNumber)); + } + @override + _StepperViewState createState() => _StepperViewState(); +} + +class _StepperViewState extends State { + int _currentCount; + StepperCallbackFuture _counterCallback; + Function _increaseCallback; + Function _decreaseCallback; + + @override + void initState() { + _currentCount = widget.initialNumber ?? 1; + _counterCallback = widget.counterCallback; + _increaseCallback = widget.increaseCallback ?? () {}; + _decreaseCallback = widget.decreaseCallback ?? () {}; + super.initState(); + } + + bool loadingInc = false; + bool loadingDec = false; + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(widget.buttonPadding), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular((widget.height/2) + (widget.buttonPadding*2)), + color: widget.backgroundColor, + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + _createDecrementButton( + (_currentCount > widget.minNumber) ? () => _decrement() : null, + ), + Container( + width: 25, + child: Center( + child: Text( + _currentCount.toString(), + style: TextStyle( + fontSize: 12, + fontWeight: FontWeight.normal, + height: 1.5, + color: Colors.black, + ) + ), + ) + ), + _createIncrementButton( + (_currentCount < widget.maxNumber) ? () => _increment() : null + ), + ], + ), + ); + } + + void _increment() async{ + doInc({@required bool can}){ + if(can) + setState(() { + _currentCount++; + _increaseCallback(); + }); + } + + if (_currentCount < widget.maxNumber){ + if(_counterCallback == null) + doInc(can: true); + else { + setState(() => loadingInc = true); + var result = (await _counterCallback(1,_currentCount)); + doInc(can: result); + setState(() => loadingInc = false); + } + } + } + + void _decrement() async{ + doDec({@required bool can}){ + if(can) + setState(() { + _currentCount--; + _decreaseCallback(); + }); + } + if (_currentCount > widget.minNumber) { + if(_counterCallback == null) + doDec(can: true); + else { + setState(() => loadingDec = true); + var result = (await _counterCallback(-1,_currentCount)); + doDec(can: result); + setState(() => loadingDec = false); + } + } + } + + Widget _createIncrementButton(Function onPressed,) { + return Stack( + children: [ + RawMaterialButton( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + constraints: BoxConstraints(minWidth: widget.height, minHeight: widget.height), + onPressed: onPressed, + elevation: 2.0, + fillColor: widget.foregroundColor, + child: + Icon( + Icons.add, + color: (_currentCount < widget.maxNumber) ? Colors.grey[700] : Colors.grey[400], + size: 12.0, + ), + shape: CircleBorder(), + ), + + if(loadingInc) + Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.8), + borderRadius: BorderRadius.circular(widget.height/2), + ), + height: widget.height, + width: widget.height, + child: CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(Colors.green) + ) + ) + ], + ); + } + + Widget _createDecrementButton(Function onPressed) { + return Stack( + children: [ + RawMaterialButton( + materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, + constraints: BoxConstraints(minWidth: widget.height, minHeight: widget.height), + onPressed: onPressed, + elevation: 2.0, + fillColor: widget.foregroundColor, + child: Icon( + Icons.remove, + color: (_currentCount > widget.minNumber) ? Colors.grey[700] : Colors.grey[400], + size: 12.0, + ), + shape: CircleBorder(), + ), + + if(loadingDec) + Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.8), + borderRadius: BorderRadius.circular(widget.height/2), + ), + height: widget.height, + width: widget.height, + child: CircularProgressIndicator( + strokeWidth: 3, + valueColor: AlwaysStoppedAnimation(Colors.red) + ) + ) + ], + ); + } +} diff --git a/lib/widgets/LoadingButton.dart b/lib/widgets/LoadingButton.dart new file mode 100644 index 00000000..46983903 --- /dev/null +++ b/lib/widgets/LoadingButton.dart @@ -0,0 +1,463 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'dart:math'; + +import 'data_display/text.dart'; + +class AnimatedButton extends StatefulWidget { + AnimatedButton({ + Key key, + @required this.text, + @required this.onPressed, + @required this.controller, + this.textColor, + this.loadingColor, + this.color, + }) : super(key: key); + + final String text; + final Color color; + final Color textColor; + final Color loadingColor; + final Function onPressed; + final AnimationController controller; + + @override + _AnimatedButtonState createState() => _AnimatedButtonState(); +} + +class _AnimatedButtonState extends State + with SingleTickerProviderStateMixin { + Animation _sizeAnimation; + Animation _textOpacityAnimation; + Animation _buttonOpacityAnimation; + Animation _ringThicknessAnimation; + Animation _ringOpacityAnimation; + Animation _colorAnimation; + var _isLoading = false; + var _hover = false; + var _width = 120.0; + + Color _color; + Color _loadingColor; + + static const _height = 40.0; + static const _loadingCircleRadius = _height / 2; + static const _loadingCircleThickness = 4.0; + + @override + void initState() { + super.initState(); + + _textOpacityAnimation = Tween(begin: 1.0, end: 0.0).animate( + CurvedAnimation( + parent: widget.controller, + curve: Interval(0.0, .25), + ), + ); + + // _colorAnimation + // _width, _sizeAnimation + + _buttonOpacityAnimation = + Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( + parent: widget.controller, + curve: Threshold(.65), + )); + + _ringThicknessAnimation = + Tween(begin: _loadingCircleRadius, end: _loadingCircleThickness) + .animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(.65, .85), + )); + _ringOpacityAnimation = + Tween(begin: 1.0, end: 0.0).animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(.85, 1.0), + )); + + widget.controller.addStatusListener(handleStatusChanged); + } + + @override + void didChangeDependencies() { + _updateColorAnimation(); + _updateWidth(); + super.didChangeDependencies(); + } + + void _updateColorAnimation() { + final theme = Theme.of(context); + final buttonTheme = theme.floatingActionButtonTheme; + + _color = widget.color ?? buttonTheme.backgroundColor; + _loadingColor = widget.loadingColor ?? theme.accentColor; + + _colorAnimation = ColorTween( + begin: _color, + end: _loadingColor, + ).animate( + CurvedAnimation( + parent: widget.controller, + curve: const Interval(0.0, .65, curve: Curves.fastOutSlowIn), + ), + ); + } + + @override + void didUpdateWidget(AnimatedButton oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.color != widget.color || + oldWidget.loadingColor != widget.loadingColor) { + _updateColorAnimation(); + } + + if (oldWidget.text != widget.text) { + _updateWidth(); + } + } + + @override + void dispose() { + super.dispose(); + widget.controller.removeStatusListener(handleStatusChanged); + } + + void handleStatusChanged(status) { + if (status == AnimationStatus.forward) { + setState(() => _isLoading = true); + } + if (status == AnimationStatus.dismissed) { + setState(() => _isLoading = false); + } + } + + /// sets width and size animation + void _updateWidth() { + final theme = Theme.of(context); + final fontSize = theme.textTheme.button.fontSize; + final renderParagraph = RenderParagraph( + TextSpan( + text: widget.text, + style: TextStyle( + fontSize: fontSize, + fontWeight: theme.textTheme.button.fontWeight, + letterSpacing: theme.textTheme.button.letterSpacing, + ), + ), + textDirection: TextDirection.ltr, + maxLines: 1, + ); + + renderParagraph.layout(BoxConstraints(minWidth: 120.0)); + + // text width based on fontSize, plus 45.0 for padding + var textWidth = + renderParagraph.getMinIntrinsicWidth(fontSize).ceilToDouble() + 45.0; + + // button width is min 120.0 and max 240.0 + _width = textWidth > 120.0 && textWidth < 240.0 + ? textWidth + : textWidth >= 240.0 ? 240.0 : 120.0; + + _sizeAnimation = Tween(begin: 1.0, end: _height / _width) + .animate(CurvedAnimation( + parent: widget.controller, + curve: Interval(0.0, .65, curve: Curves.fastOutSlowIn), + )); + } + + Widget _buildButtonText(ThemeData theme) { + return FadeTransition( + opacity: _textOpacityAnimation, + child: AnimatedText( + text: widget.text, + style: TextStyle(color: widget.textColor ?? Colors.white), + ), + ); + } + + Widget _buildButton(ThemeData theme) { + final buttonTheme = theme.floatingActionButtonTheme; + + return FadeTransition( + opacity: _buttonOpacityAnimation, + child: AnimatedContainer( + duration: Duration(milliseconds: 300), + child: AnimatedBuilder( + animation: _colorAnimation, + builder: (context, child) => Material( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(_height/2) + ), + color: _colorAnimation.value, + child: child, + shadowColor: _color, + elevation: !_isLoading + ? (_hover ? buttonTheme.highlightElevation : buttonTheme.elevation) + : 0, + ), + child: InkWell( + onTap: !_isLoading ? widget.onPressed : null, + splashColor: buttonTheme.splashColor, + customBorder: buttonTheme.shape, + onHighlightChanged: (value) => setState(() => _hover = value), + child: SizeTransition( + sizeFactor: _sizeAnimation, + axis: Axis.horizontal, + child: Container( + width: _width, + height: _height, + alignment: Alignment.center, + child: _buildButtonText(theme), + ), + ), + ), + ), + ), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + + return Stack( + alignment: Alignment.center, + children: [ + FadeTransition( + opacity: _ringOpacityAnimation, + child: AnimatedBuilder( + animation: _ringThicknessAnimation, + builder: (context, child) => Ring( + color: widget.loadingColor, + size: _height, + thickness: _ringThicknessAnimation.value, + ), + ), + ), + if (_isLoading) + SizedBox( + width: _height - _loadingCircleThickness, + height: _height - _loadingCircleThickness, + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(widget.loadingColor), + // backgroundColor: Colors.red, + strokeWidth: _loadingCircleThickness, + ), + ), + _buildButton(theme), + ], + ); + } +} + +class Ring extends StatelessWidget { + Ring({ + Key key, + this.color, + this.size = 40.0, + this.thickness = 2.0, + this.value = 1.0, + }) : assert(size - thickness > 0), + assert(thickness >= 0), + super(key: key); + + final Color color; + final double size; + final double thickness; + final double value; + + @override + Widget build(BuildContext context) { + return SizedBox( + width: size - thickness, + height: size - thickness, + child: thickness == 0 + ? null + : CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(color), + strokeWidth: thickness, + value: value, + ), + ); + } +} + + +enum AnimatedTextRotation { up, down } + +/// https://medium.com/flutter-community/flutter-challenge-3d-bottom-navigation-bar-48952a5fd996 +class AnimatedText extends StatefulWidget { + AnimatedText({ + Key key, + @required this.text, + this.style, + this.textRotation = AnimatedTextRotation.up, + }) : super(key: key); + + final String text; + final TextStyle style; + final AnimatedTextRotation textRotation; + + @override + _AnimatedTextState createState() => _AnimatedTextState(); +} + +class _AnimatedTextState extends State + with SingleTickerProviderStateMixin { + var _newText = ''; + var _oldText = ''; + var _layoutHeight = 0.0; + final _textKey = GlobalKey(); + + Animation _animation; + AnimationController _controller; + + double get radius => _layoutHeight / 2; + + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 500), + ); + + _animation = Tween(begin: 0.0, end: pi / 2).animate(CurvedAnimation( + parent: _controller, + curve: Curves.easeOutBack, + )); + + _oldText = widget.text; + + WidgetsBinding.instance.addPostFrameCallback((_) { + setState(() => _layoutHeight = getWidgetSize(_textKey)?.height); + }); + } + + @override + void didUpdateWidget(AnimatedText oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.text != oldWidget.text) { + _oldText = oldWidget.text; + _newText = widget.text; + _controller.forward().then((_) { + setState(() { + final t = _oldText; + _oldText = _newText; + _newText = t; + }); + _controller.reset(); + }); + } + } + + @override + void dispose() { + super.dispose(); + _controller.dispose(); + } + + Matrix4 get _matrix { + // Fix: The text is not centered after applying perspective effect in the web build. Idk why + if (kIsWeb) { + return Matrix4.identity(); + } + return Matrix4.identity()..setEntry(3, 2, .006); + } + + Matrix4 _getFrontSideUp(double value) { + return _matrix + ..translate( + 0.0, + -radius * sin(_animation.value), + -radius * cos(_animation.value), + ) + ..rotateX(-_animation.value); // 0 -> -pi/2 + } + + Matrix4 _getBackSideUp(double value) { + return _matrix + ..translate( + 0.0, + radius * cos(_animation.value), + -radius * sin(_animation.value), + ) + ..rotateX((pi / 2) - _animation.value); // pi/2 -> 0 + } + + Matrix4 _getFrontSideDown(double value) { + return _matrix + ..translate( + 0.0, + radius * sin(_animation.value), + -radius * cos(_animation.value), + ) + ..rotateX(_animation.value); // 0 -> pi/2 + } + + Matrix4 _getBackSideDown(double value) { + return _matrix + ..translate( + 0.0, + -radius * cos(_animation.value), + -radius * sin(_animation.value), + ) + ..rotateX(_animation.value - pi / 2); // -pi/2 -> 0 + } + + @override + Widget build(BuildContext context) { + final rollUp = widget.textRotation == AnimatedTextRotation.up; + final oldText = Text( + _oldText, + key: _textKey, + style: widget.style, + ); + final newText = Text( + _newText, + style: widget.style, + ); + + return AnimatedBuilder( + animation: _animation, + builder: (context, child) => Stack( + alignment: Alignment.center, + children: [ + if (_animation.value <= toRadian(85)) + Transform( + alignment: Alignment.center, + transform: rollUp + ? _getFrontSideUp(_animation.value) + : _getFrontSideDown(_animation.value), + child: oldText, + ), + if (_animation.value >= toRadian(5)) + Transform( + alignment: Alignment.center, + transform: rollUp + ? _getBackSideUp(_animation.value) + : _getBackSideDown(_animation.value), + child: newText, + ), + ], + ), + ); + } + + +// Helpers + double toRadian(double degree) => degree * pi / 180; + double lerp(double start, double end, double percent) => (start + percent * (end - start)); + Size getWidgetSize(GlobalKey key) { + final RenderBox renderBox = key.currentContext?.findRenderObject(); + return renderBox?.size; + } +} \ No newline at end of file diff --git a/lib/widgets/TextFieldInertiaDirection.java b/lib/widgets/TextFieldInertiaDirection.java new file mode 100644 index 00000000..627bf406 --- /dev/null +++ b/lib/widgets/TextFieldInertiaDirection.java @@ -0,0 +1,343 @@ +import 'dart:math'; + +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; + +enum TextFieldInertiaDirection { + left, + right, +} + +Interval _getInternalInterval( + double start, + double end, + double externalStart, + double externalEnd, [ + Curve curve = Curves.linear, +]) { + return Interval( + start + (end - start) * externalStart, + start + (end - start) * externalEnd, + curve: curve, + ); +} + +class AnimatedTextFormField extends StatefulWidget { + AnimatedTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.width, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.prefixIcon, + this.suffixIcon, + this.keyboardType, + this.textInputAction, + this.obscureText = false, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double width; + final bool enabled; + final String labelText; + final Widget prefixIcon; + final Widget suffixIcon; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final bool obscureText; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedTextFormFieldState createState() => _AnimatedTextFormFieldState(); +} + +class _AnimatedTextFormFieldState extends State { + Animation scaleAnimation; + Animation sizeAnimation; + Animation suffixIconOpacityAnimation; + + Animation fieldTranslateAnimation; + Animation iconRotationAnimation; + Animation iconTranslateAnimation; + + @override + void initState() { + super.initState(); + + widget.inertiaController?.addStatusListener(handleAnimationStatus); + + final interval = widget.interval; + final loadingController = widget.loadingController; + + if (loadingController != null) { + scaleAnimation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + 0, .2, interval.begin, interval.end, Curves.easeOutBack), + )); + suffixIconOpacityAnimation = + Tween(begin: 0.0, end: 1.0).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval(.65, 1.0, interval.begin, interval.end), + )); + _updateSizeAnimation(); + } + + final inertiaController = widget.inertiaController; + final inertiaDirection = widget.inertiaDirection; + final sign = inertiaDirection == TextFieldInertiaDirection.right ? 1 : -1; + + if (inertiaController != null) { + fieldTranslateAnimation = Tween( + begin: 0.0, + end: sign * 15.0, + ).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(0, .5, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconRotationAnimation = + Tween(begin: 0.0, end: sign * pi / 12 /* ~15deg */) + .animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + iconTranslateAnimation = + Tween(begin: 0.0, end: 8.0).animate(CurvedAnimation( + parent: inertiaController, + curve: Interval(.5, 1.0, curve: Curves.easeOut), + reverseCurve: Curves.easeIn, + )); + } + } + + void _updateSizeAnimation() { + final interval = widget.interval; + final loadingController = widget.loadingController; + + sizeAnimation = Tween( + begin: 48.0, + end: widget.width, + ).animate(CurvedAnimation( + parent: loadingController, + curve: _getInternalInterval( + .2, 1.0, interval.begin, interval.end, Curves.linearToEaseOut), + reverseCurve: Curves.easeInExpo, + )); + } + + @override + void didUpdateWidget(AnimatedTextFormField oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.width != widget.width) { + _updateSizeAnimation(); + } + } + + @override + dispose() { + widget.inertiaController?.removeStatusListener(handleAnimationStatus); + super.dispose(); + } + + void handleAnimationStatus(status) { + if (status == AnimationStatus.completed) { + widget.inertiaController?.reverse(); + } + } + + Widget _buildInertiaAnimation(Widget child) { + if (widget.inertiaController == null) { + return child; + } + + return AnimatedBuilder( + animation: iconTranslateAnimation, + builder: (context, child) => Transform( + alignment: Alignment.center, + transform: Matrix4.identity() + ..translate(iconTranslateAnimation.value) + ..rotateZ(iconRotationAnimation.value), + child: child, + ), + child: child, + ); + } + + InputDecoration _getInputDecoration(ThemeData theme) { + return InputDecoration( + labelText: widget.labelText, + prefixIcon: _buildInertiaAnimation(widget.prefixIcon), + suffixIcon: _buildInertiaAnimation(widget.loadingController != null + ? FadeTransition( + opacity: suffixIconOpacityAnimation, + child: widget.suffixIcon, + ) + : widget.suffixIcon), + ); + } + + @override + Widget build(BuildContext context) { + final theme = Theme.of(context); + Widget textField = TextFormField( + controller: widget.controller, + focusNode: widget.focusNode, + decoration: _getInputDecoration(theme), + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + obscureText: widget.obscureText, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + validator: widget.validator, + enabled: widget.enabled, + ); + + if (widget.loadingController != null) { + textField = ScaleTransition( + scale: scaleAnimation, + child: AnimatedBuilder( + animation: sizeAnimation, + builder: (context, child) => ConstrainedBox( + constraints: BoxConstraints.tightFor(width: sizeAnimation.value), + child: child, + ), + child: textField, + ), + ); + } + + if (widget.inertiaController != null) { + textField = AnimatedBuilder( + animation: fieldTranslateAnimation, + builder: (context, child) => Transform.translate( + offset: Offset(fieldTranslateAnimation.value, 0), + child: child, + ), + child: textField, + ); + } + + return textField; + } +} + +class AnimatedPasswordTextFormField extends StatefulWidget { + AnimatedPasswordTextFormField({ + Key key, + this.interval = const Interval(0.0, 1.0), + @required this.animatedWidth, + this.loadingController, + this.inertiaController, + this.inertiaDirection, + this.enabled = true, + this.labelText, + this.keyboardType, + this.textInputAction, + this.controller, + this.focusNode, + this.validator, + this.onFieldSubmitted, + this.onSaved, + }) : assert((inertiaController == null && inertiaDirection == null) || + (inertiaController != null && inertiaDirection != null)), + super(key: key); + + final Interval interval; + final AnimationController loadingController; + final AnimationController inertiaController; + final double animatedWidth; + final bool enabled; + final String labelText; + final TextInputType keyboardType; + final TextInputAction textInputAction; + final TextEditingController controller; + final FocusNode focusNode; + final FormFieldValidator validator; + final ValueChanged onFieldSubmitted; + final FormFieldSetter onSaved; + final TextFieldInertiaDirection inertiaDirection; + + @override + _AnimatedPasswordTextFormFieldState createState() => + _AnimatedPasswordTextFormFieldState(); +} + +class _AnimatedPasswordTextFormFieldState + extends State { + var _obscureText = true; + + @override + Widget build(BuildContext context) { + return AnimatedTextFormField( + interval: widget.interval, + loadingController: widget.loadingController, + inertiaController: widget.inertiaController, + width: widget.animatedWidth, + enabled: widget.enabled, + labelText: widget.labelText, + prefixIcon: Icon(FontAwesomeIcons.lock, size: 20), + suffixIcon: GestureDetector( + onTap: () => setState(() => _obscureText = !_obscureText), + dragStartBehavior: DragStartBehavior.down, + child: AnimatedCrossFade( + duration: const Duration(milliseconds: 250), + firstCurve: Curves.easeInOutSine, + secondCurve: Curves.easeInOutSine, + alignment: Alignment.center, + layoutBuilder: (Widget topChild, _, Widget bottomChild, __) { + return Stack( + alignment: Alignment.center, + children: [bottomChild, topChild], + ); + }, + firstChild: Icon( + Icons.visibility, + size: 25.0, + semanticLabel: 'show password', + ), + secondChild: Icon( + Icons.visibility_off, + size: 25.0, + semanticLabel: 'hide password', + ), + crossFadeState: _obscureText + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + ), + ), + obscureText: _obscureText, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + controller: widget.controller, + focusNode: widget.focusNode, + validator: widget.validator, + onFieldSubmitted: widget.onFieldSubmitted, + onSaved: widget.onSaved, + inertiaDirection: widget.inertiaDirection, + ); + } +} \ No newline at end of file diff --git a/lib/widgets/bottom_navigation/bottom_nav_bar.dart b/lib/widgets/bottom_navigation/bottom_nav_bar.dart index 66a83224..f33e9dd5 100644 --- a/lib/widgets/bottom_navigation/bottom_nav_bar.dart +++ b/lib/widgets/bottom_navigation/bottom_nav_bar.dart @@ -6,18 +6,22 @@ import 'package:diplomaticquarterapp/pages/BookAppointment/BookingOptions.dart'; import 'package:diplomaticquarterapp/pages/ToDoList/ToDo.dart'; import 'package:diplomaticquarterapp/uitl/app_toast.dart'; import 'package:diplomaticquarterapp/uitl/translations_delegate_base.dart'; +import 'package:diplomaticquarterapp/widgets/transitions/fade_page.dart'; import 'package:eva_icons_flutter/eva_icons_flutter.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:diplomaticquarterapp/services/robo_search/event_provider.dart'; import 'package:provider/provider.dart'; import '../../d_q_icons_icons.dart'; import 'bottom_navigation_item.dart'; +import 'package:diplomaticquarterapp/services/authentication/auth_provider.dart'; +import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; class BottomNavBar extends StatefulWidget { final ValueChanged changeIndex; - final int index ; - BottomNavBar({Key key, this.changeIndex,this.index}) : super(key: key); + final int index; + BottomNavBar({Key key, this.changeIndex, this.index}) : super(key: key); @override _BottomNavBarState createState() => _BottomNavBarState(); @@ -25,25 +29,12 @@ class BottomNavBar extends StatefulWidget { class _BottomNavBarState extends State { int _index = 0; - ToDoCountProviderModel model; - AuthenticatedUserObject authenticatedUserObject = - locator(); - - _changeIndex(int index) { - if (index != 4) - widget.changeIndex(index); - else { - if (authenticatedUserObject.isLogin) { - if (model.count != 0) { - widget.changeIndex(index); - } else { - AppToast.showErrorToast( - message: TranslationBase.of(context).upcomingEmpty); - } - } else { - widget.changeIndex(index); - } + var event = RobotProvider(); + _changeIndex(int index) async { + widget.changeIndex(index); + if (_index == 0) { + event.setValue({'isRobotVisible': 'true'}); } } @@ -57,79 +48,79 @@ class _BottomNavBarState extends State { color: Colors.white, child: Padding( padding: EdgeInsets.symmetric(horizontal: 18), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceAround, - children: [ - BottomNavigationItem( - icon: EvaIcons.home, - activeIcon: EvaIcons.home, - changeIndex: _changeIndex, - index: widget.index, - currentIndex: 0, - name: TranslationBase.of(context).home, - ), - BottomNavigationItem( - icon: DQIcons.my_medical_file, - activeIcon: DQIcons.my_medical_file, - changeIndex: _changeIndex, - index: widget.index, - currentIndex: 1, - name: TranslationBase.of(context).medicalProfile, - ), - if(widget.index == 0 && projectViewModel.havePrivilege(34)) - Expanded( - child: SizedBox( - height: 50, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - SizedBox(height: 22), - ], - ), - ), - ), - if(widget.index != 0 && projectViewModel.havePrivilege(34)) - BottomNavigationItem( - icon: EvaIcons.calendar, - activeIcon: EvaIcons.calendar, - changeIndex: _changeIndex, - index: _index, - currentIndex: 2, - name: TranslationBase.of(context).bookAppo, - ), - - BottomNavigationItem( - icon: DQIcons.family, - activeIcon: DQIcons.family, - changeIndex: _changeIndex, - index: widget.index, - currentIndex: 3, - name: TranslationBase.of(context).myFamily, - ), - if(projectViewModel.havePrivilege(51)) - BottomNavigationItem( - icon: EvaIcons.calendar, - activeIcon: EvaIcons.calendar, - changeIndex: _changeIndex, - index: widget.index, - currentIndex: 4, - name: TranslationBase.of(context).todoList, - ) - ], - ), + child: Directionality( + textDirection: TextDirection.ltr, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + BottomNavigationItem( + icon: DQIcons.my_medical_file, + activeIcon: DQIcons.my_medical_file, + changeIndex: _changeIndex, + index: widget.index, + currentIndex: 1, + name: TranslationBase.of(context).medicalProfile, + ), + BottomNavigationItem( + icon: DQIcons.family, + activeIcon: DQIcons.family, + changeIndex: _changeIndex, + index: widget.index, + currentIndex: 3, + name: TranslationBase.of(context).myFamily, + ), + if (widget.index == 0) + Expanded( + child: SizedBox( + height: 50, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox(height: 22), + ], + ), + ), + ), + if (widget.index != 0 && projectViewModel.havePrivilege(34)) + BottomNavigationItem( + icon: EvaIcons.calendar, + activeIcon: EvaIcons.calendar, + changeIndex: _changeIndex, + index: _index, + currentIndex: 2, + name: TranslationBase.of(context).bookAppo, + ), + if (widget.index == 0 && projectViewModel.havePrivilege(34)) + BottomNavigationItem( + icon: EvaIcons.calendar, + activeIcon: EvaIcons.calendar, + changeIndex: _changeIndex, + index: widget.index, + currentIndex: 4, + name: TranslationBase.of(context).todoList, + ), + if (projectViewModel.havePrivilege(77)) + BottomNavigationItem( + icon: DQIcons.roboticon, + activeIcon: DQIcons.roboticon, + changeIndex: _changeIndex, + index: widget.index, + currentIndex: 0, + name: TranslationBase.of(context).help, + ) + ], + )), ), ); } Future navigateToBookingOptions(context) async { - Navigator.push( - context, MaterialPageRoute(builder: (context) => BookingOptions())); + Navigator.push(context, FadePage(page: BookingOptions())); } Future navigateToToDoList(context) async { - Navigator.push(context, - MaterialPageRoute(builder: (context) => ToDo(isShowAppBar: false))); + Navigator.push(context, FadePage(page: ToDo(isShowAppBar: false))); } } diff --git a/lib/widgets/bottom_navigation/bottom_navigation_item.dart b/lib/widgets/bottom_navigation/bottom_navigation_item.dart index 391b6a3d..9a3bbafe 100644 --- a/lib/widgets/bottom_navigation/bottom_navigation_item.dart +++ b/lib/widgets/bottom_navigation/bottom_navigation_item.dart @@ -18,7 +18,8 @@ class BottomNavigationItem extends StatelessWidget { final int currentIndex; final String name; - AuthenticatedUserObject authenticatedUserObject = locator(); + AuthenticatedUserObject authenticatedUserObject = + locator(); BottomNavigationItem( {this.icon, @@ -52,7 +53,7 @@ class BottomNavigationItem extends StatelessWidget { child: Icon(currentIndex == index ? activeIcon : icon, color: currentIndex == index ? secondaryColor - : Theme.of(context).dividerColor, + : Colors.grey, size: 22.0), ), SizedBox( diff --git a/lib/widgets/buttons/button.dart b/lib/widgets/buttons/button.dart index 5d7c9257..331ce4b6 100644 --- a/lib/widgets/buttons/button.dart +++ b/lib/widgets/buttons/button.dart @@ -19,7 +19,7 @@ class Button extends StatefulWidget { this.onTap, this.backgroundColor, this.loading: false, - this.elevation: true}) + this.elevation: true, this.disabled=false}) : super(key: key); final String label; @@ -28,6 +28,7 @@ class Button extends StatefulWidget { final bool loading; final bool elevation; final Color backgroundColor; + final bool disabled; @override _ButtonState createState() => _ButtonState(); @@ -83,75 +84,78 @@ class _ButtonState extends State