From d8bd7d145da84659bc011097b15ac5b8300dadbc Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Thu, 17 Dec 2020 18:30:04 +0300 Subject: [PATCH 01/20] no message --- ios/GoogleService-Info.plist | 20 +++++++------- ios/Podfile.lock | 10 +++---- ios/Runner.xcodeproj/project.pbxproj | 10 ++++--- ios/Runner/Helper/HMG_Geofence.swift | 2 +- ios/gpx.gpx | 2 +- lib/pages/landing/landing_page.dart | 30 ++++++++++----------- lib/pages/medical/medical_profile_page.dart | 2 +- lib/widgets/drawer/app_drawer_widget.dart | 2 +- 8 files changed, 41 insertions(+), 37 deletions(-) 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.lock b/ios/Podfile.lock index d65de659..668711ce 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -20,7 +20,7 @@ PODS: - Firebase/Messaging (6.33.0): - Firebase/CoreOnly - FirebaseMessaging (~> 4.7.0) - - firebase_core (0.5.3): + - firebase_core (0.5.2): - Firebase/CoreOnly (~> 6.33.0) - Flutter - firebase_core_web (0.1.0): @@ -70,7 +70,7 @@ PODS: - Flutter - flutter_tts (0.0.1): - Flutter - - geolocator (6.1.9): + - "geolocator (6.0.0+4)": - Flutter - google_maps_flutter (0.0.1): - Flutter @@ -375,7 +375,7 @@ SPEC CHECKSUMS: device_calendar: 23b28a5f1ab3bf77e34542fb1167e1b8b29a98f5 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 - firebase_core: 5d6a02f3d85acd5f8321c2d6d62877626a670659 + firebase_core: 350ba329d1641211bc6183a3236893cafdacfea7 firebase_core_web: d501d8b946b60c8af265428ce483b0fff5ad52d1 firebase_messaging: 0aea2cd5885b65e19ede58ee3507f485c992cc75 FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd @@ -390,7 +390,7 @@ SPEC CHECKSUMS: flutter_local_notifications: 9e4738ce2471c5af910d961a6b7eadcf57c50186 flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 flutter_tts: 0f492aab6accf87059b72354fcb4ba934304771d - geolocator: 057a0c63a43e9c5296d8ad845a3ac8e6df23d899 + geolocator: 1ae40084cc6c1586ce5ad12cfc3fd38c64d05f2f google_maps_flutter: c7f9c73576de1fbe152a227bfd6e6c4ae8088619 GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 GoogleMaps: 4b5346bddfe6911bb89155d43c903020170523ac @@ -440,4 +440,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 -COCOAPODS: 1.8.4 +COCOAPODS: 1.10.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 009006ed..77d42044 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 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 */; }; /* End PBXBuildFile section */ @@ -78,6 +79,7 @@ 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 = ""; }; /* End PBXFileReference section */ @@ -128,6 +130,7 @@ 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( + E9A35328258B8E8F00CBA688 /* GoogleService-Info.plist */, E923EFD72588D17700E3E751 /* gpx.gpx */, 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, @@ -265,6 +268,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 */, @@ -472,7 +476,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)", @@ -611,7 +615,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)", @@ -644,7 +648,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)", diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index fb469165..0c39fe5a 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -156,7 +156,7 @@ extension HMG_Geofence{ 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"), + if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"), let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ diff --git a/ios/gpx.gpx b/ios/gpx.gpx index 9cc26956..6121e536 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 617.71 620.95 643.70 677.84 \ No newline at end of file diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index acbf8d78..a45f24eb 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -146,7 +146,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { _firebaseMessaging.requestNotificationPermissions(); } - // Flip Permission Checks [Zohaib Kambrani] requestPermissions().then((results) { if (results[Permission.notification].isGranted) _firebaseMessaging.getToken().then((String token) { @@ -436,7 +435,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { void checkUserStatus(token) async { var result = await authService.selectDeviceImei(token); - setUserValues(result); + await setUserValues(result); registerGeofences(); if (await sharedPref.getObject(USER_PROFILE) != null) { @@ -472,7 +471,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { } Future getUserInformation() async { - var userInfoJson = sharedPref.getObject(IMEI_USER_DATA); + var userInfoJson = await sharedPref.getObject(IMEI_USER_DATA); return userInfoJson; } @@ -484,23 +483,22 @@ class _LandingPageState extends State with WidgetsBindingObserver { registerGeofences() async { await locator().getAllGeoZones(GeoZonesRequestModel()); + var userInfo = await getUserInformation(); void doIt() { - getUserInformation().then((value) { - if (value != null) projectViewModel.platformBridge().registerHmgGeofences(); - }); + projectViewModel.platformBridge().registerHmgGeofences(); } - if (await Permission.location.isGranted) { - doIt(); - } else { - [Permission.location].request().then((value) async { - if (await Permission.location.isGranted) { - doIt(); - } - }); + if (userInfo != null) { + if (await Permission.location.isGranted) { + doIt(); + } else { + [Permission.location].request().then((value) async { + if (await Permission.location.isGranted) { + doIt(); + } + }); + } } - - requestPermissions().then((results) {}); } } diff --git a/lib/pages/medical/medical_profile_page.dart b/lib/pages/medical/medical_profile_page.dart index 6dabf9d3..3260303c 100644 --- a/lib/pages/medical/medical_profile_page.dart +++ b/lib/pages/medical/medical_profile_page.dart @@ -430,7 +430,7 @@ class _MedicalProfilePageState extends State { child: InkWell( //TODO onTap: () { - if (authProvider.isLogin) { + if (projectViewModel.isLogin) { String patientID = authProvider.getAuthenticatedUser().patientID.toString(); GifLoaderDialogUtils.showMyDialog(context); projectViewModel.platformBridge().connectHMGInternetWifi(patientID).then((value) => {GifLoaderDialogUtils.hideDialog(context)}); diff --git a/lib/widgets/drawer/app_drawer_widget.dart b/lib/widgets/drawer/app_drawer_widget.dart index 9c6375e4..05ae92e3 100644 --- a/lib/widgets/drawer/app_drawer_widget.dart +++ b/lib/widgets/drawer/app_drawer_widget.dart @@ -331,7 +331,7 @@ class _AppDrawerState extends State { await sharedPref.clear(); this.user = null; Navigator.of(context).pushNamed(HOME); - projectProvider.platformBridge().unRegisterHmgGeofences(); + // projectProvider.platformBridge().unRegisterHmgGeofences(); } login() async { From 508bc191bea7ec1d6749fe9748fcb24bbc0e48b8 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani <> Date: Sun, 20 Dec 2020 13:44:29 +0300 Subject: [PATCH 02/20] geofencing login check fix --- android/app/src/main/AndroidManifest.xml | 2 +- .../geofence/GeoZoneModel.kt | 2 + .../geofence/GeofenceBroadcastReceiver.kt | 17 +++++++- .../GeofenceBroadcastReceiverWithService.kt | 13 ++++++ .../GeofenceTransitionsJobIntentService.kt | 37 +++-------------- .../GeofencingRebootBroadcastReceiver.kt | 3 +- .../geofence/HMG_Geofence.kt | 41 ++++++++++++++++++- .../diplomaticquarterapp/utils/HMGUtils.kt | 35 ++++++++++++++-- ios/Runner/AppDelegate.swift | 22 ---------- ios/Runner/Helper/Extensions.swift | 10 +++++ ios/Runner/Helper/GlobalHelper.swift | 30 +++++++++++++- ios/Runner/Helper/HMG_Geofence.swift | 14 ++++--- lib/pages/landing/landing_page.dart | 30 ++++++-------- 13 files changed, 169 insertions(+), 87 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 1032b29b..c114b44d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -80,7 +80,7 @@ - + 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..328014e6 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 = 5 // in Minutes return Geofence.Builder() .setRequestId(identifier()) .setCircularRegion( @@ -46,6 +47,7 @@ class GeoZoneModel { ) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) // .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 index 8fc1faae..f8a861bb 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt @@ -5,9 +5,24 @@ package com.cloud.diplomaticquarterapp.geofence import android.content.BroadcastReceiver import android.content.Context import android.content.Intent +import android.util.Log +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { + private val LOG_TAG = "GeofenceBroadcastReceiver" override fun onReceive(context: Context, intent: Intent) { - GeofenceTransitionsJobIntentService.enqueueWork(context, intent) + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + saveLog(context,LOG_TAG,errorMessage) + return + } + + HMG_Geofence.shared(context).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + } + } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt new file mode 100644 index 00000000..0332f745 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt @@ -0,0 +1,13 @@ + + +package com.cloud.diplomaticquarterapp.geofence + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent + +class GeofenceBroadcastReceiverWithService : 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/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt index f28e1720..18ee92d9 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceTransitionsJobIntentService.kt @@ -52,8 +52,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { private const val LOG_TAG = "GeoTrIntentService" private const val JOB_ID = 573 - + var context_: Context? = null fun enqueueWork(context: Context, intent: Intent) { + context_ = context enqueueWork( context, GeofenceTransitionsJobIntentService::class.java, JOB_ID, @@ -70,37 +71,9 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { } 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 -> - - hmg.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 = 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.😔") - }) - - } - } - - },null) + context_?.let { + HMG_Geofence.shared(it).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); + } } } } \ 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/GeofencingRebootBroadcastReceiver.kt index 08a0c93f..4534b08f 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofencingRebootBroadcastReceiver.kt @@ -13,7 +13,8 @@ import com.cloud.diplomaticquarterapp.utils.HMGUtils class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { - if (Intent.ACTION_BOOT_COMPLETED.equals(intent.action)) { +// 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() 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..24639c6c 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,9 @@ 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.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient import com.google.android.gms.location.GeofencingRequest @@ -37,6 +39,7 @@ 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" class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java @@ -99,6 +102,7 @@ class HMG_Geofence { } .addOnFailureListener { print(it.localizedMessage) + saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage) } } },null) @@ -107,7 +111,6 @@ class HMG_Geofence { fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ getActiveGeofences({ success -> val mList = success.toMutableList() - mList.add("12345") geofencingClient .removeGeofences(success) .addOnSuccessListener { @@ -115,6 +118,7 @@ class HMG_Geofence { } .addOnFailureListener { completion(false, it) + saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage) } removeActiveGeofences() }, { failed -> @@ -154,7 +158,10 @@ 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) ?.get("PatientID") @@ -162,4 +169,34 @@ class HMG_Geofence { .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 -> + sendNotification(context, transition.named(), geofence.requestId, "Notified to server.😎") + },{ exception -> + sendNotification(context, transition.named(), geofence.requestId, "Failed to notify server.😔") + }) + + } + } + + },null) + } + } } \ 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..413e8c09 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 @@ -16,6 +16,7 @@ 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.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost import com.google.android.gms.location.Geofence @@ -76,6 +77,26 @@ class HMGUtils { return geoZones } + fun getLanguageCode(context: Context) : Int{ + val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) + val lang = pref.getString(PREF_KEY_LANGUAGE,"ar") + return if(lang == "ar") 2 else 1 + } + + fun defaultHTTPParams(context: Context) : Map{ + return mapOf( + "ZipCode" to "966", + "VersionID" to 5.6, + "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) + } + } } @@ -117,7 +138,9 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, notificationManager.notify(getUniqueId(), notification.build()) } - +//------------------------- +// Open Helper Methods +//------------------------- private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) fun isJSONValid(jsonString: String?): Boolean { @@ -129,11 +152,18 @@ 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("GEO_LOGS","") + logs += "$tag -> $message \n" + pref.edit().putString("PLATFORM_LOGS", logs).apply(); +} + 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) @@ -153,7 +183,6 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP } }, { onError(it) - it.localizedMessage }) } diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index e686619c..a9252ee5 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -8,7 +8,6 @@ import GoogleMaps let locationManager = CLLocationManager() override func application( _ application: UIApplication,didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { -// initLocationManager() GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GeneratedPluginRegistrant.register(with: self) @@ -24,24 +23,3 @@ import GoogleMaps 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 locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion) { - if region is CLCircularRegion { - } - } - - func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion) { - if region is CLCircularRegion { - } - } -} diff --git a/ios/Runner/Helper/Extensions.swift b/ios/Runner/Helper/Extensions.swift index a8793617..5c1de7c3 100644 --- a/ios/Runner/Helper/Extensions.swift +++ b/ios/Runner/Helper/Extensions.swift @@ -18,6 +18,16 @@ extension String{ } } +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/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index c5eb7295..35f89991 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -49,9 +49,35 @@ func showNotification(identifier:String? = nil, title:String?, subtitle:String?, } } +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.6, + "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 diff --git a/ios/Runner/Helper/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index 0c39fe5a..3299fa1a 100644 --- a/ios/Runner/Helper/HMG_Geofence.swift +++ b/ios/Runner/Helper/HMG_Geofence.swift @@ -156,8 +156,13 @@ extension HMG_Geofence{ func notifyServer(forRegion:CLRegion, transition:Transition, location:CLLocation?){ df.dateFormat = "MMM/dd/yyyy hh:mm:ss" - if let userProfileJson = UserDefaults.standard.string(forKey: "flutter.imei-user-data"), - let userProfile = dictionary(from: userProfileJson), let patientId = userProfile["PatientID"] as? Int{ + var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data") + if(userInfo == nil){ + userInfo = UserDefaults.standard.string(forKey: "flutter.user-profile") + } + + if let userProfile = userProfile(), + let patientId = userProfile["PatientID"] as? Int{ if let idString = forRegion.identifier.split(separator: "_").first, let idInt = Int(idString){ let body:[String:Any] = [ @@ -172,15 +177,14 @@ extension HMG_Geofence{ showNotification(title: transition.name(), subtitle: forRegion.identifier, message: status_) - var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "LOGS") ?? [:] + var logs = UserDefaults.init(suiteName: "GeoFenceLog")?.dictionary(forKey: "GEOFENCE_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") - + UserDefaults.init(suiteName: "GeoFenceLog")?.set(logs, forKey: "GEOFENCE_LOGS") } } } diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index a45f24eb..7625bcf6 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -142,11 +142,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { PlatformBridge().connectHMGGuestWifi().then((value) => {GifLoaderDialogUtils.hideDialog(context)}); }).checkAndConnectIfNoInternet(); + if (Platform.isIOS) { _firebaseMessaging.requestNotificationPermissions(); } requestPermissions().then((results) { + registerGeofences(); + if (results[Permission.notification].isGranted) _firebaseMessaging.getToken().then((String token) { sharedPref.setString(PUSH_TOKEN, token); @@ -156,7 +159,7 @@ class _LandingPageState extends State with WidgetsBindingObserver { } }); - if (results[Permission.location].isGranted) ; + if (results[Permission.locationAlways].isGranted) ; if (results[Permission.storage].isGranted) ; if (results[Permission.camera].isGranted) ; if (results[Permission.photos].isGranted) ; @@ -436,7 +439,6 @@ class _LandingPageState extends State with WidgetsBindingObserver { void checkUserStatus(token) async { var result = await authService.selectDeviceImei(token); await setUserValues(result); - registerGeofences(); if (await sharedPref.getObject(USER_PROFILE) != null) { var data = AuthenticatedUser.fromJson(await sharedPref.getObject(USER_PROFILE)); @@ -483,22 +485,14 @@ class _LandingPageState extends State with WidgetsBindingObserver { registerGeofences() async { await locator().getAllGeoZones(GeoZonesRequestModel()); - var userInfo = await getUserInformation(); - - void doIt() { - projectViewModel.platformBridge().registerHmgGeofences(); - } - - if (userInfo != null) { - if (await Permission.location.isGranted) { - doIt(); - } else { - [Permission.location].request().then((value) async { - if (await Permission.location.isGranted) { - doIt(); - } - }); - } + if (await Permission.location.isGranted) { + PlatformBridge().registerHmgGeofences(); + } else { + [Permission.location].request().then((results) async { + if (results[Permission.locationAlways].isGranted){ + PlatformBridge().registerHmgGeofences(); + } + }); } } } From 7b4a2b9e64a91e6951e537aaa49b5a76351c52de Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Sun, 20 Dec 2020 14:18:03 +0300 Subject: [PATCH 03/20] no message --- .../src/main/kotlin/com/cloud/diplomaticquarterapp/utils/API.kt | 2 +- ios/gpx.gpx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/ios/gpx.gpx b/ios/gpx.gpx index 6121e536..ed8e9be6 100644 --- a/ios/gpx.gpx +++ b/ios/gpx.gpx @@ -1 +1 @@ - Sverrir Sigmundarson 617.71 620.95 643.70 677.84 \ No newline at end of file + Sverrir Sigmundarson 608.26 620.97 617.77 643.86 \ No newline at end of file From a11d93332d6a77fabc5eff95327b6d0e7d9b4492 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 17:19:40 +0300 Subject: [PATCH 04/20] Wifi check network available - android tweaking at geofence code --- android/app/src/main/AndroidManifest.xml | 9 +++-- .../geofence/HMG_Geofence.kt | 1 + .../GeofenceBroadcastReceiver.kt | 4 +- ...eofenceBroadcastReceiverWithJobService.kt} | 4 +- .../GeofenceErrorMessages.kt | 2 +- .../GeofenceJobIntentService.kt | 29 ++++++++++++++ .../GeofenceTransitionsJobIntentService.kt | 12 ++---- .../GeofencingRebootBroadcastReceiver.kt | 9 ++--- .../diplomaticquarterapp/utils/HMGUtils.kt | 6 +-- ios/Flutter/.last_build_id | 2 +- ios/Runner/AppDelegate.swift | 14 +++++++ ios/Runner/Helper/Extensions.swift | 8 ++++ ios/Runner/Helper/GlobalHelper.swift | 36 ++++++++++------- ios/Runner/Helper/HMG_Geofence.swift | 40 +++++++------------ lib/uitl/HMGNetworkConnectivity.dart | 34 ++++++++++------ 15 files changed, 133 insertions(+), 77 deletions(-) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceBroadcastReceiver.kt (82%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{GeofenceBroadcastReceiverWithService.kt => intent_receivers/GeofenceBroadcastReceiverWithJobService.kt} (63%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceErrorMessages.kt (94%) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofenceTransitionsJobIntentService.kt (87%) rename android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/{ => intent_receivers}/GeofencingRebootBroadcastReceiver.kt (73%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c114b44d..68975071 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -76,11 +76,12 @@ - - - + + + - + + 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 24639c6c..919d478f 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 @@ -8,6 +8,7 @@ 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.utils.* import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingClient diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt similarity index 82% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt index f8a861bb..11fc4850 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiver.kt @@ -1,11 +1,13 @@ -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.util.Log +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.GeofencingEvent diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt similarity index 63% rename from android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt rename to android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt index 0332f745..250040f6 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/GeofenceBroadcastReceiverWithService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceBroadcastReceiverWithJobService.kt @@ -1,12 +1,12 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.BroadcastReceiver import android.content.Context import android.content.Intent -class GeofenceBroadcastReceiverWithService : BroadcastReceiver() { +class GeofenceBroadcastReceiverWithJobService : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { GeofenceTransitionsJobIntentService.enqueueWork(context, intent) } 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 similarity index 94% 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..74a88f87 100755 --- 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,6 +1,6 @@ -package com.cloud.diplomaticquarterapp.geofence +package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt new file mode 100644 index 00000000..84d3f230 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt @@ -0,0 +1,29 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.Intent +import android.util.Log +import androidx.core.app.JobIntentService +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.GeofencingEvent + +class GeofenceJobIntentService : JobIntentService(){ + + private val LOG_TAG = "GeofenceBroadcastReceiver" + override fun onHandleWork(intent: Intent) { + + val geofencingEvent = GeofencingEvent.fromIntent(intent) + if (geofencingEvent.hasError()) { + val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) + Log.e(LOG_TAG, errorMessage) + saveLog(this, LOG_TAG,errorMessage) + return + } + + HMG_Geofence.shared(this).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) + } + +} \ 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 similarity index 87% 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 18ee92d9..2be216a1 100755 --- 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,22 +29,16 @@ */ -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.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.google.android.gms.location.Geofence import com.google.android.gms.location.GeofencingEvent -import com.google.gson.Gson class GeofenceTransitionsJobIntentService : JobIntentService() { 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 73% 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 4534b08f..e1eda3b9 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,20 +1,19 @@ -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.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.utils.HMGUtils 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")) { + 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() 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 413e8c09..0dc0234c 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 @@ -126,7 +126,7 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, .addNextIntent(intent) val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) - val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) + val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID + ".geofence") .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) @@ -154,9 +154,9 @@ fun isJSONValid(jsonString: String?): Boolean { fun saveLog(context:Context, tag:String, message:String){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - var logs = pref.getString("GEO_LOGS","") + var logs = pref.getString("GEOFENCE_LOGS","") logs += "$tag -> $message \n" - pref.edit().putString("PLATFORM_LOGS", logs).apply(); + pref.edit().putString("GEOFENCE_LOGS", logs).apply(); } class HTTPResponse(data: T){ diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 3aa2cd1e..a7923797 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -3f3d14a0ae775b56806906c2cb14a1f0 \ No newline at end of file +d9d141e787a8aa802f90b776d75f04fc \ No newline at end of file diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index a9252ee5..d8f4c0c7 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -2,6 +2,7 @@ import UIKit import Flutter import GoogleMaps +var userNotificationCenterDelegate:UNUserNotificationCenterDelegate? = nil @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { @@ -12,6 +13,7 @@ import GoogleMaps GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") GeneratedPluginRegistrant.register(with: self) + if let mainViewController = window.rootViewController as? MainFlutterVC{ HMGPlatformBridge.initialize(flutterViewController: mainViewController) } @@ -20,6 +22,18 @@ import GoogleMaps HMG_Geofence.initGeofencing() } + UNUserNotificationCenter.current().delegate = self + return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } + +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) + } + } +} diff --git a/ios/Runner/Helper/Extensions.swift b/ios/Runner/Helper/Extensions.swift index 5c1de7c3..de67f9b9 100644 --- a/ios/Runner/Helper/Extensions.swift +++ b/ios/Runner/Helper/Extensions.swift @@ -18,6 +18,14 @@ 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?] diff --git a/ios/Runner/Helper/GlobalHelper.swift b/ios/Runner/Helper/GlobalHelper.swift index 35f89991..2e323a2a 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -31,20 +31,26 @@ 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)") + } } } } @@ -103,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/HMG_Geofence.swift b/ios/Runner/Helper/HMG_Geofence.swift index 3299fa1a..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,25 +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" - var userInfo = UserDefaults.standard.string(forKey: "flutter.imei-user-data") - if(userInfo == nil){ - userInfo = UserDefaults.standard.string(forKey: "flutter.user-profile") - } - - if let userProfile = userProfile(), - 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] = [ @@ -170,19 +161,18 @@ 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: "GEOFENCE_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) - } + 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/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) { From 187d2bcd8b6e61a6febf185fc3d7fe46a66c8a9a Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 18:01:13 +0300 Subject: [PATCH 05/20] Geofence error logging in shared_preferences --- .../intent_receivers/GeofenceErrorMessages.kt | 13 ++++++++++++- android/app/src/main/res/values/strings.xml | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 74a88f87..08d5ba62 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -4,6 +4,7 @@ package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R +import com.cloud.diplomaticquarterapp.utils.saveLog 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,17 @@ 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) } + + saveLog(context,"GeofenceErrorMessages","$errorCode | $errorMessage") + + return errorMessage } } \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 8acc0c12..4e107030 100755 --- 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. + From 3392a2431b8e9d5deb12e82ccd4a64af92aa68e0 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Mon, 21 Dec 2020 18:42:50 +0300 Subject: [PATCH 06/20] Added Location Provider Changed Receiver to Reregister the geofences --- android/app/src/main/AndroidManifest.xml | 6 +++- .../LocationProviderChangeReceiver.kt | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 68975071..649af435 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -81,7 +81,11 @@ - + + + + + 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..9de0cd6f --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/LocationProviderChangeReceiver.kt @@ -0,0 +1,32 @@ + + +package com.cloud.diplomaticquarterapp.geofence.intent_receivers + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.location.LocationManager +import android.util.Log +import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence +import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +import com.cloud.diplomaticquarterapp.utils.HMGUtils +import com.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofencingEvent + +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).unRegisterAll { status, exception -> + val geoZones = HMGUtils.getGeoZonesFromPreference(context) + HMG_Geofence.shared(context).register(geoZones) + } + } + } + +} \ No newline at end of file From 57925e3b02c9bb2f565150c94e5a39ddf8511783 Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Thu, 24 Dec 2020 18:01:32 +0300 Subject: [PATCH 07/20] Geofence fixes by JobScheduler --- android/app/src/main/AndroidManifest.xml | 3 + .../diplomaticquarterapp/MainActivity.kt | 13 +- .../geofence/GeoZoneModel.kt | 6 +- .../geofence/HMG_Geofence.kt | 74 ++++++--- .../GeofenceBroadcastReceiver.kt | 22 ++- ...GeofenceBroadcastReceiverWithJobService.kt | 3 + .../intent_receivers/GeofenceErrorMessages.kt | 4 +- .../GeofenceJobIntentService.kt | 29 ---- .../GeofenceTransitionsJobIntentService.kt | 32 +++- .../GeofencingRebootBroadcastReceiver.kt | 6 +- .../ReregisterGeofenceJobService.kt | 23 +++ .../diplomaticquarterapp/utils/HMGUtils.kt | 84 +++++++--- .../cloud/diplomaticquarterapp/utils/Logs.kt | 146 ++++++++++++++++++ ios/Flutter/.last_build_id | 2 +- ios/Runner.xcodeproj/project.pbxproj | 4 + ios/Runner/AppDelegate.swift | 39 ++++- ios/Runner/Helper/API.swift | 7 +- ios/Runner/Helper/FlutterConstants.swift | 36 +++++ ios/Runner/Helper/GlobalHelper.swift | 2 +- ios/Runner/Helper/HMGPlatformBridge.swift | 3 + lib/config/config.dart | 6 +- 21 files changed, 442 insertions(+), 102 deletions(-) delete mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt create mode 100644 ios/Runner/Helper/FlutterConstants.swift diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 649af435..79bc3dc4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -81,6 +81,7 @@ + @@ -88,6 +89,8 @@ + + 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 328014e6..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,7 +37,7 @@ class GeoZoneModel { val rad = Radius.toFloat() if(lat != null && long != null){ - val loiteringDelayMinutes:Int = 5 // in Minutes + val loiteringDelayMinutes:Int = 2 // in Minutes return Geofence.Builder() .setRequestId(identifier()) .setCircularRegion( @@ -46,8 +46,8 @@ class GeoZoneModel { rad ) .setTransitionTypes(GeofenceTransition.ENTER_EXIT.value) -// .setNotificationResponsiveness(0) -// .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) + .setNotificationResponsiveness(0) + .setLoiteringDelay(loiteringDelayMinutes * 60 * 1000) .setExpirationDuration(Geofence.NEVER_EXPIRE) .build() } 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 919d478f..ba6691f7 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 @@ -9,6 +9,7 @@ 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 @@ -20,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 } @@ -30,8 +33,9 @@ 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" } } @@ -73,13 +77,22 @@ class HMG_Geofence { } } + fun limitize(zones: List):List{ + var geoZones_ = zones + if(zones.size > 100) + geoZones_ = zones.subList(0, 99) + return geoZones_ + } + fun register(geoZones: List){ if (geoZones.isEmpty()) return + var geoZones_ = limitize(geoZones) + fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() - .setInitialTrigger(0) + .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL) .addGeofences(geofences) .build() } @@ -87,9 +100,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) } } @@ -99,19 +112,25 @@ 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()) } .addOnFailureListener { - print(it.localizedMessage) - saveLog(context,"error:ADD_GEOFENCES", it.localizedMessage) + Logs.RegisterGeofence.save(context,"FAILED_TO_REGISTER", "Failed to register geofence",Logs.STATUS.ERROR) } + + // 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.TriggerIntervalMillis) } - },null) + + }, null) + } - fun unRegisterAll(completion: (status: Boolean, exception:Exception?) -> Unit){ + fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ getActiveGeofences({ success -> val mList = success.toMutableList() + removeActiveGeofences() geofencingClient .removeGeofences(success) .addOnSuccessListener { @@ -119,14 +138,20 @@ class HMG_Geofence { } .addOnFailureListener { completion(false, it) - saveLog(context,"error:REMOVE_GEOFENCES", it.localizedMessage) + saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) } - removeActiveGeofences() }, { failed -> // Nothing to do with failed geofences. }) } + fun reRegister(){ + unRegisterAll { status, exception -> + val geoZones = HMGUtils.getGeoZonesFromPreference(context) + register(geoZones) + } + } + fun saveActiveGeofence(success: List, failed: List){ val jsonSuccess = gson.toJson(success) val jsonFailure = gson.toJson(failed) @@ -135,8 +160,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)?){ @@ -164,7 +189,7 @@ class HMG_Geofence { 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() @@ -172,32 +197,35 @@ class HMG_Geofence { } - fun handleEvent(triggerGeofences: List, location: Location, transition:GeofenceTransition) { + 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 pointID = activeGeofences.firstOrNull { it == geofence.requestId }?.split('_')?.first() + if (!pointID.isNullOrEmpty() && pointID.toIntOrNull() != null) { - val body = mutableMapOf( + 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 -> + 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 -> - sendNotification(context, transition.named(), geofence.requestId, "Failed to notify 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) + }, 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 index 11fc4850..80ef2c96 100644 --- 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 @@ -8,7 +8,9 @@ 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.cloud.diplomaticquarterapp.utils.saveLog +import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceBroadcastReceiver : BroadcastReceiver() { @@ -19,12 +21,28 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() { if (geofencingEvent.hasError()) { val errorMessage = GeofenceErrorMessages.getErrorString(context, geofencingEvent.errorCode) Log.e(LOG_TAG, errorMessage) - saveLog(context,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).reRegister() + + } } \ 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 index 250040f6..a9924ca1 100644 --- 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 @@ -5,9 +5,12 @@ 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/intent_receivers/GeofenceErrorMessages.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt index 08d5ba62..01377d49 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceErrorMessages.kt @@ -4,7 +4,7 @@ package com.cloud.diplomaticquarterapp.geofence.intent_receivers import android.content.Context import com.cloud.diplomaticquarterapp.R -import com.cloud.diplomaticquarterapp.utils.saveLog +import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.google.android.gms.common.api.ApiException import com.google.android.gms.location.GeofenceStatusCodes @@ -38,8 +38,6 @@ object GeofenceErrorMessages { else -> resources.getString(R.string.geofence_unknown_error) } - saveLog(context,"GeofenceErrorMessages","$errorCode | $errorMessage") - return errorMessage } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt deleted file mode 100644 index 84d3f230..00000000 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceJobIntentService.kt +++ /dev/null @@ -1,29 +0,0 @@ - - -package com.cloud.diplomaticquarterapp.geofence.intent_receivers - -import android.content.Intent -import android.util.Log -import androidx.core.app.JobIntentService -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.GeofencingEvent - -class GeofenceJobIntentService : JobIntentService(){ - - private val LOG_TAG = "GeofenceBroadcastReceiver" - override fun onHandleWork(intent: Intent) { - - val geofencingEvent = GeofencingEvent.fromIntent(intent) - if (geofencingEvent.hasError()) { - val errorMessage = GeofenceErrorMessages.getErrorString(this, geofencingEvent.errorCode) - Log.e(LOG_TAG, errorMessage) - saveLog(this, LOG_TAG,errorMessage) - return - } - - HMG_Geofence.shared(this).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)) - } - -} \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index 2be216a1..c008c0a5 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -37,7 +37,9 @@ import android.util.Log import androidx.core.app.JobIntentService 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.Geofence +import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent class GeofenceTransitionsJobIntentService : JobIntentService() { @@ -45,7 +47,7 @@ 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 @@ -59,15 +61,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) + + + saveLog(context_!!,LOG_TAG,errorMessage) + doReRegisterIfRequired(context_!!, geofencingEvent.errorCode) + return } - if (geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofencingEvent.geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) { - context_?.let { - HMG_Geofence.shared(it).handleEvent(geofencingEvent.triggeringGeofences,geofencingEvent.triggeringLocation, GeofenceTransition.fromInt(geofencingEvent.geofenceTransition)); - } - } + 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).reRegister() + } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index e1eda3b9..0663db3b 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -7,7 +7,6 @@ import android.content.Context import android.content.Intent import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE -import com.cloud.diplomaticquarterapp.utils.HMGUtils class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { @@ -17,10 +16,7 @@ class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ 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).reRegister() } } 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..043c5c96 --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/ReregisterGeofenceJobService.kt @@ -0,0 +1,23 @@ +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 +import com.cloud.diplomaticquarterapp.utils.timeToMillis + +class ReregisterGeofenceJobService : JobService(){ + companion object{ + val TriggerIntervalMillis:String = "24:00:00" + val JobID = 918273 + } + override fun onStartJob(params: JobParameters?): Boolean { + HMG_Geofence.shared(applicationContext).reRegister() + Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalMillis >> [HH:mm:ss]") + 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/HMGUtils.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/HMGUtils.kt index 0dc0234c..7880a7ef 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,11 +3,15 @@ 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 import android.widget.Toast import androidx.annotation.Nullable +import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import androidx.core.app.TaskStackBuilder import com.cloud.diplomaticquarterapp.BuildConfig @@ -17,15 +21,17 @@ import com.cloud.diplomaticquarterapp.geofence.GeoZoneModel import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_HMG_ZONES import com.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE +import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService 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 @@ -71,7 +77,7 @@ class HMGUtils { fun getGeoZonesFromPreference(context: Context):List{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val json = pref.getString(PREF_KEY_HMG_ZONES,"[]") + val json = pref.getString(PREF_KEY_HMG_ZONES, "[]") val geoZones = GeoZoneModel().listFrom(json) return geoZones @@ -79,14 +85,14 @@ class HMGUtils { fun getLanguageCode(context: Context) : Int{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - val lang = pref.getString(PREF_KEY_LANGUAGE,"ar") + val lang = pref.getString(PREF_KEY_LANGUAGE, "ar") return if(lang == "ar") 2 else 1 } - fun defaultHTTPParams(context: Context) : Map{ + fun defaultHTTPParams(context: Context) : Map{ return mapOf( "ZipCode" to "966", - "VersionID" to 5.6, + "VersionID" to 5.8, "Channel" to 3, "LanguageID" to getLanguageCode(context), "IPAdress" to "10.20.10.20", @@ -97,16 +103,44 @@ class HMGUtils { "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) + + 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 @@ -126,7 +160,7 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, .addNextIntent(intent) val notificationPendingIntent = stackBuilder.getPendingIntent(getUniqueId(), PendingIntent.FLAG_UPDATE_CURRENT) - val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID + ".geofence") + val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentIntent(notificationPendingIntent) .setAutoCancel(true) @@ -141,7 +175,15 @@ fun sendNotification(context: Context, title:String, @Nullable subtitle:String?, //------------------------- // Open Helper Methods //------------------------- -private fun getUniqueId() = ((System.currentTimeMillis() % 10000).toInt()) +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) { @@ -152,11 +194,16 @@ fun isJSONValid(jsonString: String?): Boolean { return true } -fun saveLog(context:Context, tag:String, message:String){ +fun saveLog(context: Context, tag: String, message: String){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) - var logs = pref.getString("GEOFENCE_LOGS","") + var logs = pref.getString("LOGS", "") logs += "$tag -> $message \n" - pref.edit().putString("GEOFENCE_LOGS", logs).apply(); + 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){ @@ -170,15 +217,16 @@ fun httpPost(url: String, body: Map, onSuccess: (response: HTTP 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)")) } }, { 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..5c11943e --- /dev/null +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -0,0 +1,146 @@ +package com.cloud.diplomaticquarterapp.utils + +import android.content.Context +import android.content.SharedPreferences +import android.os.Build +import com.cloud.diplomaticquarterapp.BuildConfig +import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +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/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index a7923797..4e1980a7 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -d9d141e787a8aa802f90b776d75f04fc \ No newline at end of file +e7c24319209ad9049a87d4c83aeeb7de \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 77d42044..8ef5d511 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -31,6 +31,7 @@ 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 */ @@ -82,6 +83,7 @@ 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 */ @@ -180,6 +182,7 @@ E923EFD125863FDF00E3E751 /* GeoZoneModel.swift */, E923EFD3258645C100E3E751 /* HMG_Geofence.swift */, E923EFD52587443800E3E751 /* HMGPlatformBridge.swift */, + E9F7623A25922BCE00FB5CCF /* FlutterConstants.swift */, ); path = Helper; sourceTree = ""; @@ -378,6 +381,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 */, diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index d8f4c0c7..2dc828d1 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -7,25 +7,39 @@ 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 { GMSServices.provideAPIKey("AIzaSyCiiJiHkocPbcziHt9O8rGWavDrxHRQys8") 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) } + + + 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 initialViewController() -> MainFlutterVC?{ + return nil //UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController() as? MainFlutterVC + } } extension AppDelegate{ @@ -37,3 +51,18 @@ extension AppDelegate{ } } } + + +/* + 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/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 2e323a2a..37687806 100644 --- a/ios/Runner/Helper/GlobalHelper.swift +++ b/ios/Runner/Helper/GlobalHelper.swift @@ -70,7 +70,7 @@ func userProfile() -> [String:Any?]?{ fileprivate let defaultHTTPParams:[String : Any?] = [ "ZipCode" : "966", - "VersionID" : 5.6, + "VersionID" : 5.8, "Channel" : 3, "LanguageID" : appLanguageCode(), "IPAdress" : "10.20.10.20", 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/lib/config/config.dart b/lib/config/config.dart index 4a420ec8..10ec0b73 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -22,6 +22,9 @@ const GET_PROJECT = 'Services/Lists.svc/REST/GetProject'; const GET_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_GetAllPoints'; const LOG_GEO_ZONES = 'Services/Patients.svc/REST/GeoF_InsertPatientFileInfo'; +// Wifi Credentials +const WIFI_CREDENTIALS = "Services/Patients.svc/Hmg_SMS_Get_By_ProjectID_And_PatientID"; + ///Doctor const GET_MY_DOCTOR = 'Services/Doctors.svc/REST/GetPatientDoctorAppointmentResult'; const GET_DOCTOR_PROFILE = 'Services/Doctors.svc/REST/GetDocProfiles'; @@ -199,7 +202,7 @@ const UPDATE_HEALTH_TERMS = '/services/Patients.svc/REST/UpdatePateintHealthSumm const CHANNEL = 3; const GENERAL_ID = 'Cs2020@2016\$2958'; const IP_ADDRESS = '10.20.10.20'; -const VERSION_ID = 5.6; +const VERSION_ID = 5.8; const SETUP_ID = '91877'; const LANGUAGE = 2; const PATIENT_OUT_SA = 0; @@ -306,7 +309,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'; From f03adb37ce46c6b704689a8968d021eec3dd68cc Mon Sep 17 00:00:00 2001 From: Zohaib Kambrani Date: Sun, 27 Dec 2020 14:27:54 +0300 Subject: [PATCH 08/20] no message --- .../geofence/HMG_Geofence.kt | 76 +++++++++++-------- .../GeofenceBroadcastReceiver.kt | 5 +- .../GeofenceTransitionsJobIntentService.kt | 3 +- .../GeofencingRebootBroadcastReceiver.kt | 4 +- .../LocationProviderChangeReceiver.kt | 11 +-- .../ReregisterGeofenceJobService.kt | 9 ++- .../diplomaticquarterapp/utils/Constants.kt | 8 ++ .../diplomaticquarterapp/utils/HMGUtils.kt | 15 +--- .../cloud/diplomaticquarterapp/utils/Logs.kt | 1 - .../utils/PlatformBridge.kt | 2 +- 10 files changed, 66 insertions(+), 68 deletions(-) create mode 100644 android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Constants.kt 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 ba6691f7..d2fb404a 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 @@ -40,12 +40,6 @@ enum class GeofenceTransition(val value: Int) { } } -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" - class HMG_Geofence { // https://developer.android.com/training/location/geofencing#java @@ -84,11 +78,42 @@ class HMG_Geofence { return geoZones_ } - fun register(geoZones: List){ + + 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 - var geoZones_ = limitize(geoZones) + val geoZones_ = limitize(geoZones) fun buildGeofencingRequest(geofences: List): GeofencingRequest { return GeofencingRequest.Builder() @@ -114,42 +139,27 @@ class HMG_Geofence { .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 { + .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.TriggerIntervalMillis) + HMGUtils.scheduleJob(context, ReregisterGeofenceJobService::class.java,ReregisterGeofenceJobService.JobID, ReregisterGeofenceJobService.TriggerIntervalDuration) } - + }, null) } - fun unRegisterAll(completion: (status: Boolean, exception: Exception?) -> Unit){ - getActiveGeofences({ success -> - val mList = success.toMutableList() - removeActiveGeofences() - geofencingClient - .removeGeofences(success) - .addOnSuccessListener { - completion(true, null) - } - .addOnFailureListener { - completion(false, it) - saveLog(context, "error:REMOVE_GEOFENCES", it.localizedMessage) - } - }, { 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, "[]") - fun reRegister(){ - unRegisterAll { status, exception -> - val geoZones = HMGUtils.getGeoZonesFromPreference(context) - register(geoZones) - } + val geoZones = GeoZoneModel().listFrom(json) + return geoZones } fun saveActiveGeofence(success: List, failed: List){ 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 index 80ef2c96..77df1572 100644 --- 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 @@ -9,7 +9,6 @@ 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.cloud.diplomaticquarterapp.utils.saveLog import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent @@ -42,7 +41,9 @@ class GeofenceBroadcastReceiver : BroadcastReceiver() { ) if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).reRegister() + 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/GeofenceTransitionsJobIntentService.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt index c008c0a5..214957cf 100755 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofenceTransitionsJobIntentService.kt @@ -38,7 +38,6 @@ import androidx.core.app.JobIntentService 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.Geofence import com.google.android.gms.location.GeofenceStatusCodes import com.google.android.gms.location.GeofencingEvent @@ -85,7 +84,7 @@ class GeofenceTransitionsJobIntentService : JobIntentService() { ) if(errorRequiredReregister.contains(errorCode)) - HMG_Geofence.shared(context).reRegister() + HMG_Geofence.shared(context).register(){ status, exc -> } } } \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt index 0663db3b..6421b327 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/geofence/intent_receivers/GeofencingRebootBroadcastReceiver.kt @@ -6,7 +6,7 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ override fun onReceive(context: Context, intent: Intent) { @@ -16,7 +16,7 @@ class GeofencingRebootBroadcastReceiver : BroadcastReceiver(){ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("REBOOT_DETECTED","YES").apply() - HMG_Geofence.shared(context).reRegister() + 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 index 9de0cd6f..273ca8f5 100644 --- 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 @@ -6,13 +6,9 @@ import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.location.LocationManager -import android.util.Log -import com.cloud.diplomaticquarterapp.geofence.GeofenceTransition import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.cloud.diplomaticquarterapp.utils.HMGUtils -import com.cloud.diplomaticquarterapp.utils.saveLog -import com.google.android.gms.location.GeofencingEvent +import com.cloud.diplomaticquarterapp.utils.PREFS_STORAGE class LocationProviderChangeReceiver : BroadcastReceiver() { private val LOG_TAG = "LocationProviderChangeReceiver" @@ -22,10 +18,7 @@ class LocationProviderChangeReceiver : BroadcastReceiver() { val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) pref.edit().putString("LOCATION_PROVIDER_CHANGE","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(){ s, e -> } } } 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 index 043c5c96..0bc496bc 100644 --- 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 @@ -4,16 +4,17 @@ import android.app.job.JobParameters import android.app.job.JobService import com.cloud.diplomaticquarterapp.geofence.HMG_Geofence import com.cloud.diplomaticquarterapp.utils.Logs -import com.cloud.diplomaticquarterapp.utils.timeToMillis class ReregisterGeofenceJobService : JobService(){ companion object{ - val TriggerIntervalMillis:String = "24:00:00" + val TriggerIntervalDuration:String = "06:00:00" val JobID = 918273 } override fun onStartJob(params: JobParameters?): Boolean { - HMG_Geofence.shared(applicationContext).reRegister() - Logs.save(applicationContext,"ReregisterGeofenceJobService.onStartJob", "triggered to re-register the geofences after $TriggerIntervalMillis >> [HH:mm:ss]") + 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 } 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 7880a7ef..1c661c19 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 @@ -11,17 +11,11 @@ import android.content.Intent import android.os.Build import android.widget.Toast import androidx.annotation.Nullable -import androidx.annotation.RequiresApi import androidx.core.app.NotificationCompat import androidx.core.app.TaskStackBuilder 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.cloud.diplomaticquarterapp.geofence.PREF_KEY_LANGUAGE -import com.cloud.diplomaticquarterapp.geofence.intent_receivers.ReregisterGeofenceJobService import com.github.kittinunf.fuel.core.extensions.jsonBody import com.github.kittinunf.fuel.httpPost import com.google.gson.Gson @@ -75,14 +69,6 @@ class HMGUtils { } } - 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 getLanguageCode(context: Context) : Int{ val pref = context.getSharedPreferences(PREFS_STORAGE, Context.MODE_PRIVATE) val lang = pref.getString(PREF_KEY_LANGUAGE, "ar") @@ -111,6 +97,7 @@ class HMGUtils { 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 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 index 5c11943e..e74f463e 100644 --- a/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt +++ b/android/app/src/main/kotlin/com/cloud/diplomaticquarterapp/utils/Logs.kt @@ -4,7 +4,6 @@ import android.content.Context import android.content.SharedPreferences import android.os.Build import com.cloud.diplomaticquarterapp.BuildConfig -import com.cloud.diplomaticquarterapp.geofence.PREFS_STORAGE import com.google.gson.Gson class Logs { 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 -> } } } From 634c874eee1fb5fc7e5b6acdf323388776f288da Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 13 Jan 2021 10:02:39 +0200 Subject: [PATCH 09/20] fix design issues --- assets/images/new-design/covid-19-car.svg | 26 ++++ lib/config/localized_values.dart | 8 ++ lib/core/service/client/base_app_client.dart | 10 +- .../ComprehensiveMedicalCheckup/cmc_page.dart | 2 +- .../E-Referral/e_referral_page.dart | 2 +- .../HomeHealthCare/home_health_care_page.dart | 2 +- .../AlHabibMedicalService/h2o/h2o_page.dart | 2 +- lib/pages/ErService/AmbulanceReq.dart | 2 +- lib/pages/feedback/feedback_home_page.dart | 2 +- lib/pages/landing/home_page.dart | 125 +++++++----------- lib/pages/medical/eye/EyeHomePage.dart | 2 +- .../my_trackers/Weight/WeightHomePage.dart | 2 +- .../blood_pressure/BloodPressureHomePage.dart | 2 +- .../blood_suger/blood_sugar_home_page.dart | 2 +- .../prescriptions_home_page.dart | 8 +- .../medical/reports/report_home_page.dart | 2 +- lib/uitl/translations_delegate_base.dart | 2 + .../medical/medical_profile_item.dart | 1 - 18 files changed, 99 insertions(+), 103 deletions(-) create mode 100644 assets/images/new-design/covid-19-car.svg 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/lib/config/localized_values.dart b/lib/config/localized_values.dart index 387dbcb1..a019ae00 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1449,4 +1449,12 @@ const Map localizedValues = { "en": "View List of Children", "ar": "عرض قائمة الأطفال" }, + "covidTest": { + "en": "COVID-19 TEST", + "ar": "فحص كورونا" + }, + "driveThru": { + "en": "Drive-Thru", + "ar": "من السيارة" + }, }; diff --git a/lib/core/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 04f599f1..8995a4e3 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -58,15 +58,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; diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart index 385d0da3..95d02d1f 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart @@ -78,7 +78,7 @@ class _CMCPageState 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/E-Referral/e_referral_page.dart b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart index 9f836860..a0583434 100644 --- a/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart +++ b/lib/pages/AlHabibMedicalService/E-Referral/e_referral_page.dart @@ -78,7 +78,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/home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart index 8f4821f6..f0dcee7c 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart @@ -80,7 +80,7 @@ class _HomeHealthCarePageState 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/h2o/h2o_page.dart b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart index ad2c6ece..8ac7b437 100644 --- a/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart +++ b/lib/pages/AlHabibMedicalService/h2o/h2o_page.dart @@ -68,7 +68,7 @@ class _H2OPageState extends State isScrollable: false, 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/ErService/AmbulanceReq.dart b/lib/pages/ErService/AmbulanceReq.dart index 1690254a..3d4192c5 100644 --- a/lib/pages/ErService/AmbulanceReq.dart +++ b/lib/pages/ErService/AmbulanceReq.dart @@ -92,7 +92,7 @@ class _AmbulanceReqState 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/feedback/feedback_home_page.dart b/lib/pages/feedback/feedback_home_page.dart index 309b5713..fe22b44a 100644 --- a/lib/pages/feedback/feedback_home_page.dart +++ b/lib/pages/feedback/feedback_home_page.dart @@ -73,7 +73,7 @@ class _FeedbackHomePageState 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/landing/home_page.dart b/lib/pages/landing/home_page.dart index cd8a8a2d..bcddd10c 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -73,7 +73,7 @@ class _HomePageState extends State { children: [ Expanded( child: Container( - height: 120, + height: 125, padding: EdgeInsets.all(5), margin: EdgeInsets.all(5), decoration: BoxDecoration( @@ -87,72 +87,50 @@ class _HomePageState extends State { 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, height: 45.0), ), Container( - margin: EdgeInsets.only( - left: 10.0, - top: 10.0), + margin: EdgeInsets.only(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( + shape: RoundedRectangleBorder( borderRadius: - BorderRadius - .circular( - 5.0), - ), - minWidth: MediaQuery.of( - context) - .size - .width * - 0.15, + BorderRadius.circular(5.0),), + minWidth: MediaQuery.of(context).size.width * 0.15, height: 25.0, child: RaisedButton( - color: Colors - .red[800], - textColor: - Colors.white, - disabledTextColor: - Colors.white, - disabledColor: - new Color( - 0xFFbcc2c4), + color: Colors.red[800], + textColor: Colors.white, + disabledTextColor: Colors.white, + disabledColor: 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 +148,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( @@ -208,7 +186,7 @@ class _HomePageState extends State { Orientation.landscape ? 0.02 : 0.03), - child: (!model.isLogin && projectViewModel.user == null) + child: (!model.isLogin) ? Container( width: double.infinity, height: 125, @@ -229,17 +207,15 @@ class _HomePageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( - height: 8, + height: 2, ), Texts( TranslationBase.of(context).myMedicalFile, color: Colors.black87, - bold: true, + fontWeight: FontWeight.w700, fontSize: 23, ), - SizedBox( - height: 5, - ), + Texts( TranslationBase.of(context) .myMedicalFileSubTitle, @@ -248,14 +224,14 @@ class _HomePageState extends State { ), Align( alignment: projectViewModel.isArabic - ? Alignment.bottomRight - : Alignment.bottomLeft, + ? Alignment.bottomLeft + : Alignment.bottomRight, child: InkWell( onTap: () { widget.goToMyProfile(); }, child: Container( - margin: EdgeInsets.all(2), + margin: EdgeInsets.only(left: 15,right: 15), width: 90, height: 30, decoration: BoxDecoration( @@ -265,13 +241,13 @@ class _HomePageState extends State { color: Colors.transparent, width: 0.5), borderRadius: BorderRadius.all( - Radius.circular(9)), + Radius.circular(0)), ), child: Center( child: Texts( - TranslationBase.of(context) - .viewMore, + TranslationBase.of(context).viewMore, color: Colors.white, + fontWeight: FontWeight.w700, fontSize: 12, ), ), @@ -303,7 +279,7 @@ class _HomePageState extends State { children: [ Row( children: [ - if (model.user != null) + if (projectViewModel.user != null && model.isLogin) Expanded( child: Column( crossAxisAlignment: @@ -368,13 +344,9 @@ class _HomePageState extends State { ], ), Row( - //crossAxisAlignment: CrossAxisAlignment.center, - //mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Expanded( child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, children: [ Image.asset( 'assets/images/height_icon.png', @@ -384,6 +356,7 @@ class _HomePageState extends State { Texts( "${model.heightCm}", color: Colors.white, + fontSize: 17, ) ], ), @@ -393,8 +366,6 @@ class _HomePageState extends State { ), Expanded( child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, children: [ Image.asset( 'assets/images/weight_icon.png', @@ -404,6 +375,7 @@ class _HomePageState extends State { Texts( '${model.weightKg}', color: Colors.white, + fontSize: 17 ) ], ), @@ -467,12 +439,11 @@ class _HomePageState extends State { height: 3, ), Texts( - TranslationBase.of(context) - .homeHealthCareService, + TranslationBase.of(context).homeHealthCareService, textAlign: TextAlign.center, color: Colors.white, - bold: true, - fontSize: SizeConfig.textMultiplier * 1.7, + fontWeight: FontWeight.w700, + fontSize: SizeConfig.textMultiplier * 1.55, ) ], ), @@ -503,8 +474,8 @@ class _HomePageState extends State { 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, ) ], ), @@ -540,8 +511,8 @@ class _HomePageState extends State { TranslationBase.of(context).emergencyService, textAlign: TextAlign.center, color: Colors.white, - bold: true, - fontSize: SizeConfig.textMultiplier * 1.7, + fontWeight: FontWeight.w700, + fontSize: SizeConfig.textMultiplier * 1.55, ) ], ), @@ -811,10 +782,8 @@ class DashboardItem extends StatelessWidget { onTap: onTap, child: Container( width: width != null ? width : MediaQuery.of(context).size.width * 0.29, - height: height != null - ? height - : MediaQuery.of(context).orientation == Orientation.portrait - ? MediaQuery.of(context).size.height * 0.19 + height: height != null ? height : MediaQuery.of(context).orientation == Orientation.portrait + ? MediaQuery.of(context).size.height * 0.17 : MediaQuery.of(context).size.height * 0.35, decoration: BoxDecoration( color: !hasBorder diff --git a/lib/pages/medical/eye/EyeHomePage.dart b/lib/pages/medical/eye/EyeHomePage.dart index 3f4df55f..bce778b8 100644 --- a/lib/pages/medical/eye/EyeHomePage.dart +++ b/lib/pages/medical/eye/EyeHomePage.dart @@ -74,7 +74,7 @@ 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), diff --git a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart index 8e6f808c..9bd89a2c 100644 --- a/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart +++ b/lib/pages/medical/my_trackers/Weight/WeightHomePage.dart @@ -70,7 +70,7 @@ class _WeightHomePageState 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/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart index e6bb3ed4..de8bb509 100644 --- a/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart +++ b/lib/pages/medical/my_trackers/blood_pressure/BloodPressureHomePage.dart @@ -73,7 +73,7 @@ class _BloodPressureHomePageState 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), 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..71df9a3a 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 @@ -74,7 +74,7 @@ class _BloodSugarHomePageState 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), 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/report_home_page.dart b/lib/pages/medical/reports/report_home_page.dart index d3c818ff..42dcf40a 100644 --- a/lib/pages/medical/reports/report_home_page.dart +++ b/lib/pages/medical/reports/report_home_page.dart @@ -101,7 +101,7 @@ 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: [ diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 63cf8a44..736e7e14 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1243,6 +1243,8 @@ 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]; } diff --git a/lib/widgets/data_display/medical/medical_profile_item.dart b/lib/widgets/data_display/medical/medical_profile_item.dart index 7fd97f52..1751e0e5 100644 --- a/lib/widgets/data_display/medical/medical_profile_item.dart +++ b/lib/widgets/data_display/medical/medical_profile_item.dart @@ -26,7 +26,6 @@ class MedicalProfileItem extends StatelessWidget { showBorder: true, borderWidth: 0, margin: 4, - height: 120, child: Container( padding: EdgeInsets.all(10), child: Column( From 30ddea6419a6d2650474c363d8031b2790c4f69b Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 13 Jan 2021 12:44:11 +0200 Subject: [PATCH 10/20] hot fixing --- lib/core/viewModels/appointment_rate_view_model.dart | 2 +- lib/main.dart | 4 ++-- lib/pages/landing/home_page.dart | 4 ++-- lib/pages/medical/balance/advance_payment_page.dart | 8 +++----- lib/pages/paymentService/payment_service.dart | 8 ++++---- lib/pages/rateAppointment/rate_appointment_clinic.dart | 4 ++-- lib/pages/rateAppointment/rate_appointment_doctor.dart | 2 +- lib/widgets/others/app_scaffold_widget.dart | 1 + 8 files changed, 16 insertions(+), 17 deletions(-) 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/main.dart b/lib/main.dart index fe129e01..e0444a32 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -100,14 +100,14 @@ class MyApp extends StatelessWidget { backgroundColor: Color.fromRGBO(255, 255, 255, 1), highlightColor: Colors.grey[100].withOpacity(0.4), splashColor: Colors.transparent, - primaryColor: Colors.grey, + primaryColor: Color(0xff515A5D), toggleableActiveColor: secondaryColor, indicatorColor: secondaryColor, bottomSheetTheme: BottomSheetThemeData(backgroundColor: HexColor('#E0E0E0')), cursorColor: Colors.grey, iconTheme: IconThemeData(), appBarTheme: AppBarTheme( - color: Colors.grey[700], + color: Color(0xff515A5D), brightness: Brightness.light, elevation: 0.0, actionsIconTheme: IconThemeData( diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index bcddd10c..fff74fd5 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -171,7 +171,7 @@ class _HomePageState extends State { ], ), ), - Container(width: double.infinity, height: 80) + Container(width: double.infinity, height:projectViewModel.isArabic ?110: 80) ], ), Positioned( @@ -260,7 +260,7 @@ class _HomePageState extends State { ) : Container( width: double.infinity, - height: 130, + height: projectViewModel.isArabic ? 160:130, decoration: BoxDecoration( color: HexColor('#A59E9E'), shape: BoxShape.rectangle, diff --git a/lib/pages/medical/balance/advance_payment_page.dart b/lib/pages/medical/balance/advance_payment_page.dart index a3005db5..fce664f7 100644 --- a/lib/pages/medical/balance/advance_payment_page.dart +++ b/lib/pages/medical/balance/advance_payment_page.dart @@ -238,15 +238,13 @@ class _AdvancePaymentPageState extends State { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.13, + height: MediaQuery.of(context).size.height * 0.10, width: double.infinity, - padding: EdgeInsets.all(12), + padding: EdgeInsets.all(18), child: SecondaryButton( textColor: Colors.white, label: TranslationBase.of(context).submit, - disabled: amount.isEmpty || - _fileTextController.text.isEmpty || - _selectedHospital == null, + disabled: amount.isEmpty || _fileTextController.text.isEmpty || _selectedHospital == null, onTap: () { var mobileNum; var patientName; diff --git a/lib/pages/paymentService/payment_service.dart b/lib/pages/paymentService/payment_service.dart index c3a19917..cca506ec 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/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/widgets/others/app_scaffold_widget.dart b/lib/widgets/others/app_scaffold_widget.dart index a1c28f7e..fca914a0 100644 --- a/lib/widgets/others/app_scaffold_widget.dart +++ b/lib/widgets/others/app_scaffold_widget.dart @@ -84,6 +84,7 @@ class AppScaffold extends StatelessWidget { isShowDecPage: isShowDecPage, image: image, ):null, + bottomSheet: bottomSheet, body: (!Provider.of(context, listen: false).isLogin && isShowDecPage) ? NotAutPage( From e2bce87e34195476195716ad4f974986388a8271 Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Wed, 13 Jan 2021 14:39:36 +0300 Subject: [PATCH 11/20] resolve merge conflicts. --- ios/Flutter/.last_build_id | 6 +---- lib/config/config.dart | 4 +-- lib/pages/landing/landing_page.dart | 35 +++++++++++++++----------- lib/uitl/utils.dart | 38 ++++++++++++++++++----------- 4 files changed, 48 insertions(+), 35 deletions(-) diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index 6ccef9d4..b8024672 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1,5 +1 @@ -<<<<<<< HEAD -e7c24319209ad9049a87d4c83aeeb7de -======= -59a6c452ee075b50114918f17f1ad8f5 ->>>>>>> development +59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file diff --git a/lib/config/config.dart b/lib/config/config.dart index 795da85b..4315f13c 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; -const BASE_URL = 'https://uat.hmgwebservices.com/'; -// const BASE_URL = 'https://hmgwebservices.com/'; +// const BASE_URL = 'https://uat.hmgwebservices.com/'; +const BASE_URL = 'https://hmgwebservices.com/'; //const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart index f45b3780..eabff77a 100644 --- a/lib/pages/landing/landing_page.dart +++ b/lib/pages/landing/landing_page.dart @@ -613,20 +613,27 @@ class _LandingPageState extends State with WidgetsBindingObserver { } } - void checkUserStatus(token) async { - var result = await authService.selectDeviceImei(token); - await setUserValues(result); + void checkUserStatus(token, {isLoader = true}) async { + if (isLoader) + //GifLoaderDialogUtils.showMyDialog(context); + authService + .selectDeviceImei(token) + .then((SelectDeviceIMEIRES value) => setUserValues(value)) + .catchError((err) { + //GifLoaderDialogUtils.hideDialog(context); + }); - if (await sharedPref.getObject(USER_PROFILE) != null) { - 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(() { - notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); - }) - }); - } - } + // if (await sharedPref.getObject(USER_PROFILE) != null) { + // 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(() { + // notificationCount = value['List_PatientDashboard'][0]['UnreadPatientNotificationCount'].toString(); + // }) + // }); + // } + // } } + } diff --git a/lib/uitl/utils.dart b/lib/uitl/utils.dart index fdbb1314..b2c52b2b 100644 --- a/lib/uitl/utils.dart +++ b/lib/uitl/utils.dart @@ -4,7 +4,9 @@ import 'dart:typed_data'; import 'package:badges/badges.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/models/Authentication/authenticated_user.dart'; import 'package:diplomaticquarterapp/pages/Blood/my_balance_page.dart'; import 'package:diplomaticquarterapp/pages/MyAppointments/MyAppointments.dart'; import 'package:diplomaticquarterapp/pages/insurance/insurance_approval_screen.dart'; @@ -33,6 +35,7 @@ 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:shared_preferences/shared_preferences.dart'; import '../Constants.dart'; import 'app_shared_preferences.dart'; @@ -491,22 +494,24 @@ class Utils { ), )); } - if (projectViewModel.havePrivilege(32)) { + if (projectViewModel.havePrivilege(32) || true) { medical.add(InkWell( onTap: () { - if (projectViewModel.isLogin) { - String patientID = AuthProvider().getAuthenticatedUser().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); - } + 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, @@ -534,6 +539,11 @@ class Utils { } } +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 extension IndexedIterable on Iterable { Iterable mapIndexed(T Function(E e, int i) f) { From d2e1a323ce4aa0b995756cc38de4204d5b05a3e6 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 13 Jan 2021 13:50:39 +0200 Subject: [PATCH 12/20] simple fix --- lib/pages/pharmacies/screens/cart-order-page.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages/pharmacies/screens/cart-order-page.dart b/lib/pages/pharmacies/screens/cart-order-page.dart index 51d93d71..cca6c1df 100644 --- a/lib/pages/pharmacies/screens/cart-order-page.dart +++ b/lib/pages/pharmacies/screens/cart-order-page.dart @@ -28,7 +28,6 @@ class CartOrderPage extends StatelessWidget { child: AppScaffold( appBarTitle: TranslationBase.of(context).shoppingCart, isShowAppBar: true, - isShowDecPage: false, isPharmacy: true, baseViewModel: model, backgroundColor: Colors.white, From 01bfe8464489de10fdcfd0f65822215e59dbc965 Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 13 Jan 2021 14:44:23 +0200 Subject: [PATCH 13/20] solving NearestEr design problem --- lib/pages/ErService/NearestEr.dart | 65 ++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 13 deletions(-) diff --git a/lib/pages/ErService/NearestEr.dart b/lib/pages/ErService/NearestEr.dart index 227cfb3b..bb8babe1 100644 --- a/lib/pages/ErService/NearestEr.dart +++ b/lib/pages/ErService/NearestEr.dart @@ -42,6 +42,57 @@ class NearestEr extends StatelessWidget { fontWeight: FontWeight.w900, color: new Color(0xFF60686b))), Container( + margin: EdgeInsets.fromLTRB(2.0, 10.0, 0.0, 10.0), + child: GridView.count( + crossAxisCount: 2, + // childAspectRatio: 2.2, + 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: 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, + ), + ), + ); + }), + ), + ), + /* Container( margin: EdgeInsets.fromLTRB(0.0, 10.0, 0.0, 10.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -85,7 +136,6 @@ class NearestEr extends StatelessWidget { .projectName, ), ), - ), Expanded( child: Container( @@ -122,7 +172,6 @@ class NearestEr extends StatelessWidget { .projectName, ), ), - ) ], ), @@ -133,14 +182,12 @@ class NearestEr extends StatelessWidget { 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 @@ -167,19 +214,16 @@ class NearestEr extends StatelessWidget { .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 @@ -217,14 +261,12 @@ class NearestEr extends StatelessWidget { 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 @@ -251,7 +293,6 @@ class NearestEr extends StatelessWidget { .projectName, ), ), - ), Expanded( child: Container( @@ -288,7 +329,6 @@ class NearestEr extends StatelessWidget { .projectName, ), ), - ) ], ), @@ -336,7 +376,7 @@ class NearestEr extends StatelessWidget { ], ), ], - )), + )),*/ ], ), ) @@ -347,4 +387,3 @@ class NearestEr extends StatelessWidget { ); } } - From 5bcc67b77d50b582490a21e20bd731899505286b Mon Sep 17 00:00:00 2001 From: mosazaid Date: Wed, 13 Jan 2021 15:53:31 +0200 Subject: [PATCH 14/20] Nearest Er fix design --- lib/config/localized_values.dart | 8 + lib/pages/ErService/NearestEr.dart | 360 ++---------------- .../ErService/widgets/card_position.dart | 19 +- lib/uitl/translations_delegate_base.dart | 2 + 4 files changed, 61 insertions(+), 328 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index a019ae00..6245735d 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1457,4 +1457,12 @@ const Map localizedValues = { "en": "Drive-Thru", "ar": "من السيارة" }, + "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" + }, }; diff --git a/lib/pages/ErService/NearestEr.dart b/lib/pages/ErService/NearestEr.dart index bb8babe1..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, @@ -45,7 +49,7 @@ class NearestEr extends StatelessWidget { margin: EdgeInsets.fromLTRB(2.0, 10.0, 0.0, 10.0), child: GridView.count( crossAxisCount: 2, - // childAspectRatio: 2.2, + childAspectRatio: (itemWidth / itemWidth), crossAxisSpacing: 10, mainAxisSpacing: 10, controller: @@ -54,329 +58,43 @@ class NearestEr extends StatelessWidget { padding: const EdgeInsets.all(4.0), children: List.generate(7, (index) { return Container( - child: 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, - ), + 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, ), ); }), ), ), - /* 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, - ), - ), - ) - ], - ), - 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, - ), - ], - ), - ], - )),*/ ], ), ) 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/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 736e7e14..257ceb8e 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1245,6 +1245,8 @@ class TranslationBase { 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]; } From b63025a9b3ee16bb39c6dbb6b4e791b6f269890a Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Wed, 13 Jan 2021 17:21:14 +0200 Subject: [PATCH 15/20] return CMC HHC --- .../AlHabibMedicalService/cmc_service.dart | 6 +- .../home_health_care_service.dart | 12 +- lib/core/service/client/base_app_client.dart | 2 +- .../Dialog/confirm_cancel_order_dialog.dart | 4 +- .../NewCMC/cmc_location_page.dart | 148 +++++++ .../NewCMC/new_cmc_page.dart | 318 ++++++++------- .../NewCMC/new_cmc_step_one_page.dart | 219 ++++++---- .../NewCMC/new_cmc_step_three_page.dart | 83 ++-- .../NewCMC/new_cmc_step_tow_page.dart | 202 ++++++--- .../ComprehensiveMedicalCheckup/cmc_page.dart | 6 +- .../orders_log_details_page.dart | 102 ++--- .../Dialog/confirm_cancel_order_dialog.dart | 4 +- .../NewHomeHealthCare/location_page.dart | 146 +++++++ .../new_Home_health_care_step_one_page.dart | 53 ++- .../new_Home_health_care_step_three_page.dart | 16 +- .../new_Home_health_care_step_tow_page.dart | 196 ++++++--- .../new_home_health_care_page.dart | 45 +- .../HomeHealthCare/home_health_care_page.dart | 1 + .../orders_log_details_page.dart | 386 +++++++++--------- lib/pages/ContactUs/findus/findus_page.dart | 3 - .../ContactUs/widgets/card_common_contat.dart | 4 +- lib/pages/feedback/send_feedback_page.dart | 26 +- .../dialogs/SelectBeneficiaryDialog.dart | 3 +- .../balance/dialogs/SelectHospitalDialog.dart | 4 +- .../dialogs/SelectPatientFamilyDialog.dart | 4 +- .../dialogs/SelectPatientInfoDialog.dart | 4 +- lib/widgets/buttons/secondary_button.dart | 2 +- .../dialogs/select_location_dialog.dart | 139 +++++++ 28 files changed, 1462 insertions(+), 676 deletions(-) create mode 100644 lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_location_page.dart create mode 100644 lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart create mode 100644 lib/widgets/dialogs/select_location_dialog.dart 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/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/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8995a4e3..cbe2410d 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -46,7 +46,7 @@ class BaseAppClient { //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); if (!isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = await sharedPref.getString(APP_LANGUAGE); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE,'ar'); var user = await sharedPref.getObject(USER_PROFILE); if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') 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..4e396427 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/cmc_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/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..ecfe31fb 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'; @@ -46,7 +49,7 @@ 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 +88,8 @@ class _NewCMCPageState extends State @override Widget build(BuildContext context) { + ProjectViewModel projectViewModel = Provider.of(context); + void showConfirmMessage( CMCViewModel model, GetOrderDetailByOrderIDResponseModel order) { showDialog( @@ -101,7 +106,7 @@ class _NewCMCPageState 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.getCmcAllPresOrders(); } }, @@ -134,183 +139,192 @@ 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: SingleChildScrollView( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - SizedBox( - height: 12, - ), Container( width: double.infinity, - padding: EdgeInsets.only( - left: 15, bottom: 15, top: 15), + margin: EdgeInsets.only(top: 15), decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, - ), - ), - // borderRadius: BorderRadius.circular(12), + border: + Border.all(color: Colors.grey, width: 1), + borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts( - "Request ID", - bold: false, - fontSize: 13, - ), SizedBox( - height: 4, + height: 12, ), - 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, + 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( + widget.model.cmcAllOrderDetail[0].iD.toString(), + fontSize: 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, + 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 ? 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), - decoration: BoxDecoration( - border: Border( - bottom: BorderSide( - color: Colors.grey, - width: 1.0, + 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(widget.model.cmcAllOrderDetail[0].createdOn)), + fontSize: 22, + ), + ], ), ), - // borderRadius: BorderRadius.circular(12), - color: Colors.white), - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Texts( - "Pickup Date", - bold: false, - fontSize: 13, + 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( + 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: 4, - ), - Texts( - DateUtil.getDayMonthYearDateFormatted( - DateUtil.convertStringToDate( - widget.model.cmcAllOrderDetail[0] - .createdOn)), - fontSize: 22, + 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, + 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), ), ), - // 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, + height: 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, + height: 22, ), ], ), 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..b80d125a 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,17 +57,17 @@ class _NewCMCStepOnePageState extends State { height: 20, ), Texts( - "Select Home Health Care Services", + TranslationBase.of(context).selectService, textAlign: TextAlign.center, ), Column( children: - widget.model.cmcAllServicesList.map((service) { + widget.model.cmcAllServicesList.map((service) { return Container( margin: EdgeInsets.only(top: 15), decoration: BoxDecoration( border: - Border.all(color: Colors.grey, width: 1), + Border.all(color: Colors.grey, width: 1), borderRadius: BorderRadius.circular(12), color: Colors.white), child: Column( @@ -72,50 +79,53 @@ class _NewCMCStepOnePageState extends State { activeColor: Colors.red[800], onChanged: (newValue) async { PatientERCMCInsertServicesList - patientERCMCInsertServicesList = - new PatientERCMCInsertServicesList( - price: service.price, - serviceID: service.serviceID - .toString(), - selectedServiceName: - service.description, - selectedServiceNameAR: - service.description, - recordID: 1, - totalPrice: - service.totalPrice, - vAT: service.vAT); + patientERCMCInsertServicesList = + new PatientERCMCInsertServicesList( + price: service.price, + serviceID: service.serviceID + .toString(), + selectedServiceName: + service.description, + selectedServiceNameAR: + service.descriptionN, + recordID: 1, + totalPrice: + service.totalPrice, + vAT: service.vAT); setState(() { widget .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList = [ + .patientERCMCInsertServicesList = + [ patientERCMCInsertServicesList ]; }); CMCGetItemsRequestModel - cMCGetItemsRequestModel = - new CMCGetItemsRequestModel( - checkupType: newValue); + cMCGetItemsRequestModel = + new CMCGetItemsRequestModel( + checkupType: newValue); await widget.model.getCheckupItems( cMCGetItemsRequestModel: - cMCGetItemsRequestModel); + cMCGetItemsRequestModel); }, groupValue: widget - .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList - .length > - 0 + .cMCInsertPresOrderRequestModel + .patientERCMCInsertServicesList + .length > + 0 ? int.parse(widget - .cMCInsertPresOrderRequestModel - .patientERCMCInsertServicesList[ - 0] - .serviceID) + .cMCInsertPresOrderRequestModel + .patientERCMCInsertServicesList[ + 0] + .serviceID) : 1), Expanded( child: Padding( padding: const EdgeInsets.all(20.0), child: Texts( - service.description, + projectViewModel.isArabic ? service + .descriptionN : service + .description, fontSize: 15, ), ), @@ -137,52 +147,67 @@ class _NewCMCStepOnePageState extends State { color: Colors.white, 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: + 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: 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: [ + 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 +222,48 @@ class _NewCMCStepOnePageState extends State { Container( width: MediaQuery.of(context).size.width * 0.9, child: SecondaryButton( - label: "Next", - textColor: Theme.of(context).backgroundColor, - onTap: () { - if (widget.cMCInsertPresOrderRequestModel.patientERCMCInsertServicesList.length = null) { + label: TranslationBase + .of(context) + .next, + textColor: Theme + .of(context) + .backgroundColor, + 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, - recordID: 1, - totalPrice: widget.model.cmcAllServicesList[index-1].totalPrice, - vAT: widget.model.cmcAllServicesList[index-1].vAT); + 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].descriptionN, + recordID: 1, + 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..eea9853b 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; @@ -63,19 +64,23 @@ 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, ), @@ -87,7 +92,9 @@ class _NewCMCStepThreePageState child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Location :'), + Texts(TranslationBase + .of(context) + .orderLocation + " : ", fontWeight: FontWeight.bold,), SizedBox( height: 12, ), @@ -108,30 +115,40 @@ class _NewCMCStepThreePageState SizedBox( height: 12, ), - Texts('Selected Service :'), + Texts(TranslationBase + .of(context) + .selectedService), ...List.generate( - widget.cmcInsertPresOrderRequestModel.patientERCMCInsertServicesList.length, - (index) => Container( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Texts( - 'Service Name :', - fontSize: 12, - ), - SizedBox( - height: 5, - ), - Texts( - widget - .cmcInsertPresOrderRequestModel.patientERCMCInsertServicesList[index] - .selectedServiceName, - fontSize: 15, - bold: true, + widget.cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList.length, + (index) => + Container( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Texts( + TranslationBase + .of(context) + .serviceName, + fontSize: 12, fontWeight: FontWeight.bold, + ), + SizedBox( + height: 5, + ), + Texts( + projectViewModel.isArabic ? widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList[index] + .selectedServiceNameAR : widget + .cmcInsertPresOrderRequestModel + .patientERCMCInsertServicesList[index] + .selectedServiceName, + fontSize: 15, + bold: true, + ), + ], ), - ], - ), - ), + ), ) ], ), @@ -148,14 +165,20 @@ 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); } }, - textColor: Theme.of(context).backgroundColor), + textColor: Theme + .of(context) + .backgroundColor), ), ], ), 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..cc8ea8dd 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,22 @@ 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: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; @@ -41,12 +44,13 @@ 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 +58,152 @@ 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( + 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, + MaterialPageRoute( + builder: (BuildContext context) => + 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: 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/ComprehensiveMedicalCheckup/cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart index 95d02d1f..c73f328d 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart @@ -40,7 +40,8 @@ class _CMCPageState extends State }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, - appBarTitle: TranslationBase.of(context).homeHealthCare, + description: TranslationBase.of(context).HHCNotAuthMsg, + appBarTitle: TranslationBase.of(context).comprehensiveMedicalCheckup, body: Scaffold( extendBodyBehindAppBar: true, appBar: PreferredSize( @@ -88,7 +89,8 @@ class _CMCPageState extends State Container( width: MediaQuery.of(context).size.width * 0.37, child: Center( - child: Texts("CMC Service"), + child: Texts(TranslationBase.of(context) + .comprehensiveMedicalCheckup), ), ), Container( 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/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..4bf3a762 --- /dev/null +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/NewHomeHealthCare/location_page.dart @@ -0,0 +1,146 @@ +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( + 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(); + }, + 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..447ba177 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 @@ -45,6 +46,8 @@ 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, + MaterialPageRoute( + builder: (BuildContext context) => + 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..d9bf67d8 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'; @@ -84,7 +87,7 @@ 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 +95,8 @@ class _NewHomeHealthCarePageState extends State )); } + ProjectViewModel projectViewModel = Provider.of(context); + return Scaffold( body: SafeArea( child: SingleChildScrollView( @@ -99,7 +104,6 @@ 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), child: StepsWidget( @@ -138,7 +142,7 @@ 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( @@ -152,7 +156,9 @@ class _NewHomeHealthCarePageState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Request ID", + TranslationBase + .of(context) + .requestID, bold: false, fontSize: 13, ), @@ -169,7 +175,7 @@ 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( @@ -183,7 +189,9 @@ class _NewHomeHealthCarePageState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Status", + TranslationBase + .of(context) + .OrderStatus, bold: false, fontSize: 13, ), @@ -191,7 +199,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 +212,7 @@ 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( @@ -214,7 +226,7 @@ class _NewHomeHealthCarePageState extends State crossAxisAlignment: CrossAxisAlignment.start, children: [ Texts( - "Pickup Date", + TranslationBase.of(context).pickupDate, bold: false, fontSize: 13, ), @@ -235,7 +247,7 @@ 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( @@ -250,7 +262,9 @@ class _NewHomeHealthCarePageState extends State CrossAxisAlignment.start, children: [ Texts( - "Service Name", + TranslationBase + .of(context) + .serviceName, bold: false, fontSize: 13, ), @@ -258,7 +272,12 @@ class _NewHomeHealthCarePageState extends State height: 4, ), Texts( - widget.model.hhcAllOrderDetail[index] + projectViewModel.isArabic + ? widget.model + .hhcAllOrderDetail[index] + .descriptionN + : widget.model + .hhcAllOrderDetail[index] .description, fontSize: 22, bold: true, @@ -275,7 +294,7 @@ class _NewHomeHealthCarePageState extends State 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]); diff --git a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart index f0dcee7c..3180cf18 100644 --- a/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart +++ b/lib/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_page.dart @@ -42,6 +42,7 @@ class _HomeHealthCarePageState extends State }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + description: TranslationBase.of(context).HHCNotAuthMsg, appBarTitle: TranslationBase.of(context).homeHealthCare, body: Scaffold( extendBodyBehindAppBar: true, 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/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/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/feedback/send_feedback_page.dart b/lib/pages/feedback/send_feedback_page.dart index 4d511452..aded1a3b 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'; @@ -417,27 +418,26 @@ class _SendFeedbackPageState extends State { ), ), bottomSheet: Container( - height: MediaQuery.of(context).size.height * 0.13, + height: MediaQuery.of(context).size.height * 0.09, 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( + height: MediaQuery.of(context).size.height * 0.8, + child: SecondaryButton( label: TranslationBase.of(context).send, - loading: model.state == ViewState.BusyLocal, + 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 +448,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); } 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/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/widgets/buttons/secondary_button.dart b/lib/widgets/buttons/secondary_button.dart index 46b4abfb..8884039b 100644 --- a/lib/widgets/buttons/secondary_button.dart +++ b/lib/widgets/buttons/secondary_button.dart @@ -23,7 +23,7 @@ class SecondaryButton extends StatefulWidget { this.icon, this.iconOnly = false, this.color , - this.textColor, + this.textColor = Colors.white, this.onTap, this.loading: false, this.small = false, diff --git a/lib/widgets/dialogs/select_location_dialog.dart b/lib/widgets/dialogs/select_location_dialog.dart new file mode 100644 index 00000000..77916ddc --- /dev/null +++ b/lib/widgets/dialogs/select_location_dialog.dart @@ -0,0 +1,139 @@ +import 'package:diplomaticquarterapp/core/service/AlHabibMedicalService/customer_addresses_service.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'; + +// ignore: must_be_immutable +class SelectLocationDialog extends StatefulWidget { + final List addresses; + final Function(AddressInfo) onValueSelected; + AddressInfo selectedAddress; + + SelectLocationDialog( + {Key key, this.addresses, this.onValueSelected, this.selectedAddress}); + + @override + _SelectLocationDialogState createState() => _SelectLocationDialogState(); +} + +class _SelectLocationDialogState extends State { + @override + void initState() { + super.initState(); + widget.selectedAddress = widget.selectedAddress ?? widget.addresses[0]; + } + + @override + Widget build(BuildContext context) { + return SimpleDialog( + title: Texts(TranslationBase.of(context).selectAddress), + children: [ + Column( + children: [ + Container( + height: 150, + child: SingleChildScrollView( + child: Column( + children: [ + Divider(), + ...List.generate( + widget.addresses.length, + (index) => Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: 2, + ), + Row( + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + setState(() { + widget.selectedAddress = widget.addresses[index]; + }); + }, + child: ListTile( + title: Text(widget.addresses[index].address1), + leading: Radio( + value: widget.addresses[index], + groupValue: widget.selectedAddress, + activeColor: Colors.red[800], + onChanged: (value) { + setState(() { + widget.selectedAddress = value; + }); + }, + ), + ), + ), + ) + ], + ), + SizedBox( + height: 5.0, + ), + ], + ), + ), + SizedBox( + height: 5.0, + ), + ], + ), + ), + ), + Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + flex: 1, + child: InkWell( + onTap: () { + Navigator.pop(context); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + child: Center( + child: Texts( + TranslationBase.of(context).cancel.toUpperCase(), + color: Colors.red, + ), + ), + ), + ), + ), + ), + Container( + width: 1, + height: 30, + color: Colors.grey[500], + ), + Expanded( + flex: 1, + child: InkWell( + onTap: () { + widget.onValueSelected(widget.selectedAddress); + Navigator.pop(context); + }, + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: Texts( + TranslationBase.of(context).ok, + fontWeight: FontWeight.w400, + )), + ), + ), + ), + ], + ) + ], + ) + ], + ); + } +} From d7a046f9ca0028a5a149638aebb2a4f21accddcc Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 13 Jan 2021 17:58:45 +0200 Subject: [PATCH 16/20] fix issue on cmc --- help/ios/Runner/Info.plist | 3 + ios/Flutter/.last_build_id | 2 +- ios/Podfile.lock | 6 +- ios/Runner.xcodeproj/project.pbxproj | 28 ++++---- lib/config/localized_values.dart | 4 ++ lib/core/model/ImagesInfo.dart | 3 +- lib/core/service/client/base_app_client.dart | 2 +- .../cmc_index_page.dart | 68 ------------------- .../ComprehensiveMedicalCheckup/cmc_page.dart | 4 ++ lib/pages/landing/home_page.dart | 4 +- lib/uitl/translations_delegate_base.dart | 1 + lib/widgets/others/not_auh_page.dart | 2 +- 12 files changed, 36 insertions(+), 91 deletions(-) delete mode 100644 lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_index_page.dart 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/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index b8024672..df846dd6 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file +269226e53e3ba1b1460fd3df51f89f77 \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index a09481c1..82d4be18 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -162,7 +162,7 @@ PODS: - "twilio_programmable_video (0.5.0+4)": - Flutter - TwilioVideo (~> 3.4) - - TwilioVideo (3.7.2) + - TwilioVideo (3.8.0) - url_launcher (0.0.1): - Flutter - url_launcher_linux (0.0.1): @@ -436,7 +436,7 @@ SPEC CHECKSUMS: TOCropViewController: da59f531f8ac8a94ef6d6c0fc34009350f9e8bfe Try: 5ef669ae832617b3cee58cb2c6f99fb767a4ff96 twilio_programmable_video: 6a41593640f3d86af60b22541fd457b22deaae7f - TwilioVideo: 5257640fab00d1b9f44db060815b03516a9eb0e8 + TwilioVideo: c13a51ceca375e91620eb7578d2573c90cf53b46 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef url_launcher_linux: ac237cb7a8058736e4aae38bdbcc748a4b394cc0 url_launcher_macos: fd7894421cd39320dce5f292fc99ea9270b2a313 @@ -452,4 +452,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 -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..0f0f942c 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -214,7 +214,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 125A739F71A29FBAE7B4D5AC /* [CP] Embed Pods Frameworks */, - 940F4A376A48B060117A1E5D /* [CP] Copy Pods Resources */, + CBB18A5CEEEB971DCFC36E00 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -330,36 +330,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 */ = { + CBB18A5CEEEB971DCFC36E00 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", ); - name = "Run Script"; - outputPaths = ( + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${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-resources.sh\"\n"; + showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index a019ae00..df1ddb97 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1457,4 +1457,8 @@ const Map localizedValues = { "en": "Drive-Thru", "ar": "من السيارة" }, + "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": "من خلال هذه الخدمة يمكنك طلب مجموعة من الفحوصات التي تساعدك وتساعد طبيبك في فهم حالتك الصحية الحالية ومن ثم تحديد المخاطر المحتملة" + }, }; 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/service/client/base_app_client.dart b/lib/core/service/client/base_app_client.dart index 8995a4e3..cbe2410d 100644 --- a/lib/core/service/client/base_app_client.dart +++ b/lib/core/service/client/base_app_client.dart @@ -46,7 +46,7 @@ class BaseAppClient { //Map profile = await sharedPref.getObj(DOCTOR_PROFILE); if (!isExternal) { String token = await sharedPref.getString(TOKEN); - var languageID = await sharedPref.getString(APP_LANGUAGE); + var languageID = await sharedPref.getStringWithDefaultValue(APP_LANGUAGE,'ar'); var user = await sharedPref.getObject(USER_PROFILE); if (body.containsKey('SetupID')) { body['SetupID'] = body.containsKey('SetupID') 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 95d02d1f..6becba6a 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'; @@ -40,6 +41,9 @@ class _CMCPageState extends State }, builder: (_, model, widget) => AppScaffold( isShowAppBar: true, + description:TranslationBase.of(context).infoCMC, + image: 'assets/images/AlHabibMedicalService/Wifi-AR.png', + imagesInfo: [ImagesInfo(imageAr: 'assets/images/AlHabibMedicalService/Wifi-AR.png',imageEn: 'assets/images/AlHabibMedicalService/Wifi-EN.png', isAsset: true)], appBarTitle: TranslationBase.of(context).homeHealthCare, body: Scaffold( extendBodyBehindAppBar: true, diff --git a/lib/pages/landing/home_page.dart b/lib/pages/landing/home_page.dart index fff74fd5..87afb17f 100644 --- a/lib/pages/landing/home_page.dart +++ b/lib/pages/landing/home_page.dart @@ -1,7 +1,7 @@ import 'package:diplomaticquarterapp/config/size_config.dart'; import 'package:diplomaticquarterapp/core/viewModels/dashboard_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/ComprehensiveMedicalCheckup/cmc_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/HomeHealthCare/home_health_care_index_page.dart'; import 'package:diplomaticquarterapp/pages/AlHabibMedicalService/all_habib_medical_service_page.dart'; import 'package:diplomaticquarterapp/pages/ContactUs/contact_us_page.dart'; @@ -490,7 +490,7 @@ class _HomePageState extends State { Navigator.push( context, FadePage( - page: CMCIndexPage(), + page: CMCPage(), ), ); }, diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 736e7e14..50e9dd48 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1245,6 +1245,7 @@ class TranslationBase { localizedValues['shoppingCart'][locale.languageCode]; String get covidTest => localizedValues['covidTest'][locale.languageCode]; String get driveThru => localizedValues['driveThru'][locale.languageCode]; + String get infoCMC => localizedValues['infoCMC'][locale.languageCode]; } diff --git a/lib/widgets/others/not_auh_page.dart b/lib/widgets/others/not_auh_page.dart index 0dbbee43..4bda58a4 100644 --- a/lib/widgets/others/not_auh_page.dart +++ b/lib/widgets/others/not_auh_page.dart @@ -108,7 +108,7 @@ class _NotAutPageState extends State { builder: (BuildContext context){ return SizedBox( width: MediaQuery.of(context).size.width * 0.50, - child: Image.network(projectViewModel.isArabic ? image.imageAr : image.imageEn)); + child: image.isAsset? Image.asset(projectViewModel.isArabic ? image.imageAr : image.imageEn) : Image.network(projectViewModel.isArabic ? image.imageAr : image.imageEn)); }, ); }).toList(), From 4ecce792585b9c3146b4b2247f0a98410b997d4d Mon Sep 17 00:00:00 2001 From: Elham Rababah Date: Wed, 13 Jan 2021 20:33:20 +0200 Subject: [PATCH 17/20] first step from fix CMC --- .../NewCMC/new_cmc_page.dart | 15 +++++++++------ .../ComprehensiveMedicalCheckup/cmc_page.dart | 6 +++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart index ecfe31fb..2a7696b7 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/NewCMC/new_cmc_page.dart @@ -119,13 +119,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(), diff --git a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart index 04fca1c6..b745e0c9 100644 --- a/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart +++ b/lib/pages/AlHabibMedicalService/ComprehensiveMedicalCheckup/cmc_page.dart @@ -36,13 +36,13 @@ 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, description:TranslationBase.of(context).infoCMC, - image: 'assets/images/AlHabibMedicalService/Wifi-AR.png', imagesInfo: [ImagesInfo(imageAr: 'assets/images/AlHabibMedicalService/Wifi-AR.png',imageEn: 'assets/images/AlHabibMedicalService/Wifi-EN.png', isAsset: true)], appBarTitle: TranslationBase.of(context).comprehensiveMedicalCheckup, body: Scaffold( From 200334d8f83866baa67bfba81e6214fe0b74b174 Mon Sep 17 00:00:00 2001 From: Mohammad Aljammal Date: Sun, 17 Jan 2021 17:07:50 +0200 Subject: [PATCH 18/20] Fix ER service --- ios/Flutter/.last_build_id | 2 +- ios/Podfile.lock | 2 +- lib/config/config.dart | 4 +- lib/config/localized_values.dart | 13 +- lib/core/model/er/PickUpRequestPresOrder.dart | 4 +- lib/core/model/reports/Reports.dart | 76 ++--- lib/core/service/medical/reports_service.dart | 13 + .../medical/reports_monthly_view_model.dart | 32 ++- lib/pages/ErService/AmbulanceReq.dart | 5 +- .../AmbulanceRequestIndex.dart | 14 +- .../BillAmount.dart | 29 +- .../PickupLocation.dart | 37 +-- .../SelectTransportationMethod.dart | 19 +- .../AmbulanceRequestIndexPages/Summary.dart | 9 +- lib/pages/feedback/feedback_home_page.dart | 1 - .../medical/reports/monthly_reports.dart | 266 ++++++++++-------- lib/uitl/translations_delegate_base.dart | 4 +- lib/widgets/input/text_field.dart | 8 +- 18 files changed, 304 insertions(+), 234 deletions(-) diff --git a/ios/Flutter/.last_build_id b/ios/Flutter/.last_build_id index df846dd6..b8024672 100644 --- a/ios/Flutter/.last_build_id +++ b/ios/Flutter/.last_build_id @@ -1 +1 @@ -269226e53e3ba1b1460fd3df51f89f77 \ No newline at end of file +59a6c452ee075b50114918f17f1ad8f5 \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 82d4be18..77dfa5e1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -452,4 +452,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 5a17be3f8af73a757fa4439c77cf6ab2db29a6e7 -COCOAPODS: 1.10.0.rc.1 +COCOAPODS: 1.10.0 diff --git a/lib/config/config.dart b/lib/config/config.dart index cd7a5383..0c6b5d59 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -225,8 +225,8 @@ const GET_LIVECARE_HISTORY = 'Services/ER_VirtualCall.svc/REST/GetPatientErVirtu 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'; //URL to get medicine and pharmacies list const CHANNEL = 3; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index afb60a9d..aaa7f16a 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -288,7 +288,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": "ملفات العائلة"}, @@ -1065,7 +1065,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", @@ -1469,4 +1469,13 @@ const Map localizedValues = { "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": " رقم الطلب" + }, + }; 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/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/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/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/pages/ErService/AmbulanceReq.dart b/lib/pages/ErService/AmbulanceReq.dart index 3d4192c5..fe245133 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( @@ -92,8 +92,7 @@ class _AmbulanceReqState extends State isScrollable: true, controller: _tabController, indicatorWeight: 5.0, - indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], + indicatorSize: TabBarIndicatorSize.label, labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart index 5f303846..c07adabc 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/AmbulanceRequestIndex.dart @@ -46,7 +46,7 @@ class _AmbulanceRequestIndexPageState extends State { @override Widget build(BuildContext context) { return AppScaffold( - body: widget.amRequestViewModel.pickUpRequestPresOrder != null + body: false ? Column( children: [ SizedBox( @@ -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, ), diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart index cc6af0f2..aeb61609 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/BillAmount.dart @@ -2,6 +2,7 @@ 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:flutter/cupertino.dart'; @@ -51,7 +52,7 @@ class _BillAmountState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Bill Amount '), + Texts(TranslationBase.of(context).billAmount), SizedBox( height: 10, ), @@ -73,7 +74,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'Amount before tax: ', + TranslationBase.of(context).patientShareB, textAlign: TextAlign.start, color: Colors.black, fontSize: 15, @@ -91,7 +92,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.price}', + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.price}', color: Colors.black, textAlign: TextAlign.start, fontSize: 15, @@ -108,7 +109,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'Tax amount :', + TranslationBase.of(context).patientShareTax, color: Colors.black, fontSize: 15, textAlign: TextAlign.start, @@ -121,7 +122,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.vAT}', + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.vAT}', color: Colors.black, fontSize: 15, textAlign: TextAlign.start, @@ -143,7 +144,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'Total amount payable', + TranslationBase.of(context).patientShareTotal, color: Colors.black, fontSize: 15, textAlign: TextAlign.start, @@ -162,7 +163,7 @@ class _BillAmountState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Texts( - 'SR ${widget.patientER.patientERTransportationMethod.totalPrice}', + TranslationBase.of(context).sar+' ${widget.patientER.patientERTransportationMethod.totalPrice}', color: Colors.black, fontSize: 15, textAlign: TextAlign.start, @@ -176,7 +177,7 @@ class _BillAmountState extends State { SizedBox( height: 10, ), - Texts('Select Ambulate',bold: true,), + Texts(TranslationBase.of(context).selectAmbulate,bold: true,), SizedBox(height: 5,), Row( children: [ @@ -196,7 +197,7 @@ class _BillAmountState extends State { color: Colors.white, ), child: ListTile( - title: Text('Wheelchair'), + title: Text(TranslationBase.of(context).wheelchair), leading: Radio( value: Ambulate.Wheelchair, groupValue: _ambulate, @@ -227,7 +228,7 @@ class _BillAmountState extends State { color: Colors.white, ), child: ListTile( - title: Text('Walker'), + title: Text(TranslationBase.of(context).walker), leading: Radio( value: Ambulate.Walker, groupValue: _ambulate, @@ -263,7 +264,7 @@ class _BillAmountState extends State { color: Colors.white, ), child: ListTile( - title: Text('Stretcher'), + title: Text(TranslationBase.of(context).stretcher), leading: Radio( value: Ambulate.Stretcher, groupValue: _ambulate, @@ -294,7 +295,7 @@ class _BillAmountState extends State { color: Colors.white, ), child: ListTile( - title: Text('None'), + title: Text(TranslationBase.of(context).none), leading: Radio( value: Ambulate.None, groupValue: _ambulate, @@ -313,7 +314,7 @@ class _BillAmountState extends State { ), SizedBox(height: 12,), NewTextFields( - hintText: 'Note', + hintText: TranslationBase.of(context).notes, initialValue: note, onChanged: (value){ setState(() { @@ -340,7 +341,7 @@ class _BillAmountState extends State { widget.changeCurrentTab(3); }); }, - label: 'Next', + label: TranslationBase.of(context).next, ), ) ], diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart index b99596c8..f6ebfde9 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/PickupLocation.dart @@ -9,6 +9,7 @@ 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/translations_delegate_base.dart'; import 'package:diplomaticquarterapp/widgets/buttons/secondary_button.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/pickupLocation/PickupLocationFromMap.dart'; @@ -78,7 +79,7 @@ class _PickupLocationState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Pickup Location'), + Texts(TranslationBase.of(context).pickupLocation), SizedBox( height: 15, ), @@ -110,7 +111,7 @@ class _PickupLocationState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getSelectFromMapName()), + Texts(getSelectFromMapName(context)), Icon( FontAwesomeIcons.mapMarkerAlt, size: 24, @@ -123,7 +124,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts('Pickup Spot'), + Texts(TranslationBase.of(context).pickupSpot), SizedBox( height: 5, ), @@ -141,7 +142,7 @@ class _PickupLocationState extends State { color: Colors.white, ), child: ListTile( - title: Texts('Inside Home'), + title: Texts(TranslationBase.of(context).insideHome), leading: Checkbox( activeColor: Colors.red[800], value: _isInsideHome, @@ -157,7 +158,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts('Do you have an appointment ?'), + Texts(TranslationBase.of(context).haveAppo), SizedBox( height: 5, ), @@ -182,7 +183,7 @@ class _PickupLocationState extends State { color: Colors.white, ), child: ListTile( - title: Text('Yes'), + title: Texts(TranslationBase.of(context).yes), leading: Radio( value: HaveAppointment.YES, groupValue: _haveAppointment, @@ -217,7 +218,7 @@ class _PickupLocationState extends State { color: Colors.white, ), child: ListTile( - title: Text('No'), + title: Texts(TranslationBase.of(context).no), leading: Radio( value: HaveAppointment.NO, groupValue: _haveAppointment, @@ -250,7 +251,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts('Drop off Location'), + Texts(TranslationBase.of(context).dropoffLocation), SizedBox( height: 8, ), @@ -270,7 +271,7 @@ class _PickupLocationState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getHospitalName('Pickup Location')), + Texts(getHospitalName(TranslationBase.of(context).pickupLocation)), Icon( Icons.arrow_drop_down, size: 24, @@ -286,7 +287,7 @@ class _PickupLocationState extends State { Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Pickup Location'), + Texts(TranslationBase.of(context).pickupLocation), SizedBox( height: 15, ), @@ -306,7 +307,7 @@ class _PickupLocationState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getHospitalName('Pickup Location')), + Texts(getHospitalName(TranslationBase.of(context).pickupLocation)), Icon( Icons.arrow_drop_down, size: 24, @@ -319,7 +320,7 @@ class _PickupLocationState extends State { SizedBox( height: 12, ), - Texts('Drop off Location'), + Texts(TranslationBase.of(context).dropoffLocation), SizedBox( height: 8, ), @@ -351,7 +352,7 @@ class _PickupLocationState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Texts(getSelectFromMapName()), + Texts(getSelectFromMapName(context)), Icon( FontAwesomeIcons.mapMarkerAlt, size: 24, @@ -377,7 +378,7 @@ class _PickupLocationState extends State { onTap: () { if (_result == null || _selectedHospital == null) AppToast.showErrorToast( - message: 'please select all fields'); + message: TranslationBase.of(context).selectAll); else setState(() { widget.patientER.pickupSpot = _isInsideHome ? 1 : 0; @@ -427,7 +428,7 @@ class _PickupLocationState extends State { widget.changeCurrentTab(2); }); }, - label: 'Next', + label: TranslationBase.of(context).next, ), ) ], @@ -455,8 +456,8 @@ 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() { @@ -494,7 +495,7 @@ class _PickupLocationState extends State { 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); diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart index 01683b55..69669ed3 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/SelectTransportationMethod.dart @@ -5,6 +5,7 @@ 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/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'; @@ -67,7 +68,7 @@ class _SelectTransportationMethodState SizedBox( height: 12, ), - Texts('Select Transportation Method'), + Texts(TranslationBase.of(context).transportHeading), ...List.generate( widget.amRequestViewModel.amRequestModeList.length, (index) => InkWell( @@ -108,7 +109,7 @@ class _SelectTransportationMethodState Expanded( flex: 1, child: Texts( - 'SR ${widget.amRequestViewModel.amRequestModeList[index].price}'), + TranslationBase.of(context).sar+' ${widget.amRequestViewModel.amRequestModeList[index].price}'), ) ], ), @@ -118,7 +119,7 @@ class _SelectTransportationMethodState SizedBox( height: 12, ), - Texts('Select Direction'), + Texts(TranslationBase.of(context).directionHeading), SizedBox( height: 5, ), @@ -144,7 +145,7 @@ class _SelectTransportationMethodState color: Colors.white, ), child: ListTile( - title: Text('To Hospital'), + title: Text(TranslationBase.of(context).toHospital), leading: Radio( value: Direction.ToHospital, groupValue: _direction, @@ -175,7 +176,7 @@ class _SelectTransportationMethodState color: Colors.white, ), child: ListTile( - title: Text('Form Hospital'), + title: Text(TranslationBase.of(context).fromHospital), leading: Radio( value: Direction.FromHospital, groupValue: _direction, @@ -200,7 +201,7 @@ class _SelectTransportationMethodState SizedBox( height: 8, ), - Texts('Select Direction'), + Texts(TranslationBase.of(context).directionHeading), SizedBox( height: 5, ), @@ -222,7 +223,7 @@ class _SelectTransportationMethodState color: Colors.white, ), child: ListTile( - title: Text('One Way'), + title: Text(TranslationBase.of(context).oneDirec), leading: Radio( value: Way.OneWay, groupValue: _way, @@ -253,7 +254,7 @@ class _SelectTransportationMethodState color: Colors.white, ), child: ListTile( - title: Text('Two Ways'), + title: Text(TranslationBase.of(context).twoDirec), leading: Radio( value: Way.TwoWays, groupValue: _way, @@ -298,7 +299,7 @@ class _SelectTransportationMethodState widget.changeCurrentTab(1); }); }, - label: 'Next', + label: TranslationBase.of(context).next, ), ) ], diff --git a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart index 7696dd09..8fd72b8f 100644 --- a/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart +++ b/lib/pages/ErService/AmbulanceRequestIndexPages/Summary.dart @@ -1,5 +1,6 @@ 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:flutter/cupertino.dart'; @@ -27,7 +28,7 @@ class _SummaryState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Summary'), + Texts(TranslationBase.of(context).RRTSummary), SizedBox(height: 5,), Container( width: double.infinity, @@ -39,11 +40,11 @@ class _SummaryState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Texts('Transportation Method',color: Colors.grey,), + Texts(TranslationBase.of(context).transportMethod,color: Colors.grey,), Texts('${widget.patientER.patientERTransportationMethod.title}',bold: true,), SizedBox(height: 8,), - Texts('Direction',color: Colors.grey,), + Texts(TranslationBase.of(context).directions,color: Colors.grey,), Texts('From Hospital',bold: true,), SizedBox(height: 8,), @@ -92,7 +93,7 @@ class _SummaryState extends State { child:SecondaryButton( color: Colors.grey[800], textColor: Colors.white, - label: 'Send', + label: TranslationBase.of(context).send, onTap: () async { await widget.amRequestViewModel.insertERPressOrder(patientER: widget.patientER); diff --git a/lib/pages/feedback/feedback_home_page.dart b/lib/pages/feedback/feedback_home_page.dart index fe22b44a..f7f998bf 100644 --- a/lib/pages/feedback/feedback_home_page.dart +++ b/lib/pages/feedback/feedback_home_page.dart @@ -74,7 +74,6 @@ class _FeedbackHomePageState extends State controller: _tabController, indicatorWeight: 5.0, indicatorSize: TabBarIndicatorSize.tab, - indicatorColor: Colors.red[800], labelColor: Theme.of(context).primaryColor, labelPadding: EdgeInsets.only(top: 4.0, left: 18.0, right: 18.0), 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/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index f49c5d34..cb08bd17 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -1042,7 +1042,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]; @@ -1248,6 +1248,8 @@ class TranslationBase { 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]; } diff --git a/lib/widgets/input/text_field.dart b/lib/widgets/input/text_field.dart index 6e740fc8..55ebbc3d 100644 --- a/lib/widgets/input/text_field.dart +++ b/lib/widgets/input/text_field.dart @@ -46,8 +46,7 @@ class TextFields extends StatefulWidget { this.suffixIcon, this.autoFocus, this.onChanged, - - // this.initialValue, + this.initialValue, this.minLines, this.maxLines, this.inputFormatters, @@ -78,8 +77,7 @@ class TextFields extends StatefulWidget { : super(key: key); final String hintText; - - // final String initialValue; + final String initialValue; final String type; final bool autoFocus; final IconData suffixIcon; @@ -230,7 +228,7 @@ class _TextFieldsState extends State { minLines: widget.minLines ?? 1, maxLines: widget.maxLines ?? 1, maxLengthEnforced: widget.maxLengthEnforced, - // initialValue: widget.initialValue, + initialValue: widget.initialValue, onChanged: widget.onChanged, focusNode: _focusNode, maxLength: widget.maxLength ?? null, From f5d478fd27233d7cc996182dc4cb4edea39ae5dc Mon Sep 17 00:00:00 2001 From: mosazaid Date: Mon, 18 Jan 2021 17:55:49 +0200 Subject: [PATCH 19/20] re-design child vaccine and fix some funcrionalities --- lib/config/localized_values.dart | 34 ++ .../vaccination_table_service.dart | 15 +- .../vaccination_table_view_model.dart | 9 +- .../all_habib_medical_service_page.dart | 20 +- .../ChildVaccines/add_newchild_page.dart | 122 +++--- lib/pages/ChildVaccines/child_page.dart | 168 ++++---- .../ChildVaccines/child_vaccines_page.dart | 372 +++++++++--------- .../dialogs/SelectGenderDialog.dart | 16 +- .../ChildVaccines/vaccinationtable_page.dart | 217 ++++++---- .../vital_sing_chart_and_detials.dart | 1 + lib/uitl/date_uitl.dart | 2 +- lib/uitl/translations_delegate_base.dart | 15 +- 12 files changed, 563 insertions(+), 428 deletions(-) diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 6245735d..596bb086 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -242,6 +242,10 @@ const Map localizedValues = { "en": "Email Sent Successfully", "ar": "تم إرسال البريد الإلكتروني بنجاح" }, + "EmailSentError": { + "en": "Error Sending Email", + "ar": "خطأ في إرسال البريد الإلكتروني" + }, "close": {"en": "Close", "ar": "مغلق"}, "booked": {"en": "Booked", "ar": "محجوز"}, "confirmed": {"en": "Confirmed", "ar": "مؤكد"}, @@ -1218,6 +1222,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.", @@ -1465,4 +1473,30 @@ const Map localizedValues = { "en": "Nearest ER", "ar": "أقرب ER" }, + "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": "إضافة طفل جديد"}, + "visit": {"en" : "Visit", "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": "تمت إضافة الطفل بنجاح"}, + }; 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/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/pages/AlHabibMedicalService/all_habib_medical_service_page.dart b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart index 1359ab8d..3c3c18c1 100644 --- a/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart +++ b/lib/pages/AlHabibMedicalService/all_habib_medical_service_page.dart @@ -203,7 +203,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 +227,7 @@ class _AllHabibMedicalServiceState extends State { ), ), imageLocation: 'assets/images/pharmacy_logo.png', - title: 'Pharmacy'), + title: TranslationBase.of(context).pharmacy), ServicesContainer( onTap: () => Navigator.push( context, @@ -248,7 +248,7 @@ class _AllHabibMedicalServiceState extends State { : EReferralPage()), ), imageLocation: 'assets/images/ereferral_service_icon.png', - title: 'E-Referral', + title: TranslationBase.of(context).ereferral, ), ServicesContainer( onTap: () => Navigator.push( @@ -259,7 +259,7 @@ 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( @@ -269,7 +269,7 @@ class _AllHabibMedicalServiceState extends State { ), imageLocation: 'assets/images/new-design/children_vaccines_icon.png', - title: 'Child Vaccines', + title: TranslationBase.of(context).childVaccine, ), ServicesContainer( onTap: () => Navigator.push( @@ -289,7 +289,7 @@ class _AllHabibMedicalServiceState extends State { FadePage(page: SymptomInfo()), ), imageLocation: 'assets/images/new-design/body_icon.png', - title: 'Symptom Checker'), + title: TranslationBase.of(context).symptomCheckerTitle), if(projectViewModel.havePrivilege(36)) ServicesContainer( onTap: () => Navigator.push( @@ -297,7 +297,7 @@ class _AllHabibMedicalServiceState extends State { FadePage(page: BloodDonationPage()), ), imageLocation: 'assets/images/new-design/blood_icon.png', - title: 'Blood Donation', + title: TranslationBase.of(context).bloodD, ), ServicesContainer( onTap: () => Navigator.push( @@ -308,7 +308,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,7 +319,7 @@ 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( @@ -370,7 +370,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/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..ae33cc03 100644 --- a/lib/pages/ChildVaccines/child_page.dart +++ b/lib/pages/ChildVaccines/child_page.dart @@ -5,6 +5,7 @@ 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/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'; @@ -22,30 +23,51 @@ 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 +76,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 +119,14 @@ 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,73 +146,71 @@ 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, - width: double.infinity, - padding: EdgeInsets.all(15), - child: SecondaryButton( - textColor: Colors.white, - color: checkedValue == false - ? Colors.white24 - : Color.fromRGBO( - 63, - 72, - 74, - 1, - ), - label: "ADD NEW CHILD ", - // - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => AddNewChildPage(), - ), - ).then((value) { - if (value) model.getNewUserOrders(); - }); - }, - ), + bottomSheet: Container( + height: height * 0.15, + width: double.infinity, + padding: EdgeInsets.all(16), + child: SecondaryButton( + textColor: Colors.white, + color: checkedValue == false + ? Colors.white24 + : Color.fromRGBO( + 63, + 72, + 74, + 1, ), + label: TranslationBase.of(context).addNewChild, + // + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => 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/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/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/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 257ceb8e..fe0b6bc3 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -581,6 +581,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 => @@ -1172,6 +1174,7 @@ class TranslationBase { 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 recordDeleted => localizedValues['recordDeleted'][locale.languageCode]; String get referralStatus => localizedValues['referralStatus'][locale.languageCode]; @@ -1214,7 +1217,6 @@ class TranslationBase { 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]; @@ -1247,7 +1249,16 @@ class TranslationBase { String get driveThru => localizedValues['driveThru'][locale.languageCode]; String get NearestErDesc => localizedValues['NearestErDesc'][locale.languageCode]; String get NearestEr => localizedValues['NearestEr'][locale.languageCode]; - + String get covid19_driveThrueTest => localizedValues['covid19_driveThrueTest'][locale.languageCode]; + String get eReferral => localizedValues['E-Referral'][locale.languageCode]; + String get vaccination => localizedValues["vaccination"][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 childName => localizedValues["childName"][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]; } From bbd953ae43cf5c49d3ec8df0e370d10ae653c1cf Mon Sep 17 00:00:00 2001 From: Zohaib Iqbal Kambrani <> Date: Tue, 19 Jan 2021 11:41:55 +0300 Subject: [PATCH 20/20] Order Delivery Driver tracking [inprogress] --- .../map_markers/destination_map_marker.png | Bin 0 -> 4974 bytes assets/images/map_markers/driver-pin.png | Bin 0 -> 13918 bytes .../images/map_markers/source_map_marker.png | Bin 0 -> 5311 bytes lib/config/config.dart | 4 +- lib/config/localized_values.dart | 5 + lib/core/model/pharmacies/order_model.dart | 28 ++- lib/pages/pharmacy/order/Order.dart | 17 +- lib/pages/pharmacy/order/OrderDetails.dart | 177 ++++++++------- lib/pages/pharmacy/order/TrackDriver.dart | 211 ++++++++++++++++++ lib/uitl/translations_delegate_base.dart | 1 + pubspec.yaml | 4 +- 11 files changed, 356 insertions(+), 91 deletions(-) create mode 100644 assets/images/map_markers/destination_map_marker.png create mode 100644 assets/images/map_markers/driver-pin.png create mode 100644 assets/images/map_markers/source_map_marker.png create mode 100644 lib/pages/pharmacy/order/TrackDriver.dart 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 0000000000000000000000000000000000000000..4f4eca3531d475b04944fc5341f98cd910e313eb GIT binary patch literal 4974 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 literal 0 HcmV?d00001 diff --git a/assets/images/map_markers/driver-pin.png b/assets/images/map_markers/driver-pin.png new file mode 100644 index 0000000000000000000000000000000000000000..9d16ceca4edf852f6c6e969dce7a63342a332073 GIT binary patch literal 13918 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 X{s0vkKK?KU0ihtHD%~h)9`^qMzf|}` literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4b493b097b087a641bfbadb013f4a59935c7f394 GIT binary patch literal 5311 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 R8VCRY002ovPDHLkV1k@%_;3IK literal 0 HcmV?d00001 diff --git a/lib/config/config.dart b/lib/config/config.dart index 4315f13c..795da85b 100644 --- a/lib/config/config.dart +++ b/lib/config/config.dart @@ -12,8 +12,8 @@ const EXA_CART_API_BASE_URL = 'https://mdlaboratories.com/exacartapi'; const PACKAGES_CATEGORIES = '/api/categories'; const PACKAGES_PRODUCTS = '/api/products'; -// const BASE_URL = 'https://uat.hmgwebservices.com/'; -const BASE_URL = 'https://hmgwebservices.com/'; +const BASE_URL = 'https://uat.hmgwebservices.com/'; +// const BASE_URL = 'https://hmgwebservices.com/'; //const BASE_PHARMACY_URL = 'http://swd-pharapp-01:7200/api/'; const BASE_PHARMACY_URL = 'https://uat.hmgwebservices.com/epharmacy/api/'; diff --git a/lib/config/localized_values.dart b/lib/config/localized_values.dart index 387dbcb1..b103825c 100644 --- a/lib/config/localized_values.dart +++ b/lib/config/localized_values.dart @@ -1449,4 +1449,9 @@ const Map localizedValues = { "en": "View List of Children", "ar": "عرض قائمة الأطفال" }, + + "trackDeliveryDriver": { + "en": "Track Delivery Driver", + "ar": "trackDeliveryDriver" + }, }; diff --git a/lib/core/model/pharmacies/order_model.dart b/lib/core/model/pharmacies/order_model.dart index 027d1f81..c0a12caa 100644 --- a/lib/core/model/pharmacies/order_model.dart +++ b/lib/core/model/pharmacies/order_model.dart @@ -2,6 +2,7 @@ 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))); @@ -306,7 +307,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 +342,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 +363,7 @@ class IngAddress { "customer_attributes": customerAttributes, "created_on_utc": createdOnUtc.toIso8601String(), "province": province, - "lat_long": latLongValues.reverse[latLong], + "lat_long": latLong, }; } @@ -491,9 +507,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)), ); diff --git a/lib/pages/pharmacy/order/Order.dart b/lib/pages/pharmacy/order/Order.dart index 576bf2a0..5bb4ea42 100644 --- a/lib/pages/pharmacy/order/Order.dart +++ b/lib/pages/pharmacy/order/Order.dart @@ -924,6 +924,7 @@ class _OrderPageState extends State with SingleTickerProviderStateMix } 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){ @@ -1136,13 +1137,17 @@ class _OrderPageState extends State with SingleTickerProviderStateMix ), ), ); - } + int test = Test()["1"]; + } } - - - - - +class Test{ + static const values = { + "1":1, + "2":2, + "3":3 + }; + int operator [](String key) => values[key]; +} \ No newline at end of file diff --git a/lib/pages/pharmacy/order/OrderDetails.dart b/lib/pages/pharmacy/order/OrderDetails.dart index 5438663d..d5d064a7 100644 --- a/lib/pages/pharmacy/order/OrderDetails.dart +++ b/lib/pages/pharmacy/order/OrderDetails.dart @@ -1,6 +1,7 @@ import 'package:diplomaticquarterapp/core/viewModels/pharmacyModule/order_model_view_model.dart'; import 'package:diplomaticquarterapp/pages/base/base_view.dart'; import 'package:diplomaticquarterapp/pages/pharmacy/order/Order.dart'; +import 'package:diplomaticquarterapp/pages/pharmacy/order/TrackDriver.dart'; import 'package:diplomaticquarterapp/widgets/data_display/text.dart'; import 'package:diplomaticquarterapp/widgets/dialogs/confirm_dialog.dart'; import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; @@ -46,6 +47,7 @@ class _OrderDetailsPageState extends State { var model; var isCancel = false; var isRefund = false; + var isActiveDelivery = true; var dataIsCancel; var dataIsRefund; @@ -105,9 +107,9 @@ class _OrderDetailsPageState extends State { color: getStatusBackgroundColor(), borderRadius: BorderRadius.circular(30.0)), child: Text( - languageID == "ar" - ? widget.orderModel.orderStatusn.toString(): - widget.orderModel.orderStatus.toString().substring(12) , + languageID == "ar" + ? widget.orderModel.orderStatusn.toString(): + widget.orderModel.orderStatus.toString().substring(12) , // TranslationBase.of(context).delivered, style: TextStyle( color: Colors.white, @@ -125,8 +127,8 @@ class _OrderDetailsPageState extends State { children: [ Text( widget.orderModel.shippingAddress.firstName - .toString() - .substring(10) + + .toString() + .substring(10) + ' ' + widget.orderModel.shippingAddress.lastName .toString() @@ -141,18 +143,18 @@ class _OrderDetailsPageState extends State { 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, - ), - ),] + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.orderModel.shippingAddress.address1 + .toString() + .substring(9), + style: TextStyle( + fontSize: 10.0, + fontWeight: FontWeight.bold, + color: Colors.grey, + ), + ),] ), ), Container( @@ -162,8 +164,8 @@ class _OrderDetailsPageState extends State { children: [ Text( widget.orderModel.shippingAddress.address2 - .toString() - .substring(9) + + .toString() + .substring(9) + ' ' + widget.orderModel.shippingAddress.country .toString() + @@ -231,7 +233,7 @@ class _OrderDetailsPageState extends State { Container( child: flutterImage.Image.asset( widget.orderModel.shippingRateComputationMethodSystemName != - "Shipping.Aramex" + "Shipping.Aramex" ? "assets/images/pharmacy_module/payment/LogoParmacyGreen.png" : "assets/images/pharmacy_module/payment/aramex_shipping_logo.png", fit: BoxFit.contain, @@ -320,19 +322,19 @@ class _OrderDetailsPageState extends State { 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, + 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, ), @@ -510,58 +512,81 @@ class _OrderDetailsPageState extends State { ), widget.orderModel.orderStatusId == 10 ? InkWell( - onTap: () { - model.makeOrder(); - }, - child: Container( + onTap: () { + model.makeOrder(); + }, + 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(), // getCancelOrder(canCancel, canRefund), isCancel ? InkWell( - onTap: () { - presentConfirmDialog(model, - widget.orderModel.id); //(widget.orderModel.id)); + onTap: () { + presentConfirmDialog(model, + widget.orderModel.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), - ), - ), - ), - ) + 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(), ], ), diff --git a/lib/pages/pharmacy/order/TrackDriver.dart b/lib/pages/pharmacy/order/TrackDriver.dart new file mode 100644 index 00000000..b9a8056f --- /dev/null +++ b/lib/pages/pharmacy/order/TrackDriver.dart @@ -0,0 +1,211 @@ +import 'dart:async'; + +import 'package:diplomaticquarterapp/config/config.dart'; +import 'package:diplomaticquarterapp/core/model/pharmacies/order_model.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_polyline_points/flutter_polyline_points.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:location/location.dart'; + + +class TrackDriver extends StatefulWidget { + final OrderModel order; + TrackDriver({this.order}); + + @override + State createState() => _TrackDriverState(); +} + +class _TrackDriverState extends State { + OrderModel _order; + + Completer _controller = Completer(); + + + double CAMERA_ZOOM = 16; + 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 + + @override + void initState() { + _order = widget.order; + DEST_LOCATION = _order.shippingAddress.getLocation(); + location = new Location(); + polylinePoints = PolylinePoints(); + setSourceAndDestinationIcons(); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + body: GoogleMap( + myLocationEnabled: true, + compassEnabled: true, + markers: _markers, + polylines: _polylines, + mapType: MapType.normal, + initialCameraPosition: _orderDeliveryLocationCamera(), + 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 { + sourceIcon = await BitmapDescriptor.fromAssetImage( + ImageConfiguration(devicePixelRatio: 2.5), + 'assets/images/map_markers/source_map_marker.png'); + + destinationIcon = await BitmapDescriptor.fromAssetImage( + ImageConfiguration(devicePixelRatio: 2.5), + 'assets/images/map_markers/destination_map_marker.png'); + } + + CameraPosition _orderDeliveryLocationCamera(){ + + final CameraPosition orderDeliveryLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: DEST_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return orderDeliveryLocCamera; + } + + CameraPosition _driverLocationCamera(){ + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + return driverLocCamera; + } + + + 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)); + } + + + Future _fitCameraBetweenBothPoints() async { + final GoogleMapController controller = await _controller.future; + final CameraPosition driverLocCamera = CameraPosition( + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + tilt: CAMERA_TILT, + zoom: CAMERA_ZOOM); + controller.animateCamera(CameraUpdate.newCameraPosition(driverLocCamera)); + } + + void showPinsOnMap() { + // source pin + if(SOURCE_LOCATION != null){ + setState(() { + var pinPosition = SOURCE_LOCATION; + _markers.add(Marker( + markerId: MarkerId('sourcePin'), + position: pinPosition, + icon: sourceIcon + )); + }); + } + + // destination pin + if(DEST_LOCATION != null){ + setState(() { + var destPosition = DEST_LOCATION; + _markers.add(Marker( + markerId: MarkerId('destPin'), + position: destPosition, + icon: destinationIcon + )); + }); + } + // set the route lines on the map from source to destination + // for more info follow this tutorial + // drawRoute(); + } + + void updatePinOnMap() async { + // create a new CameraPosition instance + // every time the location changes, so the camera + // follows the pin as it moves with an animation + CameraPosition cPosition = CameraPosition( + zoom: CAMERA_ZOOM, + tilt: CAMERA_TILT, + bearing: CAMERA_BEARING, + target: SOURCE_LOCATION, + ); + final GoogleMapController controller = await _controller.future; + controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); + // do this inside the setState() so Flutter gets notified + // that a widget update is due + setState(() { + // updated position + var pinPosition = SOURCE_LOCATION; + + // the trick is to remove the marker (by id) + // and add it again at the updated location + _markers.removeWhere((m) => m.markerId.value == 'sourcePin'); + _markers.add(Marker( + markerId: MarkerId('sourcePin'), + position: pinPosition, // updated position + icon: sourceIcon + )); + }); + } + + 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 + )); + }); + } + } +} \ No newline at end of file diff --git a/lib/uitl/translations_delegate_base.dart b/lib/uitl/translations_delegate_base.dart index 63cf8a44..954af3b9 100644 --- a/lib/uitl/translations_delegate_base.dart +++ b/lib/uitl/translations_delegate_base.dart @@ -550,6 +550,7 @@ 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]; diff --git a/pubspec.yaml b/pubspec.yaml index 785e831d..24589cbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -82,7 +82,8 @@ dependencies: google_maps_flutter: ^1.0.3 - + flutter_polyline_points: ^0.1.0 + location: ^2.3.5 # Qr code Scanner barcode_scan_fix: ^1.0.2 @@ -183,6 +184,7 @@ flutter: # assets: assets: - assets/images/ + - assets/images/map_markers/ - assets/images/pharmacy/ - assets/images/medical/ - assets/images/new-design/